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 |