1- name: 2d.canvas.reference
2  desc: canvas refers back to its canvas
3  testing:
4  - 2d.canvas
5  code: |
6    @assert ctx.canvas === canvas;
7    t.done();
8
9- name: 2d.canvas.readonly
10  desc: canvas is readonly
11  testing:
12  - 2d.canvas.attribute
13  code: |
14    var offscreenCanvas2 = new OffscreenCanvas(100, 50);
15    var d = ctx.canvas;
16    @assert offscreenCanvas2 !== d;
17    ctx.canvas = offscreenCanvas2;
18    @assert ctx.canvas === d;
19    t.done();
20
21- name: 2d.getcontext.exists
22  desc: The 2D context is implemented
23  testing:
24  - context.2d
25  code: |
26    var offscreenCanvas2 = new OffscreenCanvas(100, 50);
27    @assert offscreenCanvas2.getContext('2d') !== null;
28    t.done();
29
30- name: 2d.getcontext.extraargs.create
31  desc: The 2D context doesn't throw with extra getContext arguments (new context)
32  testing:
33  - context.2d.extraargs
34  code: |
35    @assert (new OffscreenCanvas(100, 50)).getContext('2d', false, {}, [], 1, "2") !== null;
36    @assert (new OffscreenCanvas(100, 50)).getContext('2d', 123) !== null;
37    @assert (new OffscreenCanvas(100, 50)).getContext('2d', "test") !== null;
38    @assert (new OffscreenCanvas(100, 50)).getContext('2d', undefined) !== null;
39    @assert (new OffscreenCanvas(100, 50)).getContext('2d', null) !== null;
40    @assert (new OffscreenCanvas(100, 50)).getContext('2d', Symbol.hasInstance) !== null;
41    t.done();
42
43- name: 2d.getcontext.extraargs.cache
44  desc: The 2D context doesn't throw with extra getContext arguments (cached)
45  testing:
46  - context.2d.extraargs
47  code: |
48    @assert canvas.getContext('2d', false, {}, [], 1, "2") !== null;
49    @assert canvas.getContext('2d', 123) !== null;
50    @assert canvas.getContext('2d', "test") !== null;
51    @assert canvas.getContext('2d', undefined) !== null;
52    @assert canvas.getContext('2d', null) !== null;
53    @assert canvas.getContext('2d', Symbol.hasInstance) !== null;
54    t.done();
55
56- name: 2d.getcontext.unique
57  desc: getContext('2d') returns the same object
58  testing:
59  - context.unique
60  code: |
61    var offscreenCanvas2 = new OffscreenCanvas(100, 50);
62    @assert offscreenCanvas2.getContext('2d') === offscreenCanvas2.getContext('2d');
63    t.done();
64
65- name: 2d.getcontext.shared
66  desc: getContext('2d') returns objects which share canvas state
67  testing:
68  - context.unique
69  code: |
70    var ctx2 = canvas.getContext('2d');
71    ctx.fillStyle = '#f00';
72    ctx2.fillStyle = '#0f0';
73    ctx.fillRect(0, 0, 100, 50);
74    @assert pixel 50,25 == 0,255,0,255;
75    t.done();
76
77- name: context.emptystring
78  desc: getContext with empty string returns null
79  testing:
80  - context.unrecognised
81  code: |
82    var offscreenCanvas2 = new OffscreenCanvas(100, 50);
83    @assert throws TypeError offscreenCanvas2.getContext("");
84    t.done();
85
86- name: context.unrecognised.badname
87  desc: getContext with unrecognised context name returns null
88  testing:
89  - context.unrecognised
90  code: |
91    var offscreenCanvas2 = new OffscreenCanvas(100, 50);
92    @assert throws TypeError offscreenCanvas2.getContext('This is not an implemented context in any real browser');
93    t.done();
94
95- name: context.unrecognised.badsuffix
96  desc: Context name "2d" plus a suffix is unrecognised
97  testing:
98  - context.unrecognised
99  code: |
100    var offscreenCanvas2 = new OffscreenCanvas(100, 50);
101    @assert throws TypeError offscreenCanvas2.getContext("2d#");
102    t.done();
103
104- name: context.unrecognised.nullsuffix
105  desc: Context name "2d" plus a "\0" suffix is unrecognised
106  testing:
107  - context.unrecognised
108  code: |
109    var offscreenCanvas2 = new OffscreenCanvas(100, 50);
110    @assert throws TypeError offscreenCanvas2.getContext("2d\0");
111    t.done();
112
113- name: context.unrecognised.unicode
114  desc: Context name which kind of looks like "2d" is unrecognised
115  testing:
116  - context.unrecognised
117  code: |
118    var offscreenCanvas2 = new OffscreenCanvas(100, 50);
119    @assert throws TypeError offscreenCanvas2.getContext("2\uFF44");
120    t.done();
121
122- name: context.casesensitive
123  desc: Context name "2D" is unrecognised; matching is case sensitive
124  testing:
125  - context.unrecognised
126  code: |
127    var offscreenCanvas2 = new OffscreenCanvas(100, 50);
128    @assert throws TypeError offscreenCanvas2.getContext('2D');
129    t.done();
130
131- name: context.arguments.missing
132  testing:
133  - canvas.getContext
134  code: |
135    var offscreenCanvas2 = new OffscreenCanvas(100, 50);
136    @assert throws TypeError offscreenCanvas2.getContext(); @moz-todo
137    t.done();
138
139
140- name: initial.colour
141  desc: Initial state is transparent black
142  testing:
143  - initial.colour
144  code: |
145    @assert pixel 20,20 == 0,0,0,0;
146    t.done();
147
148- name: initial.reset.different
149  desc: Changing size resets canvas to transparent black
150  testing:
151  - initial.reset
152  code: |
153    ctx.fillStyle = '#f00';
154    ctx.fillRect(0, 0, 50, 50);
155    @assert pixel 20,20 == 255,0,0,255;
156    canvas.width = 50;
157    @assert pixel 20,20 == 0,0,0,0;
158    t.done();
159
160- name: initial.reset.same
161  desc: Setting size (not changing the value) resets canvas to transparent black
162  testing:
163  - initial.reset
164  code: |
165    canvas.width = 100;
166    ctx.fillStyle = '#f00';
167    ctx.fillRect(0, 0, 50, 50);
168    @assert pixel 20,20 == 255,0,0,255;
169    canvas.width = 100;
170    @assert pixel 20,20 == 0,0,0,0;
171    t.done();
172
173- name: initial.reset.path
174  desc: Resetting the canvas state resets the current path
175  testing:
176  - initial.reset
177  code: |
178    canvas.width = 100;
179    ctx.rect(0, 0, 100, 50);
180    canvas.width = 100;
181    ctx.fillStyle = '#f00';
182    ctx.fill();
183    @assert pixel 20,20 == 0,0,0,0;
184    t.done();
185
186- name: initial.reset.clip
187  desc: Resetting the canvas state resets the current clip region
188  testing:
189  - initial.reset
190  code: |
191    canvas.width = 100;
192    ctx.rect(0, 0, 1, 1);
193    ctx.clip();
194    canvas.width = 100;
195    ctx.fillStyle = '#0f0';
196    ctx.fillRect(0, 0, 100, 50);
197    @assert pixel 20,20 == 0,255,0,255;
198    t.done();
199
200- name: initial.reset.transform
201  desc: Resetting the canvas state resets the current transformation matrix
202  testing:
203  - initial.reset
204  code: |
205    canvas.width = 100;
206    ctx.scale(0.1, 0.1);
207    canvas.width = 100;
208    ctx.fillStyle = '#0f0';
209    ctx.fillRect(0, 0, 100, 50);
210    @assert pixel 20,20 == 0,255,0,255;
211    t.done();
212
213- name: initial.reset.gradient
214  desc: Resetting the canvas state does not invalidate any existing gradients
215  testing:
216  - initial.reset
217  code: |
218    canvas.width = 50;
219    var g = ctx.createLinearGradient(0, 0, 100, 0);
220    g.addColorStop(0, '#0f0');
221    g.addColorStop(1, '#0f0');
222    canvas.width = 100;
223    ctx.fillStyle = '#f00';
224    ctx.fillRect(0, 0, 100, 50);
225    ctx.fillStyle = g;
226    ctx.fillRect(0, 0, 100, 50);
227    @assert pixel 50,25 == 0,255,0,255;
228    t.done();
229
230- name: initial.reset.pattern
231  desc: Resetting the canvas state does not invalidate any existing patterns
232  testing:
233  - initial.reset
234  code: |
235    canvas.width = 30;
236    ctx.fillStyle = '#0f0';
237    ctx.fillRect(0, 0, 30, 50);
238    var p = ctx.createPattern(canvas, 'repeat-x');
239    canvas.width = 100;
240    ctx.fillStyle = '#f00';
241    ctx.fillRect(0, 0, 100, 50);
242    ctx.fillStyle = p;
243    ctx.fillRect(0, 0, 100, 50);
244    @assert pixel 50,25 == 0,255,0,255;
245    t.done();
246
247- name: size.attributes.idl.set.zero
248  desc: Setting width/height IDL attributes to 0
249  testing:
250  - size.width
251  - size.height
252  code: |
253    canvas.width = 0;
254    canvas.height = 0;
255    @assert canvas.width === 0;
256    @assert canvas.height === 0;
257    t.done();
258
259- name: size.attributes.idl
260  desc: Getting/setting width/height IDL attributes
261  testing:
262  - size.width
263  - size.height
264  webidl:
265  - es-unsigned-long
266  code: |
267    canvas.width = "100";
268    canvas.height = "100";
269    @assert canvas.width === 100;
270    @assert canvas.height === 100;
271    canvas.width = "+1.5e2";
272    canvas.height = "0x96";
273    @assert canvas.width === 150;
274    @assert canvas.height === 150;
275    canvas.width = 301.999;
276    canvas.height = 301.001;
277    @assert canvas.width === 301;
278    @assert canvas.height === 301;
279    @assert throws TypeError canvas.width = "400x";
280    @assert throws TypeError canvas.height = "foo";
281    @assert canvas.width === 301;
282    @assert canvas.height === 301;
283    t.done();
284
285- name: size.attributes.default
286  desc: Default width/height when attributes are missing
287  testing:
288  - size.default
289  - size.missing
290  code: |
291    @assert canvas.width === 100;
292    @assert canvas.height === 50;
293    t.done();
294
295- name: size.attributes.reflect.setidl
296  desc: Setting IDL attributes updates IDL and content attributes
297  testing:
298  - size.reflect
299  code: |
300    canvas.width = 120;
301    canvas.height = 60;
302    @assert canvas.width === 120;
303    @assert canvas.height === 60;
304    t.done();
305
306- name: size.attributes.reflect.setidlzero
307  desc: Setting IDL attributes to 0 updates IDL and content attributes
308  testing:
309  - size.reflect
310  code: |
311    canvas.width = 0;
312    canvas.height = 0;
313    @assert canvas.width === 0;
314    @assert canvas.height === 0;
315    t.done();
316
317- name: size.large
318  testing:
319  - size.width
320  - size.height
321  notes: Not sure how reasonable this is, but the spec doesn't say there's an upper
322    limit on the size.
323  code: |
324    var n = 2147483647; // 2^31 - 1, which should be supported by any sensible definition of "long"
325    canvas.width = n;
326    canvas.height = n;
327    @assert canvas.width === n;
328    @assert canvas.height === n;
329    t.done();
330
331- name: 2d.text.setFont.mathFont
332  desc: crbug.com/1212190, make sure offscreencanvas doesn't crash with Math Font
333  testing:
334  - 2d.text.setFont.mathFont
335  code: |
336    ctx.font = "math serif";
337    t.done();
338