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

Side by Side Diff: third_party/WebKit/Source/core/streams/ReadableStreamTest.cpp

Issue 2227403002: Remove blink::ReadableStream (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix Created 4 years, 4 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
OLDNEW
(Empty)
1 // Copyright 2014 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 "core/streams/ReadableStream.h"
6
7 #include "bindings/core/v8/ExceptionState.h"
8 #include "bindings/core/v8/ScriptPromiseResolver.h"
9 #include "bindings/core/v8/ScriptState.h"
10 #include "bindings/core/v8/V8Binding.h"
11 #include "core/dom/DOMArrayBuffer.h"
12 #include "core/dom/DOMException.h"
13 #include "core/dom/Document.h"
14 #include "core/dom/ExceptionCode.h"
15 #include "core/streams/ReadableStreamImpl.h"
16 #include "core/streams/ReadableStreamReader.h"
17 #include "core/streams/UnderlyingSource.h"
18 #include "core/testing/DummyPageHolder.h"
19 #include "testing/gmock/include/gmock/gmock-more-actions.h"
20 #include "testing/gmock/include/gmock/gmock.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22 #include <memory>
23
24 namespace blink {
25
26 using ::testing::_;
27 using ::testing::InSequence;
28 using ::testing::Invoke;
29 using ::testing::Return;
30 using ::testing::ReturnPointee;
31
32 namespace {
33
34 using Checkpoint = ::testing::StrictMock<::testing::MockFunction<void(int)>>;
35 using StringStream = ReadableStreamImpl<ReadableStreamChunkTypeTraits<String>>;
36
37 class StringCapturingFunction : public ScriptFunction {
38 public:
39 static v8::Local<v8::Function> createFunction(ScriptState* scriptState, Stri ng* value)
40 {
41 StringCapturingFunction* self = new StringCapturingFunction(scriptState, value);
42 return self->bindToV8Function();
43 }
44
45 private:
46 StringCapturingFunction(ScriptState* scriptState, String* value)
47 : ScriptFunction(scriptState)
48 , m_value(value)
49 {
50 }
51
52 ScriptValue call(ScriptValue value) override
53 {
54 ASSERT(!value.isEmpty());
55 *m_value = toCoreString(value.v8Value()->ToString(getScriptState()->cont ext()).ToLocalChecked());
56 return value;
57 }
58
59 String* m_value;
60 };
61
62 class MockUnderlyingSource : public GarbageCollectedFinalized<MockUnderlyingSour ce>, public UnderlyingSource {
63 USING_GARBAGE_COLLECTED_MIXIN(MockUnderlyingSource);
64 public:
65 ~MockUnderlyingSource() override { }
66 DEFINE_INLINE_VIRTUAL_TRACE()
67 {
68 UnderlyingSource::trace(visitor);
69 }
70
71 MOCK_METHOD0(pullSource, void());
72 MOCK_METHOD2(cancelSource, ScriptPromise(ScriptState*, ScriptValue));
73 };
74
75 class PermissiveStrategy : public StringStream::Strategy {
76 public:
77 bool shouldApplyBackpressure(size_t, ReadableStream*) override { return fals e; }
78 };
79
80 class MockStrategy : public StringStream::Strategy {
81 public:
82 static ::testing::StrictMock<MockStrategy>* create() { return new ::testing: :StrictMock<MockStrategy>; }
83
84 MOCK_METHOD2(shouldApplyBackpressure, bool(size_t, ReadableStream*));
85 MOCK_METHOD2(size, size_t(const String&, ReadableStream*));
86 };
87
88 class ThrowError {
89 public:
90 explicit ThrowError(const String& message)
91 : m_message(message) { }
92
93 void operator()(ExceptionState* exceptionState)
94 {
95 exceptionState->throwTypeError(m_message);
96 }
97
98 private:
99 String m_message;
100 };
101
102 } // unnamed namespace
103
104 // ReadableStream::read and some related functionalities are tested in
105 // ReadableStreamReaderTest.
106 class ReadableStreamTest : public ::testing::Test {
107 public:
108 ReadableStreamTest()
109 : m_page(DummyPageHolder::create(IntSize(1, 1)))
110 , m_underlyingSource(new ::testing::StrictMock<MockUnderlyingSource>)
111 {
112 }
113
114 ~ReadableStreamTest() override
115 {
116 }
117
118 ScriptState* getScriptState() { return ScriptState::forMainWorld(m_page->doc ument().frame()); }
119 v8::Isolate* isolate() { return getScriptState()->isolate(); }
120
121 v8::Local<v8::Function> createCaptor(String* value)
122 {
123 return StringCapturingFunction::createFunction(getScriptState(), value);
124 }
125
126 StringStream* construct(MockStrategy* strategy)
127 {
128 Checkpoint checkpoint;
129 {
130 InSequence s;
131 EXPECT_CALL(checkpoint, Call(0));
132 EXPECT_CALL(*strategy, shouldApplyBackpressure(0, _)).WillOnce(Retur n(true));
133 EXPECT_CALL(checkpoint, Call(1));
134 }
135 StringStream* stream = new StringStream(m_underlyingSource, strategy);
136 checkpoint.Call(0);
137 stream->didSourceStart();
138 checkpoint.Call(1);
139 return stream;
140 }
141 StringStream* construct()
142 {
143 Checkpoint checkpoint;
144 {
145 InSequence s;
146 EXPECT_CALL(checkpoint, Call(0));
147 EXPECT_CALL(*m_underlyingSource, pullSource()).Times(1);
148 EXPECT_CALL(checkpoint, Call(1));
149 }
150 StringStream* stream = new StringStream(m_underlyingSource, new Permissi veStrategy);
151 checkpoint.Call(0);
152 stream->didSourceStart();
153 checkpoint.Call(1);
154 return stream;
155 }
156
157 std::unique_ptr<DummyPageHolder> m_page;
158 Persistent<MockUnderlyingSource> m_underlyingSource;
159 };
160
161 TEST_F(ReadableStreamTest, Start)
162 {
163 ScriptState::Scope scope(getScriptState());
164 ExceptionState exceptionState(ExceptionState::ConstructionContext, "property ", "interface", getScriptState()->context()->Global(), isolate());
165 Checkpoint checkpoint;
166 {
167 InSequence s;
168 EXPECT_CALL(checkpoint, Call(0));
169 EXPECT_CALL(*m_underlyingSource, pullSource()).Times(1);
170 EXPECT_CALL(checkpoint, Call(1));
171 }
172
173 StringStream* stream = new StringStream(m_underlyingSource);
174 EXPECT_FALSE(exceptionState.hadException());
175 EXPECT_FALSE(stream->isStarted());
176 EXPECT_FALSE(stream->isDraining());
177 EXPECT_FALSE(stream->isPulling());
178 EXPECT_FALSE(stream->isDisturbed());
179 EXPECT_EQ(stream->stateInternal(), ReadableStream::Readable);
180
181 checkpoint.Call(0);
182 stream->didSourceStart();
183 checkpoint.Call(1);
184
185 EXPECT_TRUE(stream->isStarted());
186 EXPECT_FALSE(stream->isDraining());
187 EXPECT_TRUE(stream->isPulling());
188 EXPECT_EQ(stream->stateInternal(), ReadableStream::Readable);
189
190 // We need to call |error| in order to make
191 // ActiveDOMObject::hasPendingActivity return false.
192 stream->error(DOMException::create(AbortError, "done"));
193 }
194
195 TEST_F(ReadableStreamTest, StartFail)
196 {
197 ScriptState::Scope scope(getScriptState());
198 ExceptionState exceptionState(ExceptionState::ConstructionContext, "property ", "interface", getScriptState()->context()->Global(), isolate());
199 StringStream* stream = new StringStream(m_underlyingSource);
200 EXPECT_FALSE(exceptionState.hadException());
201 EXPECT_FALSE(stream->isStarted());
202 EXPECT_FALSE(stream->isDraining());
203 EXPECT_FALSE(stream->isPulling());
204 EXPECT_EQ(stream->stateInternal(), ReadableStream::Readable);
205
206 stream->error(DOMException::create(NotFoundError));
207
208 EXPECT_FALSE(stream->isStarted());
209 EXPECT_FALSE(stream->isDraining());
210 EXPECT_FALSE(stream->isPulling());
211 EXPECT_EQ(stream->stateInternal(), ReadableStream::Errored);
212 }
213
214 TEST_F(ReadableStreamTest, ErrorAndEnqueue)
215 {
216 ScriptState::Scope scope(getScriptState());
217 ExceptionState exceptionState(ExceptionState::ConstructionContext, "property ", "interface", getScriptState()->context()->Global(), isolate());
218 StringStream* stream = construct();
219
220 stream->error(DOMException::create(NotFoundError, "error"));
221 EXPECT_EQ(ReadableStream::Errored, stream->stateInternal());
222
223 bool result = stream->enqueue("hello");
224 EXPECT_FALSE(result);
225 EXPECT_EQ(ReadableStream::Errored, stream->stateInternal());
226 }
227
228 TEST_F(ReadableStreamTest, CloseAndEnqueue)
229 {
230 ScriptState::Scope scope(getScriptState());
231 ExceptionState exceptionState(ExceptionState::ConstructionContext, "property ", "interface", getScriptState()->context()->Global(), isolate());
232 StringStream* stream = construct();
233
234 stream->close();
235 EXPECT_EQ(ReadableStream::Closed, stream->stateInternal());
236
237 bool result = stream->enqueue("hello");
238 EXPECT_FALSE(result);
239 EXPECT_EQ(ReadableStream::Closed, stream->stateInternal());
240 }
241
242 TEST_F(ReadableStreamTest, CloseWhenErrored)
243 {
244 ScriptState::Scope scope(getScriptState());
245 ExceptionState exceptionState(ExceptionState::ConstructionContext, "property ", "interface", getScriptState()->context()->Global(), isolate());
246 StringStream* stream = construct();
247 EXPECT_EQ(ReadableStream::Readable, stream->stateInternal());
248
249 stream->error(DOMException::create(NotFoundError, "error"));
250 stream->close();
251
252 EXPECT_EQ(ReadableStream::Errored, stream->stateInternal());
253 }
254
255 TEST_F(ReadableStreamTest, ReadQueue)
256 {
257 ScriptState::Scope scope(getScriptState());
258 ExceptionState exceptionState(ExceptionState::ConstructionContext, "property ", "interface", getScriptState()->context()->Global(), isolate());
259 StringStream* stream = construct();
260 Checkpoint checkpoint;
261
262 {
263 InSequence s;
264 EXPECT_CALL(checkpoint, Call(0));
265 EXPECT_CALL(*m_underlyingSource, pullSource()).Times(1);
266 EXPECT_CALL(checkpoint, Call(1));
267 }
268
269 Deque<std::pair<String, size_t>> queue;
270
271 EXPECT_TRUE(stream->enqueue("hello"));
272 EXPECT_TRUE(stream->enqueue("bye"));
273 EXPECT_EQ(ReadableStream::Readable, stream->stateInternal());
274 EXPECT_FALSE(stream->isPulling());
275
276 checkpoint.Call(0);
277 EXPECT_FALSE(stream->isDisturbed());
278 stream->readInternal(queue);
279 EXPECT_TRUE(stream->isDisturbed());
280 checkpoint.Call(1);
281 ASSERT_EQ(2u, queue.size());
282
283 EXPECT_EQ(std::make_pair(String("hello"), static_cast<size_t>(5)), queue[0]) ;
284 EXPECT_EQ(std::make_pair(String("bye"), static_cast<size_t>(3)), queue[1]);
285
286 EXPECT_EQ(ReadableStream::Readable, stream->stateInternal());
287 EXPECT_TRUE(stream->isPulling());
288 EXPECT_FALSE(stream->isDraining());
289 }
290
291 TEST_F(ReadableStreamTest, CloseWhenReadable)
292 {
293 ScriptState::Scope scope(getScriptState());
294 ExceptionState exceptionState(ExceptionState::ConstructionContext, "property ", "interface", getScriptState()->context()->Global(), isolate());
295 StringStream* stream = construct();
296
297 EXPECT_TRUE(stream->enqueue("hello"));
298 EXPECT_TRUE(stream->enqueue("bye"));
299 stream->close();
300 EXPECT_FALSE(stream->enqueue("should be ignored"));
301
302 EXPECT_EQ(ReadableStream::Readable, stream->stateInternal());
303 EXPECT_FALSE(stream->isPulling());
304 EXPECT_TRUE(stream->isDraining());
305
306 stream->read(getScriptState());
307
308 v8::MicrotasksScope::PerformCheckpoint(isolate());
309
310 EXPECT_EQ(ReadableStream::Readable, stream->stateInternal());
311 EXPECT_FALSE(stream->isPulling());
312 EXPECT_TRUE(stream->isDraining());
313
314 stream->read(getScriptState());
315
316 EXPECT_EQ(ReadableStream::Closed, stream->stateInternal());
317 EXPECT_FALSE(stream->isPulling());
318 EXPECT_TRUE(stream->isDraining());
319 }
320
321 TEST_F(ReadableStreamTest, CancelWhenClosed)
322 {
323 ScriptState::Scope scope(getScriptState());
324 ExceptionState exceptionState(ExceptionState::ConstructionContext, "property ", "interface", getScriptState()->context()->Global(), isolate());
325 StringStream* stream = construct();
326 String onFulfilled, onRejected;
327 stream->close();
328 EXPECT_EQ(ReadableStream::Closed, stream->stateInternal());
329
330 EXPECT_FALSE(stream->isDisturbed());
331 ScriptPromise promise = stream->cancel(getScriptState(), ScriptValue());
332 EXPECT_TRUE(stream->isDisturbed());
333 EXPECT_EQ(ReadableStream::Closed, stream->stateInternal());
334
335 promise.then(createCaptor(&onFulfilled), createCaptor(&onRejected));
336 EXPECT_TRUE(onFulfilled.isNull());
337 EXPECT_TRUE(onRejected.isNull());
338
339 v8::MicrotasksScope::PerformCheckpoint(isolate());
340 EXPECT_EQ("undefined", onFulfilled);
341 EXPECT_TRUE(onRejected.isNull());
342 }
343
344 TEST_F(ReadableStreamTest, CancelWhenErrored)
345 {
346 ScriptState::Scope scope(getScriptState());
347 ExceptionState exceptionState(ExceptionState::ConstructionContext, "property ", "interface", getScriptState()->context()->Global(), isolate());
348 StringStream* stream = construct();
349 String onFulfilled, onRejected;
350 stream->error(DOMException::create(NotFoundError, "error"));
351 EXPECT_EQ(ReadableStream::Errored, stream->stateInternal());
352
353 EXPECT_FALSE(stream->isDisturbed());
354 ScriptPromise promise = stream->cancel(getScriptState(), ScriptValue());
355 EXPECT_TRUE(stream->isDisturbed());
356 EXPECT_EQ(ReadableStream::Errored, stream->stateInternal());
357
358 promise.then(createCaptor(&onFulfilled), createCaptor(&onRejected));
359 EXPECT_TRUE(onFulfilled.isNull());
360 EXPECT_TRUE(onRejected.isNull());
361
362 v8::MicrotasksScope::PerformCheckpoint(isolate());
363 EXPECT_TRUE(onFulfilled.isNull());
364 EXPECT_EQ("NotFoundError: error", onRejected);
365 }
366
367 TEST_F(ReadableStreamTest, CancelWhenReadable)
368 {
369 ScriptState::Scope scope(getScriptState());
370 ExceptionState exceptionState(ExceptionState::ConstructionContext, "property ", "interface", getScriptState()->context()->Global(), isolate());
371 StringStream* stream = construct();
372 String onFulfilled, onRejected;
373 String onCancelFulfilled, onCancelRejected;
374 ScriptValue reason(getScriptState(), v8String(getScriptState()->isolate(), " reason"));
375 ScriptPromise promise = ScriptPromise::cast(getScriptState(), v8String(getSc riptState()->isolate(), "hello"));
376
377 {
378 InSequence s;
379 EXPECT_CALL(*m_underlyingSource, cancelSource(getScriptState(), reason)) .WillOnce(ReturnPointee(&promise));
380 }
381
382 stream->enqueue("hello");
383 EXPECT_EQ(ReadableStream::Readable, stream->stateInternal());
384
385 EXPECT_FALSE(stream->isDisturbed());
386 ScriptPromise cancelResult = stream->cancel(getScriptState(), reason);
387 EXPECT_TRUE(stream->isDisturbed());
388 cancelResult.then(createCaptor(&onCancelFulfilled), createCaptor(&onCancelRe jected));
389
390 EXPECT_NE(promise, cancelResult);
391 EXPECT_EQ(ReadableStream::Closed, stream->stateInternal());
392
393 EXPECT_TRUE(onCancelFulfilled.isNull());
394 EXPECT_TRUE(onCancelRejected.isNull());
395
396 v8::MicrotasksScope::PerformCheckpoint(isolate());
397 EXPECT_EQ("undefined", onCancelFulfilled);
398 EXPECT_TRUE(onCancelRejected.isNull());
399 }
400
401 TEST_F(ReadableStreamTest, CancelWhenLocked)
402 {
403 ScriptState::Scope scope(getScriptState());
404 ExceptionState exceptionState(ExceptionState::ConstructionContext, "property ", "interface", getScriptState()->context()->Global(), isolate());
405 String onFulfilled, onRejected;
406 StringStream* stream = construct();
407 ReadableStreamReader* reader = stream->getReader(getScriptState()->getExecut ionContext(), exceptionState);
408
409 EXPECT_TRUE(reader->isActive());
410 EXPECT_FALSE(exceptionState.hadException());
411 EXPECT_EQ(ReadableStream::Readable, stream->stateInternal());
412
413 EXPECT_FALSE(stream->isDisturbed());
414 stream->cancel(getScriptState(), ScriptValue(getScriptState(), v8::Undefined (isolate()))).then(createCaptor(&onFulfilled), createCaptor(&onRejected));
415 EXPECT_FALSE(stream->isDisturbed());
416
417 EXPECT_TRUE(onFulfilled.isNull());
418 EXPECT_TRUE(onRejected.isNull());
419
420 v8::MicrotasksScope::PerformCheckpoint(isolate());
421
422 EXPECT_TRUE(onFulfilled.isNull());
423 EXPECT_EQ("TypeError: this stream is locked to a ReadableStreamReader", onRe jected);
424 EXPECT_TRUE(reader->isActive());
425 EXPECT_EQ(ReadableStream::Readable, stream->stateInternal());
426 }
427
428 TEST_F(ReadableStreamTest, ReadableArrayBufferStreamCompileTest)
429 {
430 ScriptState::Scope scope(getScriptState());
431 ExceptionState exceptionState(ExceptionState::ConstructionContext, "property ", "interface", getScriptState()->context()->Global(), isolate());
432 // This test tests if ReadableStreamImpl<DOMArrayBuffer> can be
433 // instantiated.
434 new ReadableStreamImpl<ReadableStreamChunkTypeTraits<DOMArrayBuffer>>(m_unde rlyingSource);
435 }
436
437 TEST_F(ReadableStreamTest, ReadableArrayBufferViewStreamCompileTest)
438 {
439 ScriptState::Scope scope(getScriptState());
440 ExceptionState exceptionState(ExceptionState::ConstructionContext, "property ", "interface", getScriptState()->context()->Global(), isolate());
441 // This test tests if ReadableStreamImpl<DOMArrayBufferVIew> can be
442 // instantiated.
443 new ReadableStreamImpl<ReadableStreamChunkTypeTraits<DOMArrayBufferView>>(m_ underlyingSource);
444 }
445
446 TEST_F(ReadableStreamTest, BackpressureOnEnqueueing)
447 {
448 ScriptState::Scope scope(getScriptState());
449 ExceptionState exceptionState(ExceptionState::ConstructionContext, "property ", "interface", getScriptState()->context()->Global(), isolate());
450 auto strategy = MockStrategy::create();
451 Checkpoint checkpoint;
452
453 StringStream* stream = construct(strategy);
454 EXPECT_EQ(ReadableStream::Readable, stream->stateInternal());
455
456 {
457 InSequence s;
458 EXPECT_CALL(checkpoint, Call(0));
459 EXPECT_CALL(*strategy, size(String("hello"), stream)).WillOnce(Return(1) );
460 EXPECT_CALL(*strategy, shouldApplyBackpressure(1, stream)).WillOnce(Retu rn(false));
461 EXPECT_CALL(checkpoint, Call(1));
462 EXPECT_CALL(checkpoint, Call(2));
463 EXPECT_CALL(*strategy, size(String("world"), stream)).WillOnce(Return(2) );
464 EXPECT_CALL(*strategy, shouldApplyBackpressure(3, stream)).WillOnce(Retu rn(true));
465 EXPECT_CALL(checkpoint, Call(3));
466 }
467 checkpoint.Call(0);
468 bool result = stream->enqueue("hello");
469 checkpoint.Call(1);
470 EXPECT_TRUE(result);
471
472 checkpoint.Call(2);
473 result = stream->enqueue("world");
474 checkpoint.Call(3);
475 EXPECT_FALSE(result);
476
477 stream->error(DOMException::create(AbortError, "done"));
478 }
479
480 TEST_F(ReadableStreamTest, BackpressureOnReading)
481 {
482 ScriptState::Scope scope(getScriptState());
483 ExceptionState exceptionState(ExceptionState::ConstructionContext, "property ", "interface", getScriptState()->context()->Global(), isolate());
484 auto strategy = MockStrategy::create();
485 Checkpoint checkpoint;
486
487 StringStream* stream = construct(strategy);
488 EXPECT_EQ(ReadableStream::Readable, stream->stateInternal());
489
490 {
491 InSequence s;
492 EXPECT_CALL(*strategy, size(String("hello"), stream)).WillOnce(Return(2) );
493 EXPECT_CALL(*strategy, shouldApplyBackpressure(2, stream)).WillOnce(Retu rn(false));
494 EXPECT_CALL(*strategy, size(String("world"), stream)).WillOnce(Return(3) );
495 EXPECT_CALL(*strategy, shouldApplyBackpressure(5, stream)).WillOnce(Retu rn(false));
496
497 EXPECT_CALL(checkpoint, Call(0));
498 EXPECT_CALL(*strategy, shouldApplyBackpressure(3, stream)).WillOnce(Retu rn(false));
499 EXPECT_CALL(*m_underlyingSource, pullSource()).Times(1);
500 EXPECT_CALL(checkpoint, Call(1));
501 // shouldApplyBackpressure and pullSource are not called because the
502 // stream is pulling.
503 EXPECT_CALL(checkpoint, Call(2));
504 EXPECT_CALL(*strategy, size(String("foo"), stream)).WillOnce(Return(4));
505 EXPECT_CALL(*strategy, shouldApplyBackpressure(4, stream)).WillOnce(Retu rn(true));
506 EXPECT_CALL(*strategy, size(String("bar"), stream)).WillOnce(Return(5));
507 EXPECT_CALL(*strategy, shouldApplyBackpressure(9, stream)).WillOnce(Retu rn(true));
508 EXPECT_CALL(checkpoint, Call(3));
509 EXPECT_CALL(*strategy, shouldApplyBackpressure(5, stream)).WillOnce(Retu rn(true));
510 EXPECT_CALL(checkpoint, Call(4));
511 }
512 stream->enqueue("hello");
513 stream->enqueue("world");
514
515 checkpoint.Call(0);
516 stream->read(getScriptState());
517 checkpoint.Call(1);
518 stream->read(getScriptState());
519 checkpoint.Call(2);
520 stream->enqueue("foo");
521 stream->enqueue("bar");
522 checkpoint.Call(3);
523 stream->read(getScriptState());
524 checkpoint.Call(4);
525
526 stream->error(DOMException::create(AbortError, "done"));
527 }
528
529 // Note: Detailed tests are on ReadableStreamReaderTest.
530 TEST_F(ReadableStreamTest, ReadableStreamReader)
531 {
532 ScriptState::Scope scope(getScriptState());
533 ExceptionState exceptionState(ExceptionState::ConstructionContext, "property ", "interface", getScriptState()->context()->Global(), isolate());
534 StringStream* stream = construct();
535 ReadableStreamReader* reader = stream->getReader(getScriptState()->getExecut ionContext(), exceptionState);
536
537 ASSERT_TRUE(reader);
538 EXPECT_FALSE(exceptionState.hadException());
539 EXPECT_TRUE(reader->isActive());
540 EXPECT_TRUE(stream->isLockedTo(reader));
541
542 ReadableStreamReader* another = stream->getReader(getScriptState()->getExecu tionContext(), exceptionState);
543 ASSERT_EQ(nullptr, another);
544 EXPECT_TRUE(exceptionState.hadException());
545 EXPECT_TRUE(reader->isActive());
546 EXPECT_TRUE(stream->isLockedTo(reader));
547 }
548
549 TEST_F(ReadableStreamTest, GetClosedReader)
550 {
551 ScriptState::Scope scope(getScriptState());
552 ExceptionState exceptionState(ExceptionState::ConstructionContext, "property ", "interface", getScriptState()->context()->Global(), isolate());
553 StringStream* stream = construct();
554 stream->close();
555 ReadableStreamReader* reader = stream->getReader(getScriptState()->getExecut ionContext(), exceptionState);
556
557 ASSERT_TRUE(reader);
558 EXPECT_FALSE(exceptionState.hadException());
559
560 String onFulfilled, onRejected;
561 reader->closed(getScriptState()).then(createCaptor(&onFulfilled), createCapt or(&onRejected));
562
563 EXPECT_TRUE(reader->isActive());
564 EXPECT_TRUE(onFulfilled.isNull());
565 EXPECT_TRUE(onRejected.isNull());
566
567 v8::MicrotasksScope::PerformCheckpoint(isolate());
568 EXPECT_EQ("undefined", onFulfilled);
569 EXPECT_TRUE(onRejected.isNull());
570 }
571
572 TEST_F(ReadableStreamTest, GetErroredReader)
573 {
574 ScriptState::Scope scope(getScriptState());
575 ExceptionState exceptionState(ExceptionState::ConstructionContext, "property ", "interface", getScriptState()->context()->Global(), isolate());
576 StringStream* stream = construct();
577 stream->error(DOMException::create(SyntaxError, "some error"));
578 ReadableStreamReader* reader = stream->getReader(getScriptState()->getExecut ionContext(), exceptionState);
579
580 ASSERT_TRUE(reader);
581 EXPECT_FALSE(exceptionState.hadException());
582
583 String onFulfilled, onRejected;
584 reader->closed(getScriptState()).then(createCaptor(&onFulfilled), createCapt or(&onRejected));
585
586 EXPECT_TRUE(reader->isActive());
587 EXPECT_TRUE(onFulfilled.isNull());
588 EXPECT_TRUE(onRejected.isNull());
589
590 v8::MicrotasksScope::PerformCheckpoint(isolate());
591 EXPECT_TRUE(onFulfilled.isNull());
592 EXPECT_EQ("SyntaxError: some error", onRejected);
593 }
594
595 TEST_F(ReadableStreamTest, StrictStrategy)
596 {
597 ScriptState::Scope scope(getScriptState());
598 ExceptionState exceptionState(ExceptionState::ConstructionContext, "property ", "interface", getScriptState()->context()->Global(), isolate());
599 Checkpoint checkpoint;
600 {
601 InSequence s;
602 EXPECT_CALL(checkpoint, Call(0));
603 EXPECT_CALL(checkpoint, Call(1));
604 EXPECT_CALL(*m_underlyingSource, pullSource());
605 EXPECT_CALL(checkpoint, Call(2));
606 EXPECT_CALL(checkpoint, Call(3));
607 EXPECT_CALL(*m_underlyingSource, pullSource());
608 EXPECT_CALL(checkpoint, Call(4));
609 EXPECT_CALL(checkpoint, Call(5));
610 EXPECT_CALL(checkpoint, Call(6));
611 EXPECT_CALL(checkpoint, Call(7));
612 EXPECT_CALL(checkpoint, Call(8));
613 EXPECT_CALL(checkpoint, Call(9));
614 EXPECT_CALL(*m_underlyingSource, pullSource());
615 }
616 StringStream* stream = new StringStream(m_underlyingSource, new StringStream ::StrictStrategy);
617 ReadableStreamReader* reader = stream->getReader(getScriptState()->getExecut ionContext(), exceptionState);
618
619 checkpoint.Call(0);
620 stream->didSourceStart();
621
622 checkpoint.Call(1);
623 EXPECT_FALSE(stream->isPulling());
624 reader->read(getScriptState());
625 EXPECT_TRUE(stream->isPulling());
626 checkpoint.Call(2);
627 stream->enqueue("hello");
628 EXPECT_FALSE(stream->isPulling());
629 checkpoint.Call(3);
630 reader->read(getScriptState());
631 EXPECT_TRUE(stream->isPulling());
632 checkpoint.Call(4);
633 reader->read(getScriptState());
634 EXPECT_TRUE(stream->isPulling());
635 checkpoint.Call(5);
636 stream->enqueue("hello");
637 EXPECT_FALSE(stream->isPulling());
638 checkpoint.Call(6);
639 stream->enqueue("hello");
640 EXPECT_FALSE(stream->isPulling());
641 checkpoint.Call(7);
642 stream->enqueue("hello");
643 EXPECT_FALSE(stream->isPulling());
644 checkpoint.Call(8);
645 reader->read(getScriptState());
646 EXPECT_FALSE(stream->isPulling());
647 checkpoint.Call(9);
648 reader->read(getScriptState());
649 EXPECT_TRUE(stream->isPulling());
650
651 stream->error(DOMException::create(AbortError, "done"));
652 }
653
654 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698