summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/html/canvas/tools/gentestutilsunion.py
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/html/canvas/tools/gentestutilsunion.py')
-rw-r--r--testing/web-platform/tests/html/canvas/tools/gentestutilsunion.py213
1 files changed, 133 insertions, 80 deletions
diff --git a/testing/web-platform/tests/html/canvas/tools/gentestutilsunion.py b/testing/web-platform/tests/html/canvas/tools/gentestutilsunion.py
index cf141f2f07..d7042810be 100644
--- a/testing/web-platform/tests/html/canvas/tools/gentestutilsunion.py
+++ b/testing/web-platform/tests/html/canvas/tools/gentestutilsunion.py
@@ -28,7 +28,7 @@
#
# * Test the tests, add new ones to Git, remove deleted ones from Git, etc.
-from typing import Any, List, Mapping, Optional, Set, Tuple
+from typing import Any, DefaultDict, List, Mapping, Optional, Set, Tuple
import re
import collections
@@ -184,6 +184,10 @@ def _remove_extra_newlines(text: str) -> str:
return text
def _expand_test_code(code: str) -> str:
+ code = re.sub(r' @moz-todo', '', code)
+
+ code = re.sub(r'@moz-UniversalBrowserRead;', '', code)
+
code = _remove_extra_newlines(code)
# Unroll expressions with a cross-product-style parameter expansion.
@@ -202,11 +206,13 @@ def _expand_test_code(code: str) -> str:
code = re.sub(r'@assert pixel (\d+,\d+) ==~ (\d+,\d+,\d+,\d+) \+/- (\d+);',
r'_assertPixelApprox(canvas, \1, \2, \3);', code)
- code = re.sub(r'@assert throws (\S+_ERR) (.*);',
- r'assert_throws_dom("\1", function() { \2; });', code)
+ code = re.sub(r'@assert throws (\S+_ERR) (.*?);$',
+ r'assert_throws_dom("\1", function() { \2; });', code,
+ flags=re.MULTILINE | re.DOTALL)
- code = re.sub(r'@assert throws (\S+Error) (.*);',
- r'assert_throws_js(\1, function() { \2; });', code)
+ code = re.sub(r'@assert throws (\S+Error) (.*?);$',
+ r'assert_throws_js(\1, function() { \2; });', code,
+ flags=re.MULTILINE | re.DOTALL)
code = re.sub(
r'@assert (.*) === (.*);', lambda m: '_assertSame(%s, %s, "%s", "%s");'
@@ -226,10 +232,6 @@ def _expand_test_code(code: str) -> str:
r'@assert (.*);', lambda m: '_assert(%s, "%s");' % (m.group(
1), _escapeJS(m.group(1))), code)
- code = re.sub(r' @moz-todo', '', code)
-
- code = re.sub(r'@moz-UniversalBrowserRead;', '', code)
-
assert ('@' not in code)
return code
@@ -376,45 +378,50 @@ def _write_testharness_test(jinja_env: jinja2.Environment,
'utf-8')
+def _generate_expected_image(expected: str, name: str, sub_dir: str,
+ enabled_canvas_types: Set[CanvasType],
+ html_canvas_cfg: TestConfig,
+ offscreen_canvas_cfg: TestConfig) -> str:
+ """Creates a reference image using Cairo and returns the file location."""
+ if expected == 'green':
+ return '/images/green-100x50.png'
+ if expected == 'clear':
+ return '/images/clear-100x50.png'
+ if ';' in expected:
+ print('Found semicolon in %s' % name)
+ expected = re.sub(
+ r'^size (\d+) (\d+)',
+ r'surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, \1, \2)'
+ r'\ncr = cairo.Context(surface)', expected)
+
+ if CanvasType.HTML_CANVAS in enabled_canvas_types:
+ expected_canvas = (
+ expected + "\nsurface.write_to_png('%s.png')\n" %
+ os.path.join(html_canvas_cfg.image_out_dir, sub_dir, name))
+ eval(compile(expected_canvas, '<test %s>' % name, 'exec'), {},
+ {'cairo': cairo})
+
+ if {CanvasType.OFFSCREEN_CANVAS, CanvasType.WORKER} & enabled_canvas_types:
+ expected_offscreen = (
+ expected + "\nsurface.write_to_png('%s.png')\n" %
+ os.path.join(offscreen_canvas_cfg.image_out_dir, sub_dir, name))
+ eval(compile(expected_offscreen, '<test %s>' % name, 'exec'), {},
+ {'cairo': cairo})
+
+ return '%s.png' % name
+
+
def _generate_test(test: Mapping[str, Any], jinja_env: jinja2.Environment,
- sub_dir: str, enabled_tests: Set[CanvasType],
+ name_to_sub_dir: Mapping[str, str],
+ used_tests: DefaultDict[str, Set[CanvasType]],
html_canvas_cfg: TestConfig,
offscreen_canvas_cfg: TestConfig) -> None:
_validate_test(test)
name = test['name']
- expected_img = None
- if 'expected' in test and test['expected'] is not None:
- expected = test['expected']
- if expected == 'green':
- expected_img = '/images/green-100x50.png'
- elif expected == 'clear':
- expected_img = '/images/clear-100x50.png'
- else:
- if ';' in expected:
- print('Found semicolon in %s' % name)
- expected = re.sub(
- r'^size (\d+) (\d+)',
- r'surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, \1, \2)'
- r'\ncr = cairo.Context(surface)', expected)
-
- if CanvasType.HTML_CANVAS in enabled_tests:
- expected_canvas = (
- expected + "\nsurface.write_to_png('%s.png')\n" %
- os.path.join(html_canvas_cfg.image_out_dir, sub_dir, name))
- eval(compile(expected_canvas, '<test %s>' % name, 'exec'), {},
- {'cairo': cairo})
-
- if {CanvasType.OFFSCREEN_CANVAS, CanvasType.WORKER} & enabled_tests:
- expected_offscreen = (
- expected +
- "\nsurface.write_to_png('%s.png')\n" % os.path.join(
- offscreen_canvas_cfg.image_out_dir, sub_dir, name))
- eval(compile(expected_offscreen, '<test %s>' % name, 'exec'),
- {}, {'cairo': cairo})
-
- expected_img = '%s.png' % name
+ sub_dir = _get_test_sub_dir(name, name_to_sub_dir)
+ enabled_canvas_types = _get_enabled_canvas_types(test)
# Defaults:
params = {
@@ -423,11 +430,29 @@ def _generate_test(test: Mapping[str, Any], jinja_env: jinja2.Environment,
}
params.update(test)
+
+ # Render parameters used in the test name.
+ name = jinja_env.from_string(name).render(params)
+ print('\r(%s)' % name, ' ' * 32, '\t')
+
+ expected_img = None
+ if 'expected' in test and test['expected'] is not None:
+ expected_img = _generate_expected_image(test['expected'], name,
+ sub_dir, enabled_canvas_types,
+ html_canvas_cfg,
+ offscreen_canvas_cfg)
+
params.update({
'code': _expand_test_code(test['code']),
'expected_img': expected_img
})
+ already_tested = used_tests[name].intersection(enabled_canvas_types)
+ if already_tested:
+ raise InvalidTestDefinitionError(
+ f'Test {name} is defined twice for types {already_tested}')
+ used_tests[name].update(enabled_canvas_types)
+
canvas_path = os.path.join(html_canvas_cfg.out_dir, sub_dir, name)
offscreen_path = os.path.join(offscreen_canvas_cfg.out_dir, sub_dir, name)
if 'manual' in test:
@@ -435,11 +460,55 @@ def _generate_test(test: Mapping[str, Any], jinja_env: jinja2.Environment,
offscreen_path += '-manual'
if 'reference' in test or 'html_reference' in test:
- _write_reference_test(jinja_env, params, enabled_tests,
+ _write_reference_test(jinja_env, params, enabled_canvas_types,
canvas_path, offscreen_path)
else:
- _write_testharness_test(jinja_env, params, enabled_tests, canvas_path,
- offscreen_path)
+ _write_testharness_test(jinja_env, params, enabled_canvas_types,
+ canvas_path, offscreen_path)
+
+
+def _recursive_expand_variant_matrix(test_list: List[Mapping[str, Any]],
+ variant_matrix: List[Mapping[str, Any]],
+ current_selection: List[Tuple[str, Any]],
+ original_test: Mapping[str, Any]):
+ if len(current_selection) == len(variant_matrix):
+ # Selection for each variant is done, so add a new test to test_list.
+ test = original_test.copy()
+ variant_name_list = []
+ should_append_variant_names = original_test.get(
+ 'append_variants_to_name', True)
+ for variant_name, variant_params in current_selection:
+ variant_name_list.append(variant_name)
+ # Append variant name. Variant names starting with '_' are
+ # not appended, which is useful to create variants with the same
+ # name in different folders (element vs. offscreen).
+ if (should_append_variant_names
+ and not variant_name.startswith('_')):
+ test['name'] += '.' + variant_name
+ test.update(variant_params)
+ # Expose variant names as a list so they can be used from the yaml
+ # files, which helps with better naming of tests.
+ test.update({'variant_names': variant_name_list})
+ test_list.append(test)
+ else:
+ # Continue the recursion with each possible selection for the current
+ # variant.
+ variant = variant_matrix[len(current_selection)]
+ for variant_options in variant.items():
+ current_selection.append(variant_options)
+ _recursive_expand_variant_matrix(test_list, variant_matrix,
+ current_selection, original_test)
+ current_selection.pop()
+
+
+def _expand_variant_matrix(
+ variant_matrix: List[Mapping[str, Any]],
+ original_test: Mapping[str, Any]) -> List[Mapping[str, Any]]:
+ current_selection = []
+ matrix_tests = []
+ _recursive_expand_variant_matrix(matrix_tests, variant_matrix,
+ current_selection, original_test)
+ return matrix_tests
def genTestUtils_union(NAME2DIRFILE: str) -> None:
@@ -495,41 +564,25 @@ def genTestUtils_union(NAME2DIRFILE: str) -> None:
pass # Ignore if it already exists,
used_tests = collections.defaultdict(set)
- for original_test in tests:
- variants = original_test.get('variants', {'': dict()})
- for variant_name, variant_params in variants.items():
- test = original_test.copy()
- if variant_name or variant_params:
- # Append variant name. Variant names starting with '_' are
- # not appended, which is useful to create variants with the same
- # name in different folders (element vs. offscreen).
- if not variant_name.startswith('_'):
- test['name'] += '.' + variant_name
- test.update(variant_params)
-
- name = test['name']
- print('\r(%s)' % name, ' ' * 32, '\t')
-
- enabled_canvas_types = _get_enabled_canvas_types(test)
-
- already_tested = used_tests[name].intersection(
- enabled_canvas_types)
- if already_tested:
- raise InvalidTestDefinitionError(
- f'Test {name} is defined twice for types {already_tested}')
- used_tests[name].update(enabled_canvas_types)
-
- sub_dir = _get_test_sub_dir(name, name_to_sub_dir)
- _generate_test(
- test,
- jinja_env,
- sub_dir,
- enabled_canvas_types,
- html_canvas_cfg=TestConfig(
- out_dir=CANVASOUTPUTDIR,
- image_out_dir=CANVASIMAGEOUTPUTDIR),
- offscreen_canvas_cfg=TestConfig(
- out_dir=OFFSCREENCANVASOUTPUTDIR,
- image_out_dir=OFFSCREENCANVASIMAGEOUTPUTDIR))
+ for test in tests:
+ if 'variant_matrix' in test:
+ variants = _expand_variant_matrix(test['variant_matrix'], test)
+ elif 'variants' in test:
+ variant_matrix = [test['variants']]
+ variants = _expand_variant_matrix(variant_matrix, test)
+ else:
+ variants = [test]
+
+ for variant in variants:
+ _generate_test(variant,
+ jinja_env,
+ name_to_sub_dir,
+ used_tests,
+ html_canvas_cfg=TestConfig(
+ out_dir=CANVASOUTPUTDIR,
+ image_out_dir=CANVASIMAGEOUTPUTDIR),
+ offscreen_canvas_cfg=TestConfig(
+ out_dir=OFFSCREENCANVASOUTPUTDIR,
+ image_out_dir=OFFSCREENCANVASIMAGEOUTPUTDIR))
print()