Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(221)

Side by Side Diff: Source/core/streams/ExclusiveStreamReaderTest.cpp

Issue 1001233002: Streams Implementation Update: Reader name and Stream methods (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Source/core/streams/ExclusiveStreamReader.idl ('k') | Source/core/streams/ReadableStream.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "config.h"
6 #include "core/streams/ExclusiveStreamReader.h"
7
8 #include "bindings/core/v8/ExceptionState.h"
9 #include "bindings/core/v8/ScriptState.h"
10 #include "bindings/core/v8/ToV8.h"
11 #include "bindings/core/v8/V8ThrowException.h"
12 #include "core/dom/DOMException.h"
13 #include "core/dom/Document.h"
14 #include "core/dom/ExceptionCode.h"
15 #include "core/streams/ReadableStream.h"
16 #include "core/streams/ReadableStreamImpl.h"
17 #include "core/streams/UnderlyingSource.h"
18 #include "core/testing/DummyPageHolder.h"
19 #include <gtest/gtest.h>
20
21 namespace blink {
22
23 using StringStream = ReadableStreamImpl<ReadableStreamChunkTypeTraits<String>>;
24
25 namespace {
26
27 class StringCapturingFunction final : public ScriptFunction {
28 public:
29 static v8::Handle<v8::Function> createFunction(ScriptState* scriptState, Str ing* value)
30 {
31 StringCapturingFunction* self = new StringCapturingFunction(scriptState, value);
32 return self->bindToV8Function();
33 }
34
35 private:
36 StringCapturingFunction(ScriptState* scriptState, String* value)
37 : ScriptFunction(scriptState)
38 , m_value(value)
39 {
40 }
41
42 ScriptValue call(ScriptValue value) override
43 {
44 ASSERT(!value.isEmpty());
45 *m_value = toCoreString(value.v8Value()->ToString(scriptState()->isolate ()));
46 return value;
47 }
48
49 String* m_value;
50 };
51
52 class NoopUnderlyingSource final : public GarbageCollectedFinalized<NoopUnderlyi ngSource>, public UnderlyingSource {
53 USING_GARBAGE_COLLECTED_MIXIN(NoopUnderlyingSource);
54 public:
55 ~NoopUnderlyingSource() override { }
56
57 void pullSource() override { }
58 ScriptPromise cancelSource(ScriptState* scriptState, ScriptValue reason) { r eturn ScriptPromise::cast(scriptState, reason); }
59 DEFINE_INLINE_VIRTUAL_TRACE() { UnderlyingSource::trace(visitor); }
60 };
61
62 class PermissiveStrategy final : public StringStream::Strategy {
63 public:
64 bool shouldApplyBackpressure(size_t, ReadableStream*) override { return fals e; }
65 };
66
67 class ExclusiveStreamReaderTest : public ::testing::Test {
68 public:
69 ExclusiveStreamReaderTest()
70 : m_page(DummyPageHolder::create(IntSize(1, 1)))
71 , m_scope(scriptState())
72 , m_exceptionState(ExceptionState::ConstructionContext, "property", "int erface", scriptState()->context()->Global(), isolate())
73 , m_stream(new StringStream(scriptState()->executionContext(), new NoopU nderlyingSource, new PermissiveStrategy))
74 {
75 m_stream->didSourceStart();
76 }
77
78 ~ExclusiveStreamReaderTest()
79 {
80 // We need to call |error| in order to make
81 // ActiveDOMObject::hasPendingActivity return false.
82 m_stream->error(DOMException::create(AbortError, "done"));
83 }
84
85 ScriptState* scriptState() { return ScriptState::forMainWorld(m_page->docume nt().frame()); }
86 v8::Isolate* isolate() { return scriptState()->isolate(); }
87
88 v8::Handle<v8::Function> createCaptor(String* value)
89 {
90 return StringCapturingFunction::createFunction(scriptState(), value);
91 }
92
93 OwnPtr<DummyPageHolder> m_page;
94 ScriptState::Scope m_scope;
95 ExceptionState m_exceptionState;
96 Persistent<StringStream> m_stream;
97 };
98
99 TEST_F(ExclusiveStreamReaderTest, Construct)
100 {
101 ExclusiveStreamReader* reader = new ExclusiveStreamReader(m_stream);
102 EXPECT_TRUE(reader->isActive());
103 }
104
105 TEST_F(ExclusiveStreamReaderTest, Release)
106 {
107 ExclusiveStreamReader* reader = new ExclusiveStreamReader(m_stream);
108 EXPECT_TRUE(reader->isActive());
109 reader->releaseLock();
110 EXPECT_FALSE(reader->isActive());
111
112 ExclusiveStreamReader* another = new ExclusiveStreamReader(m_stream);
113 EXPECT_TRUE(another->isActive());
114 EXPECT_FALSE(reader->isActive());
115 reader->releaseLock();
116 EXPECT_TRUE(another->isActive());
117 EXPECT_FALSE(reader->isActive());
118 }
119
120 TEST_F(ExclusiveStreamReaderTest, MaskState)
121 {
122 m_stream->enqueue("hello");
123 EXPECT_EQ("readable", m_stream->stateString());
124
125 ExclusiveStreamReader* reader = new ExclusiveStreamReader(m_stream);
126 EXPECT_EQ("waiting", m_stream->stateString());
127 EXPECT_EQ("readable", reader->state());
128
129 reader->releaseLock();
130 EXPECT_EQ("readable", m_stream->stateString());
131 EXPECT_EQ("closed", reader->state());
132
133 ExclusiveStreamReader* another = new ExclusiveStreamReader(m_stream);
134 EXPECT_EQ("waiting", m_stream->stateString());
135 EXPECT_EQ("closed", reader->state());
136 EXPECT_EQ("readable", another->state());
137 }
138
139 TEST_F(ExclusiveStreamReaderTest, MaskReady)
140 {
141 m_stream->enqueue("hello");
142 isolate()->RunMicrotasks();
143
144 ExclusiveStreamReader* reader = new ExclusiveStreamReader(m_stream);
145 {
146 String s1, s2;
147 reader->ready(scriptState()).then(createCaptor(&s1));
148 m_stream->ready(scriptState()).then(createCaptor(&s2));
149 isolate()->RunMicrotasks();
150 EXPECT_EQ("undefined", s1);
151 EXPECT_TRUE(s2.isNull());
152
153 reader->releaseLock();
154 isolate()->RunMicrotasks();
155 EXPECT_EQ("undefined", s2);
156 }
157
158 {
159 String s1, s2;
160 reader->ready(scriptState()).then(createCaptor(&s1));
161 m_stream->ready(scriptState()).then(createCaptor(&s2));
162 isolate()->RunMicrotasks();
163 EXPECT_EQ("undefined", s1);
164 EXPECT_EQ("undefined", s2);
165 }
166
167 ExclusiveStreamReader* another = new ExclusiveStreamReader(m_stream);
168 {
169 String s1, s2, s3;
170 reader->ready(scriptState()).then(createCaptor(&s1));
171 m_stream->ready(scriptState()).then(createCaptor(&s2));
172 another->ready(scriptState()).then(createCaptor(&s3));
173 isolate()->RunMicrotasks();
174 EXPECT_EQ("undefined", s1);
175 EXPECT_TRUE(s2.isNull());
176 EXPECT_EQ("undefined", s3);
177
178 // We need to call here to ensure all promises having captors are
179 // resolved or rejected.
180 m_stream->error(DOMException::create(AbortError, "done"));
181 isolate()->RunMicrotasks();
182 }
183 }
184
185 TEST_F(ExclusiveStreamReaderTest, ReaderRead)
186 {
187 m_stream->enqueue("hello");
188 ExclusiveStreamReader* reader = new ExclusiveStreamReader(m_stream);
189
190 EXPECT_EQ(ReadableStream::Readable, m_stream->stateInternal());
191 ScriptValue value = reader->read(scriptState(), m_exceptionState);
192
193 EXPECT_FALSE(m_exceptionState.hadException());
194 String stringValue;
195 EXPECT_TRUE(value.toString(stringValue));
196 EXPECT_EQ("hello", stringValue);
197 }
198
199 TEST_F(ExclusiveStreamReaderTest, StreamReadShouldFailWhenLocked)
200 {
201 m_stream->enqueue("hello");
202 ExclusiveStreamReader* reader = new ExclusiveStreamReader(m_stream);
203 EXPECT_TRUE(reader->isActive());
204
205 EXPECT_EQ(ReadableStream::Readable, m_stream->stateInternal());
206 m_stream->read(scriptState(), m_exceptionState);
207
208 EXPECT_TRUE(m_exceptionState.hadException());
209 EXPECT_EQ(ReadableStream::Readable, m_stream->stateInternal());
210 }
211
212 TEST_F(ExclusiveStreamReaderTest, ReaderReadShouldFailWhenNotLocked)
213 {
214 m_stream->enqueue("hello");
215 ExclusiveStreamReader* reader = new ExclusiveStreamReader(m_stream);
216 reader->releaseLock();
217 EXPECT_FALSE(reader->isActive());
218
219 EXPECT_EQ(ReadableStream::Readable, m_stream->stateInternal());
220 reader->read(scriptState(), m_exceptionState);
221
222 EXPECT_TRUE(m_exceptionState.hadException());
223 EXPECT_EQ(ReadableStream::Readable, m_stream->stateInternal());
224 }
225
226 TEST_F(ExclusiveStreamReaderTest, ClosedReader)
227 {
228 ExclusiveStreamReader* reader = new ExclusiveStreamReader(m_stream);
229
230 m_stream->close();
231
232 EXPECT_EQ("closed", m_stream->stateString());
233 EXPECT_EQ("closed", reader->state());
234 EXPECT_FALSE(reader->isActive());
235
236 String onClosedFulfilled, onClosedRejected;
237 String onReadyFulfilled, onReadyRejected;
238 isolate()->RunMicrotasks();
239 reader->closed(scriptState()).then(createCaptor(&onClosedFulfilled), createC aptor(&onClosedRejected));
240 reader->ready(scriptState()).then(createCaptor(&onReadyFulfilled), createCap tor(&onReadyRejected));
241 EXPECT_TRUE(onClosedFulfilled.isNull());
242 EXPECT_TRUE(onClosedRejected.isNull());
243 EXPECT_TRUE(onReadyFulfilled.isNull());
244 EXPECT_TRUE(onReadyRejected.isNull());
245
246 isolate()->RunMicrotasks();
247 EXPECT_EQ("undefined", onClosedFulfilled);
248 EXPECT_TRUE(onClosedRejected.isNull());
249 EXPECT_EQ("undefined", onReadyFulfilled);
250 EXPECT_TRUE(onReadyRejected.isNull());
251 }
252
253 TEST_F(ExclusiveStreamReaderTest, ErroredReader)
254 {
255 ExclusiveStreamReader* reader = new ExclusiveStreamReader(m_stream);
256
257 m_stream->error(DOMException::create(SyntaxError, "some error"));
258
259 EXPECT_EQ("errored", m_stream->stateString());
260 EXPECT_EQ("errored", reader->state());
261 EXPECT_FALSE(reader->isActive());
262
263 String onClosedFulfilled, onClosedRejected;
264 String onReadyFulfilled, onReadyRejected;
265 reader->closed(scriptState()).then(createCaptor(&onClosedFulfilled), createC aptor(&onClosedRejected));
266 reader->ready(scriptState()).then(createCaptor(&onReadyFulfilled), createCap tor(&onReadyRejected));
267 EXPECT_TRUE(onClosedFulfilled.isNull());
268 EXPECT_TRUE(onClosedRejected.isNull());
269 EXPECT_TRUE(onReadyFulfilled.isNull());
270 EXPECT_TRUE(onReadyRejected.isNull());
271
272 isolate()->RunMicrotasks();
273 EXPECT_TRUE(onClosedFulfilled.isNull());
274 EXPECT_EQ("SyntaxError: some error", onClosedRejected);
275 EXPECT_EQ("undefined", onReadyFulfilled);
276 EXPECT_TRUE(onReadyRejected.isNull());
277 }
278
279 TEST_F(ExclusiveStreamReaderTest, ReadyPromiseShouldNotBeResolvedWhenLocked)
280 {
281 String s;
282 ScriptPromise ready = m_stream->ready(scriptState());
283 ready.then(createCaptor(&s));
284 isolate()->RunMicrotasks();
285 EXPECT_TRUE(s.isNull());
286
287 ExclusiveStreamReader* reader = new ExclusiveStreamReader(m_stream);
288 EXPECT_TRUE(reader->isActive());
289 EXPECT_NE(ready, m_stream->ready(scriptState()));
290
291 isolate()->RunMicrotasks();
292 EXPECT_TRUE(s.isNull());
293
294 // We need to call here to ensure all promises having captors are resolved
295 // or rejected.
296 m_stream->error(DOMException::create(AbortError, "done"));
297 isolate()->RunMicrotasks();
298 }
299
300 TEST_F(ExclusiveStreamReaderTest, ReaderShouldBeReleasedWhenClosed)
301 {
302 ExclusiveStreamReader* reader = new ExclusiveStreamReader(m_stream);
303 EXPECT_TRUE(reader->isActive());
304 m_stream->close();
305 EXPECT_FALSE(reader->isActive());
306 }
307
308 TEST_F(ExclusiveStreamReaderTest, ReaderShouldBeReleasedWhenCanceled)
309 {
310 ExclusiveStreamReader* reader = new ExclusiveStreamReader(m_stream);
311 EXPECT_TRUE(reader->isActive());
312 reader->cancel(scriptState(), ScriptValue(scriptState(), v8::Undefined(isola te())));
313 EXPECT_FALSE(reader->isActive());
314 }
315
316 TEST_F(ExclusiveStreamReaderTest, ReaderShouldBeReleasedWhenErrored)
317 {
318 ExclusiveStreamReader* reader = new ExclusiveStreamReader(m_stream);
319 EXPECT_TRUE(reader->isActive());
320 m_stream->error(DOMException::create(SyntaxError, "some error"));
321 EXPECT_FALSE(reader->isActive());
322 }
323
324 TEST_F(ExclusiveStreamReaderTest, StreamCancelShouldFailWhenLocked)
325 {
326 ExclusiveStreamReader* reader = new ExclusiveStreamReader(m_stream);
327 EXPECT_TRUE(reader->isActive());
328 ScriptPromise p = m_stream->cancel(scriptState(), ScriptValue(scriptState(), v8::Undefined(isolate())));
329 EXPECT_EQ(ReadableStream::Waiting, m_stream->stateInternal());
330 String onFulfilled, onRejected;
331 p.then(createCaptor(&onFulfilled), createCaptor(&onRejected));
332
333 EXPECT_TRUE(onFulfilled.isNull());
334 EXPECT_TRUE(onRejected.isNull());
335 isolate()->RunMicrotasks();
336 EXPECT_TRUE(onFulfilled.isNull());
337 EXPECT_EQ("TypeError: this stream is locked to an ExclusiveStreamReader", on Rejected);
338 }
339
340 TEST_F(ExclusiveStreamReaderTest, ReaderCancelShouldNotWorkWhenNotActive)
341 {
342 ExclusiveStreamReader* reader = new ExclusiveStreamReader(m_stream);
343 reader->releaseLock();
344 EXPECT_FALSE(reader->isActive());
345
346 ScriptPromise p = reader->cancel(scriptState(), ScriptValue(scriptState(), v 8::Undefined(isolate())));
347 EXPECT_EQ(ReadableStream::Waiting, m_stream->stateInternal());
348 String onFulfilled, onRejected;
349 p.then(createCaptor(&onFulfilled), createCaptor(&onRejected));
350
351 EXPECT_TRUE(onFulfilled.isNull());
352 EXPECT_TRUE(onRejected.isNull());
353 isolate()->RunMicrotasks();
354 EXPECT_EQ("undefined", onFulfilled);
355 EXPECT_TRUE(onRejected.isNull());
356 }
357
358 TEST_F(ExclusiveStreamReaderTest, ReadyShouldNotBeResolvedWhileLocked)
359 {
360 String onFulfilled;
361 m_stream->ready(scriptState()).then(createCaptor(&onFulfilled));
362
363 ExclusiveStreamReader* reader = new ExclusiveStreamReader(m_stream);
364
365 m_stream->enqueue("hello");
366 m_stream->enqueue("world");
367
368 ASSERT_EQ("readable", reader->state());
369 reader->read(scriptState(), m_exceptionState);
370 ASSERT_EQ("readable", reader->state());
371 reader->read(scriptState(), m_exceptionState);
372 ASSERT_EQ("waiting", reader->state());
373
374 isolate()->RunMicrotasks();
375 EXPECT_TRUE(onFulfilled.isNull());
376
377 // We need to call here to ensure all promises having captors are resolved
378 // or rejected.
379 m_stream->error(DOMException::create(AbortError, "done"));
380 isolate()->RunMicrotasks();
381 }
382
383 TEST_F(ExclusiveStreamReaderTest, ReadyShouldNotBeResolvedWhenReleasedIfNotReady )
384 {
385 String onFulfilled;
386 m_stream->ready(scriptState()).then(createCaptor(&onFulfilled));
387
388 ExclusiveStreamReader* reader = new ExclusiveStreamReader(m_stream);
389
390 m_stream->enqueue("hello");
391 m_stream->enqueue("world");
392
393 ASSERT_EQ("readable", reader->state());
394 reader->read(scriptState(), m_exceptionState);
395 ASSERT_EQ("readable", reader->state());
396 reader->read(scriptState(), m_exceptionState);
397 ASSERT_EQ("waiting", reader->state());
398
399 reader->releaseLock();
400
401 isolate()->RunMicrotasks();
402 EXPECT_TRUE(onFulfilled.isNull());
403
404 // We need to call here to ensure all promises having captors are resolved
405 // or rejected.
406 m_stream->error(DOMException::create(AbortError, "done"));
407 isolate()->RunMicrotasks();
408 }
409
410 TEST_F(ExclusiveStreamReaderTest, ReadyShouldBeResolvedWhenReleasedIfReady)
411 {
412 String onFulfilled;
413 m_stream->ready(scriptState()).then(createCaptor(&onFulfilled));
414
415 ExclusiveStreamReader* reader = new ExclusiveStreamReader(m_stream);
416
417 m_stream->enqueue("hello");
418 m_stream->enqueue("world");
419
420 ASSERT_EQ("readable", reader->state());
421 reader->read(scriptState(), m_exceptionState);
422 ASSERT_EQ("readable", reader->state());
423
424 isolate()->RunMicrotasks();
425 reader->releaseLock();
426 EXPECT_TRUE(onFulfilled.isNull());
427
428 isolate()->RunMicrotasks();
429 EXPECT_EQ("undefined", onFulfilled);
430 }
431
432 } // namespace
433
434 } // namespace blink
OLDNEW
« no previous file with comments | « Source/core/streams/ExclusiveStreamReader.idl ('k') | Source/core/streams/ReadableStream.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698