Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(86)

Unified Diff: third_party/WebKit/Source/bindings/core/v8/ReadableStreamOperationsTest.cpp

Issue 1492763002: Add a utility class to call stream methods implemented with v8 extras. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@v8-extra-switch
Patch Set: Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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
new file mode 100644
index 0000000000000000000000000000000000000000..e489d64202661ac22916cd8c42bbfe7df2eb4724
--- /dev/null
+++ b/third_party/WebKit/Source/bindings/core/v8/ReadableStreamOperationsTest.cpp
@@ -0,0 +1,307 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "bindings/core/v8/ReadableStreamOperations.h"
+
+#include "bindings/core/v8/ScriptFunction.h"
+#include "bindings/core/v8/ScriptState.h"
+#include "bindings/core/v8/V8Binding.h"
+#include "core/testing/DummyPageHolder.h"
+#include "platform/heap/Handle.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include <v8.h>
+
+namespace blink {
+
+namespace {
+
+class NotReached : public ScriptFunction {
+public:
+ static v8::Local<v8::Function> createFunction(ScriptState* scriptState)
+ {
+ NotReached* self = new NotReached(scriptState);
+ return self->bindToV8Function();
+ }
+
+private:
+ explicit NotReached(ScriptState* scriptState)
+ : ScriptFunction(scriptState)
+ {
+ }
+
+ ScriptValue call(ScriptValue) override;
+};
+
+ScriptValue NotReached::call(ScriptValue)
+{
+ EXPECT_TRUE(false) << "'Unreachable' code was reached";
+ return ScriptValue();
+}
+
+class Iteration final : public GarbageCollectedFinalized<Iteration> {
+public:
+ Iteration()
+ : m_isSet(false)
+ , m_isDone(false)
+ , m_isValid(true) {}
+
+ void set(ScriptValue v)
+ {
+ m_isSet = true;
+ if (v.isEmpty() || !v.v8Value()->IsObject()) {
+ m_isValid = false;
+ return;
+ }
+ v8::Local<v8::Object> object = v.v8Value().As<v8::Object>();
+ v8::Local<v8::Value> done;
+ if (!object->Get(v.scriptState()->context(), v8String(v.isolate(), "done")).ToLocal(&done)
+ || done->IsUndefined()) {
+ m_isValid = false;
+ return;
+ }
+ m_isDone = done->ToBoolean()->Value();
+
+ v8::Local<v8::Value> value;
+ if (!object->Get(v.scriptState()->context(), v8String(v.isolate(), "value")).ToLocal(&value)) {
+ m_isValid = false;
+ return;
+ }
+ m_value = toCoreString(value->ToString());
+ }
+
+ bool isSet() const { return m_isSet; }
+ bool isDone() const { return m_isDone; }
+ bool isValid() const { return m_isValid; }
+ const String& value() const { return m_value; }
+
+ DEFINE_INLINE_TRACE() {}
+
+private:
+ bool m_isSet;
+ bool m_isDone;
+ bool m_isValid;
+ String m_value;
+};
+
+class Function : public ScriptFunction {
+public:
+ static v8::Local<v8::Function> createFunction(ScriptState* scriptState, Iteration* iteration)
+ {
+ Function* self = new Function(scriptState, iteration);
+ return self->bindToV8Function();
+ }
+
+ DEFINE_INLINE_VIRTUAL_TRACE()
+ {
+ visitor->trace(m_iteration);
+ ScriptFunction::trace(visitor);
+ }
+
+private:
+ Function(ScriptState* scriptState, Iteration* iteration)
+ : ScriptFunction(scriptState)
+ , m_iteration(iteration)
+ {
+ }
+
+ ScriptValue call(ScriptValue value) override
+ {
+ m_iteration->set(value);
+ return value;
+ }
+
+ Member<Iteration> m_iteration;
+};
+
+class ReadableStreamOperationsTest : public ::testing::Test {
+public:
+ ReadableStreamOperationsTest()
+ : m_pageHolder(DummyPageHolder::create())
+ {
+ }
+
+ ~ReadableStreamOperationsTest() override
+ {
+ ScriptState::Scope scope(scriptState());
+ // Execute all pending microtasks
+ isolate()->RunMicrotasks();
+ }
+
+ OwnPtr<DummyPageHolder> m_pageHolder;
+ ScriptState* scriptState() const { return ScriptState::forMainWorld(&m_pageHolder->frame()); }
+ v8::Isolate* isolate() const { return scriptState()->isolate(); }
+
+ v8::MaybeLocal<v8::Value> eval(const char* s)
+ {
+ v8::MaybeLocal<v8::String> source = v8::String::NewFromUtf8(isolate(), s, v8::String::kNormalString);
+ if (source.IsEmpty()) {
+ ADD_FAILURE();
+ return v8::MaybeLocal<v8::Value>();
+ }
+ v8::MaybeLocal<v8::Script> script = v8::Script::Compile(scriptState()->context(), source.ToLocalChecked());
+ if (script.IsEmpty()) {
+ ADD_FAILURE() << "Compilation fails";
+ return v8::MaybeLocal<v8::Value>();
+ }
+ return script.ToLocalChecked()->Run(scriptState()->context());
+ }
+ v8::MaybeLocal<v8::Value> evalNoThrow(const char* s)
+ {
+ v8::TryCatch block(isolate());
+ v8::MaybeLocal<v8::Value> r = eval(s);
+ if (block.HasCaught())
+ ADD_FAILURE() << toCoreString(block.Exception()->ToString(isolate())).utf8().data();
+ return r;
+ }
+};
+
+TEST_F(ReadableStreamOperationsTest, IsReadableStream)
+{
+ ScriptState::Scope scope(scriptState());
+
+ {
+ v8::TryCatch block(isolate());
+ EXPECT_FALSE(ReadableStreamOperations::isReadableStream(scriptState(), v8::Undefined(isolate())));
+ EXPECT_FALSE(block.HasCaught());
+ }
+ {
+ v8::TryCatch block(isolate());
+ EXPECT_FALSE(ReadableStreamOperations::isReadableStream(scriptState(), v8::Null(isolate())));
+ EXPECT_FALSE(block.HasCaught());
+ }
+ {
+ v8::TryCatch block(isolate());
+ EXPECT_FALSE(ReadableStreamOperations::isReadableStream(scriptState(), v8::Object::New(isolate())));
+ EXPECT_FALSE(block.HasCaught());
+ }
+ {
+ v8::Local<v8::Value> stream;
+ ASSERT_TRUE(evalNoThrow("new ReadableStream()").ToLocal(&stream));
+
+ v8::TryCatch block(isolate());
+ EXPECT_TRUE(ReadableStreamOperations::isReadableStream(scriptState(), stream));
+ EXPECT_FALSE(block.HasCaught());
+ }
+}
+
+TEST_F(ReadableStreamOperationsTest, IsReadableStreamReaderInvalid)
+{
+ ScriptState::Scope scope(scriptState());
+
+ {
+ v8::TryCatch block(isolate());
+ EXPECT_FALSE(ReadableStreamOperations::isReadableStreamReader(scriptState(), v8::Undefined(isolate())));
+ EXPECT_FALSE(block.HasCaught());
+ }
+ {
+ v8::TryCatch block(isolate());
+ EXPECT_FALSE(ReadableStreamOperations::isReadableStreamReader(scriptState(), v8::Null(isolate())));
+ EXPECT_FALSE(block.HasCaught());
+ }
+ {
+ v8::TryCatch block(isolate());
+ EXPECT_FALSE(ReadableStreamOperations::isReadableStreamReader(scriptState(), v8::Object::New(isolate())));
+ EXPECT_FALSE(block.HasCaught());
+ }
+ {
+ v8::Local<v8::Value> stream;
+ ASSERT_TRUE(evalNoThrow("new ReadableStream()").ToLocal(&stream));
+
+ v8::TryCatch block(isolate());
+ EXPECT_FALSE(ReadableStreamOperations::isReadableStreamReader(scriptState(), stream));
+ EXPECT_FALSE(block.HasCaught());
+ }
+}
+
+TEST_F(ReadableStreamOperationsTest, GetReader)
+{
+ ScriptState::Scope scope(scriptState());
+ v8::Local<v8::Value> stream;
+ ASSERT_TRUE(evalNoThrow("new ReadableStream()").ToLocal(&stream));
+
+ {
+ v8::TryCatch block(isolate());
+ EXPECT_FALSE(ReadableStreamOperations::isLocked(scriptState(), stream));
+ ScriptValue reader = ReadableStreamOperations::getReader(scriptState(), stream);
+ EXPECT_TRUE(ReadableStreamOperations::isLocked(scriptState(), stream));
+ ASSERT_FALSE(reader.isEmpty());
+ EXPECT_FALSE(block.HasCaught());
+
+ EXPECT_FALSE(ReadableStreamOperations::isReadableStream(scriptState(), reader.v8Value()));
+ EXPECT_TRUE(ReadableStreamOperations::isReadableStreamReader(scriptState(), reader.v8Value()));
+ EXPECT_FALSE(block.HasCaught());
+ }
+
+ {
+ // Already locked!
+ v8::TryCatch block(isolate());
+ ScriptValue reader = ReadableStreamOperations::getReader(scriptState(), stream);
+ ASSERT_TRUE(reader.isEmpty());
+ EXPECT_TRUE(block.HasCaught());
+ }
+}
+
+TEST_F(ReadableStreamOperationsTest, IsDisturbed)
+{
+ ScriptState::Scope scope(scriptState());
+ v8::Local<v8::Value> stream;
+ ASSERT_TRUE(evalNoThrow("stream = new ReadableStream()").ToLocal(&stream));
+
+ v8::TryCatch block(isolate());
+ EXPECT_FALSE(ReadableStreamOperations::isDisturbed(scriptState(), stream));
+
+ ASSERT_FALSE(evalNoThrow("stream.cancel()").IsEmpty());
+
+ EXPECT_TRUE(ReadableStreamOperations::isDisturbed(scriptState(), stream));
+ EXPECT_FALSE(block.HasCaught());
+}
+
+TEST_F(ReadableStreamOperationsTest, Read)
+{
+ ScriptState::Scope scope(scriptState());
+ v8::Local<v8::Value> reader;
+ ASSERT_TRUE(evalNoThrow(
+ "var controller;"
+ "function start(c) { controller = c; }"
+ "new ReadableStream({start}).getReader()").ToLocal(&reader));
+ ASSERT_TRUE(ReadableStreamOperations::isReadableStreamReader(scriptState(), reader));
+
+ Iteration* it1 = new Iteration();
+ Iteration* it2 = new Iteration();
+ v8::TryCatch block(isolate());
+ ReadableStreamOperations::read(scriptState(), reader).then(
domenic 2015/12/02 17:53:03 This is workable but kind of takes a lot of suppor
yhirano 2015/12/03 11:18:29 Unfortunately, we cannot use lambda for the purpos
+ Function::createFunction(scriptState(), it1),
+ NotReached::createFunction(scriptState()));
+ ReadableStreamOperations::read(scriptState(), reader).then(
+ Function::createFunction(scriptState(), it2),
+ NotReached::createFunction(scriptState()));
+
+ isolate()->RunMicrotasks();
+ EXPECT_FALSE(it1->isSet());
+ EXPECT_FALSE(it2->isSet());
+
+ ASSERT_FALSE(evalNoThrow("controller.enqueue('hello')").IsEmpty());
+ isolate()->RunMicrotasks();
+ EXPECT_TRUE(it1->isSet());
+ EXPECT_TRUE(it1->isValid());
+ EXPECT_FALSE(it1->isDone());
+ EXPECT_EQ("hello", it1->value());
+ EXPECT_FALSE(it2->isSet());
+
+ ASSERT_FALSE(evalNoThrow("controller.close()").IsEmpty());
+ isolate()->RunMicrotasks();
+ EXPECT_TRUE(it1->isSet());
+ EXPECT_TRUE(it1->isValid());
+ EXPECT_FALSE(it1->isDone());
+ EXPECT_EQ("hello", it1->value());
+ EXPECT_TRUE(it2->isSet());
+ EXPECT_TRUE(it2->isValid());
+ EXPECT_TRUE(it2->isDone());
+}
+
+} // namespace
+
+} // namespace blink
+

Powered by Google App Engine
This is Rietveld 408576698