1// META: global=window,worker 2// META: script=../resources/test-utils.js 3// META: script=../resources/recording-streams.js 4'use strict'; 5 6const error1 = new Error('error1'); 7error1.name = 'error1'; 8 9test(() => { 10 assert_throws_exactly(error1, () => { 11 new WritableStream({ 12 get start() { 13 throw error1; 14 } 15 }); 16 }, 'constructor should throw same error as throwing start getter'); 17 18 assert_throws_exactly(error1, () => { 19 new WritableStream({ 20 start() { 21 throw error1; 22 } 23 }); 24 }, 'constructor should throw same error as throwing start method'); 25 26 assert_throws_js(TypeError, () => { 27 new WritableStream({ 28 start: 'not a function or undefined' 29 }); 30 }, 'constructor should throw TypeError when passed a non-function start property'); 31 32 assert_throws_js(TypeError, () => { 33 new WritableStream({ 34 start: { apply() {} } 35 }); 36 }, 'constructor should throw TypeError when passed a non-function start property with an .apply method'); 37}, 'start: errors in start cause WritableStream constructor to throw'); 38 39promise_test(t => { 40 41 const ws = recordingWritableStream({ 42 close() { 43 throw error1; 44 } 45 }); 46 47 const writer = ws.getWriter(); 48 49 return promise_rejects_exactly(t, error1, writer.close(), 'close() promise must reject with the thrown error') 50 .then(() => promise_rejects_exactly(t, error1, writer.ready, 'ready promise must reject with the thrown error')) 51 .then(() => promise_rejects_exactly(t, error1, writer.closed, 'closed promise must reject with the thrown error')) 52 .then(() => { 53 assert_array_equals(ws.events, ['close']); 54 }); 55 56}, 'close: throwing method should cause writer close() and ready to reject'); 57 58promise_test(t => { 59 60 const ws = recordingWritableStream({ 61 close() { 62 return Promise.reject(error1); 63 } 64 }); 65 66 const writer = ws.getWriter(); 67 68 return promise_rejects_exactly(t, error1, writer.close(), 'close() promise must reject with the same error') 69 .then(() => promise_rejects_exactly(t, error1, writer.ready, 'ready promise must reject with the same error')) 70 .then(() => assert_array_equals(ws.events, ['close'])); 71 72}, 'close: returning a rejected promise should cause writer close() and ready to reject'); 73 74test(() => { 75 assert_throws_exactly(error1, () => new WritableStream({ 76 get close() { 77 throw error1; 78 } 79 }), 'constructor should throw'); 80}, 'close: throwing getter should cause constructor to throw'); 81 82test(() => { 83 assert_throws_exactly(error1, () => new WritableStream({ 84 get write() { 85 throw error1; 86 } 87 }), 'constructor should throw'); 88}, 'write: throwing getter should cause write() and closed to reject'); 89 90promise_test(t => { 91 const ws = new WritableStream({ 92 write() { 93 throw error1; 94 } 95 }); 96 97 const writer = ws.getWriter(); 98 99 return promise_rejects_exactly(t, error1, writer.write('a'), 'write should reject with the thrown error') 100 .then(() => promise_rejects_exactly(t, error1, writer.closed, 'closed should reject with the thrown error')); 101}, 'write: throwing method should cause write() and closed to reject'); 102 103promise_test(t => { 104 105 let rejectSinkWritePromise; 106 const ws = recordingWritableStream({ 107 write() { 108 return new Promise((r, reject) => { 109 rejectSinkWritePromise = reject; 110 }); 111 } 112 }); 113 114 return flushAsyncEvents().then(() => { 115 const writer = ws.getWriter(); 116 const writePromise = writer.write('a'); 117 rejectSinkWritePromise(error1); 118 119 return Promise.all([ 120 promise_rejects_exactly(t, error1, writePromise, 'writer write must reject with the same error'), 121 promise_rejects_exactly(t, error1, writer.ready, 'ready promise must reject with the same error') 122 ]); 123 }) 124 .then(() => { 125 assert_array_equals(ws.events, ['write', 'a']); 126 }); 127 128}, 'write: returning a promise that becomes rejected after the writer write() should cause writer write() and ready ' + 129 'to reject'); 130 131promise_test(t => { 132 133 const ws = recordingWritableStream({ 134 write() { 135 if (ws.events.length === 2) { 136 return delay(0); 137 } 138 139 return Promise.reject(error1); 140 } 141 }); 142 143 const writer = ws.getWriter(); 144 145 // Do not wait for this; we want to test the ready promise when the stream is "full" (desiredSize = 0), but if we wait 146 // then the stream will transition back to "empty" (desiredSize = 1) 147 writer.write('a'); 148 const readyPromise = writer.ready; 149 150 return promise_rejects_exactly(t, error1, writer.write('b'), 'second write must reject with the same error').then(() => { 151 assert_equals(writer.ready, readyPromise, 152 'the ready promise must not change, since the queue was full after the first write, so the pending one simply ' + 153 'transitioned'); 154 return promise_rejects_exactly(t, error1, writer.ready, 'ready promise must reject with the same error'); 155 }) 156 .then(() => assert_array_equals(ws.events, ['write', 'a', 'write', 'b'])); 157 158}, 'write: returning a rejected promise (second write) should cause writer write() and ready to reject'); 159 160test(() => { 161 assert_throws_js(TypeError, () => new WritableStream({ 162 start: 'test' 163 }), 'constructor should throw'); 164}, 'start: non-function start method'); 165 166test(() => { 167 assert_throws_js(TypeError, () => new WritableStream({ 168 write: 'test' 169 }), 'constructor should throw'); 170}, 'write: non-function write method'); 171 172test(() => { 173 assert_throws_js(TypeError, () => new WritableStream({ 174 close: 'test' 175 }), 'constructor should throw'); 176}, 'close: non-function close method'); 177 178test(() => { 179 assert_throws_js(TypeError, () => new WritableStream({ 180 abort: { apply() {} } 181 }), 'constructor should throw'); 182}, 'abort: non-function abort method with .apply'); 183 184test(() => { 185 assert_throws_exactly(error1, () => new WritableStream({ 186 get abort() { 187 throw error1; 188 } 189 }), 'constructor should throw'); 190}, 'abort: throwing getter should cause abort() and closed to reject'); 191 192promise_test(t => { 193 const abortReason = new Error('different string'); 194 const ws = new WritableStream({ 195 abort() { 196 throw error1; 197 } 198 }); 199 200 const writer = ws.getWriter(); 201 202 return promise_rejects_exactly(t, error1, writer.abort(abortReason), 'abort should reject with the thrown error') 203 .then(() => promise_rejects_exactly(t, abortReason, writer.closed, 'closed should reject with abortReason')); 204}, 'abort: throwing method should cause abort() and closed to reject'); 205