Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(77)

Side by Side Diff: third_party/WebKit/LayoutTests/http/tests/streams/piping/error-propagation-backward.js

Issue 2561443004: Implementation of ReadableStream pipeTo and pipeThrough (Closed)
Patch Set: Stop waiting for writes to terminate at shutdown Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 'use strict';
2
3 if (self.importScripts) {
4 self.importScripts('/resources/testharness.js');
5 self.importScripts('../resources/test-utils.js');
6 self.importScripts('../resources/recording-streams.js');
7 }
8
9 const error1 = new Error('error1!');
10 error1.name = 'error1';
11
12 const error2 = new Error('error2!');
13 error2.name = 'error2';
14
15 promise_test(t => {
16
17 const rs = recordingReadableStream();
18
19 const ws = recordingWritableStream({
20 start() {
21 return Promise.reject(error1);
22 }
23 });
24
25 return promise_rejects(t, error1, rs.pipeTo(ws), 'pipeTo must reject with the same error')
26 .then(() => {
27 assert_array_equals(rs.eventsWithoutPulls, ['cancel', error1]);
28 assert_array_equals(ws.events, []);
29 });
30
31 }, 'Errors must be propagated backward: starts errored; preventCancel omitted; f ulfilled cancel promise');
32
33 promise_test(t => {
34
35 const rs = recordingReadableStream();
36
37 const ws = recordingWritableStream({
38 write() {
39 return Promise.reject(error1);
40 }
41 });
42
43 const writer = ws.getWriter();
44
45 return promise_rejects(t, error1, writer.write('Hello'), 'writer.write() must reject with the write error')
46 .then(() => promise_rejects(t, error1, writer.closed, 'writer.closed must re ject with the write error'))
47 .then(() => {
48 writer.releaseLock();
49
50 return promise_rejects(t, error1, rs.pipeTo(ws), 'pipeTo must reject with the write error')
51 .then(() => {
52 assert_array_equals(rs.eventsWithoutPulls, ['cancel', error1]);
53 assert_array_equals(ws.events, ['write', 'Hello']);
54 });
55 });
56
57 }, 'Errors must be propagated backward: becomes errored before piping due to wri te; preventCancel omitted; ' +
58 'fulfilled cancel promise');
59
60 promise_test(t => {
61
62 const rs = recordingReadableStream({
63 cancel() {
64 throw error2;
65 }
66 });
67
68 const ws = recordingWritableStream({
69 write() {
70 return Promise.reject(error1);
71 }
72 });
73
74 const writer = ws.getWriter();
75
76 return promise_rejects(t, error1, writer.write('Hello'), 'writer.write() must reject with the write error')
77 .then(() => promise_rejects(t, error1, writer.closed, 'writer.closed must re ject with the write error'))
78 .then(() => {
79 writer.releaseLock();
80
81 return promise_rejects(t, error2, rs.pipeTo(ws), 'pipeTo must reject with the cancel error')
82 .then(() => {
83 assert_array_equals(rs.eventsWithoutPulls, ['cancel', error1]);
84 assert_array_equals(ws.events, ['write', 'Hello']);
85 });
86 });
87
88 }, 'Errors must be propagated backward: becomes errored before piping due to wri te; preventCancel omitted; rejected ' +
89 'cancel promise');
90
91 for (const falsy of [undefined, null, false, +0, -0, NaN, '']) {
92 promise_test(t => {
93
94 const rs = recordingReadableStream();
95
96 const ws = recordingWritableStream({
97 write() {
98 return Promise.reject(error1);
99 }
100 });
101
102 const writer = ws.getWriter();
103
104 return promise_rejects(t, error1, writer.write('Hello'), 'writer.write() mus t reject with the write error')
105 .then(() => promise_rejects(t, error1, writer.closed, 'writer.closed must reject with the write error'))
106 .then(() => {
107 writer.releaseLock();
108
109 return promise_rejects(t, error1, rs.pipeTo(ws, { preventCancel: falsy } ),
110 'pipeTo must reject with the write error')
111 .then(() => {
112 assert_array_equals(rs.eventsWithoutPulls, ['cancel', error1]);
113 assert_array_equals(ws.events, ['write', 'Hello']);
114 });
115 });
116
117 }, `Errors must be propagated backward: becomes errored before piping due to w rite; preventCancel = ${falsy} ` +
118 `(falsy); fulfilled cancel promise`);
119 }
120
121 for (const truthy of [true, 'a', 1, Symbol(), { }]) {
122 promise_test(t => {
123
124 const rs = recordingReadableStream();
125
126 const ws = recordingWritableStream({
127 write() {
128 return Promise.reject(error1);
129 }
130 });
131
132 const writer = ws.getWriter();
133
134 return promise_rejects(t, error1, writer.write('Hello'), 'writer.write() mus t reject with the write error')
135 .then(() => promise_rejects(t, error1, writer.closed, 'writer.closed must reject with the write error'))
136 .then(() => {
137 writer.releaseLock();
138
139 return promise_rejects(t, error1, rs.pipeTo(ws, { preventCancel: truthy }),
140 'pipeTo must reject with the write error')
141 .then(() => {
142 assert_array_equals(rs.eventsWithoutPulls, []);
143 assert_array_equals(ws.events, ['write', 'Hello']);
144 });
145 });
146
147 }, `Errors must be propagated backward: becomes errored before piping due to w rite; preventCancel = ` +
148 `${String(truthy)} (truthy)`);
149 }
150
151 promise_test(t => {
152
153 const rs = recordingReadableStream();
154
155 const ws = recordingWritableStream({
156 write() {
157 return Promise.reject(error1);
158 }
159 });
160
161 const writer = ws.getWriter();
162
163 return promise_rejects(t, error1, writer.write('Hello'), 'writer.write() must reject with the write error')
164 .then(() => promise_rejects(t, error1, writer.closed, 'writer.closed must re ject with the write error'))
165 .then(() => {
166 writer.releaseLock();
167
168 return promise_rejects(t, error1, rs.pipeTo(ws, { preventCancel: true, pre ventAbort: true }),
169 'pipeTo must reject with the write error')
170 .then(() => {
171 assert_array_equals(rs.eventsWithoutPulls, []);
172 assert_array_equals(ws.events, ['write', 'Hello']);
173 });
174 });
175
176 }, 'Errors must be propagated backward: becomes errored before piping due to wri te, preventCancel = true; ' +
177 'preventAbort = true');
178
179 promise_test(t => {
180
181 const rs = recordingReadableStream();
182
183 const ws = recordingWritableStream({
184 write() {
185 return Promise.reject(error1);
186 }
187 });
188
189 const writer = ws.getWriter();
190
191 return promise_rejects(t, error1, writer.write('Hello'), 'writer.write() must reject with the write error')
192 .then(() => promise_rejects(t, error1, writer.closed, 'writer.closed must re ject with the write error'))
193 .then(() => {
194 writer.releaseLock();
195
196 return promise_rejects(t, error1, rs.pipeTo(ws, { preventCancel: true, pre ventAbort: true, preventClose: true }),
197 'pipeTo must reject with the write error')
198 .then(() => {
199 assert_array_equals(rs.eventsWithoutPulls, []);
200 assert_array_equals(ws.events, ['write', 'Hello']);
201 });
202 });
203
204 }, 'Errors must be propagated backward: becomes errored before piping due to wri te; preventCancel = true, ' +
205 'preventAbort = true, preventClose = true');
206
207 promise_test(t => {
208
209 const rs = recordingReadableStream({
210 start(controller) {
211 controller.enqueue('Hello');
212 }
213 });
214
215 const ws = recordingWritableStream({
216 write() {
217 throw error1;
218 }
219 });
220
221 return promise_rejects(t, error1, rs.pipeTo(ws), 'pipeTo must reject with the same error').then(() => {
222 assert_array_equals(rs.eventsWithoutPulls, ['cancel', error1]);
223 assert_array_equals(ws.events, ['write', 'Hello']);
224 });
225
226 }, 'Errors must be propagated backward: becomes errored during piping due to wri te; preventCancel omitted; fulfilled ' +
227 'cancel promise');
228
229 promise_test(t => {
230
231 const rs = recordingReadableStream({
232 start(controller) {
233 controller.enqueue('Hello');
234 },
235 cancel() {
236 throw error2;
237 }
238 });
239
240 const ws = recordingWritableStream({
241 write() {
242 throw error1;
243 }
244 });
245
246 return promise_rejects(t, error2, rs.pipeTo(ws), 'pipeTo must reject with the cancel error').then(() => {
247 assert_array_equals(rs.eventsWithoutPulls, ['cancel', error1]);
248 assert_array_equals(ws.events, ['write', 'Hello']);
249 });
250
251 }, 'Errors must be propagated backward: becomes errored during piping due to wri te; preventCancel omitted; rejected ' +
252 'cancel promise');
253
254 promise_test(t => {
255
256 const rs = recordingReadableStream({
257 start(controller) {
258 controller.enqueue('Hello');
259 }
260 });
261
262 const ws = recordingWritableStream({
263 write() {
264 throw error1;
265 }
266 });
267
268 return promise_rejects(t, error1, rs.pipeTo(ws, { preventCancel: true }), 'pip eTo must reject with the same error')
269 .then(() => {
270 assert_array_equals(rs.eventsWithoutPulls, []);
271 assert_array_equals(ws.events, ['write', 'Hello']);
272 });
273
274 }, 'Errors must be propagated backward: becomes errored during piping due to wri te; preventCancel = true');
275
276 promise_test(t => {
277
278 const rs = recordingReadableStream({
279 start(controller) {
280 controller.enqueue('a');
281 controller.enqueue('b');
282 controller.enqueue('c');
283 }
284 });
285
286 const ws = recordingWritableStream({
287 write() {
288 if (ws.events.length > 2) {
289 return delay(0).then(() => {
290 throw error1;
291 });
292 }
293 return undefined;
294 }
295 });
296
297 return promise_rejects(t, error1, rs.pipeTo(ws), 'pipeTo must reject with the same error').then(() => {
298 assert_array_equals(rs.eventsWithoutPulls, ['cancel', error1]);
299 assert_array_equals(ws.events, ['write', 'a', 'write', 'b']);
300 });
301
302 }, 'Errors must be propagated backward: becomes errored during piping due to wri te, but async; preventCancel = ' +
303 'false; fulfilled cancel promise');
304
305 promise_test(t => {
306
307 const rs = recordingReadableStream({
308 start(controller) {
309 controller.enqueue('a');
310 controller.enqueue('b');
311 controller.enqueue('c');
312 },
313 cancel() {
314 throw error2;
315 }
316 });
317
318 const ws = recordingWritableStream({
319 write() {
320 if (ws.events.length > 2) {
321 return delay(0).then(() => {
322 throw error1;
323 });
324 }
325 return undefined;
326 }
327 });
328
329 return promise_rejects(t, error2, rs.pipeTo(ws), 'pipeTo must reject with the cancel error').then(() => {
330 assert_array_equals(rs.eventsWithoutPulls, ['cancel', error1]);
331 assert_array_equals(ws.events, ['write', 'a', 'write', 'b']);
332 });
333
334 }, 'Errors must be propagated backward: becomes errored during piping due to wri te, but async; preventCancel = ' +
335 'false; rejected cancel promise');
336
337 promise_test(t => {
338
339 const rs = recordingReadableStream({
340 start(controller) {
341 controller.enqueue('a');
342 controller.enqueue('b');
343 controller.enqueue('c');
344 }
345 });
346
347 const ws = recordingWritableStream({
348 write() {
349 if (ws.events.length > 2) {
350 return delay(0).then(() => {
351 throw error1;
352 });
353 }
354 return undefined;
355 }
356 });
357
358 return promise_rejects(t, error1, rs.pipeTo(ws, { preventCancel: true }), 'pip eTo must reject with the same error')
359 .then(() => {
360 assert_array_equals(rs.eventsWithoutPulls, []);
361 assert_array_equals(ws.events, ['write', 'a', 'write', 'b']);
362 });
363
364 }, 'Errors must be propagated backward: becomes errored during piping due to wri te, but async; preventCancel = true');
365
366 promise_test(t => {
367
368 const rs = recordingReadableStream();
369
370 const ws = recordingWritableStream();
371
372 const pipePromise = promise_rejects(t, error1, rs.pipeTo(ws), 'pipeTo must rej ect with the same error');
373
374 setTimeout(() => ws.controller.error(error1), 10);
375
376 return pipePromise.then(() => {
377 assert_array_equals(rs.eventsWithoutPulls, ['cancel', error1]);
378 assert_array_equals(ws.events, []);
379 });
380
381 }, 'Errors must be propagated backward: becomes errored after piping; preventCan cel omitted; fulfilled cancel promise');
382
383 promise_test(t => {
384
385 const rs = recordingReadableStream({
386 cancel() {
387 throw error2;
388 }
389 });
390
391 const ws = recordingWritableStream();
392
393 const pipePromise = promise_rejects(t, error2, rs.pipeTo(ws), 'pipeTo must rej ect with the cancel error');
394
395 setTimeout(() => ws.controller.error(error1), 10);
396
397 return pipePromise.then(() => {
398 assert_array_equals(rs.eventsWithoutPulls, ['cancel', error1]);
399 assert_array_equals(ws.events, []);
400 });
401
402 }, 'Errors must be propagated backward: becomes errored after piping; preventCan cel omitted; rejected cancel promise');
403
404 promise_test(t => {
405
406 const rs = recordingReadableStream();
407
408 const ws = recordingWritableStream();
409
410 const pipePromise = promise_rejects(t, error1, rs.pipeTo(ws, { preventCancel: true }),
411 'pipeTo must reject with the same error');
412
413 setTimeout(() => ws.controller.error(error1), 10);
414
415 return pipePromise.then(() => {
416 assert_array_equals(rs.eventsWithoutPulls, []);
417 assert_array_equals(ws.events, []);
418 });
419
420 }, 'Errors must be propagated backward: becomes errored after piping; preventCan cel = true');
421
422 promise_test(t => {
423
424 const rs = recordingReadableStream({
425 start(controller) {
426 controller.enqueue('a');
427 controller.enqueue('b');
428 controller.enqueue('c');
429 controller.close();
430 }
431 });
432
433 const ws = recordingWritableStream({
434 write(chunk) {
435 if (chunk === 'c') {
436 return Promise.reject(error1);
437 }
438 return undefined;
439 }
440 });
441
442 return promise_rejects(t, error1, rs.pipeTo(ws), 'pipeTo must reject with the same error').then(() => {
443 assert_array_equals(rs.eventsWithoutPulls, []);
444 assert_array_equals(ws.events, ['write', 'a', 'write', 'b', 'write', 'c']);
445 });
446
447 }, 'Errors must be propagated backward: becomes errored after piping due to last write; source is closed; ' +
448 'preventCancel omitted (but cancel is never called)');
449
450 promise_test(t => {
451
452 const rs = recordingReadableStream({
453 start(controller) {
454 controller.enqueue('a');
455 controller.enqueue('b');
456 controller.enqueue('c');
457 controller.close();
458 }
459 });
460
461 const ws = recordingWritableStream({
462 write(chunk) {
463 if (chunk === 'c') {
464 return Promise.reject(error1);
465 }
466 return undefined;
467 }
468 });
469
470 return promise_rejects(t, error1, rs.pipeTo(ws, { preventCancel: true }), 'pip eTo must reject with the same error')
471 .then(() => {
472 assert_array_equals(rs.eventsWithoutPulls, []);
473 assert_array_equals(ws.events, ['write', 'a', 'write', 'b', 'write', 'c']) ;
474 });
475
476 }, 'Errors must be propagated backward: becomes errored after piping due to last write; source is closed; ' +
477 'preventCancel = true');
478
479 promise_test(t => {
480
481 const rs = recordingReadableStream();
482
483 const ws = recordingWritableStream(undefined, new CountQueuingStrategy({ highW aterMark: 0 }));
484
485 const pipePromise = promise_rejects(t, error1, rs.pipeTo(ws), 'pipeTo must rej ect with the same error');
486
487 setTimeout(() => ws.controller.error(error1), 10);
488
489 return pipePromise.then(() => {
490 assert_array_equals(rs.eventsWithoutPulls, ['cancel', error1]);
491 assert_array_equals(ws.events, []);
492 });
493
494 }, 'Errors must be propagated backward: becomes errored after piping; dest never desires chunks; preventCancel = ' +
495 'false; fulfilled cancel promise');
496
497 promise_test(t => {
498
499 const rs = recordingReadableStream({
500 cancel() {
501 throw error2;
502 }
503 });
504
505 const ws = recordingWritableStream(undefined, new CountQueuingStrategy({ highW aterMark: 0 }));
506
507 const pipePromise = promise_rejects(t, error2, rs.pipeTo(ws), 'pipeTo must rej ect with the cancel error');
508
509 setTimeout(() => ws.controller.error(error1), 10);
510
511 return pipePromise.then(() => {
512 assert_array_equals(rs.eventsWithoutPulls, ['cancel', error1]);
513 assert_array_equals(ws.events, []);
514 });
515
516 }, 'Errors must be propagated backward: becomes errored after piping; dest never desires chunks; preventCancel = ' +
517 'false; rejected cancel promise');
518
519 promise_test(t => {
520
521 const rs = recordingReadableStream();
522
523 const ws = recordingWritableStream(undefined, new CountQueuingStrategy({ highW aterMark: 0 }));
524
525 const pipePromise = promise_rejects(t, error1, rs.pipeTo(ws, { preventCancel: true }),
526 'pipeTo must reject with the same error');
527
528 setTimeout(() => ws.controller.error(error1), 10);
529
530 return pipePromise.then(() => {
531 assert_array_equals(rs.eventsWithoutPulls, []);
532 assert_array_equals(ws.events, []);
533 });
534
535 }, 'Errors must be propagated backward: becomes errored after piping; dest never desires chunks; preventCancel = ' +
536 'true');
537
538 promise_test(() => {
539
540 const rs = recordingReadableStream();
541
542 const ws = recordingWritableStream();
543
544 ws.abort(error1);
545
546 return rs.pipeTo(ws).then(
547 () => assert_unreached('the promise must not fulfill'),
548 err => {
549 assert_equals(err.name, 'TypeError', 'the promise must reject with a TypeE rror (_not_ with error1)');
550
551 assert_array_equals(rs.eventsWithoutPulls, ['cancel', err]);
552 assert_array_equals(ws.events, ['abort', error1]);
553 }
554 );
555
556 }, 'Errors must be propagated backward: becomes errored before piping via abort; preventCancel omitted; fulfilled ' +
557 'cancel promise');
558
559 promise_test(t => {
560
561 const rs = recordingReadableStream({
562 cancel() {
563 throw error2;
564 }
565 });
566
567 const ws = recordingWritableStream();
568
569 ws.abort(error1);
570
571 return promise_rejects(t, error2, rs.pipeTo(ws), 'pipeTo must reject with the cancel error')
572 .then(() => {
573 return ws.getWriter().closed.then(
574 () => assert_unreached('the promise must not fulfill'),
575 err => {
576 assert_equals(err.name, 'TypeError', 'the promise must reject with a T ypeError (_not_ with error1)');
577
578 assert_array_equals(rs.eventsWithoutPulls, ['cancel', err]);
579 assert_array_equals(ws.events, ['abort', error1]);
580 }
581 );
582 });
583
584 }, 'Errors must be propagated backward: becomes errored before piping via abort; preventCancel omitted; rejected ' +
585 'cancel promise');
586
587 promise_test(t => {
588
589 const rs = recordingReadableStream();
590
591 const ws = recordingWritableStream();
592
593 ws.abort(error1);
594
595 return promise_rejects(t, new TypeError(), rs.pipeTo(ws, { preventCancel: true })).then(() => {
596 assert_array_equals(rs.eventsWithoutPulls, []);
597 assert_array_equals(ws.events, ['abort', error1]);
598 });
599
600 }, 'Errors must be propagated backward: becomes errored before piping via abort; preventCancel = true');
601
602 promise_test(t => {
603
604 const rs = recordingReadableStream();
605
606 let resolveWriteCalled;
607 const writeCalledPromise = new Promise(resolve => {
608 resolveWriteCalled = resolve;
609 });
610
611 const ws = recordingWritableStream({
612 write() {
613 resolveWriteCalled();
614 return flushAsyncEvents();
615 }
616 });
617
618 const pipePromise = rs.pipeTo(ws);
619
620 rs.controller.enqueue('a');
621
622 return writeCalledPromise.then(() => {
623 ws.controller.error(error1);
624
625 return promise_rejects(t, error1, pipePromise);
626 }).then(() => {
627 assert_array_equals(rs.eventsWithoutPulls, ['cancel', error1]);
628 assert_array_equals(ws.events, ['write', 'a']);
629 });
630
631 }, 'Errors must be propagated backward: erroring via the controller errors once pending write completes');
632
633 done();
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698