TEST_F(ReadableStreamTest, CancelWhenReadable) { ScriptState::Scope scope(scriptState()); ExceptionState exceptionState(ExceptionState::ConstructionContext, "property", "interface", scriptState()->context()->Global(), isolate()); StringStream* stream = construct(); String onFulfilled, onRejected; String onCancelFulfilled, onCancelRejected; ScriptValue reason(scriptState(), v8String(scriptState()->isolate(), "reason")); ScriptPromise promise = ScriptPromise::cast(scriptState(), v8String(scriptState()->isolate(), "hello")); { InSequence s; EXPECT_CALL(*m_underlyingSource, cancelSource(scriptState(), reason)).WillOnce(ReturnPointee(&promise)); } stream->enqueue("hello"); EXPECT_EQ(ReadableStream::Readable, stream->stateInternal()); EXPECT_FALSE(stream->isDisturbed()); ScriptPromise cancelResult = stream->cancel(scriptState(), reason); EXPECT_TRUE(stream->isDisturbed()); cancelResult.then(createCaptor(&onCancelFulfilled), createCaptor(&onCancelRejected)); EXPECT_NE(promise, cancelResult); EXPECT_EQ(ReadableStream::Closed, stream->stateInternal()); EXPECT_TRUE(onCancelFulfilled.isNull()); EXPECT_TRUE(onCancelRejected.isNull()); isolate()->RunMicrotasks(); EXPECT_EQ("undefined", onCancelFulfilled); EXPECT_TRUE(onCancelRejected.isNull()); }
TEST_F(ScriptPromiseTest, rejectWithExceptionState) { String onFulfilled, onRejected; ScriptPromise promise = ScriptPromise::rejectWithDOMException(scriptState(), DOMException::create(SyntaxError, "some syntax error")); promise.then(Function::create(isolate(), &onFulfilled), Function::create(isolate(), &onRejected)); ASSERT_FALSE(promise.isEmpty()); EXPECT_EQ(String(), onFulfilled); EXPECT_EQ(String(), onRejected); isolate()->RunMicrotasks(); EXPECT_EQ(String(), onFulfilled); EXPECT_EQ("SyntaxError: some syntax error", onRejected); }
void PaymentRequestUpdateEvent::updateWith(ScriptState* scriptState, ScriptPromise promise, ExceptionState& exceptionState) { if (!m_updater) return; if (!isBeingDispatched()) { exceptionState.throwDOMException( InvalidStateError, "Cannot update details when the event is not being dispatched"); return; } if (m_waitForUpdate) { exceptionState.throwDOMException(InvalidStateError, "Cannot update details twice"); return; } stopImmediatePropagation(); m_waitForUpdate = true; m_abortTimer.stop(); promise.then( UpdatePaymentDetailsFunction::createFunction(scriptState, m_updater), UpdatePaymentDetailsErrorFunction::createFunction(scriptState, m_updater)); }
TEST_F(ScriptPromiseTest, rejectThen) { RefPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState()); ScriptPromise promise = resolver->promise(); String onFulfilled, onRejected; resolver->reject("hello"); promise.then(Function::create(isolate(), &onFulfilled), Function::create(isolate(), &onRejected)); ASSERT_FALSE(promise.isEmpty()); EXPECT_EQ(String(), onFulfilled); EXPECT_EQ(String(), onRejected); isolate()->RunMicrotasks(); EXPECT_EQ(String(), onFulfilled); EXPECT_EQ("hello", onRejected); }
TEST_F(ScriptPromiseTest, reject) { String onFulfilled, onRejected; ScriptValue value = ScriptValue(scriptState(), v8String(isolate(), "hello")); ScriptPromise promise = ScriptPromise::reject(scriptState(), ScriptValue(value)); promise.then(Function::create(isolate(), &onFulfilled), Function::create(isolate(), &onRejected)); ASSERT_FALSE(promise.isEmpty()); ASSERT_TRUE(promise.v8Value()->IsPromise()); EXPECT_EQ(String(), onFulfilled); EXPECT_EQ(String(), onRejected); isolate()->RunMicrotasks(); EXPECT_EQ(String(), onFulfilled); EXPECT_EQ("hello", onRejected); }
ScriptPromise Body::text(ScriptState* scriptState) { ScriptPromise promise = rejectInvalidConsumption(scriptState); if (!promise.isEmpty()) return promise; // See above comment. if (!scriptState->executionContext()) return ScriptPromise(); ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); promise = resolver->promise(); if (bodyBuffer()) { bodyBuffer()->startLoading(scriptState->executionContext(), FetchDataLoader::createLoaderAsString(), new BodyTextConsumer(resolver)); } else { resolver->resolve(String()); } return promise; }
ScriptPromise Body::json(ScriptState* scriptState) { ScriptPromise promise = rejectInvalidConsumption(scriptState); if (!promise.isEmpty()) return promise; // See above comment. if (!scriptState->executionContext()) return ScriptPromise(); ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); promise = resolver->promise(); if (bodyBuffer()) { bodyBuffer()->startLoading(scriptState->executionContext(), FetchDataLoader::createLoaderAsString(), new BodyJsonConsumer(resolver)); } else { resolver->reject(V8ThrowException::createSyntaxError(scriptState->isolate(), "Unexpected end of input")); } return promise; }
void AcceptConnectionObserver::acceptConnection(ScriptState* scriptState, ScriptPromise value, ExceptionState& exceptionState) { if (m_state != Initial) { exceptionState.throwDOMException(InvalidStateError, "acceptConnection was already called."); return; } m_state = Pending; value.then( ThenFunction::createFunction(scriptState, this, ThenFunction::Fulfilled), ThenFunction::createFunction(scriptState, this, ThenFunction::Rejected)); }
TEST_F(ReadableStreamTest, CancelWhenErrored) { ScriptState::Scope scope(scriptState()); ExceptionState exceptionState(ExceptionState::ConstructionContext, "property", "interface", scriptState()->context()->Global(), isolate()); StringStream* stream = construct(); String onFulfilled, onRejected; stream->error(DOMException::create(NotFoundError, "error")); EXPECT_EQ(ReadableStream::Errored, stream->stateInternal()); EXPECT_FALSE(stream->isDisturbed()); ScriptPromise promise = stream->cancel(scriptState(), ScriptValue()); EXPECT_TRUE(stream->isDisturbed()); EXPECT_EQ(ReadableStream::Errored, stream->stateInternal()); promise.then(createCaptor(&onFulfilled), createCaptor(&onRejected)); EXPECT_TRUE(onFulfilled.isNull()); EXPECT_TRUE(onRejected.isNull()); isolate()->RunMicrotasks(); EXPECT_TRUE(onFulfilled.isNull()); EXPECT_EQ("NotFoundError: error", onRejected); }
ScriptPromise Body::blob(ScriptState* scriptState) { ScriptPromise promise = rejectInvalidConsumption(scriptState); if (!promise.isEmpty()) return promise; // See above comment. if (!scriptState->executionContext()) return ScriptPromise(); ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); promise = resolver->promise(); if (bodyBuffer()) { bodyBuffer()->startLoading(scriptState->executionContext(), FetchDataLoader::createLoaderAsBlobHandle(mimeType()), new BodyBlobConsumer(resolver)); } else { OwnPtr<BlobData> blobData = BlobData::create(); blobData->setContentType(mimeType()); resolver->resolve(Blob::create(BlobDataHandle::create(blobData.release(), 0))); } return promise; }
TEST_F(ScriptPromiseTest, castPromise) { ScriptPromise promise = ScriptPromiseResolver::create(scriptState())->promise(); ScriptPromise newPromise = ScriptPromise::cast(scriptState(), promise.v8Value()); ASSERT_FALSE(promise.isEmpty()); EXPECT_EQ(promise.v8Value(), newPromise.v8Value()); }
ScriptPromise AcceptConnectionObserver::respondWith(ScriptState* scriptState, ScriptPromise value, ExceptionState& exceptionState) { if (m_state != Initial) { return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(InvalidStateError, "respondWith was already called.")); } m_state = Pending; m_resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = m_resolver->promise(); value.then( ThenFunction::createFunction(scriptState, this, ThenFunction::Fulfilled), ThenFunction::createFunction(scriptState, this, ThenFunction::Rejected)); return promise; }
ScriptPromise Body::arrayBuffer(ScriptState* scriptState) { ScriptPromise promise = rejectInvalidConsumption(scriptState); if (!promise.isEmpty()) return promise; // When the main thread sends a V8::TerminateExecution() signal to a worker // thread, any V8 API on the worker thread starts returning an empty // handle. This can happen in Body::readAsync. To avoid the situation, we // first check the ExecutionContext and return immediately if it's already // gone (which means that the V8::TerminateExecution() signal has been sent // to this worker thread). if (!scriptState->executionContext()) return ScriptPromise(); ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); promise = resolver->promise(); if (bodyBuffer()) { bodyBuffer()->startLoading(scriptState->executionContext(), FetchDataLoader::createLoaderAsArrayBuffer(), new BodyArrayBufferConsumer(resolver)); } else { resolver->resolve(DOMArrayBuffer::create(0u, 1)); } return promise; }