streams/reference-implementation/readable-stream-reader.html and streams/reference...
[WebKit-https.git] / LayoutTests / streams / reference-implementation / bad-underlying-sources.html
1 <!DOCTYPE html>
2 <script src='../../resources/testharness.js'></script>
3 <script src='../../resources/testharnessreport.js'></script>
4 <script src='resources/streams-utils.js'></script>
5 <script>
6 test(function() {
7     var theError = new Error('a unique string');
8
9     assert_throws(theError, function() {
10         new ReadableStream({
11             get start() {
12                 throw theError;
13             }
14         });
15     }, 'constructing the stream should re-throw the error');
16 }, 'Underlying source start: throwing getter');
17
18 test(function() {
19     var theError = new Error('a unique string');
20
21     assert_throws(theError, function() {
22         new ReadableStream({
23             start: function() {
24                 throw theError;
25             }
26         });
27     }, 'constructing the stream should re-throw the error');
28 }, 'Underlying source start: throwing method');
29
30 var test1 = async_test('Underlying source: throwing pull getter (initial pull)', { timeout: 50 });
31 test1.step(function() {
32     var theError = new Error('a unique string');
33     var rs = new ReadableStream({
34         get pull() {
35             throw theError;
36         }
37     });
38
39     rs.getReader().closed.then(
40         test1.step_func(function() { assert_unreached('closed should not fulfill'); }),
41         test1.step_func(function(r) {
42             assert_equals(r, theError, 'closed should reject with the thrown error');
43             test1.done();
44         }));
45 });
46
47 var test2 = async_test('Underlying source: throwing pull method (initial pull)', { timeout: 50 });
48 test2.step(function() {
49     var theError = new Error('a unique string');
50     var rs = new ReadableStream({
51         pull: function() {
52             throw theError;
53         }
54     });
55
56     rs.getReader().closed.then(
57         test2.step_func(function() { assert_unreached('closed should not fulfill'); }),
58         test2.step_func(function(r) {
59             assert_equals(r, theError, 'closed should reject with the thrown error');
60             test2.done();
61         }));
62 });
63
64 var test3 = async_test('Underlying source: throwing pull getter (second pull)');
65 test3.step(function() {
66     var theError = new Error('a unique string');
67     var counter = 0;
68     var rs = new ReadableStream({
69         get pull() {
70             ++counter;
71             if (counter === 1) {
72                 return test3.step_func(function(c) { c.enqueue('a'); })
73             }
74
75             throw theError;
76         }
77     });
78     var reader = rs.getReader();
79
80     reader.read().then(test3.step_func(function(r) {
81         assert_object_equals(r, { value: 'a', done: false }, 'the chunk read should be correct');
82     }));
83
84     reader.closed.then(
85         test3.step_func(function() { assert_unreached('closed should not fulfill'); }),
86         test3.step_func(function(r) {
87             assert_equals(r, theError, 'closed should reject with the thrown error');
88             test3.done();
89         }));
90 });
91
92 var test4 = async_test('Underlying source: throwing pull method (second pull)');
93 test4.step(function() {
94     var theError = new Error('a unique string');
95     var counter = 0;
96     var rs = new ReadableStream({
97         pull: function(c) {
98             ++counter;
99             if (counter === 1) {
100                 c.enqueue('a');
101             } else {
102                 throw theError;
103             }
104         }
105     });
106     var reader = rs.getReader();
107
108     reader.read().then(test4.step_func(function(r) { assert_object_equals(r, { value: 'a', done: false }, 'the chunk read should be correct'); }));
109
110     reader.closed.then(
111         test4.step_func(function() { assert_unreached('closed should not fulfill'); }),
112         test4.step_func(function(r) {
113             assert_equals(r, theError, 'closed should reject with the thrown error');
114             test4.done();
115         }));
116 });
117
118 var test5 = async_test('Underlying source: throwing cancel getter');
119 test5.step(function() {
120     var theError = new Error('a unique string');
121     var rs = new ReadableStream({
122         get cancel() {
123             throw theError;
124         }
125     });
126
127     rs.cancel().then(
128         test5.step_func(function() { assert_unreached('cancel should not fulfill'); }),
129         test5.step_func(function(r) {
130             assert_equals(r, theError, 'cancel should reject with the thrown error');
131             test5.done();
132         }));
133 });
134
135 var test6 = async_test('Underlying source: throwing cancel method');
136 test6.step(function() {
137     var theError = new Error('a unique string');
138     var rs = new ReadableStream({
139         cancel: function() {
140             throw theError;
141         }
142     });
143
144     rs.cancel().then(
145         test6.step_func(function() { assert_unreached('cancel should not fulfill'); }),
146         test6.step_func(function(r) {
147             assert_equals(r, theError, 'cancel should reject with the thrown error');
148             test6.done();
149         }));
150 });
151
152 var test7 = async_test('Underlying source: throwing strategy getter', { timeout: 50 });
153 test7.step(function() {
154     var started = false;
155     var theError = new Error('a unique string');
156
157     var rs = new ReadableStream({
158         start: function(c) {
159             started = true;
160             assert_throws(theError, function() { c.enqueue('a'); }, 'enqueue should throw the error');
161         },
162         get strategy() {
163             throw theError;
164         }
165     });
166
167     rs.getReader().closed.catch(test7.step_func(function(e) {
168         assert_true(started);
169         assert_equals(e, theError, 'closed should reject with the error');
170         test7.done();
171     }));
172 });
173
174 var test8 = async_test('Underlying source: throwing strategy.size getter', { timeout: 50 });
175 test8.step(function() {
176     var started = false;
177     var theError = new Error('a unique string');
178     var rs = new ReadableStream({
179         start: function(c) {
180             started = true;
181             assert_throws(theError, function() { c.enqueue('a'); }, 'enqueue should throw the error');
182         },
183         strategy: {
184             get size() {
185                 throw theError;
186             },
187             shouldApplyBackpressure: function() {
188                 return true;
189             }
190         }
191     });
192
193     rs.getReader().closed.catch(test8.step_func(function(e) {
194         assert_true(started);
195         assert_equals(e, theError, 'closed should reject with the error');
196         test8.done();
197     }));
198 });
199
200 var test9 = async_test('Underlying source: throwing strategy.size method', { timeout: 50 });
201 test9.step(function() {
202     var started = false;
203     var theError = new Error('a unique string');
204     var rs = new ReadableStream({
205         start: function(c) {
206             started = true;
207             assert_throws(theError, function() { c.enqueue('a'); }, 'enqueue should throw the error');
208         },
209         strategy: {
210             size: function() {
211                 throw theError;
212             },
213             shouldApplyBackpressure: function() {
214                 return true;
215             }
216         }
217     });
218
219     rs.getReader().closed.catch(test9.step_func(function(e) {
220         assert_true(started);
221         assert_equals(e, theError, 'closed should reject with the error');
222         test9.done();
223     }));
224 });
225
226 var test10 = async_test('Underlying source: throwing strategy.shouldApplyBackpressure getter', { timeout: 50 });
227 test10.step(function() {
228     var started = false;
229     var theError = new Error('a unique string');
230     var rs = new ReadableStream({
231         start: function(c) {
232             started = true;
233             assert_throws(theError, function() { c.enqueue('a'); }, 'enqueue should throw the error');
234         },
235         strategy: {
236             size: function() {
237                 return 1;
238             },
239             get shouldApplyBackpressure() {
240                 throw theError;
241             }
242         }
243     });
244
245     rs.getReader().closed.catch(test10.step_func(function(e) {
246         assert_true(started);
247         assert_equals(e, theError, 'closed should reject with the error');
248         test10.done();
249     }));
250 });
251
252 var test11 = async_test('Underlying source: throwing strategy.shouldApplyBackpressure method', { timeout: 50 });
253 test11.step(function() {
254     var started = false;
255     var theError = new Error('a unique string');
256     var rs = new ReadableStream({
257         start: function(c) {
258             started = true;
259             assert_throws(theError, function() { c.enqueue('a'); }, 'enqueue should throw the error');
260         },
261         strategy: {
262             size: function() {
263                 return 1;
264             },
265             shouldApplyBackpressure: function() {
266                 throw theError;
267             }
268         }
269     });
270
271     rs.getReader().closed.catch(test11.step_func(function(e) {
272         assert_true(started);
273         assert_equals(e, theError, 'closed should reject with the error');
274         test11.done();
275     }));
276 });
277
278 var test12 = async_test('Underlying source: strategy.size returning NaN', { timeout: 50 });
279 test12.step(function() {
280     var theError = undefined;
281     var rs = new ReadableStream({
282         start: function(c) {
283             try {
284                 c.enqueue('hi');
285                 assert_unreached('enqueue didn\'t throw');
286             } catch (error) {
287                 theError = error;
288                 assert_throws(new RangeError(), function() { throw error; }, 'enqueue should throw a RangeError');
289             }
290         },
291         strategy: {
292             size: function() {
293                 return NaN;
294             },
295             shouldApplyBackpressure: function() {
296                 return true;
297             }
298         }
299     });
300
301     rs.getReader().closed.catch(test12.step_func(function(e) {
302         assert_equals(e, theError, 'closed should reject with the error');
303         test12.done();
304     }));
305 });
306
307 var test13 = async_test('Underlying source: strategy.size returning -Infinity', { timeout: 50 });
308 test13.step(function() {
309     var theError = undefined;
310     var rs = new ReadableStream({
311         start: function(c) {
312             try {
313                 c.enqueue('hi');
314                 assert_unreached('enqueue didn\'t throw');
315             } catch (error) {
316                 theError = error;
317                 assert_throws(new RangeError(), function() { throw error; }, 'enqueue should throw a RangeError');
318             }
319         },
320         strategy: {
321             size: function() {
322                 return -Infinity;
323             },
324             shouldApplyBackpressure: function() {
325                 return true;
326             }
327         }
328     });
329
330     rs.getReader().closed.catch(test13.step_func(function(e) {
331         assert_equals(e, theError, 'closed should reject with the error');
332         test13.done();
333     }));
334 });
335
336 var test14 = async_test('Underlying source: strategy.size returning +Infinity', { timeout: 50 });
337 test14.step(function() {
338     var theError = undefined;
339     var rs = new ReadableStream({
340         start: function(c) {
341             try {
342                 c.enqueue('hi');
343                 assert_unreached('enqueue didn\'t throw');
344             } catch (error) {
345                 theError = error;
346                 assert_throws(new RangeError(), function() { throw error; }, 'enqueue should throw a RangeError');
347             }
348         },
349         strategy: {
350             size: function() {
351                 return +Infinity;
352             },
353             shouldApplyBackpressure: function() {
354                 return true;
355             }
356         }
357     });
358
359     rs.getReader().closed.catch(test14.step_func(function(e) {
360         assert_equals(e, theError, 'closed should reject with the error');
361         test14.done();
362     }));
363 });
364
365 var test15 = async_test('Underlying source: calling close twice on an empty stream should throw the second time');
366 test15.step(function() {
367     new ReadableStream({
368         start: function(c) {
369             c.close();
370             assert_throws(new TypeError(), c.close, 'second call to close should throw a TypeError');
371         }
372     }).getReader().closed.then(test15.step_func(function() { test15.done('closed should fulfill'); }));
373 });
374
375 var test16 = async_test('Underlying source: calling close twice on a non-empty stream should throw the second time');
376 test16.step(function() {
377     var startCalled = false;
378     var readCalled = false;
379     var reader = new ReadableStream({
380         start: function(c) {
381             c.enqueue('a');
382             c.close();
383             assert_throws(new TypeError(), c.close, 'second call to close should throw a TypeError');
384             startCalled = true;
385         }
386     }).getReader();
387
388     reader.read().then(test16.step_func(function(r) {
389         assert_object_equals(r, { value: 'a', done: false }, 'read() should read the enqueued chunk');
390         readCalled = true;
391     }));
392     reader.closed.then(test16.step_func(function() {
393         assert_true(startCalled);
394         assert_true(readCalled);
395         test16.done('closed should fulfill');
396     }));
397 });
398
399 var test17 = async_test('Underlying source: calling close on an empty canceled stream should not throw');
400 test17.step(function() {
401     var controller;
402     var startCalled = false;
403     var rs = new ReadableStream({
404         start: function(c) {
405             controller = c;
406             startCalled = true;
407         }
408     });
409
410     rs.cancel();
411     controller.close(); // Calling close after canceling should not throw anything.
412
413     rs.getReader().closed.then(test17.step_func(function() {
414         assert_true(startCalled);
415         test17.done('closed should fulfill');
416     }));
417 });
418
419 var test18 = async_test('Underlying source: calling close on a non-empty canceled stream should not throw');
420 test18.step(function() {
421     var controller;
422     var startCalled = false;
423     var rs = new ReadableStream({
424         start: function(c) {
425             controller = c;
426             c.enqueue('a');
427             startCalled = true;
428         }
429     });
430
431     rs.cancel();
432     controller.close(); // Calling close after canceling should not throw anything.
433
434     rs.getReader().closed.then(test18.step_func(function() {
435         assert_true(startCalled);
436         test18.done('closed should fulfill');
437     }));
438 });
439
440 var test19 = async_test('Underlying source: calling close after error should throw', { timeout: 50 });
441 test19.step(function() {
442     var theError = new Error('boo');
443     var startCalled = false;
444     new ReadableStream({
445         start: function(c) {
446             c.error(theError);
447             assert_throws(new TypeError(), c.close, 'call to close should throw a TypeError');
448             startCalled = true;
449         }
450     }).getReader().closed.catch(test19.step_func(function(e) {
451         assert_true(startCalled);
452         assert_equals(e, theError, 'closed should reject with the error')
453         test19.done();
454     }));
455 });
456
457 var test20 = async_test('Underlying source: calling error twice should throw the second time', { timeout: 50 });
458 test20.step(function() {
459     var theError = new Error('boo');
460     var startCalled = false;
461     new ReadableStream({
462         start: function(c) {
463             c.error(theError);
464             assert_throws(new TypeError(), c.error, 'second call to error should throw a TypeError');
465             startCalled = true;
466         }
467     }).getReader().closed.catch(test20.step_func(function(e) {
468         assert_true(startCalled);
469         assert_equals(e, theError, 'closed should reject with the error');
470         test20.done();
471     }));
472 });
473
474 var test21 = async_test('Underlying source: calling error after close should throw', { timeout: 50 });
475 test21.step(function() {
476     var startCalled = false;
477     new ReadableStream({
478         start: function(c) {
479             c.close();
480             assert_throws(new TypeError(), c.error, 'call to error should throw a TypeError');
481             startCalled = true;
482         }
483     }).getReader().closed.then(test21.step_func(function() {
484         assert_true(startCalled);
485         test21.done('closed should fulfill');
486     }));
487 });
488 </script>