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

Side by Side 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 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 "bindings/core/v8/ReadableStreamOperations.h"
7
8 #include "bindings/core/v8/ExceptionState.h"
9 #include "bindings/core/v8/ScriptFunction.h"
10 #include "bindings/core/v8/ScriptState.h"
11 #include "bindings/core/v8/V8Binding.h"
12 #include "bindings/core/v8/V8BindingForTesting.h"
13 #include "bindings/core/v8/V8BindingMacros.h"
14 #include "bindings/core/v8/V8IteratorResultValue.h"
15 #include "bindings/core/v8/V8ThrowException.h"
16 #include "platform/heap/Handle.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18 #include <v8.h>
19
20 namespace blink {
21
22 namespace {
23
24 // Unpacks |item|, stores the value of "done" member to |done| and returns
25 // the value of "value" member. Returns an empty handle when errored.
26 v8::MaybeLocal<v8::Value> unpack(ScriptState* scriptState, v8::Local<v8::Value> item, bool* done)
27 {
28 if (!item->IsObject()) {
29 V8ThrowException::throwTypeError(scriptState->isolate(), "The iteration item is not an object.");
30 return v8::MaybeLocal<v8::Value>();
31 }
32 v8::Local<v8::Object> object = item.As<v8::Object>();
33 v8::Local<v8::Value> doneValue;
34 if (!v8Call(object->Get(scriptState->context(), v8String(scriptState->isolat e(), "done")), doneValue))
35 return v8::MaybeLocal<v8::Value>();
36 v8::MaybeLocal<v8::Value> r = object->Get(scriptState->context(), v8String(s criptState->isolate(), "value"));
37 if (!r.IsEmpty())
38 *done = doneValue->ToBoolean()->Value();
39 return r;
40 }
41
42 class NotReached : public ScriptFunction {
43 public:
44 static v8::Local<v8::Function> createFunction(ScriptState* scriptState)
45 {
46 NotReached* self = new NotReached(scriptState);
47 return self->bindToV8Function();
48 }
49
50 private:
51 explicit NotReached(ScriptState* scriptState)
52 : ScriptFunction(scriptState)
53 {
54 }
55
56 ScriptValue call(ScriptValue) override;
57 };
58
59 ScriptValue NotReached::call(ScriptValue)
60 {
61 EXPECT_TRUE(false) << "'Unreachable' code was reached";
62 return ScriptValue();
63 }
64
65 class Iteration final : public GarbageCollectedFinalized<Iteration> {
66 public:
67 Iteration()
68 : m_isSet(false)
69 , m_isDone(false)
70 , m_isValid(true) {}
71
72 void set(ScriptValue v)
73 {
74 ASSERT(!v.isEmpty());
75 m_isSet = true;
76 v8::TryCatch block(v.scriptState()->isolate());
77 v8::Local<v8::Value> value;
78 if (!v8Call(unpack(v.scriptState(), v.v8Value(), &m_isDone), value)) {
79 m_isValid = false;
80 return;
81 }
82 m_value = toCoreString(value->ToString());
83 }
84
85 bool isSet() const { return m_isSet; }
86 bool isDone() const { return m_isDone; }
87 bool isValid() const { return m_isValid; }
88 const String& value() const { return m_value; }
89
90 DEFINE_INLINE_TRACE() {}
91
92 private:
93 bool m_isSet;
94 bool m_isDone;
95 bool m_isValid;
96 String m_value;
97 };
98
99 class Function : public ScriptFunction {
100 public:
101 static v8::Local<v8::Function> createFunction(ScriptState* scriptState, Iter ation* iteration)
102 {
103 Function* self = new Function(scriptState, iteration);
104 return self->bindToV8Function();
105 }
106
107 DEFINE_INLINE_VIRTUAL_TRACE()
108 {
109 visitor->trace(m_iteration);
110 ScriptFunction::trace(visitor);
111 }
112
113 private:
114 Function(ScriptState* scriptState, Iteration* iteration)
115 : ScriptFunction(scriptState)
116 , m_iteration(iteration)
117 {
118 }
119
120 ScriptValue call(ScriptValue value) override
121 {
122 m_iteration->set(value);
123 return value;
124 }
125
126 Member<Iteration> m_iteration;
127 };
128
129 class ReadableStreamOperationsTest : public ::testing::Test {
130 public:
131 ReadableStreamOperationsTest() : m_scope(v8::Isolate::GetCurrent()), m_block (isolate()) {}
132 ~ReadableStreamOperationsTest() override
133 {
134 // Execute all pending microtasks
135 isolate()->RunMicrotasks();
136 EXPECT_FALSE(m_block.HasCaught());
137 }
138
139 ScriptState* scriptState() const { return m_scope.scriptState(); }
140 v8::Isolate* isolate() const { return scriptState()->isolate(); }
141
142 v8::MaybeLocal<v8::Value> eval(const char* s)
143 {
144 v8::Local<v8::String> source;
145 v8::Local<v8::Script> script;
146 if (!v8Call(v8::String::NewFromUtf8(isolate(), s, v8::NewStringType::kNo rmal), source)) {
147 ADD_FAILURE();
148 return v8::MaybeLocal<v8::Value>();
149 }
150 if (!v8Call(v8::Script::Compile(scriptState()->context(), source), scrip t)) {
151 ADD_FAILURE() << "Compilation fails";
152 return v8::MaybeLocal<v8::Value>();
153 }
154 return script->Run(scriptState()->context());
155 }
156 v8::MaybeLocal<v8::Value> evalWithPrintingError(const char* s)
157 {
158 v8::TryCatch block(isolate());
159 v8::MaybeLocal<v8::Value> r = eval(s);
160 if (block.HasCaught()) {
161 ADD_FAILURE() << toCoreString(block.Exception()->ToString(isolate()) ).utf8().data();
162 block.ReThrow();
163 }
164 return r;
165 }
166
167 V8TestingScope m_scope;
168 v8::TryCatch m_block;
169 };
170
171 TEST_F(ReadableStreamOperationsTest, IsReadableStream)
172 {
173 EXPECT_FALSE(ReadableStreamOperations::isReadableStream(scriptState(), v8::U ndefined(isolate())));
174 EXPECT_FALSE(ReadableStreamOperations::isReadableStream(scriptState(), v8::N ull(isolate())));
175 EXPECT_FALSE(ReadableStreamOperations::isReadableStream(scriptState(), v8::O bject::New(isolate())));
176 v8::Local<v8::Value> stream;
177 ASSERT_TRUE(v8Call(evalWithPrintingError("new ReadableStream()"), stream));
178 EXPECT_TRUE(ReadableStreamOperations::isReadableStream(scriptState(), stream ));
179 }
180
181 TEST_F(ReadableStreamOperationsTest, IsReadableStreamReaderInvalid)
182 {
183 EXPECT_FALSE(ReadableStreamOperations::isReadableStreamReader(scriptState(), v8::Undefined(isolate())));
184 EXPECT_FALSE(ReadableStreamOperations::isReadableStreamReader(scriptState(), v8::Null(isolate())));
185 EXPECT_FALSE(ReadableStreamOperations::isReadableStreamReader(scriptState(), v8::Object::New(isolate())));
186 v8::Local<v8::Value> stream;
187 ASSERT_TRUE(v8Call(evalWithPrintingError("new ReadableStream()"), stream));
188
189 EXPECT_FALSE(ReadableStreamOperations::isReadableStreamReader(scriptState(), stream));
190 }
191
192 TEST_F(ReadableStreamOperationsTest, GetReader)
193 {
194 v8::Local<v8::Value> stream;
195 ASSERT_TRUE(v8Call(evalWithPrintingError("new ReadableStream()"), stream));
196
197 EXPECT_FALSE(ReadableStreamOperations::isLocked(scriptState(), stream));
198 ScriptValue reader;
199 {
200 TrackExceptionState es;
201 reader = ReadableStreamOperations::getReader(scriptState(), stream, es);
202 ASSERT_FALSE(es.hadException());
203 }
204 EXPECT_TRUE(ReadableStreamOperations::isLocked(scriptState(), stream));
205 ASSERT_FALSE(reader.isEmpty());
206
207 EXPECT_FALSE(ReadableStreamOperations::isReadableStream(scriptState(), reade r.v8Value()));
208 EXPECT_TRUE(ReadableStreamOperations::isReadableStreamReader(scriptState(), reader.v8Value()));
209
210 // Already locked!
211 {
212 TrackExceptionState es;
213 reader = ReadableStreamOperations::getReader(scriptState(), stream, es);
214 ASSERT_TRUE(es.hadException());
215 }
216 ASSERT_TRUE(reader.isEmpty());
217 }
218
219 TEST_F(ReadableStreamOperationsTest, IsDisturbed)
220 {
221 v8::Local<v8::Value> stream;
222 ASSERT_TRUE(v8Call(evalWithPrintingError("stream = new ReadableStream()"), s tream));
223
224 EXPECT_FALSE(ReadableStreamOperations::isDisturbed(scriptState(), stream));
225
226 ASSERT_FALSE(evalWithPrintingError("stream.cancel()").IsEmpty());
227
228 EXPECT_TRUE(ReadableStreamOperations::isDisturbed(scriptState(), stream));
229 }
230
231 TEST_F(ReadableStreamOperationsTest, Read)
232 {
233 v8::Local<v8::Value> reader;
234 ASSERT_TRUE(v8Call(evalWithPrintingError(
235 "var controller;"
236 "function start(c) { controller = c; }"
237 "new ReadableStream({start}).getReader()"), reader));
238 ASSERT_TRUE(ReadableStreamOperations::isReadableStreamReader(scriptState(), reader));
239
240 Iteration* it1 = new Iteration();
241 Iteration* it2 = new Iteration();
242 ReadableStreamOperations::read(scriptState(), reader).then(
243 Function::createFunction(scriptState(), it1),
244 NotReached::createFunction(scriptState()));
245 ReadableStreamOperations::read(scriptState(), reader).then(
246 Function::createFunction(scriptState(), it2),
247 NotReached::createFunction(scriptState()));
248
249 isolate()->RunMicrotasks();
250 EXPECT_FALSE(it1->isSet());
251 EXPECT_FALSE(it2->isSet());
252
253 ASSERT_FALSE(evalWithPrintingError("controller.enqueue('hello')").IsEmpty()) ;
254 isolate()->RunMicrotasks();
255 EXPECT_TRUE(it1->isSet());
256 EXPECT_TRUE(it1->isValid());
257 EXPECT_FALSE(it1->isDone());
258 EXPECT_EQ("hello", it1->value());
259 EXPECT_FALSE(it2->isSet());
260
261 ASSERT_FALSE(evalWithPrintingError("controller.close()").IsEmpty());
262 isolate()->RunMicrotasks();
263 EXPECT_TRUE(it1->isSet());
264 EXPECT_TRUE(it1->isValid());
265 EXPECT_FALSE(it1->isDone());
266 EXPECT_EQ("hello", it1->value());
267 EXPECT_TRUE(it2->isSet());
268 EXPECT_TRUE(it2->isValid());
269 EXPECT_TRUE(it2->isDone());
270 }
271
272 } // namespace
273
274 } // namespace blink
275
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698