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 |