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

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

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

Powered by Google App Engine
This is Rietveld 408576698