OLD | NEW |
| (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 "core/dom/ScriptRunner.h" | |
7 | |
8 #include "core/dom/Document.h" | |
9 #include "core/dom/ScriptLoader.h" | |
10 #include "platform/heap/Handle.h" | |
11 #include "platform/scheduler/Scheduler.h" | |
12 #include "public/platform/Platform.h" | |
13 #include "wtf/PassOwnPtr.h" | |
14 #include <gmock/gmock.h> | |
15 #include <gtest/gtest.h> | |
16 | |
17 using ::testing::Invoke; | |
18 using ::testing::ElementsAre; | |
19 using ::testing::Return; | |
20 | |
21 namespace blink { | |
22 | |
23 class MockScriptLoader: public ScriptLoader { | |
24 public: | |
25 explicit MockScriptLoader(Element* element) : ScriptLoader(element, false, f
alse) { } | |
26 | |
27 ~MockScriptLoader() override { } | |
28 | |
29 MOCK_METHOD0(execute, void()); | |
30 MOCK_CONST_METHOD0(isReady, bool()); | |
31 }; | |
32 | |
33 class MockPlatform : public Platform, private WebScheduler { | |
34 public: | |
35 MockPlatform() : m_shouldYield(false), m_shouldYieldEveryOtherTime(false) {
} | |
36 | |
37 WebScheduler* scheduler() override | |
38 { | |
39 return this; | |
40 } | |
41 | |
42 void postLoadingTask(const WebTraceLocation&, WebThread::Task* task) overrid
e | |
43 { | |
44 m_tasks.append(adoptPtr(task)); | |
45 } | |
46 | |
47 void cryptographicallyRandomValues(unsigned char* buffer, size_t length) ove
rride { } | |
48 | |
49 void runSingleTask() | |
50 { | |
51 if (m_tasks.isEmpty()) | |
52 return; | |
53 m_tasks.takeFirst()->run(); | |
54 } | |
55 | |
56 void runAllTasks() | |
57 { | |
58 while (!m_tasks.isEmpty()) | |
59 m_tasks.takeFirst()->run(); | |
60 } | |
61 | |
62 bool shouldYieldForHighPriorityWork() override | |
63 { | |
64 if (m_shouldYieldEveryOtherTime) | |
65 m_shouldYield = !m_shouldYield; | |
66 return m_shouldYield; | |
67 } | |
68 | |
69 void setShouldYield(bool shouldYield) | |
70 { | |
71 m_shouldYield = shouldYield; | |
72 } | |
73 | |
74 // NOTE if we yield 100% of the time, nothing will get run. | |
75 void setShouldYieldEveryOtherTime(bool shouldYieldEveryOtherTime) | |
76 { | |
77 m_shouldYieldEveryOtherTime = shouldYieldEveryOtherTime; | |
78 } | |
79 | |
80 private: | |
81 Deque<OwnPtr<WebThread::Task>> m_tasks; | |
82 bool m_shouldYield; | |
83 bool m_shouldYieldEveryOtherTime; | |
84 }; | |
85 | |
86 class ScriptRunnerTest : public testing::Test { | |
87 public: | |
88 void SetUp() override | |
89 { | |
90 m_document = Document::create(); | |
91 m_element = m_document->createElement("foo", ASSERT_NO_EXCEPTION); | |
92 | |
93 m_scriptRunner = ScriptRunner::create(m_document.get()); | |
94 m_oldPlatform = Platform::current(); | |
95 Platform::initialize(&m_platform); | |
96 m_platform.setShouldYield(false); | |
97 m_platform.setShouldYieldEveryOtherTime(false); | |
98 } | |
99 | |
100 void TearDown() override | |
101 { | |
102 m_scriptRunner.release(); | |
103 Scheduler::shutdown(); | |
104 Platform::initialize(m_oldPlatform); | |
105 } | |
106 | |
107 RefPtrWillBePersistent<Document> m_document; | |
108 RefPtrWillBePersistent<Element> m_element; | |
109 OwnPtrWillBePersistent<ScriptRunner> m_scriptRunner; | |
110 std::vector<int> m_order; // gmock matchers don't work nicely with WTF::Vect
or | |
111 MockPlatform m_platform; | |
112 Platform* m_oldPlatform; | |
113 }; | |
114 | |
115 TEST_F(ScriptRunnerTest, QueueSingleScript_Async) | |
116 { | |
117 MockScriptLoader scriptLoader(m_element.get()); | |
118 m_scriptRunner->queueScriptForExecution(&scriptLoader, ScriptRunner::ASYNC_E
XECUTION); | |
119 m_scriptRunner->notifyScriptReady(&scriptLoader, ScriptRunner::ASYNC_EXECUTI
ON); | |
120 | |
121 EXPECT_CALL(scriptLoader, execute()); | |
122 m_platform.runAllTasks(); | |
123 } | |
124 | |
125 TEST_F(ScriptRunnerTest, QueueSingleScript_InOrder) | |
126 { | |
127 MockScriptLoader scriptLoader(m_element.get()); | |
128 m_scriptRunner->queueScriptForExecution(&scriptLoader, ScriptRunner::IN_ORDE
R_EXECUTION); | |
129 m_scriptRunner->resume(); | |
130 | |
131 EXPECT_CALL(scriptLoader, isReady()).WillOnce(Return(true)); | |
132 EXPECT_CALL(scriptLoader, execute()); | |
133 m_platform.runAllTasks(); | |
134 } | |
135 | |
136 TEST_F(ScriptRunnerTest, QueueMultipleScripts_InOrder) | |
137 { | |
138 MockScriptLoader scriptLoader1(m_element.get()); | |
139 MockScriptLoader scriptLoader2(m_element.get()); | |
140 MockScriptLoader scriptLoader3(m_element.get()); | |
141 | |
142 m_scriptRunner->queueScriptForExecution(&scriptLoader1, ScriptRunner::IN_ORD
ER_EXECUTION); | |
143 m_scriptRunner->queueScriptForExecution(&scriptLoader2, ScriptRunner::IN_ORD
ER_EXECUTION); | |
144 m_scriptRunner->queueScriptForExecution(&scriptLoader3, ScriptRunner::IN_ORD
ER_EXECUTION); | |
145 | |
146 EXPECT_CALL(scriptLoader1, execute()).WillOnce(Invoke([this] { | |
147 m_order.push_back(1); | |
148 })); | |
149 EXPECT_CALL(scriptLoader2, execute()).WillOnce(Invoke([this] { | |
150 m_order.push_back(2); | |
151 })); | |
152 EXPECT_CALL(scriptLoader3, execute()).WillOnce(Invoke([this] { | |
153 m_order.push_back(3); | |
154 })); | |
155 | |
156 // Make the scripts become ready in reverse order. | |
157 bool isReady[] = { false, false, false }; | |
158 EXPECT_CALL(scriptLoader1, isReady()).WillRepeatedly(Invoke([&isReady] { | |
159 return isReady[0]; | |
160 })); | |
161 EXPECT_CALL(scriptLoader2, isReady()).WillRepeatedly(Invoke([&isReady] { | |
162 return isReady[1]; | |
163 })); | |
164 EXPECT_CALL(scriptLoader3, isReady()).WillRepeatedly(Invoke([&isReady] { | |
165 return isReady[2]; | |
166 })); | |
167 | |
168 for (int i = 2; i >= 0; i--) { | |
169 isReady[i] = true; | |
170 m_scriptRunner->resume(); | |
171 m_platform.runAllTasks(); | |
172 } | |
173 | |
174 // But ensure the scripts were run in the expected order. | |
175 EXPECT_THAT(m_order, ElementsAre(1, 2, 3)); | |
176 } | |
177 | |
178 TEST_F(ScriptRunnerTest, QueueMixedScripts) | |
179 { | |
180 MockScriptLoader scriptLoader1(m_element.get()); | |
181 MockScriptLoader scriptLoader2(m_element.get()); | |
182 MockScriptLoader scriptLoader3(m_element.get()); | |
183 MockScriptLoader scriptLoader4(m_element.get()); | |
184 MockScriptLoader scriptLoader5(m_element.get()); | |
185 | |
186 EXPECT_CALL(scriptLoader1, isReady()).WillRepeatedly(Return(true)); | |
187 EXPECT_CALL(scriptLoader2, isReady()).WillRepeatedly(Return(true)); | |
188 EXPECT_CALL(scriptLoader3, isReady()).WillRepeatedly(Return(true)); | |
189 | |
190 m_scriptRunner->queueScriptForExecution(&scriptLoader1, ScriptRunner::IN_ORD
ER_EXECUTION); | |
191 m_scriptRunner->queueScriptForExecution(&scriptLoader2, ScriptRunner::IN_ORD
ER_EXECUTION); | |
192 m_scriptRunner->queueScriptForExecution(&scriptLoader3, ScriptRunner::IN_ORD
ER_EXECUTION); | |
193 m_scriptRunner->queueScriptForExecution(&scriptLoader4, ScriptRunner::ASYNC_
EXECUTION); | |
194 m_scriptRunner->queueScriptForExecution(&scriptLoader5, ScriptRunner::ASYNC_
EXECUTION); | |
195 | |
196 m_scriptRunner->notifyScriptReady(&scriptLoader4, ScriptRunner::ASYNC_EXECUT
ION); | |
197 m_scriptRunner->notifyScriptReady(&scriptLoader5, ScriptRunner::ASYNC_EXECUT
ION); | |
198 | |
199 EXPECT_CALL(scriptLoader1, execute()).WillOnce(Invoke([this] { | |
200 m_order.push_back(1); | |
201 })); | |
202 EXPECT_CALL(scriptLoader2, execute()).WillOnce(Invoke([this] { | |
203 m_order.push_back(2); | |
204 })); | |
205 EXPECT_CALL(scriptLoader3, execute()).WillOnce(Invoke([this] { | |
206 m_order.push_back(3); | |
207 })); | |
208 EXPECT_CALL(scriptLoader4, execute()).WillOnce(Invoke([this] { | |
209 m_order.push_back(4); | |
210 })); | |
211 EXPECT_CALL(scriptLoader5, execute()).WillOnce(Invoke([this] { | |
212 m_order.push_back(5); | |
213 })); | |
214 | |
215 m_platform.runAllTasks(); | |
216 | |
217 // Make sure the async scripts were run before the in-order ones. | |
218 EXPECT_THAT(m_order, ElementsAre(4, 5, 1, 2, 3)); | |
219 } | |
220 | |
221 TEST_F(ScriptRunnerTest, QueueMixedScripts_YieldAfterEveryExecution) | |
222 { | |
223 MockScriptLoader scriptLoader1(m_element.get()); | |
224 MockScriptLoader scriptLoader2(m_element.get()); | |
225 MockScriptLoader scriptLoader3(m_element.get()); | |
226 MockScriptLoader scriptLoader4(m_element.get()); | |
227 MockScriptLoader scriptLoader5(m_element.get()); | |
228 | |
229 m_platform.setShouldYieldEveryOtherTime(true); | |
230 | |
231 EXPECT_CALL(scriptLoader1, isReady()).WillRepeatedly(Return(true)); | |
232 EXPECT_CALL(scriptLoader2, isReady()).WillRepeatedly(Return(true)); | |
233 EXPECT_CALL(scriptLoader3, isReady()).WillRepeatedly(Return(true)); | |
234 | |
235 m_scriptRunner->queueScriptForExecution(&scriptLoader1, ScriptRunner::IN_ORD
ER_EXECUTION); | |
236 m_scriptRunner->queueScriptForExecution(&scriptLoader2, ScriptRunner::IN_ORD
ER_EXECUTION); | |
237 m_scriptRunner->queueScriptForExecution(&scriptLoader3, ScriptRunner::IN_ORD
ER_EXECUTION); | |
238 m_scriptRunner->queueScriptForExecution(&scriptLoader4, ScriptRunner::ASYNC_
EXECUTION); | |
239 m_scriptRunner->queueScriptForExecution(&scriptLoader5, ScriptRunner::ASYNC_
EXECUTION); | |
240 | |
241 m_scriptRunner->notifyScriptReady(&scriptLoader4, ScriptRunner::ASYNC_EXECUT
ION); | |
242 m_scriptRunner->notifyScriptReady(&scriptLoader5, ScriptRunner::ASYNC_EXECUT
ION); | |
243 | |
244 EXPECT_CALL(scriptLoader1, execute()).WillOnce(Invoke([this] { | |
245 m_order.push_back(1); | |
246 })); | |
247 EXPECT_CALL(scriptLoader2, execute()).WillOnce(Invoke([this] { | |
248 m_order.push_back(2); | |
249 })); | |
250 EXPECT_CALL(scriptLoader3, execute()).WillOnce(Invoke([this] { | |
251 m_order.push_back(3); | |
252 })); | |
253 EXPECT_CALL(scriptLoader4, execute()).WillOnce(Invoke([this] { | |
254 m_order.push_back(4); | |
255 })); | |
256 EXPECT_CALL(scriptLoader5, execute()).WillOnce(Invoke([this] { | |
257 m_order.push_back(5); | |
258 })); | |
259 | |
260 m_platform.runAllTasks(); | |
261 | |
262 // Make sure the async scripts were run before the in-order ones. | |
263 EXPECT_THAT(m_order, ElementsAre(4, 5, 1, 2, 3)); | |
264 } | |
265 | |
266 TEST_F(ScriptRunnerTest, QueueReentrantScript_Async) | |
267 { | |
268 MockScriptLoader scriptLoader1(m_element.get()); | |
269 MockScriptLoader scriptLoader2(m_element.get()); | |
270 MockScriptLoader scriptLoader3(m_element.get()); | |
271 | |
272 m_scriptRunner->queueScriptForExecution(&scriptLoader1, ScriptRunner::ASYNC_
EXECUTION); | |
273 m_scriptRunner->queueScriptForExecution(&scriptLoader2, ScriptRunner::ASYNC_
EXECUTION); | |
274 m_scriptRunner->queueScriptForExecution(&scriptLoader3, ScriptRunner::ASYNC_
EXECUTION); | |
275 m_scriptRunner->notifyScriptReady(&scriptLoader1, ScriptRunner::ASYNC_EXECUT
ION); | |
276 | |
277 EXPECT_CALL(scriptLoader1, execute()).WillOnce(Invoke([&scriptLoader2, this]
{ | |
278 m_order.push_back(1); | |
279 m_scriptRunner->notifyScriptReady(&scriptLoader2, ScriptRunner::ASYNC_EX
ECUTION); | |
280 })); | |
281 | |
282 EXPECT_CALL(scriptLoader2, execute()).WillOnce(Invoke([&scriptLoader3, this]
{ | |
283 m_order.push_back(2); | |
284 m_scriptRunner->notifyScriptReady(&scriptLoader3, ScriptRunner::ASYNC_EX
ECUTION); | |
285 })); | |
286 | |
287 EXPECT_CALL(scriptLoader3, execute()).WillOnce(Invoke([this] { | |
288 m_order.push_back(3); | |
289 })); | |
290 | |
291 // Make sure that re-entrant calls to notifyScriptReady don't cause ScriptRu
nner::execute to do | |
292 // more work than expected. | |
293 m_platform.runSingleTask(); | |
294 EXPECT_THAT(m_order, ElementsAre(1)); | |
295 | |
296 m_platform.runSingleTask(); | |
297 EXPECT_THAT(m_order, ElementsAre(1, 2)); | |
298 | |
299 m_platform.runSingleTask(); | |
300 EXPECT_THAT(m_order, ElementsAre(1, 2, 3)); | |
301 } | |
302 | |
303 TEST_F(ScriptRunnerTest, QueueReentrantScript_InOrder) | |
304 { | |
305 MockScriptLoader scriptLoader1(m_element.get()); | |
306 MockScriptLoader scriptLoader2(m_element.get()); | |
307 MockScriptLoader scriptLoader3(m_element.get()); | |
308 | |
309 EXPECT_CALL(scriptLoader1, isReady()).WillRepeatedly(Return(true)); | |
310 EXPECT_CALL(scriptLoader2, isReady()).WillRepeatedly(Return(true)); | |
311 EXPECT_CALL(scriptLoader3, isReady()).WillRepeatedly(Return(true)); | |
312 | |
313 m_scriptRunner->queueScriptForExecution(&scriptLoader1, ScriptRunner::IN_ORD
ER_EXECUTION); | |
314 m_scriptRunner->resume(); | |
315 | |
316 EXPECT_CALL(scriptLoader1, execute()).WillOnce(Invoke([&scriptLoader2, this]
{ | |
317 m_order.push_back(1); | |
318 m_scriptRunner->queueScriptForExecution(&scriptLoader2, ScriptRunner::IN
_ORDER_EXECUTION); | |
319 m_scriptRunner->resume(); | |
320 })); | |
321 | |
322 EXPECT_CALL(scriptLoader2, execute()).WillOnce(Invoke([&scriptLoader3, this]
{ | |
323 m_order.push_back(2); | |
324 m_scriptRunner->queueScriptForExecution(&scriptLoader3, ScriptRunner::IN
_ORDER_EXECUTION); | |
325 m_scriptRunner->resume(); | |
326 })); | |
327 | |
328 EXPECT_CALL(scriptLoader3, execute()).WillOnce(Invoke([this] { | |
329 m_order.push_back(3); | |
330 })); | |
331 | |
332 // Make sure that re-entrant calls to queueScriptForExecution don't cause Sc
riptRunner::execute to do | |
333 // more work than expected. | |
334 m_platform.runSingleTask(); | |
335 EXPECT_THAT(m_order, ElementsAre(1)); | |
336 | |
337 m_platform.runSingleTask(); | |
338 EXPECT_THAT(m_order, ElementsAre(1, 2)); | |
339 | |
340 m_platform.runSingleTask(); | |
341 EXPECT_THAT(m_order, ElementsAre(1, 2, 3)); | |
342 } | |
343 | |
344 TEST_F(ScriptRunnerTest, ShouldYield_AsyncScripts) | |
345 { | |
346 MockScriptLoader scriptLoader1(m_element.get()); | |
347 MockScriptLoader scriptLoader2(m_element.get()); | |
348 MockScriptLoader scriptLoader3(m_element.get()); | |
349 | |
350 m_scriptRunner->queueScriptForExecution(&scriptLoader1, ScriptRunner::ASYNC_
EXECUTION); | |
351 m_scriptRunner->queueScriptForExecution(&scriptLoader2, ScriptRunner::ASYNC_
EXECUTION); | |
352 m_scriptRunner->queueScriptForExecution(&scriptLoader3, ScriptRunner::ASYNC_
EXECUTION); | |
353 m_scriptRunner->notifyScriptReady(&scriptLoader1, ScriptRunner::ASYNC_EXECUT
ION); | |
354 m_scriptRunner->notifyScriptReady(&scriptLoader2, ScriptRunner::ASYNC_EXECUT
ION); | |
355 m_scriptRunner->notifyScriptReady(&scriptLoader3, ScriptRunner::ASYNC_EXECUT
ION); | |
356 | |
357 EXPECT_CALL(scriptLoader1, execute()).WillOnce(Invoke([this] { | |
358 m_order.push_back(1); | |
359 m_platform.setShouldYield(true); | |
360 })); | |
361 EXPECT_CALL(scriptLoader2, execute()).WillOnce(Invoke([this] { | |
362 m_order.push_back(2); | |
363 })); | |
364 EXPECT_CALL(scriptLoader3, execute()).WillOnce(Invoke([this] { | |
365 m_order.push_back(3); | |
366 })); | |
367 | |
368 m_platform.runSingleTask(); | |
369 EXPECT_THAT(m_order, ElementsAre(1)); | |
370 | |
371 // Make sure the interrupted tasks are executed next 'tick'. | |
372 m_platform.setShouldYield(false); | |
373 m_platform.runSingleTask(); | |
374 EXPECT_THAT(m_order, ElementsAre(1, 2, 3)); | |
375 } | |
376 | |
377 TEST_F(ScriptRunnerTest, ShouldYield_InOrderScripts) | |
378 { | |
379 MockScriptLoader scriptLoader1(m_element.get()); | |
380 MockScriptLoader scriptLoader2(m_element.get()); | |
381 MockScriptLoader scriptLoader3(m_element.get()); | |
382 | |
383 EXPECT_CALL(scriptLoader1, isReady()).WillRepeatedly(Return(true)); | |
384 EXPECT_CALL(scriptLoader2, isReady()).WillRepeatedly(Return(true)); | |
385 EXPECT_CALL(scriptLoader3, isReady()).WillRepeatedly(Return(true)); | |
386 | |
387 m_scriptRunner->queueScriptForExecution(&scriptLoader1, ScriptRunner::IN_ORD
ER_EXECUTION); | |
388 m_scriptRunner->queueScriptForExecution(&scriptLoader2, ScriptRunner::IN_ORD
ER_EXECUTION); | |
389 m_scriptRunner->queueScriptForExecution(&scriptLoader3, ScriptRunner::IN_ORD
ER_EXECUTION); | |
390 m_scriptRunner->resume(); | |
391 | |
392 EXPECT_CALL(scriptLoader1, execute()).WillOnce(Invoke([this] { | |
393 m_order.push_back(1); | |
394 m_platform.setShouldYield(true); | |
395 })); | |
396 EXPECT_CALL(scriptLoader2, execute()).WillOnce(Invoke([this] { | |
397 m_order.push_back(2); | |
398 })); | |
399 EXPECT_CALL(scriptLoader3, execute()).WillOnce(Invoke([this] { | |
400 m_order.push_back(3); | |
401 })); | |
402 | |
403 m_platform.runSingleTask(); | |
404 EXPECT_THAT(m_order, ElementsAre(1)); | |
405 | |
406 // Make sure the interrupted tasks are executed next 'tick'. | |
407 m_platform.setShouldYield(false); | |
408 m_platform.runSingleTask(); | |
409 EXPECT_THAT(m_order, ElementsAre(1, 2, 3)); | |
410 } | |
411 | |
412 TEST_F(ScriptRunnerTest, ShouldYield_RunsAtLastOneTask_AsyncScripts) | |
413 { | |
414 MockScriptLoader scriptLoader1(m_element.get()); | |
415 MockScriptLoader scriptLoader2(m_element.get()); | |
416 MockScriptLoader scriptLoader3(m_element.get()); | |
417 | |
418 m_scriptRunner->queueScriptForExecution(&scriptLoader1, ScriptRunner::ASYNC_
EXECUTION); | |
419 m_scriptRunner->queueScriptForExecution(&scriptLoader2, ScriptRunner::ASYNC_
EXECUTION); | |
420 m_scriptRunner->queueScriptForExecution(&scriptLoader3, ScriptRunner::ASYNC_
EXECUTION); | |
421 m_scriptRunner->notifyScriptReady(&scriptLoader1, ScriptRunner::ASYNC_EXECUT
ION); | |
422 m_scriptRunner->notifyScriptReady(&scriptLoader2, ScriptRunner::ASYNC_EXECUT
ION); | |
423 m_scriptRunner->notifyScriptReady(&scriptLoader3, ScriptRunner::ASYNC_EXECUT
ION); | |
424 | |
425 m_platform.setShouldYield(true); | |
426 EXPECT_CALL(scriptLoader1, execute()).Times(1); | |
427 EXPECT_CALL(scriptLoader2, execute()).Times(0); | |
428 EXPECT_CALL(scriptLoader3, execute()).Times(0); | |
429 | |
430 m_platform.runSingleTask(); | |
431 | |
432 // We can't safely distruct ScriptRunner with unexecuted MockScriptLoaders (
real ScriptLoader is fine) so drain them. | |
433 testing::Mock::VerifyAndClear(&scriptLoader2); | |
434 testing::Mock::VerifyAndClear(&scriptLoader3); | |
435 m_platform.runAllTasks(); | |
436 } | |
437 | |
438 TEST_F(ScriptRunnerTest, ShouldYield_RunsAtLastOneTask_InOrderScripts) | |
439 { | |
440 MockScriptLoader scriptLoader1(m_element.get()); | |
441 MockScriptLoader scriptLoader2(m_element.get()); | |
442 MockScriptLoader scriptLoader3(m_element.get()); | |
443 | |
444 EXPECT_CALL(scriptLoader1, isReady()).WillRepeatedly(Return(true)); | |
445 EXPECT_CALL(scriptLoader2, isReady()).WillRepeatedly(Return(true)); | |
446 EXPECT_CALL(scriptLoader3, isReady()).WillRepeatedly(Return(true)); | |
447 | |
448 m_scriptRunner->queueScriptForExecution(&scriptLoader1, ScriptRunner::IN_ORD
ER_EXECUTION); | |
449 m_scriptRunner->queueScriptForExecution(&scriptLoader2, ScriptRunner::IN_ORD
ER_EXECUTION); | |
450 m_scriptRunner->queueScriptForExecution(&scriptLoader3, ScriptRunner::IN_ORD
ER_EXECUTION); | |
451 m_scriptRunner->resume(); | |
452 | |
453 m_platform.setShouldYield(true); | |
454 EXPECT_CALL(scriptLoader1, execute()).Times(1); | |
455 EXPECT_CALL(scriptLoader2, execute()).Times(0); | |
456 EXPECT_CALL(scriptLoader3, execute()).Times(0); | |
457 | |
458 m_platform.runSingleTask(); | |
459 | |
460 // We can't safely distruct ScriptRunner with unexecuted MockScriptLoaders (
real ScriptLoader is fine) so drain them. | |
461 testing::Mock::VerifyAndClear(&scriptLoader2); | |
462 testing::Mock::VerifyAndClear(&scriptLoader3); | |
463 EXPECT_CALL(scriptLoader2, isReady()).WillRepeatedly(Return(true)); | |
464 EXPECT_CALL(scriptLoader3, isReady()).WillRepeatedly(Return(true)); | |
465 m_platform.runAllTasks(); | |
466 } | |
467 | |
468 } // namespace blink | |
OLD | NEW |