@@ -628,3 +628,57 @@ promise_test(t => {
628
628
} ) ;
629
629
630
630
} , 'Errors must be propagated backward: erroring via the controller errors once pending write completes' ) ;
631
+
632
+ promise_test ( async t => {
633
+ let resolvePullCalled ;
634
+ const pullCalledPromise = new Promise ( resolve => {
635
+ resolvePullCalled = resolve ;
636
+ } ) ;
637
+ const rs = recordingReadableStream ( {
638
+ pull : t . step_func ( ( ) => {
639
+ resolvePullCalled ( ) ;
640
+ } )
641
+ } , { highWaterMark : 0 } ) ;
642
+
643
+ let resolveWriteCalled ;
644
+ const writeCalledPromise = new Promise ( resolve => {
645
+ resolveWriteCalled = resolve ;
646
+ } ) ;
647
+ let resolveWrite ;
648
+ const writePromise = new Promise ( resolve => {
649
+ resolveWrite = resolve ;
650
+ } ) ;
651
+ const ws = recordingWritableStream ( {
652
+ write : t . step_func ( ( ) => {
653
+ resolveWriteCalled ( ) ;
654
+ return writePromise ;
655
+ } ) ,
656
+ } , { highWaterMark : Infinity } ) ;
657
+
658
+ rs . controller . enqueue ( 'a' ) ;
659
+ assert_array_equals ( rs . events , [ ] , 'pull() has not yet been called' ) ;
660
+
661
+ const pipePromise = rs . pipeTo ( ws , { preventCancel : true } ) ;
662
+
663
+ // The pipe must start writing the first chunk.
664
+ await writeCalledPromise ;
665
+ assert_array_equals ( ws . events , [ 'write' , 'a' ] , 'write() must have been called once' ) ;
666
+ // The pipe must immediately try to read the next chunk, since the destination desired more chunks.
667
+ await pullCalledPromise ;
668
+ assert_array_equals ( rs . events , [ 'pull' ] , 'pull() must have been called once' ) ;
669
+
670
+ // Error the destination.
671
+ // Any chunks enqueued after erroring must not be piped to the destination.
672
+ ws . controller . error ( error1 ) ;
673
+ rs . controller . enqueue ( 'b' ) ;
674
+ resolveWrite ( ) ;
675
+
676
+ await promise_rejects_exactly ( t , error1 , pipePromise , 'pipeTo() should reject with writable error' ) ;
677
+ assert_array_equals ( rs . events , [ 'pull' ] , 'pull() must have been called once' ) ;
678
+ assert_array_equals ( ws . events , [ 'write' , 'a' ] , 'write() must have been called once' ) ;
679
+
680
+ rs . controller . close ( ) ;
681
+ const reader = rs . getReader ( ) ;
682
+ const result = await reader . read ( ) ;
683
+ assert_object_equals ( result , { value : 'b' , done : false } , 'first read after pipeTo() should be correct' ) ;
684
+ } , 'Errors must be propagated backward: becomes errored immediately before source receives a chunk; preventCancel = true' ) ;
0 commit comments