| Index: third_party/WebKit/Source/bindings/core/v8/ReadableStreamOperationsTest.cpp
|
| diff --git a/third_party/WebKit/Source/bindings/core/v8/ReadableStreamOperationsTest.cpp b/third_party/WebKit/Source/bindings/core/v8/ReadableStreamOperationsTest.cpp
|
| index 0339a605dbd179b96c5c6349f822fefbaef88387..2a42db4f32abf3edc301a4cc3829887111e54c61 100644
|
| --- a/third_party/WebKit/Source/bindings/core/v8/ReadableStreamOperationsTest.cpp
|
| +++ b/third_party/WebKit/Source/bindings/core/v8/ReadableStreamOperationsTest.cpp
|
| @@ -7,11 +7,16 @@
|
| #include "bindings/core/v8/ExceptionState.h"
|
| #include "bindings/core/v8/ScriptFunction.h"
|
| #include "bindings/core/v8/ScriptState.h"
|
| +#include "bindings/core/v8/ScriptValue.h"
|
| +#include "bindings/core/v8/ScriptWrappable.h"
|
| #include "bindings/core/v8/V8Binding.h"
|
| #include "bindings/core/v8/V8BindingForTesting.h"
|
| #include "bindings/core/v8/V8BindingMacros.h"
|
| #include "bindings/core/v8/V8IteratorResultValue.h"
|
| #include "bindings/core/v8/V8ThrowException.h"
|
| +#include "core/dom/Document.h"
|
| +#include "core/streams/ReadableStreamController.h"
|
| +#include "core/streams/UnderlyingSourceBase.h"
|
| #include "platform/heap/Handle.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
| #include <v8.h>
|
| @@ -108,9 +113,29 @@ private:
|
| Member<Iteration> m_iteration;
|
| };
|
|
|
| +class UnderlyingSourceTest final : public UnderlyingSourceBase {
|
| +public:
|
| + UnderlyingSourceTest(ScriptState* scriptState)
|
| + : UnderlyingSourceBase(scriptState)
|
| + {
|
| + }
|
| +
|
| + // Just expose the controller methods for easy testing
|
| + void enqueue(ScriptValue v) { controller()->enqueue(v); }
|
| + void close() { controller()->close(); }
|
| + void error(ScriptValue e) { controller()->error(e); }
|
| + double desiredSize() { return controller()->desiredSize(); }
|
| +};
|
| +
|
| class ReadableStreamOperationsTest : public ::testing::Test {
|
| public:
|
| - ReadableStreamOperationsTest() : m_scope(v8::Isolate::GetCurrent()), m_block(isolate()) {}
|
| + ReadableStreamOperationsTest()
|
| + : m_scope(v8::Isolate::GetCurrent())
|
| + , m_block(isolate())
|
| + , m_document(Document::create())
|
| + {
|
| + scriptState()->setExecutionContext(m_document.get());
|
| + }
|
| ~ReadableStreamOperationsTest() override
|
| {
|
| // Execute all pending microtasks
|
| @@ -121,24 +146,24 @@ public:
|
| ScriptState* scriptState() const { return m_scope.scriptState(); }
|
| v8::Isolate* isolate() const { return scriptState()->isolate(); }
|
|
|
| - v8::MaybeLocal<v8::Value> eval(const char* s)
|
| + ScriptValue eval(const char* s)
|
| {
|
| v8::Local<v8::String> source;
|
| v8::Local<v8::Script> script;
|
| if (!v8Call(v8::String::NewFromUtf8(isolate(), s, v8::NewStringType::kNormal), source)) {
|
| ADD_FAILURE();
|
| - return v8::MaybeLocal<v8::Value>();
|
| + return ScriptValue();
|
| }
|
| if (!v8Call(v8::Script::Compile(scriptState()->context(), source), script)) {
|
| ADD_FAILURE() << "Compilation fails";
|
| - return v8::MaybeLocal<v8::Value>();
|
| + return ScriptValue();
|
| }
|
| - return script->Run(scriptState()->context());
|
| + return ScriptValue(scriptState(), script->Run(scriptState()->context()));
|
| }
|
| - v8::MaybeLocal<v8::Value> evalWithPrintingError(const char* s)
|
| + ScriptValue evalWithPrintingError(const char* s)
|
| {
|
| v8::TryCatch block(isolate());
|
| - v8::MaybeLocal<v8::Value> r = eval(s);
|
| + ScriptValue r = eval(s);
|
| if (block.HasCaught()) {
|
| ADD_FAILURE() << toCoreString(block.Exception()->ToString(isolate())).utf8().data();
|
| block.ReThrow();
|
| @@ -148,33 +173,34 @@ public:
|
|
|
| V8TestingScope m_scope;
|
| v8::TryCatch m_block;
|
| + RefPtrWillBePersistent<Document> m_document;
|
| };
|
|
|
| TEST_F(ReadableStreamOperationsTest, IsReadableStream)
|
| {
|
| - EXPECT_FALSE(ReadableStreamOperations::isReadableStream(scriptState(), v8::Undefined(isolate())));
|
| - EXPECT_FALSE(ReadableStreamOperations::isReadableStream(scriptState(), v8::Null(isolate())));
|
| - EXPECT_FALSE(ReadableStreamOperations::isReadableStream(scriptState(), v8::Object::New(isolate())));
|
| - v8::Local<v8::Value> stream;
|
| - ASSERT_TRUE(v8Call(evalWithPrintingError("new ReadableStream()"), stream));
|
| + EXPECT_FALSE(ReadableStreamOperations::isReadableStream(scriptState(), ScriptValue(scriptState(), v8::Undefined(isolate()))));
|
| + EXPECT_FALSE(ReadableStreamOperations::isReadableStream(scriptState(), ScriptValue::createNull(scriptState())));
|
| + EXPECT_FALSE(ReadableStreamOperations::isReadableStream(scriptState(), ScriptValue(scriptState(), v8::Object::New(isolate()))));
|
| + ScriptValue stream = evalWithPrintingError("new ReadableStream()");
|
| + EXPECT_FALSE(stream.isEmpty());
|
| EXPECT_TRUE(ReadableStreamOperations::isReadableStream(scriptState(), stream));
|
| }
|
|
|
| TEST_F(ReadableStreamOperationsTest, IsReadableStreamReaderInvalid)
|
| {
|
| - EXPECT_FALSE(ReadableStreamOperations::isReadableStreamReader(scriptState(), v8::Undefined(isolate())));
|
| - EXPECT_FALSE(ReadableStreamOperations::isReadableStreamReader(scriptState(), v8::Null(isolate())));
|
| - EXPECT_FALSE(ReadableStreamOperations::isReadableStreamReader(scriptState(), v8::Object::New(isolate())));
|
| - v8::Local<v8::Value> stream;
|
| - ASSERT_TRUE(v8Call(evalWithPrintingError("new ReadableStream()"), stream));
|
| + EXPECT_FALSE(ReadableStreamOperations::isReadableStreamReader(scriptState(), ScriptValue(scriptState(), v8::Undefined(isolate()))));
|
| + EXPECT_FALSE(ReadableStreamOperations::isReadableStreamReader(scriptState(), ScriptValue::createNull(scriptState())));
|
| + EXPECT_FALSE(ReadableStreamOperations::isReadableStreamReader(scriptState(), ScriptValue(scriptState(), v8::Object::New(isolate()))));
|
| + ScriptValue stream = evalWithPrintingError("new ReadableStream()");
|
| + EXPECT_FALSE(stream.isEmpty());
|
|
|
| EXPECT_FALSE(ReadableStreamOperations::isReadableStreamReader(scriptState(), stream));
|
| }
|
|
|
| TEST_F(ReadableStreamOperationsTest, GetReader)
|
| {
|
| - v8::Local<v8::Value> stream;
|
| - ASSERT_TRUE(v8Call(evalWithPrintingError("new ReadableStream()"), stream));
|
| + ScriptValue stream = evalWithPrintingError("new ReadableStream()");
|
| + EXPECT_FALSE(stream.isEmpty());
|
|
|
| EXPECT_FALSE(ReadableStreamOperations::isLocked(scriptState(), stream));
|
| ScriptValue reader;
|
| @@ -186,8 +212,8 @@ TEST_F(ReadableStreamOperationsTest, GetReader)
|
| EXPECT_TRUE(ReadableStreamOperations::isLocked(scriptState(), stream));
|
| ASSERT_FALSE(reader.isEmpty());
|
|
|
| - EXPECT_FALSE(ReadableStreamOperations::isReadableStream(scriptState(), reader.v8Value()));
|
| - EXPECT_TRUE(ReadableStreamOperations::isReadableStreamReader(scriptState(), reader.v8Value()));
|
| + EXPECT_FALSE(ReadableStreamOperations::isReadableStream(scriptState(), reader));
|
| + EXPECT_TRUE(ReadableStreamOperations::isReadableStreamReader(scriptState(), reader));
|
|
|
| // Already locked!
|
| {
|
| @@ -200,23 +226,23 @@ TEST_F(ReadableStreamOperationsTest, GetReader)
|
|
|
| TEST_F(ReadableStreamOperationsTest, IsDisturbed)
|
| {
|
| - v8::Local<v8::Value> stream;
|
| - ASSERT_TRUE(v8Call(evalWithPrintingError("stream = new ReadableStream()"), stream));
|
| + ScriptValue stream = evalWithPrintingError("stream = new ReadableStream()");
|
| + EXPECT_FALSE(stream.isEmpty());
|
|
|
| EXPECT_FALSE(ReadableStreamOperations::isDisturbed(scriptState(), stream));
|
|
|
| - ASSERT_FALSE(evalWithPrintingError("stream.cancel()").IsEmpty());
|
| + ASSERT_FALSE(evalWithPrintingError("stream.cancel()").isEmpty());
|
|
|
| EXPECT_TRUE(ReadableStreamOperations::isDisturbed(scriptState(), stream));
|
| }
|
|
|
| TEST_F(ReadableStreamOperationsTest, Read)
|
| {
|
| - v8::Local<v8::Value> reader;
|
| - ASSERT_TRUE(v8Call(evalWithPrintingError(
|
| + ScriptValue reader = evalWithPrintingError(
|
| "var controller;"
|
| "function start(c) { controller = c; }"
|
| - "new ReadableStream({start}).getReader()"), reader));
|
| + "new ReadableStream({start}).getReader()");
|
| + EXPECT_FALSE(reader.isEmpty());
|
| ASSERT_TRUE(ReadableStreamOperations::isReadableStreamReader(scriptState(), reader));
|
|
|
| Iteration* it1 = new Iteration();
|
| @@ -232,7 +258,7 @@ TEST_F(ReadableStreamOperationsTest, Read)
|
| EXPECT_FALSE(it1->isSet());
|
| EXPECT_FALSE(it2->isSet());
|
|
|
| - ASSERT_FALSE(evalWithPrintingError("controller.enqueue('hello')").IsEmpty());
|
| + ASSERT_FALSE(evalWithPrintingError("controller.enqueue('hello')").isEmpty());
|
| isolate()->RunMicrotasks();
|
| EXPECT_TRUE(it1->isSet());
|
| EXPECT_TRUE(it1->isValid());
|
| @@ -240,7 +266,7 @@ TEST_F(ReadableStreamOperationsTest, Read)
|
| EXPECT_EQ("hello", it1->value());
|
| EXPECT_FALSE(it2->isSet());
|
|
|
| - ASSERT_FALSE(evalWithPrintingError("controller.close()").IsEmpty());
|
| + ASSERT_FALSE(evalWithPrintingError("controller.close()").isEmpty());
|
| isolate()->RunMicrotasks();
|
| EXPECT_TRUE(it1->isSet());
|
| EXPECT_TRUE(it1->isValid());
|
| @@ -251,6 +277,63 @@ TEST_F(ReadableStreamOperationsTest, Read)
|
| EXPECT_TRUE(it2->isDone());
|
| }
|
|
|
| +TEST_F(ReadableStreamOperationsTest, CreateReadableStreamWithCustomUnderlyingSourceAndStrategy)
|
| +{
|
| + auto underlyingSource = new UnderlyingSourceTest(scriptState());
|
| +
|
| + ScriptValue strategy = ReadableStreamOperations::createCountQueuingStrategy(scriptState(), 10);
|
| + ASSERT_FALSE(strategy.isEmpty());
|
| +
|
| + ScriptValue stream = ReadableStreamOperations::createReadableStream(scriptState(), underlyingSource, strategy);
|
| + ASSERT_FALSE(stream.isEmpty());
|
| +
|
| + EXPECT_EQ(10, underlyingSource->desiredSize());
|
| +
|
| + underlyingSource->enqueue(ScriptValue::from(scriptState(), "a"));
|
| + EXPECT_EQ(9, underlyingSource->desiredSize());
|
| +
|
| + underlyingSource->enqueue(ScriptValue::from(scriptState(), "b"));
|
| + EXPECT_EQ(8, underlyingSource->desiredSize());
|
| +
|
| + ScriptValue reader;
|
| + {
|
| + TrackExceptionState es;
|
| + reader = ReadableStreamOperations::getReader(scriptState(), stream, es);
|
| + ASSERT_FALSE(es.hadException());
|
| + }
|
| + ASSERT_FALSE(reader.isEmpty());
|
| +
|
| + Iteration* it1 = new Iteration();
|
| + Iteration* it2 = new Iteration();
|
| + Iteration* it3 = new Iteration();
|
| + ReadableStreamOperations::read(scriptState(), reader).then(Function::createFunction(scriptState(), it1), NotReached::createFunction(scriptState()));
|
| + ReadableStreamOperations::read(scriptState(), reader).then(Function::createFunction(scriptState(), it2), NotReached::createFunction(scriptState()));
|
| + ReadableStreamOperations::read(scriptState(), reader).then(Function::createFunction(scriptState(), it3), NotReached::createFunction(scriptState()));
|
| +
|
| + isolate()->RunMicrotasks();
|
| +
|
| + EXPECT_EQ(10, underlyingSource->desiredSize());
|
| +
|
| + EXPECT_TRUE(it1->isSet());
|
| + EXPECT_TRUE(it1->isValid());
|
| + EXPECT_FALSE(it1->isDone());
|
| + EXPECT_EQ("a", it1->value());
|
| +
|
| + EXPECT_TRUE(it2->isSet());
|
| + EXPECT_TRUE(it2->isValid());
|
| + EXPECT_FALSE(it2->isDone());
|
| + EXPECT_EQ("b", it2->value());
|
| +
|
| + EXPECT_FALSE(it3->isSet());
|
| +
|
| + underlyingSource->close();
|
| + isolate()->RunMicrotasks();
|
| +
|
| + EXPECT_TRUE(it3->isSet());
|
| + EXPECT_TRUE(it3->isValid());
|
| + EXPECT_TRUE(it3->isDone());
|
| +}
|
| +
|
| } // namespace
|
|
|
| } // namespace blink
|
|
|