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