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