Modified: trunk/Tools/ChangeLog (284978 => 284979)
--- trunk/Tools/ChangeLog 2021-10-28 15:18:17 UTC (rev 284978)
+++ trunk/Tools/ChangeLog 2021-10-28 15:30:07 UTC (rev 284979)
@@ -1,3 +1,29 @@
+2021-10-28 Simon Fraser <simon.fra...@apple.com>
+
+ Enhance test_parser.py to find fuzzy matching metadata
+ https://bugs.webkit.org/show_bug.cgi?id=232399
+
+ Reviewed by Martin Robinson.
+
+ w3c/test_parser is used by wpt import code, and it knows how to parse a file for various
+ meta tags. Enhance it to find <meta name=fuzzy> and return the data in test_info for future
+ use by layout tests, using code copied from wpt/tools/manifest/sourcefile.py.
+
+ Tested by new unit tests in test_parser_unittest.py
+
+ * Scripts/webkitpy/w3c/test_parser.py:
+ (TestParser.analyze_test):
+ (TestParser.has_fuzzy_metadata):
+ (TestParser):
+ (TestParser.fuzzy_metadata):
+ * Scripts/webkitpy/w3c/test_parser_unittest.py:
+ (_test_info_from_test_with_contents):
+ (test_simple_fuzzy_data):
+ (test_nameless_fuzzy_data):
+ (test_range_fuzzy_data):
+ (test_nameless_range_fuzzy_data):
+ (test_per_ref_fuzzy_data):
+
2021-10-28 David Kilzer <ddkil...@apple.com>
[Tools] Enable -Wformat=2 warnings
Modified: trunk/Tools/Scripts/webkitpy/w3c/test_parser.py (284978 => 284979)
--- trunk/Tools/Scripts/webkitpy/w3c/test_parser.py 2021-10-28 15:18:17 UTC (rev 284978)
+++ trunk/Tools/Scripts/webkitpy/w3c/test_parser.py 2021-10-28 15:30:07 UTC (rev 284979)
@@ -30,6 +30,8 @@
import logging
import re
+from collections import deque
+
from webkitpy.common.host import Host
from webkitpy.thirdparty.BeautifulSoup import BeautifulSoup as Parser
@@ -133,6 +135,9 @@
if test_info and self.is_slow_test():
test_info['slow'] = True
+ if test_info:
+ test_info['fuzzy'] = self.fuzzy_metadata()
+
return test_info
def reference_links_of_type(self, reftest_type):
@@ -164,6 +169,72 @@
def is_slow_test(self):
return any([match.name == 'meta' and match['name'] == 'timeout' for match in self.test_doc.findAll(content='long')])
+ def has_fuzzy_metadata(self):
+ return any([match['name'] == 'fuzzy' for match in self.test_doc.findAll('meta')])
+
+ def fuzzy_metadata(self):
+ fuzzy_nodes = self.test_doc.findAll('meta', attrs={"name": "fuzzy"})
+ if not fuzzy_nodes:
+ return None
+
+ args = [u"maxDifference", u"totalPixels"]
+ result = {}
+
+ # Taken from wpt/tools/manifest/sourcefile.py, and copied to avoid having webkitpy depend on wpt.
+ for node in fuzzy_nodes:
+ content = node['content']
+ key = None
+ # from parse_ref_keyed_meta; splits out the optional reference prefix.
+ parts = content.rsplit(u":", 1)
+ if len(parts) == 1:
+ fuzzy_data = parts[0]
+ else:
+ ref_file = parts[0]
+ key = ref_file
+ fuzzy_data = parts[1]
+
+ ranges = fuzzy_data.split(u";")
+ if len(ranges) != 2:
+ raise ValueError("Malformed fuzzy value %s" % value)
+
+ arg_values = {} # type: Dict[Text, List[int]]
+ positional_args = deque() # type: Deque[List[int]]
+
+ for range_str_value in ranges: # type: Text
+ name = None # type: Optional[Text]
+ if u"=" in range_str_value:
+ name, range_str_value = [part.strip() for part in range_str_value.split(u"=", 1)]
+ if name not in args:
+ raise ValueError("%s is not a valid fuzzy property" % name)
+ if arg_values.get(name):
+ raise ValueError("Got multiple values for argument %s" % name)
+
+ if u"-" in range_str_value:
+ range_min, range_max = range_str_value.split(u"-")
+ else:
+ range_min = range_str_value
+ range_max = range_str_value
+ try:
+ range_value = [int(x.strip()) for x in (range_min, range_max)]
+ except ValueError:
+ raise ValueError("Fuzzy value %s must be a range of integers" % range_str_value)
+
+ if name is None:
+ positional_args.append(range_value)
+ else:
+ arg_values[name] = range_value
+
+ result[key] = []
+ for arg_name in args:
+ if arg_values.get(arg_name):
+ arg_value = arg_values.pop(arg_name)
+ else:
+ arg_value = positional_args.popleft()
+ result[key].append(arg_value)
+ assert len(arg_values) == 0 and len(positional_args) == 0
+
+ return result
+
def potential_ref_filename(self):
parts = self.filesystem.splitext(self.filename)
return parts[0] + '-ref' + parts[1]
Property changes on: trunk/Tools/Scripts/webkitpy/w3c/test_parser.py
___________________________________________________________________
Modified: trunk/Tools/Scripts/webkitpy/w3c/test_parser_unittest.py (284978 => 284979)
--- trunk/Tools/Scripts/webkitpy/w3c/test_parser_unittest.py 2021-10-28 15:18:17 UTC (rev 284978)
+++ trunk/Tools/Scripts/webkitpy/w3c/test_parser_unittest.py 2021-10-28 15:30:07 UTC (rev 284979)
@@ -293,3 +293,78 @@
test_info = parser.analyze_test(test_contents=test_html)
self.assertTrue('referencefile' in test_info, 'test should be detected as reference file')
+
+ def _test_info_from_test_with_contents(self, test_contents):
+ test_path = os.path.join(os.path.sep, 'some', 'madeup', 'path')
+ parser = TestParser({'all': True}, os.path.join(test_path, 'test-fuzzy.html'))
+ return parser.analyze_test(test_contents=test_contents)
+
+ def test_simple_fuzzy_data(self):
+ """ Tests basic form of fuzzy_metadata()"""
+
+ test_html = """<html><head>
+<meta name=fuzzy content="maxDifference = 15 ; totalPixels = 300">
+</head>
+<body>CONTENT OF TEST</body></html>
+"""
+ test_info = self._test_info_from_test_with_contents(test_html)
+
+ expected_fuzzy = {None: [[15, 15], [300, 300]]}
+ self.assertEqual(test_info['fuzzy'], expected_fuzzy, 'fuzzy data did not match expected')
+
+ def test_nameless_fuzzy_data(self):
+ """ Tests fuzzy_metadata() in short form"""
+
+ test_html = """<html><head>
+<meta name=fuzzy content=" 15 ; 300 ">
+</head>
+<body>CONTENT OF TEST</body></html>
+"""
+ test_info = self._test_info_from_test_with_contents(test_html)
+ expected_fuzzy = {None: [[15, 15], [300, 300]]}
+ self.assertEqual(test_info['fuzzy'], expected_fuzzy, 'fuzzy data did not match expected')
+
+ def test_range_fuzzy_data(self):
+ """ Tests fuzzy_metadata() in range form"""
+
+ test_html = """<html><head>
+<meta name=fuzzy content="maxDifference=5-15;totalPixels = 200 - 300 ">
+</head>
+<body>CONTENT OF TEST</body></html>
+"""
+ test_info = self._test_info_from_test_with_contents(test_html)
+
+ expected_fuzzy = {None: [[5, 15], [200, 300]]}
+ self.assertEqual(test_info['fuzzy'], expected_fuzzy, 'fuzzy data did not match expected')
+
+ def test_nameless_range_fuzzy_data(self):
+ """ Tests fuzzy_metadata() in short range form"""
+
+ test_html = """<html><head>
+<meta name=fuzzy content="5-15; 200 - 300 ">
+</head>
+<body>CONTENT OF TEST</body></html>
+"""
+ test_info = self._test_info_from_test_with_contents(test_html)
+
+ expected_fuzzy = {None: [[5, 15], [200, 300]]}
+ self.assertEqual(test_info['fuzzy'], expected_fuzzy, 'fuzzy data did not match expected')
+
+ def test_per_ref_fuzzy_data(self):
+ """ Tests fuzzy_metadata() with values for difference reference files"""
+
+ test_html = """<html><head>
+<meta name=fuzzy content="5-15;200-300 ">
+<meta name=fuzzy content="close-match-ref.html:5;20">
+<meta name=fuzzy content="worse-match-ref.html: 15;30">
+</head>
+<body>CONTENT OF TEST</body></html>
+"""
+ test_info = self._test_info_from_test_with_contents(test_html)
+
+ expected_fuzzy = {
+ None: [[5, 15], [200, 300]],
+ 'close-match-ref.html': [[5, 5], [20, 20]],
+ 'worse-match-ref.html': [[15, 15], [30, 30]]
+ }
+ self.assertEqual(test_info['fuzzy'], expected_fuzzy, 'fuzzy data did not match expected')