Skip to content

Commit f98387d

Browse files
graveljpchromium-wpt-export-bot
authored andcommitted
Migrate 2d.canvas.host.size.attributes.* to the new canvas WPT generator
This test uses different types of newline characters, like \n, \r and \f. The `indent` Jinja filter used by the test template [1] was dropping all of these, replacing them with normal newlines. This looks like a bug in Jinja: the `indent` filter could easily be made to preserve newline types. This CL overrides the default `indent` filter with a version doing exactly that. [1]: https://crsrc.org/c/third_party/blink/web_tests/external/wpt/html/canvas/tools/templates/testharness_element.html;l=62;drc=44ada975c0f28bc2d30c780314081ec2bb97bbe5 Bug: 40207206 Change-Id: I5ece8e0ce4199bb0c915e59131c26eed4ce58693 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6172748 Commit-Queue: Jean-Philippe Gravel <[email protected]> Reviewed-by: Yi Xu <[email protected]> Cr-Commit-Position: refs/heads/main@{#1408116}
1 parent a806ea5 commit f98387d

File tree

4 files changed

+162
-111
lines changed

4 files changed

+162
-111
lines changed

html/canvas/tools/gentestutilsunion.py

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
# * Test the tests, add new ones to Git, remove deleted ones from Git, etc.
3131

3232
from typing import Any, DefaultDict, FrozenSet, List, Mapping, MutableMapping
33-
from typing import Set
33+
from typing import Set, Union
3434

3535
import re
3636
import collections
@@ -439,7 +439,7 @@ def finalize_params(self, jinja_env: jinja2.Environment,
439439
variant_id: int) -> None:
440440
"""Finalize this variant by adding computed param fields."""
441441
self._params['id'] = variant_id
442-
for param_name in ('name', 'desc', 'attributes'):
442+
for param_name in ('attributes', 'desc', 'expected', 'name'):
443443
self._render_param(jinja_env, param_name)
444444
self._params['file_name'] = self._get_file_name()
445445
self._params['canvas_types'] = self._get_canvas_types()
@@ -875,6 +875,29 @@ def _check_uniqueness(tested: DefaultDict[str, Set[_CanvasType]], name: str,
875875
tested[name].update(canvas_types)
876876

877877

878+
def _indent_filter(s: str, width: Union[int, str] = 4,
879+
first: bool = False, blank: bool = False) -> str:
880+
"""Returns a copy of the string with each line indented by the `width` str.
881+
882+
If `width` is a number, `s` is indented by that number of whitespaces. The
883+
first line and blank lines are not indented by default, unless `first` or
884+
`blank` are `True`, respectively.
885+
886+
This is a re-implementation of the default `indent` Jinja filter, preserving
887+
line ending characters (\r, \n, \f, etc.) The default `indent` Jinja filter
888+
incorrectly replaces all of these characters with newlines."""
889+
is_first_line = True
890+
def indent_needed(line):
891+
nonlocal first, blank, is_first_line
892+
is_blank = not line.strip()
893+
need_indent = (not is_first_line or first) and (not is_blank or blank)
894+
is_first_line = False
895+
return need_indent
896+
897+
indentation = width if isinstance(width, str) else ' ' * width
898+
return textwrap.indent(s, indentation, indent_needed)
899+
900+
878901
def generate_test_files(name_to_dir_file: str) -> None:
879902
"""Generate Canvas tests from YAML file definition."""
880903
output_dirs = _OutputPaths(element=pathlib.Path('..') / 'element',
@@ -887,6 +910,7 @@ def generate_test_files(name_to_dir_file: str) -> None:
887910
lstrip_blocks=True)
888911

889912
jinja_env.filters['double_quote_escape'] = _double_quote_escape
913+
jinja_env.filters['indent'] = _indent_filter
890914

891915
# Run with --test argument to run unit tests.
892916
if len(sys.argv) > 1 and sys.argv[1] == '--test':

html/canvas/tools/yaml-new/the-canvas.yaml

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,142 @@
2323
new_canvas: |-
2424
new OffscreenCanvas(100, 50)
2525
26+
- name: 2d.canvas.host.size.attributes
27+
canvas_types: ['HtmlCanvas']
28+
code: |
29+
{{ set_attributes -}}
30+
@assert canvas.width === {{ result_size[0] }};
31+
@assert canvas.height === {{ result_size[1] }};
32+
{% if result_size[0] != 300 %}
33+
{# With "100%", Opera gets canvas.width = 100 but renders at 100% of the
34+
frame width, so check the CSS display width -#}
35+
@assert window.getComputedStyle(canvas, null)\-
36+
.getPropertyValue("width") === "{{ result_size[0] }}px";
37+
{% endif -%}
38+
39+
{% set attrib_size = escaped_size or input_size %}
40+
@assert canvas.getAttribute('width') === '{{ attrib_size }}';
41+
@assert canvas.getAttribute('height') === '{{ attrib_size }}';
42+
expected: |
43+
{% if result_size[0] != 0 -%}
44+
size {{ result_size[0] }} {{ result_size[1] }}
45+
{% endif %}
46+
variants:
47+
- parse:
48+
desc: Parsing of non-negative integers
49+
size: ['{{ input_size }}', '{{ input_size }}']
50+
setAttribute:
51+
desc: Parsing of non-negative integers in setAttribute
52+
size: [ 50, 50 ]
53+
set_attributes: |
54+
canvas.setAttribute('width', '{{ escaped_size or input_size }}');
55+
canvas.setAttribute('height', '{{ escaped_size or input_size }}');
56+
- zero:
57+
input_size: '0'
58+
result_size: [0, 0]
59+
empty:
60+
input_size: ''
61+
result_size: [300, 150]
62+
onlyspace:
63+
input_size: ' '
64+
result_size: [300, 150]
65+
space:
66+
input_size: ' 100'
67+
result_size: [100, 100]
68+
whitespace:
69+
input_size: "&#xD;\n\t\x0c100"
70+
escaped_size: "\\r\\n\\t\\x0c100"
71+
result_size: [100, 100]
72+
plus:
73+
input_size: '+100'
74+
result_size: [100, 100]
75+
minus:
76+
input_size: '-100'
77+
result_size: [300, 150]
78+
octal:
79+
input_size: '0100'
80+
result_size: [100, 100]
81+
hex:
82+
input_size: '0x100'
83+
result_size: [0, 0]
84+
exp:
85+
input_size: '100e1'
86+
result_size: [100, 100]
87+
decimal:
88+
input_size: '100.999'
89+
result_size: [100, 100]
90+
percent:
91+
input_size: '100%'
92+
result_size: [100, 100]
93+
em:
94+
input_size: '100em'
95+
result_size: [100, 100]
96+
junk:
97+
input_size: '#!?'
98+
result_size: [300, 150]
99+
trailingjunk:
100+
input_size: '100#!?'
101+
result_size: [100, 100]
102+
103+
- name: 2d.canvas.host.size.attributes.parse
104+
desc: Parsing of non-negative integers
105+
canvas_types: ['OffscreenCanvas', 'Worker']
106+
code: |
107+
{% if result_size == 'exception' %}
108+
@assert throws TypeError canvas.width = '{{ input_size }}';
109+
{% else %}
110+
canvas.width = '{{ input_size }}';
111+
canvas.height = '{{ input_size }}';
112+
@assert canvas.width === {{ result_size }};
113+
@assert canvas.height === {{ result_size }};
114+
{% endif %}
115+
variants:
116+
- zero:
117+
input_size: '0'
118+
result_size: 0
119+
empty:
120+
input_size: ''
121+
result_size: 0
122+
onlyspace:
123+
input_size: ' '
124+
result_size: 0
125+
space:
126+
input_size: ' 100'
127+
result_size: 100
128+
whitespace:
129+
input_size: "\t\f100"
130+
result_size: 100
131+
plus:
132+
input_size: '+100'
133+
result_size: 100
134+
minus:
135+
input_size: '-100'
136+
result_size: 'exception'
137+
octal:
138+
input_size: '0100'
139+
result_size: 100
140+
hex:
141+
input_size: '0x100'
142+
result_size: 0x100
143+
exp:
144+
input_size: '100e1'
145+
result_size: 1000.0
146+
decimal:
147+
input_size: '100.999'
148+
result_size: 100
149+
percent:
150+
input_size: '100%'
151+
result_size: 'exception'
152+
em:
153+
input_size: '100em'
154+
result_size: 'exception'
155+
junk:
156+
input_size: '#!?'
157+
result_size: 'exception'
158+
trailingjunk:
159+
input_size: '100#!?'
160+
result_size: 'exception'
161+
26162
- name: 2d.canvas.host.type.delete
27163
canvas_types: ['HtmlCanvas']
28164
desc: window.HTMLCanvasElement interface object is [[Configurable]]

html/canvas/tools/yaml/element/meta.yaml

Lines changed: 0 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,3 @@
1-
- meta: |
2-
cases = [
3-
("zero", "0", 0),
4-
("empty", "", None),
5-
("onlyspace", " ", None),
6-
("space", " 100", 100),
7-
("whitespace", "\r\n\t\f100", 100),
8-
("plus", "+100", 100),
9-
("minus", "-100", None),
10-
("octal", "0100", 100),
11-
("hex", "0x100", 0),
12-
("exp", "100e1", 100),
13-
("decimal", "100.999", 100),
14-
("percent", "100%", 100),
15-
("em", "100em", 100),
16-
("junk", "#!?", None),
17-
("trailingjunk", "100#!?", 100),
18-
]
19-
def gen(name, string, exp, code):
20-
if exp is None:
21-
code += "@assert canvas.width === 300;\n@assert canvas.height === 150;\n"
22-
expected = "size 300 150"
23-
else:
24-
code += "@assert canvas.width === %s;\n@assert canvas.height === %s;\n" % (exp, exp)
25-
expected = "size %s %s" % (exp, exp)
26-
27-
# With "100%", Opera gets canvas.width = 100 but renders at 100% of the frame width,
28-
# so check the CSS display width
29-
code += '@assert window.getComputedStyle(canvas, null).getPropertyValue("width") === "%spx";\n' % (exp, )
30-
31-
code += "@assert canvas.getAttribute('width') === %r;\n" % string
32-
code += "@assert canvas.getAttribute('height') === %r;\n" % string
33-
34-
if exp == 0:
35-
expected = None # can't generate zero-sized PNGs for the expected image
36-
37-
return code, expected
38-
39-
for name, string, exp in cases:
40-
code = ""
41-
code, expected = gen(name, string, exp, code)
42-
# We need to replace \r with &#xD; because \r\n gets converted to \n in the HTML parser.
43-
htmlString = string.replace('\r', '&#xD;')
44-
tests.append( {
45-
"name": "2d.canvas.host.size.attributes.parse.%s" % name,
46-
"desc": "Parsing of non-negative integers",
47-
"size": '%s, %s' % (htmlString, htmlString),
48-
"code": code,
49-
"expected": expected
50-
} )
51-
52-
for name, string, exp in cases:
53-
code = "canvas.setAttribute('width', %r);\ncanvas.setAttribute('height', %r);\n" % (string, string)
54-
code, expected = gen(name, string, exp, code)
55-
tests.append( {
56-
"name": "2d.canvas.host.size.attributes.setAttribute.%s" % name,
57-
"desc": "Parsing of non-negative integers in setAttribute",
58-
"size": '50, 50',
59-
"code": code,
60-
"expected": expected
61-
} )
62-
631
- meta: |
642
# Composite operation tests
653
# <http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2007-March/010608.html>

html/canvas/tools/yaml/offscreen/meta.yaml

Lines changed: 0 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -429,50 +429,3 @@
429429
""" % (string,),
430430
}
431431
tests.append(test)
432-
433-
- meta: |
434-
cases = [
435-
("zero", "0", 0),
436-
("empty", "", 0),
437-
("onlyspace", " ", 0),
438-
("space", " 100", 100),
439-
("whitespace", "\t\f100", 100),
440-
("plus", "+100", 100),
441-
("minus", "-100", "exception"),
442-
("octal", "0100", 100),
443-
("hex", "0x100", 0x100),
444-
("exp", "100e1", 100e1),
445-
("decimal", "100.999", 100),
446-
("percent", "100%", "exception"),
447-
("em", "100em", "exception"),
448-
("junk", "#!?", "exception"),
449-
("trailingjunk", "100#!?", "exception"),
450-
]
451-
def gen(name, string, exp, code):
452-
if exp is None:
453-
code += "canvas.width = '%s';\ncanvas.height = '%s';\n" % (string, string)
454-
code += "@assert canvas.width === 100;\n@assert canvas.height === 50;\n"
455-
expected = None
456-
elif exp == "exception":
457-
code += "@assert throws TypeError canvas.width = '%s';\n" % string
458-
expected = None
459-
else:
460-
code += "canvas.width = '%s';\ncanvas.height = '%s';\n" % (string, string)
461-
code += "@assert canvas.width === %s;\n@assert canvas.height === %s;\n" % (exp, exp)
462-
expected = None
463-
464-
code += "t.done();\n"
465-
466-
if exp == 0:
467-
expected = None # can't generate zero-sized PNGs for the expected image
468-
469-
return code, expected
470-
471-
for name, string, exp in cases:
472-
code = ""
473-
code, expected = gen(name, string, exp, code)
474-
tests.append( {
475-
"name": "2d.canvas.host.size.attributes.parse.%s" % name,
476-
"desc": "Parsing of non-negative integers",
477-
"code": code,
478-
} )

0 commit comments

Comments
 (0)