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

Side by Side Diff: third_party/WebKit/Source/modules/fetch/ReadableStreamBytesConsumerTest.cpp

Issue 2365853002: Implement ReadableStreamBytesConsumer (Closed)
Patch Set: git cl format Created 4 years, 2 months 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 2016 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 "modules/fetch/ReadableStreamBytesConsumer.h"
6
7 #include "bindings/core/v8/ScriptState.h"
8 #include "bindings/core/v8/V8BindingMacros.h"
9 #include "bindings/core/v8/V8GCController.h"
10 #include "core/dom/Document.h"
11 #include "core/streams/ReadableStreamOperations.h"
12 #include "core/testing/DummyPageHolder.h"
13 #include "modules/fetch/BytesConsumerTestUtil.h"
14 #include "platform/heap/Handle.h"
15 #include "platform/testing/UnitTestHelpers.h"
16 #include "testing/gmock/include/gmock/gmock.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18 #include <memory>
19 #include <v8.h>
20
21 namespace blink {
22
23 namespace {
24
25 using ::testing::InSequence;
26 using ::testing::StrictMock;
27 using Checkpoint = StrictMock<::testing::MockFunction<void(int)>>;
28 using Result = BytesConsumer::Result;
29 using PublicState = BytesConsumer::PublicState;
30
31 class MockClient : public GarbageCollectedFinalized<MockClient>,
32 public BytesConsumer::Client {
33 USING_GARBAGE_COLLECTED_MIXIN(MockClient);
34
35 public:
36 static MockClient* create() { return new StrictMock<MockClient>(); }
37 MOCK_METHOD0(onStateChange, void());
38
39 DEFINE_INLINE_TRACE() {}
40
41 protected:
42 MockClient() = default;
43 };
44
45 class ReadableStreamBytesConsumerTest : public ::testing::Test {
46 public:
47 ReadableStreamBytesConsumerTest() : m_page(DummyPageHolder::create()) {}
48
49 ScriptState* getScriptState() {
50 return ScriptState::forMainWorld(m_page->document().frame());
51 }
52 v8::Isolate* isolate() { return getScriptState()->isolate(); }
53
54 v8::MaybeLocal<v8::Value> eval(const char* s) {
55 v8::Local<v8::String> source;
56 v8::Local<v8::Script> script;
57 v8::MicrotasksScope microtasks(isolate(),
58 v8::MicrotasksScope::kDoNotRunMicrotasks);
59 if (!v8Call(
60 v8::String::NewFromUtf8(isolate(), s, v8::NewStringType::kNormal),
61 source)) {
62 ADD_FAILURE();
63 return v8::MaybeLocal<v8::Value>();
64 }
65 if (!v8Call(v8::Script::Compile(getScriptState()->context(), source),
66 script)) {
67 ADD_FAILURE() << "Compilation fails";
68 return v8::MaybeLocal<v8::Value>();
69 }
70 return script->Run(getScriptState()->context());
71 }
72 v8::MaybeLocal<v8::Value> evalWithPrintingError(const char* s) {
73 v8::TryCatch block(isolate());
74 v8::MaybeLocal<v8::Value> r = eval(s);
75 if (block.HasCaught()) {
76 ADD_FAILURE()
77 << toCoreString(block.Exception()->ToString(isolate())).utf8().data();
78 block.ReThrow();
79 }
80 return r;
81 }
82
83 ReadableStreamBytesConsumer* createConsumer(ScriptValue stream) {
84 NonThrowableExceptionState es;
85 ScriptValue reader =
86 ReadableStreamOperations::getReader(getScriptState(), stream, es);
87 DCHECK(!reader.isEmpty());
88 DCHECK(reader.v8Value()->IsObject());
89 return new ReadableStreamBytesConsumer(getScriptState(), reader);
90 }
91
92 void gc() { V8GCController::collectAllGarbageForTesting(isolate()); }
93
94 private:
95 std::unique_ptr<DummyPageHolder> m_page;
96 };
97
98 TEST_F(ReadableStreamBytesConsumerTest, Create) {
99 ScriptState::Scope scope(getScriptState());
100 ScriptValue stream(getScriptState(),
101 evalWithPrintingError("new ReadableStream"));
102 ASSERT_FALSE(stream.isEmpty());
103 Persistent<BytesConsumer> consumer = createConsumer(stream);
104
105 EXPECT_EQ(PublicState::ReadableOrWaiting, consumer->getPublicState());
106 }
107
108 TEST_F(ReadableStreamBytesConsumerTest, EmptyStream) {
109 ScriptState::Scope scope(getScriptState());
110 ScriptValue stream(
111 getScriptState(),
112 evalWithPrintingError("new ReadableStream({start: c => c.close()})"));
113 ASSERT_FALSE(stream.isEmpty());
114 Persistent<BytesConsumer> consumer = createConsumer(stream);
115 Persistent<MockClient> client = MockClient::create();
116 consumer->setClient(client);
117
118 Checkpoint checkpoint;
119 InSequence s;
120 EXPECT_CALL(checkpoint, Call(1));
121 EXPECT_CALL(checkpoint, Call(2));
122 EXPECT_CALL(checkpoint, Call(3));
123 EXPECT_CALL(*client, onStateChange());
124 EXPECT_CALL(checkpoint, Call(4));
125
126 const char* buffer = nullptr;
127 size_t available = 0;
128 checkpoint.Call(1);
129 testing::runPendingTasks();
130 checkpoint.Call(2);
131 EXPECT_EQ(PublicState::ReadableOrWaiting, consumer->getPublicState());
132 EXPECT_EQ(Result::ShouldWait, consumer->beginRead(&buffer, &available));
133 checkpoint.Call(3);
134 testing::runPendingTasks();
135 checkpoint.Call(4);
136 EXPECT_EQ(PublicState::Closed, consumer->getPublicState());
137 EXPECT_EQ(Result::Done, consumer->beginRead(&buffer, &available));
138 }
139
140 TEST_F(ReadableStreamBytesConsumerTest, ErroredStream) {
141 ScriptState::Scope scope(getScriptState());
142 ScriptValue stream(
143 getScriptState(),
144 evalWithPrintingError("new ReadableStream({start: c => c.error()})"));
145 ASSERT_FALSE(stream.isEmpty());
146 Persistent<BytesConsumer> consumer = createConsumer(stream);
147 Persistent<MockClient> client = MockClient::create();
148 consumer->setClient(client);
149 Checkpoint checkpoint;
150
151 InSequence s;
152 EXPECT_CALL(checkpoint, Call(1));
153 EXPECT_CALL(checkpoint, Call(2));
154 EXPECT_CALL(checkpoint, Call(3));
155 EXPECT_CALL(*client, onStateChange());
156 EXPECT_CALL(checkpoint, Call(4));
157
158 const char* buffer = nullptr;
159 size_t available = 0;
160 checkpoint.Call(1);
161 testing::runPendingTasks();
162 checkpoint.Call(2);
163 EXPECT_EQ(PublicState::ReadableOrWaiting, consumer->getPublicState());
164 EXPECT_EQ(Result::ShouldWait, consumer->beginRead(&buffer, &available));
165 checkpoint.Call(3);
166 testing::runPendingTasks();
167 checkpoint.Call(4);
168 EXPECT_EQ(PublicState::Errored, consumer->getPublicState());
169 EXPECT_EQ(Result::Error, consumer->beginRead(&buffer, &available));
170 }
171
172 TEST_F(ReadableStreamBytesConsumerTest, TwoPhaseRead) {
173 ScriptState::Scope scope(getScriptState());
174 ScriptValue stream(
175 getScriptState(),
176 evalWithPrintingError(
177 "var controller;"
178 "var stream = new ReadableStream({start: c => controller = c});"
179 "controller.enqueue(new Uint8Array());"
180 "controller.enqueue(new Uint8Array([0x43, 0x44, 0x45, 0x46]));"
181 "controller.enqueue(new Uint8Array([0x47, 0x48, 0x49, 0x4a]));"
182 "controller.close();"
183 "stream"));
184 ASSERT_FALSE(stream.isEmpty());
185 Persistent<BytesConsumer> consumer = createConsumer(stream);
186 Persistent<MockClient> client = MockClient::create();
187 consumer->setClient(client);
188 Checkpoint checkpoint;
189
190 InSequence s;
191 EXPECT_CALL(checkpoint, Call(1));
192 EXPECT_CALL(checkpoint, Call(2));
193 EXPECT_CALL(checkpoint, Call(3));
194 EXPECT_CALL(*client, onStateChange());
195 EXPECT_CALL(checkpoint, Call(4));
196 EXPECT_CALL(checkpoint, Call(5));
197 EXPECT_CALL(*client, onStateChange());
198 EXPECT_CALL(checkpoint, Call(6));
199 EXPECT_CALL(checkpoint, Call(7));
200 EXPECT_CALL(*client, onStateChange());
201 EXPECT_CALL(checkpoint, Call(8));
202 EXPECT_CALL(checkpoint, Call(9));
203 EXPECT_CALL(*client, onStateChange());
204 EXPECT_CALL(checkpoint, Call(10));
205
206 const char* buffer = nullptr;
207 size_t available = 0;
208 checkpoint.Call(1);
209 testing::runPendingTasks();
210 checkpoint.Call(2);
211 EXPECT_EQ(Result::ShouldWait, consumer->beginRead(&buffer, &available));
212 checkpoint.Call(3);
213 testing::runPendingTasks();
214 checkpoint.Call(4);
215 EXPECT_EQ(Result::Ok, consumer->beginRead(&buffer, &available));
216 ASSERT_EQ(0u, available);
217 EXPECT_EQ(Result::Ok, consumer->endRead(0));
218 EXPECT_EQ(Result::ShouldWait, consumer->beginRead(&buffer, &available));
219 checkpoint.Call(5);
220 testing::runPendingTasks();
221 checkpoint.Call(6);
222 EXPECT_EQ(PublicState::ReadableOrWaiting, consumer->getPublicState());
223 EXPECT_EQ(Result::Ok, consumer->beginRead(&buffer, &available));
224 ASSERT_EQ(4u, available);
225 EXPECT_EQ(0x43, buffer[0]);
226 EXPECT_EQ(0x44, buffer[1]);
227 EXPECT_EQ(0x45, buffer[2]);
228 EXPECT_EQ(0x46, buffer[3]);
229 EXPECT_EQ(Result::Ok, consumer->endRead(0));
230 EXPECT_EQ(Result::Ok, consumer->beginRead(&buffer, &available));
231 ASSERT_EQ(4u, available);
232 EXPECT_EQ(0x43, buffer[0]);
233 EXPECT_EQ(0x44, buffer[1]);
234 EXPECT_EQ(0x45, buffer[2]);
235 EXPECT_EQ(0x46, buffer[3]);
236 EXPECT_EQ(Result::Ok, consumer->endRead(1));
237 EXPECT_EQ(Result::Ok, consumer->beginRead(&buffer, &available));
238 ASSERT_EQ(3u, available);
239 EXPECT_EQ(0x44, buffer[0]);
240 EXPECT_EQ(0x45, buffer[1]);
241 EXPECT_EQ(0x46, buffer[2]);
242 EXPECT_EQ(Result::Ok, consumer->endRead(3));
243 EXPECT_EQ(Result::ShouldWait, consumer->beginRead(&buffer, &available));
244 checkpoint.Call(7);
245 testing::runPendingTasks();
246 checkpoint.Call(8);
247 EXPECT_EQ(PublicState::ReadableOrWaiting, consumer->getPublicState());
248 EXPECT_EQ(Result::Ok, consumer->beginRead(&buffer, &available));
249 ASSERT_EQ(4u, available);
250 EXPECT_EQ(0x47, buffer[0]);
251 EXPECT_EQ(0x48, buffer[1]);
252 EXPECT_EQ(0x49, buffer[2]);
253 EXPECT_EQ(0x4a, buffer[3]);
254 EXPECT_EQ(Result::Ok, consumer->endRead(4));
255 EXPECT_EQ(Result::ShouldWait, consumer->beginRead(&buffer, &available));
256 checkpoint.Call(9);
257 testing::runPendingTasks();
258 checkpoint.Call(10);
259 EXPECT_EQ(PublicState::Closed, consumer->getPublicState());
260 EXPECT_EQ(Result::Done, consumer->beginRead(&buffer, &available));
261 }
262
263 TEST_F(ReadableStreamBytesConsumerTest, EnqueueUndefined) {
264 ScriptState::Scope scope(getScriptState());
265 ScriptValue stream(
266 getScriptState(),
267 evalWithPrintingError(
268 "var controller;"
269 "var stream = new ReadableStream({start: c => controller = c});"
270 "controller.enqueue(undefined);"
271 "controller.close();"
272 "stream"));
273 ASSERT_FALSE(stream.isEmpty());
274 Persistent<BytesConsumer> consumer = createConsumer(stream);
275 Persistent<MockClient> client = MockClient::create();
276 consumer->setClient(client);
277 Checkpoint checkpoint;
278
279 InSequence s;
280 EXPECT_CALL(checkpoint, Call(1));
281 EXPECT_CALL(checkpoint, Call(2));
282 EXPECT_CALL(checkpoint, Call(3));
283 EXPECT_CALL(*client, onStateChange());
284 EXPECT_CALL(checkpoint, Call(4));
285
286 const char* buffer = nullptr;
287 size_t available = 0;
288 checkpoint.Call(1);
289 testing::runPendingTasks();
290 checkpoint.Call(2);
291 EXPECT_EQ(PublicState::ReadableOrWaiting, consumer->getPublicState());
292 EXPECT_EQ(Result::ShouldWait, consumer->beginRead(&buffer, &available));
293 checkpoint.Call(3);
294 testing::runPendingTasks();
295 checkpoint.Call(4);
296 EXPECT_EQ(PublicState::Errored, consumer->getPublicState());
297 EXPECT_EQ(Result::Error, consumer->beginRead(&buffer, &available));
298 }
299
300 TEST_F(ReadableStreamBytesConsumerTest, EnqueueNull) {
301 ScriptState::Scope scope(getScriptState());
302 ScriptValue stream(
303 getScriptState(),
304 evalWithPrintingError(
305 "var controller;"
306 "var stream = new ReadableStream({start: c => controller = c});"
307 "controller.enqueue(null);"
308 "controller.close();"
309 "stream"));
310
311 ASSERT_FALSE(stream.isEmpty());
312 Persistent<BytesConsumer> consumer = createConsumer(stream);
313 Persistent<MockClient> client = MockClient::create();
314 consumer->setClient(client);
315 Checkpoint checkpoint;
316
317 InSequence s;
318 EXPECT_CALL(checkpoint, Call(1));
319 EXPECT_CALL(checkpoint, Call(2));
320 EXPECT_CALL(checkpoint, Call(3));
321 EXPECT_CALL(*client, onStateChange());
322 EXPECT_CALL(checkpoint, Call(4));
323
324 const char* buffer = nullptr;
325 size_t available = 0;
326 checkpoint.Call(1);
327 testing::runPendingTasks();
328 checkpoint.Call(2);
329 EXPECT_EQ(PublicState::ReadableOrWaiting, consumer->getPublicState());
330 EXPECT_EQ(Result::ShouldWait, consumer->beginRead(&buffer, &available));
331 checkpoint.Call(3);
332 testing::runPendingTasks();
333 checkpoint.Call(4);
334 EXPECT_EQ(PublicState::Errored, consumer->getPublicState());
335 EXPECT_EQ(Result::Error, consumer->beginRead(&buffer, &available));
336 }
337
338 TEST_F(ReadableStreamBytesConsumerTest, EnqueueString) {
339 ScriptState::Scope scope(getScriptState());
340 ScriptValue stream(
341 getScriptState(),
342 evalWithPrintingError(
343 "var controller;"
344 "var stream = new ReadableStream({start: c => controller = c});"
345 "controller.enqueue('hello');"
346 "controller.close();"
347 "stream"));
348 ASSERT_FALSE(stream.isEmpty());
349 Persistent<BytesConsumer> consumer = createConsumer(stream);
350 Persistent<MockClient> client = MockClient::create();
351 consumer->setClient(client);
352 Checkpoint checkpoint;
353
354 InSequence s;
355 EXPECT_CALL(checkpoint, Call(1));
356 EXPECT_CALL(checkpoint, Call(2));
357 EXPECT_CALL(checkpoint, Call(3));
358 EXPECT_CALL(*client, onStateChange());
359 EXPECT_CALL(checkpoint, Call(4));
360
361 const char* buffer = nullptr;
362 size_t available = 0;
363 checkpoint.Call(1);
364 testing::runPendingTasks();
365 checkpoint.Call(2);
366 EXPECT_EQ(PublicState::ReadableOrWaiting, consumer->getPublicState());
367 EXPECT_EQ(Result::ShouldWait, consumer->beginRead(&buffer, &available));
368 checkpoint.Call(3);
369 testing::runPendingTasks();
370 checkpoint.Call(4);
371 EXPECT_EQ(PublicState::Errored, consumer->getPublicState());
372 EXPECT_EQ(Result::Error, consumer->beginRead(&buffer, &available));
373 }
374
375 } // namespace
376
377 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698