OLD | NEW |
| (Empty) |
1 'use strict'; | |
2 | |
3 if (self.importScripts) { | |
4 self.importScripts('/resources/testharness.js'); | |
5 } | |
6 | |
7 test(() => { | |
8 const ws = new WritableStream({}); | |
9 const writer = ws.getWriter(); | |
10 writer.releaseLock(); | |
11 | |
12 assert_throws(new TypeError(), () => writer.desiredSize, 'desiredSize should t
hrow a TypeError'); | |
13 }, 'desiredSize on a released writer'); | |
14 | |
15 test(() => { | |
16 const ws = new WritableStream({}); | |
17 | |
18 const writer = ws.getWriter(); | |
19 | |
20 assert_equals(writer.desiredSize, 1, 'desiredSize should be 1'); | |
21 }, 'desiredSize initial value'); | |
22 | |
23 promise_test(() => { | |
24 const ws = new WritableStream({}); | |
25 | |
26 const writer = ws.getWriter(); | |
27 | |
28 writer.close(); | |
29 | |
30 return writer.closed.then(() => { | |
31 assert_equals(writer.desiredSize, 0, 'desiredSize should be 0'); | |
32 }); | |
33 }, 'desiredSize on a writer for a closed stream'); | |
34 | |
35 test(() => { | |
36 const ws = new WritableStream({}); | |
37 | |
38 const writer = ws.getWriter(); | |
39 writer.close(); | |
40 writer.releaseLock(); | |
41 | |
42 ws.getWriter(); | |
43 }, 'ws.getWriter() on a closing WritableStream'); | |
44 | |
45 promise_test(() => { | |
46 const ws = new WritableStream({}); | |
47 | |
48 const writer = ws.getWriter(); | |
49 return writer.close().then(() => { | |
50 writer.releaseLock(); | |
51 | |
52 ws.getWriter(); | |
53 }); | |
54 }, 'ws.getWriter() on a closed WritableStream'); | |
55 | |
56 test(() => { | |
57 const ws = new WritableStream({}); | |
58 | |
59 const writer = ws.getWriter(); | |
60 writer.abort(); | |
61 writer.releaseLock(); | |
62 | |
63 ws.getWriter(); | |
64 }, 'ws.getWriter() on an aborted WritableStream'); | |
65 | |
66 promise_test(() => { | |
67 const ws = new WritableStream({ | |
68 start(c) { | |
69 c.error(); | |
70 } | |
71 }); | |
72 | |
73 const writer = ws.getWriter(); | |
74 return writer.closed.then( | |
75 v => assert_unreached('writer.closed fulfilled unexpectedly with: ' + v), | |
76 () => { | |
77 writer.releaseLock(); | |
78 | |
79 ws.getWriter(); | |
80 } | |
81 ); | |
82 }, 'ws.getWriter() on an errored WritableStream'); | |
83 | |
84 promise_test(() => { | |
85 const ws = new WritableStream({}); | |
86 | |
87 const writer = ws.getWriter(); | |
88 writer.releaseLock(); | |
89 | |
90 return writer.closed.then( | |
91 v => assert_unreached('writer.closed fulfilled unexpectedly with: ' + v), | |
92 closedRejection => { | |
93 assert_equals(closedRejection.name, 'TypeError', 'closed promise should re
ject with a TypeError'); | |
94 return writer.ready.then( | |
95 v => assert_unreached('writer.ready fulfilled unexpectedly with: ' + v), | |
96 readyRejection => assert_equals(readyRejection, closedRejection, | |
97 'ready promise should reject with the same error') | |
98 ); | |
99 } | |
100 ); | |
101 }, 'closed and ready on a released writer'); | |
102 | |
103 promise_test(() => { | |
104 const promises = {}; | |
105 const resolvers = {}; | |
106 for (const methodName of ['start', 'write', 'close', 'abort']) { | |
107 promises[methodName] = new Promise(resolve => { | |
108 resolvers[methodName] = resolve; | |
109 }); | |
110 } | |
111 | |
112 // Calls to Sink methods after the first are implicitly ignored. Only the firs
t value that is passed to the resolver | |
113 // is used. | |
114 class Sink { | |
115 start() { | |
116 // Called twice | |
117 resolvers.start(this); | |
118 } | |
119 | |
120 write() { | |
121 resolvers.write(this); | |
122 } | |
123 | |
124 close() { | |
125 resolvers.close(this); | |
126 } | |
127 | |
128 abort() { | |
129 resolvers.abort(this); | |
130 } | |
131 } | |
132 | |
133 const theSink = new Sink(); | |
134 const ws = new WritableStream(theSink); | |
135 | |
136 const writer = ws.getWriter(); | |
137 | |
138 writer.write('a'); | |
139 writer.close(); | |
140 | |
141 const ws2 = new WritableStream(theSink); | |
142 const writer2 = ws2.getWriter(); | |
143 writer2.abort(); | |
144 | |
145 return promises.start | |
146 .then(thisValue => assert_equals(thisValue, theSink, 'start should be call
ed as a method')) | |
147 .then(() => promises.write) | |
148 .then(thisValue => assert_equals(thisValue, theSink, 'write should be call
ed as a method')) | |
149 .then(() => promises.close) | |
150 .then(thisValue => assert_equals(thisValue, theSink, 'close should be call
ed as a method')) | |
151 .then(() => promises.abort) | |
152 .then(thisValue => assert_equals(thisValue, theSink, 'abort should be call
ed as a method')); | |
153 }, 'WritableStream should call underlying sink methods as methods'); | |
154 | |
155 promise_test(t => { | |
156 function functionWithOverloads() {} | |
157 functionWithOverloads.apply = () => assert_unreached('apply() should not be ca
lled'); | |
158 functionWithOverloads.call = () => assert_unreached('call() should not be call
ed'); | |
159 const underlyingSink = { | |
160 start: functionWithOverloads, | |
161 write: functionWithOverloads, | |
162 close: functionWithOverloads, | |
163 abort: functionWithOverloads | |
164 }; | |
165 // Test start(), write(), close(). | |
166 const ws1 = new WritableStream(underlyingSink); | |
167 const writer1 = ws1.getWriter(); | |
168 writer1.write('a'); | |
169 writer1.close(); | |
170 | |
171 // Test abort(). | |
172 const ws2 = new WritableStream(underlyingSink); | |
173 const writer2 = ws2.getWriter(); | |
174 writer2.abort(); | |
175 | |
176 // Test abort() with a close underlying sink method present. (Historical; see | |
177 // https://github.com/whatwg/streams/issues/620#issuecomment-263483953 for wha
t used to be | |
178 // tested here. But more coverage can't hurt.) | |
179 const ws3 = new WritableStream({ | |
180 start: functionWithOverloads, | |
181 write: functionWithOverloads, | |
182 close: functionWithOverloads | |
183 }); | |
184 const writer3 = ws3.getWriter(); | |
185 writer3.abort(); | |
186 | |
187 return writer1.closed | |
188 .then(() => promise_rejects(t, new TypeError(), writer2.closed, 'writer2.c
losed should be rejected')) | |
189 .then(() => promise_rejects(t, new TypeError(), writer3.closed, 'writer3.c
losed should be rejected')); | |
190 }, 'methods should not not have .apply() or .call() called'); | |
191 | |
192 promise_test(() => { | |
193 const strategy = { | |
194 size() { | |
195 if (this !== undefined) { | |
196 throw new Error('size called as a method'); | |
197 } | |
198 return 1; | |
199 } | |
200 }; | |
201 | |
202 const ws = new WritableStream({}, strategy); | |
203 const writer = ws.getWriter(); | |
204 return writer.write('a'); | |
205 }, 'WritableStream\'s strategy.size should not be called as a method'); | |
206 | |
207 promise_test(() => { | |
208 const ws = new WritableStream(); | |
209 const writer1 = ws.getWriter(); | |
210 assert_equals(undefined, writer1.releaseLock(), 'releaseLock() should return u
ndefined'); | |
211 const writer2 = ws.getWriter(); | |
212 assert_equals(undefined, writer1.releaseLock(), 'no-op releaseLock() should re
turn undefined'); | |
213 // Calling releaseLock() on writer1 should not interfere with writer2. If it d
id, then the ready promise would be | |
214 // rejected. | |
215 return writer2.ready; | |
216 }, 'redundant releaseLock() is no-op'); | |
217 | |
218 done(); | |
OLD | NEW |