| OLD | NEW |
| (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 function writeArrayToStream(array, writableStreamWriter) { | |
| 10 array.forEach(chunk => writableStreamWriter.write(chunk)); | |
| 11 return writableStreamWriter.close(); | |
| 12 } | |
| 13 | |
| 14 promise_test(() => { | |
| 15 let storage; | |
| 16 const ws = new WritableStream({ | |
| 17 start() { | |
| 18 storage = []; | |
| 19 }, | |
| 20 | |
| 21 write(chunk) { | |
| 22 return delay(0).then(() => storage.push(chunk)); | |
| 23 }, | |
| 24 | |
| 25 close() { | |
| 26 return delay(0); | |
| 27 } | |
| 28 }); | |
| 29 | |
| 30 const writer = ws.getWriter(); | |
| 31 | |
| 32 const input = [1, 2, 3, 4, 5]; | |
| 33 return writeArrayToStream(input, writer) | |
| 34 .then(() => assert_array_equals(storage, input, 'correct data should be re
layed to underlying sink')); | |
| 35 }, 'WritableStream should complete asynchronous writes before close resolves'); | |
| 36 | |
| 37 promise_test(() => { | |
| 38 const ws = recordingWritableStream(); | |
| 39 | |
| 40 const writer = ws.getWriter(); | |
| 41 | |
| 42 const input = [1, 2, 3, 4, 5]; | |
| 43 return writeArrayToStream(input, writer) | |
| 44 .then(() => assert_array_equals(ws.events, ['write', 1, 'write', 2, 'write
', 3, 'write', 4, 'write', 5, 'close'], | |
| 45 'correct data should be relayed to underly
ing sink')); | |
| 46 }, 'WritableStream should complete synchronous writes before close resolves'); | |
| 47 | |
| 48 promise_test(() => { | |
| 49 const ws = new WritableStream({ | |
| 50 write() { | |
| 51 return 'Hello'; | |
| 52 } | |
| 53 }); | |
| 54 | |
| 55 const writer = ws.getWriter(); | |
| 56 | |
| 57 const writePromise = writer.write('a'); | |
| 58 return writePromise | |
| 59 .then(value => assert_equals(value, undefined, 'fulfillment value must be
undefined')); | |
| 60 }, 'fulfillment value of ws.write() call should be undefined even if the underly
ing sink returns a non-undefined ' + | |
| 61 'value'); | |
| 62 | |
| 63 promise_test(() => { | |
| 64 let resolveSinkWritePromise; | |
| 65 const ws = new WritableStream({ | |
| 66 write() { | |
| 67 return new Promise(resolve => { | |
| 68 resolveSinkWritePromise = resolve; | |
| 69 }); | |
| 70 } | |
| 71 }); | |
| 72 | |
| 73 const writer = ws.getWriter(); | |
| 74 | |
| 75 assert_equals(writer.desiredSize, 1, 'desiredSize should be 1'); | |
| 76 | |
| 77 return writer.ready.then(() => { | |
| 78 const writePromise = writer.write('a'); | |
| 79 let writePromiseResolved = false; | |
| 80 assert_not_equals(resolveSinkWritePromise, undefined, 'resolveSinkWritePromi
se should not be undefined'); | |
| 81 | |
| 82 assert_equals(writer.desiredSize, 0, 'desiredSize should be 0 after writer.w
rite()'); | |
| 83 | |
| 84 return Promise.all([ | |
| 85 writePromise.then(value => { | |
| 86 writePromiseResolved = true; | |
| 87 assert_equals(resolveSinkWritePromise, undefined, 'sinkWritePromise shou
ld be fulfilled before writePromise'); | |
| 88 | |
| 89 assert_equals(value, undefined, 'writePromise should be fulfilled with u
ndefined'); | |
| 90 }), | |
| 91 writer.ready.then(value => { | |
| 92 assert_equals(resolveSinkWritePromise, undefined, 'sinkWritePromise shou
ld be fulfilled before writer.ready'); | |
| 93 assert_true(writePromiseResolved, 'writePromise should be fulfilled befo
re writer.ready'); | |
| 94 | |
| 95 assert_equals(writer.desiredSize, 1, 'desiredSize should be 1 again'); | |
| 96 | |
| 97 assert_equals(value, undefined, 'writePromise should be fulfilled with u
ndefined'); | |
| 98 }), | |
| 99 flushAsyncEvents().then(() => { | |
| 100 resolveSinkWritePromise(); | |
| 101 resolveSinkWritePromise = undefined; | |
| 102 }) | |
| 103 ]); | |
| 104 }); | |
| 105 }, 'WritableStream should transition to waiting until write is acknowledged'); | |
| 106 | |
| 107 promise_test(t => { | |
| 108 let sinkWritePromiseRejectors = []; | |
| 109 const ws = new WritableStream({ | |
| 110 write() { | |
| 111 const sinkWritePromise = new Promise((r, reject) => sinkWritePromiseReject
ors.push(reject)); | |
| 112 return sinkWritePromise; | |
| 113 } | |
| 114 }); | |
| 115 | |
| 116 const writer = ws.getWriter(); | |
| 117 | |
| 118 assert_equals(writer.desiredSize, 1, 'desiredSize should be 1'); | |
| 119 | |
| 120 return writer.ready.then(() => { | |
| 121 const writePromise = writer.write('a'); | |
| 122 assert_equals(sinkWritePromiseRejectors.length, 1, 'there should be 1 reject
or'); | |
| 123 assert_equals(writer.desiredSize, 0, 'desiredSize should be 0'); | |
| 124 | |
| 125 const writePromise2 = writer.write('b'); | |
| 126 assert_equals(sinkWritePromiseRejectors.length, 1, 'there should be still 1
rejector'); | |
| 127 assert_equals(writer.desiredSize, -1, 'desiredSize should be -1'); | |
| 128 | |
| 129 const closedPromise = writer.close(); | |
| 130 | |
| 131 assert_equals(writer.desiredSize, -1, 'desiredSize should still be -1'); | |
| 132 | |
| 133 const passedError = new Error('horrible things'); | |
| 134 | |
| 135 return Promise.all([ | |
| 136 promise_rejects(t, passedError, closedPromise, 'closedPromise should rejec
t with passedError') | |
| 137 .then(() => assert_equals(sinkWritePromiseRejectors.length, 0, | |
| 138 'sinkWritePromise should reject before close
dPromise')), | |
| 139 promise_rejects(t, passedError, writePromise, 'writePromise should reject
with passedError') | |
| 140 .then(() => assert_equals(sinkWritePromiseRejectors.length, 0, | |
| 141 'sinkWritePromise should reject before write
Promise')), | |
| 142 promise_rejects(t, passedError, writePromise2, 'writePromise2 should rejec
t with passedError') | |
| 143 .then(() => assert_equals(sinkWritePromiseRejectors.length, 0, | |
| 144 'sinkWritePromise should reject before write
Promise2')), | |
| 145 flushAsyncEvents().then(() => { | |
| 146 sinkWritePromiseRejectors[0](passedError); | |
| 147 sinkWritePromiseRejectors = []; | |
| 148 }) | |
| 149 ]); | |
| 150 }); | |
| 151 }, 'when write returns a rejected promise, queued writes and close should be cle
ared'); | |
| 152 | |
| 153 promise_test(t => { | |
| 154 const thrownError = new Error('throw me'); | |
| 155 const ws = new WritableStream({ | |
| 156 write() { | |
| 157 throw thrownError; | |
| 158 } | |
| 159 }); | |
| 160 | |
| 161 const writer = ws.getWriter(); | |
| 162 | |
| 163 return promise_rejects(t, thrownError, writer.write('a'), 'write() should reje
ct with thrownError') | |
| 164 .then(() => promise_rejects(t, new TypeError(), writer.close(), 'close() s
hould be rejected')); | |
| 165 }, 'when sink\'s write throws an error, the stream should become errored and the
promise should reject'); | |
| 166 | |
| 167 promise_test(() => { | |
| 168 const numberOfWrites = 1000; | |
| 169 | |
| 170 let resolveFirstWritePromise; | |
| 171 let writeCount = 0; | |
| 172 const ws = new WritableStream({ | |
| 173 write() { | |
| 174 ++writeCount; | |
| 175 if (!resolveFirstWritePromise) { | |
| 176 return new Promise(resolve => { | |
| 177 resolveFirstWritePromise = resolve; | |
| 178 }); | |
| 179 } | |
| 180 return Promise.resolve(); | |
| 181 } | |
| 182 }); | |
| 183 | |
| 184 const writer = ws.getWriter(); | |
| 185 return writer.ready.then(() => { | |
| 186 for (let i = 1; i < numberOfWrites; ++i) { | |
| 187 writer.write('a'); | |
| 188 } | |
| 189 const writePromise = writer.write('a'); | |
| 190 | |
| 191 assert_equals(writeCount, 1, 'should have called sink\'s write once'); | |
| 192 | |
| 193 resolveFirstWritePromise(); | |
| 194 | |
| 195 return writePromise | |
| 196 .then(() => | |
| 197 assert_equals(writeCount, numberOfWrites, `should have called sink's wri
te ${numberOfWrites} times`)); | |
| 198 }); | |
| 199 }, 'a large queue of writes should be processed completely'); | |
| 200 | |
| 201 promise_test(() => { | |
| 202 const stream = recordingWritableStream(); | |
| 203 const w = stream.getWriter(); | |
| 204 const WritableStreamDefaultWriter = w.constructor; | |
| 205 w.releaseLock(); | |
| 206 const writer = new WritableStreamDefaultWriter(stream); | |
| 207 return writer.ready.then(() => { | |
| 208 writer.write('a'); | |
| 209 assert_array_equals(stream.events, ['write', 'a'], 'write() should be passed
to sink'); | |
| 210 }); | |
| 211 }, 'WritableStreamDefaultWriter should work when manually constructed'); | |
| 212 | |
| 213 promise_test(() => { | |
| 214 let thenCalled = false; | |
| 215 const ws = new WritableStream({ | |
| 216 write() { | |
| 217 return { | |
| 218 then(onFulfilled) { | |
| 219 thenCalled = true; | |
| 220 onFulfilled(); | |
| 221 } | |
| 222 }; | |
| 223 } | |
| 224 }); | |
| 225 return ws.getWriter().write('a').then(() => assert_true(thenCalled, 'thenCalle
d should be true')); | |
| 226 }, 'returning a thenable from write() should work'); | |
| 227 | |
| 228 done(); | |
| OLD | NEW |