Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / third_party / WebKit / Source / core / dom / ScriptRunnerTest.cpp
blob813273a32a2860d1bfe95956124c1d64c19b7d8f
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.
5 #include "config.h"
6 #include "core/dom/ScriptRunner.h"
8 #include "core/dom/Document.h"
9 #include "core/dom/Element.h"
10 #include "core/dom/ScriptLoader.h"
11 #include "platform/scheduler/CancellableTaskFactory.h"
12 #include "public/platform/Platform.h"
13 #include <gmock/gmock.h>
14 #include <gtest/gtest.h>
16 using ::testing::Invoke;
17 using ::testing::ElementsAre;
18 using ::testing::Return;
20 namespace blink {
22 class MockScriptLoader final : public ScriptLoader {
23 public:
24 static PassOwnPtrWillBeRawPtr<MockScriptLoader> create(Element* element)
26 return adoptPtrWillBeNoop(new MockScriptLoader(element));
28 ~MockScriptLoader() override { }
30 MOCK_METHOD0(execute, void());
31 MOCK_CONST_METHOD0(isReady, bool());
32 private:
33 explicit MockScriptLoader(Element* element) : ScriptLoader(element, false, false)
38 class MockWebThread : public WebThread {
39 public:
40 explicit MockWebThread(WebScheduler* webScheduler) : m_webScheduler(webScheduler) { }
41 ~MockWebThread() override { }
43 bool isCurrentThread() const override
45 ASSERT_NOT_REACHED();
46 return false;
49 PlatformThreadId threadId() const override
51 ASSERT_NOT_REACHED();
52 return 0;
55 WebTaskRunner* taskRunner() override
57 ASSERT_NOT_REACHED();
58 return nullptr;
61 void addTaskObserver(TaskObserver*) override { ASSERT_NOT_REACHED(); }
62 void removeTaskObserver(TaskObserver*) override { ASSERT_NOT_REACHED(); }
64 WebScheduler* scheduler() const override { return m_webScheduler; }
66 private:
67 WebScheduler* m_webScheduler;
70 class MockWebTaskRunner : public WebTaskRunner {
71 public:
72 explicit MockWebTaskRunner(Deque<OwnPtr<WebTaskRunner::Task>>* tasks) : m_tasks(tasks) { }
73 ~MockWebTaskRunner() override { }
75 virtual void postTask(const WebTraceLocation&, Task* task)
77 m_tasks->append(adoptPtr(task));
80 void postDelayedTask(const WebTraceLocation&, Task* task, long long delayMs) override
82 ASSERT_NOT_REACHED();
85 Deque<OwnPtr<WebTaskRunner::Task>>* m_tasks; // NOT OWNED
88 class MockPlatform : public Platform, private WebScheduler {
89 public:
90 MockPlatform()
91 : m_mockWebThread(this)
92 , m_mockWebTaskRunner(&m_tasks)
93 , m_shouldYield(false)
94 , m_shouldYieldEveryOtherTime(false) { }
96 void cryptographicallyRandomValues(unsigned char* buffer, size_t length) override { }
98 WebThread* currentThread() override { return &m_mockWebThread; }
100 WebTaskRunner* loadingTaskRunner() override
102 return &m_mockWebTaskRunner;
105 WebTaskRunner* timerTaskRunner() override
107 ASSERT_NOT_REACHED();
108 return nullptr;
111 void runSingleTask()
113 if (m_tasks.isEmpty())
114 return;
115 m_tasks.takeFirst()->run();
118 void runAllTasks()
120 while (!m_tasks.isEmpty())
121 m_tasks.takeFirst()->run();
124 bool shouldYieldForHighPriorityWork() override
126 if (m_shouldYieldEveryOtherTime)
127 m_shouldYield = !m_shouldYield;
128 return m_shouldYield;
131 void setShouldYield(bool shouldYield)
133 m_shouldYield = shouldYield;
136 // NOTE if we yield 100% of the time, nothing will get run.
137 void setShouldYieldEveryOtherTime(bool shouldYieldEveryOtherTime)
139 m_shouldYieldEveryOtherTime = shouldYieldEveryOtherTime;
142 private:
143 MockWebThread m_mockWebThread;
144 Deque<OwnPtr<WebTaskRunner::Task>> m_tasks;
145 MockWebTaskRunner m_mockWebTaskRunner;
146 bool m_shouldYield;
147 bool m_shouldYieldEveryOtherTime;
150 class ScriptRunnerTest : public testing::Test {
151 public:
152 void SetUp() override
154 m_document = Document::create();
155 m_element = m_document->createElement("foo", ASSERT_NO_EXCEPTION);
157 m_scriptRunner = ScriptRunner::create(m_document.get());
158 m_oldPlatform = Platform::current();
160 // Force Platform::initialize to create a new one pointing at MockPlatform.
161 Platform::initialize(&m_platform);
162 m_platform.setShouldYield(false);
163 m_platform.setShouldYieldEveryOtherTime(false);
166 void TearDown() override
168 m_scriptRunner.release();
169 Platform::initialize(m_oldPlatform);
172 RefPtrWillBePersistent<Document> m_document;
173 RefPtrWillBePersistent<Element> m_element;
174 OwnPtrWillBePersistent<ScriptRunner> m_scriptRunner;
175 std::vector<int> m_order; // gmock matchers don't work nicely with WTF::Vector
176 MockPlatform m_platform;
177 Platform* m_oldPlatform; // NOT OWNED
180 TEST_F(ScriptRunnerTest, QueueSingleScript_Async)
182 OwnPtrWillBeRawPtr<MockScriptLoader> scriptLoader = MockScriptLoader::create(m_element.get());
183 m_scriptRunner->queueScriptForExecution(scriptLoader.get(), ScriptRunner::ASYNC_EXECUTION);
184 m_scriptRunner->notifyScriptReady(scriptLoader.get(), ScriptRunner::ASYNC_EXECUTION);
186 EXPECT_CALL(*scriptLoader, execute());
187 m_platform.runAllTasks();
190 TEST_F(ScriptRunnerTest, QueueSingleScript_InOrder)
192 OwnPtrWillBeRawPtr<MockScriptLoader> scriptLoader = MockScriptLoader::create(m_element.get());
193 m_scriptRunner->queueScriptForExecution(scriptLoader.get(), ScriptRunner::IN_ORDER_EXECUTION);
194 m_scriptRunner->resume();
196 EXPECT_CALL(*scriptLoader, isReady()).WillOnce(Return(true));
197 EXPECT_CALL(*scriptLoader, execute());
198 m_platform.runAllTasks();
201 TEST_F(ScriptRunnerTest, QueueMultipleScripts_InOrder)
203 OwnPtrWillBeRawPtr<MockScriptLoader> scriptLoader1 = MockScriptLoader::create(m_element.get());
204 OwnPtrWillBeRawPtr<MockScriptLoader> scriptLoader2 = MockScriptLoader::create(m_element.get());
205 OwnPtrWillBeRawPtr<MockScriptLoader> scriptLoader3 = MockScriptLoader::create(m_element.get());
207 m_scriptRunner->queueScriptForExecution(scriptLoader1.get(), ScriptRunner::IN_ORDER_EXECUTION);
208 m_scriptRunner->queueScriptForExecution(scriptLoader2.get(), ScriptRunner::IN_ORDER_EXECUTION);
209 m_scriptRunner->queueScriptForExecution(scriptLoader3.get(), ScriptRunner::IN_ORDER_EXECUTION);
211 EXPECT_CALL(*scriptLoader1, execute()).WillOnce(Invoke([this] {
212 m_order.push_back(1);
213 }));
214 EXPECT_CALL(*scriptLoader2, execute()).WillOnce(Invoke([this] {
215 m_order.push_back(2);
216 }));
217 EXPECT_CALL(*scriptLoader3, execute()).WillOnce(Invoke([this] {
218 m_order.push_back(3);
219 }));
221 // Make the scripts become ready in reverse order.
222 bool isReady[] = { false, false, false };
223 EXPECT_CALL(*scriptLoader1, isReady()).WillRepeatedly(Invoke([&isReady] {
224 return isReady[0];
225 }));
226 EXPECT_CALL(*scriptLoader2, isReady()).WillRepeatedly(Invoke([&isReady] {
227 return isReady[1];
228 }));
229 EXPECT_CALL(*scriptLoader3, isReady()).WillRepeatedly(Invoke([&isReady] {
230 return isReady[2];
231 }));
233 for (int i = 2; i >= 0; i--) {
234 isReady[i] = true;
235 m_scriptRunner->resume();
236 m_platform.runAllTasks();
239 // But ensure the scripts were run in the expected order.
240 EXPECT_THAT(m_order, ElementsAre(1, 2, 3));
243 TEST_F(ScriptRunnerTest, QueueMixedScripts)
245 OwnPtrWillBeRawPtr<MockScriptLoader> scriptLoader1 = MockScriptLoader::create(m_element.get());
246 OwnPtrWillBeRawPtr<MockScriptLoader> scriptLoader2 = MockScriptLoader::create(m_element.get());
247 OwnPtrWillBeRawPtr<MockScriptLoader> scriptLoader3 = MockScriptLoader::create(m_element.get());
248 OwnPtrWillBeRawPtr<MockScriptLoader> scriptLoader4 = MockScriptLoader::create(m_element.get());
249 OwnPtrWillBeRawPtr<MockScriptLoader> scriptLoader5 = MockScriptLoader::create(m_element.get());
251 EXPECT_CALL(*scriptLoader1, isReady()).WillRepeatedly(Return(true));
252 EXPECT_CALL(*scriptLoader2, isReady()).WillRepeatedly(Return(true));
253 EXPECT_CALL(*scriptLoader3, isReady()).WillRepeatedly(Return(true));
255 m_scriptRunner->queueScriptForExecution(scriptLoader1.get(), ScriptRunner::IN_ORDER_EXECUTION);
256 m_scriptRunner->queueScriptForExecution(scriptLoader2.get(), ScriptRunner::IN_ORDER_EXECUTION);
257 m_scriptRunner->queueScriptForExecution(scriptLoader3.get(), ScriptRunner::IN_ORDER_EXECUTION);
258 m_scriptRunner->queueScriptForExecution(scriptLoader4.get(), ScriptRunner::ASYNC_EXECUTION);
259 m_scriptRunner->queueScriptForExecution(scriptLoader5.get(), ScriptRunner::ASYNC_EXECUTION);
261 m_scriptRunner->notifyScriptReady(scriptLoader4.get(), ScriptRunner::ASYNC_EXECUTION);
262 m_scriptRunner->notifyScriptReady(scriptLoader5.get(), ScriptRunner::ASYNC_EXECUTION);
264 EXPECT_CALL(*scriptLoader1, execute()).WillOnce(Invoke([this] {
265 m_order.push_back(1);
266 }));
267 EXPECT_CALL(*scriptLoader2, execute()).WillOnce(Invoke([this] {
268 m_order.push_back(2);
269 }));
270 EXPECT_CALL(*scriptLoader3, execute()).WillOnce(Invoke([this] {
271 m_order.push_back(3);
272 }));
273 EXPECT_CALL(*scriptLoader4, execute()).WillOnce(Invoke([this] {
274 m_order.push_back(4);
275 }));
276 EXPECT_CALL(*scriptLoader5, execute()).WillOnce(Invoke([this] {
277 m_order.push_back(5);
278 }));
280 m_platform.runAllTasks();
282 // Make sure the async scripts were run before the in-order ones.
283 EXPECT_THAT(m_order, ElementsAre(4, 5, 1, 2, 3));
286 TEST_F(ScriptRunnerTest, QueueMixedScripts_YieldAfterEveryExecution)
288 OwnPtrWillBeRawPtr<MockScriptLoader> scriptLoader1 = MockScriptLoader::create(m_element.get());
289 OwnPtrWillBeRawPtr<MockScriptLoader> scriptLoader2 = MockScriptLoader::create(m_element.get());
290 OwnPtrWillBeRawPtr<MockScriptLoader> scriptLoader3 = MockScriptLoader::create(m_element.get());
291 OwnPtrWillBeRawPtr<MockScriptLoader> scriptLoader4 = MockScriptLoader::create(m_element.get());
292 OwnPtrWillBeRawPtr<MockScriptLoader> scriptLoader5 = MockScriptLoader::create(m_element.get());
294 m_platform.setShouldYieldEveryOtherTime(true);
296 EXPECT_CALL(*scriptLoader1, isReady()).WillRepeatedly(Return(true));
297 EXPECT_CALL(*scriptLoader2, isReady()).WillRepeatedly(Return(true));
298 EXPECT_CALL(*scriptLoader3, isReady()).WillRepeatedly(Return(true));
300 m_scriptRunner->queueScriptForExecution(scriptLoader1.get(), ScriptRunner::IN_ORDER_EXECUTION);
301 m_scriptRunner->queueScriptForExecution(scriptLoader2.get(), ScriptRunner::IN_ORDER_EXECUTION);
302 m_scriptRunner->queueScriptForExecution(scriptLoader3.get(), ScriptRunner::IN_ORDER_EXECUTION);
303 m_scriptRunner->queueScriptForExecution(scriptLoader4.get(), ScriptRunner::ASYNC_EXECUTION);
304 m_scriptRunner->queueScriptForExecution(scriptLoader5.get(), ScriptRunner::ASYNC_EXECUTION);
306 m_scriptRunner->notifyScriptReady(scriptLoader4.get(), ScriptRunner::ASYNC_EXECUTION);
307 m_scriptRunner->notifyScriptReady(scriptLoader5.get(), ScriptRunner::ASYNC_EXECUTION);
309 EXPECT_CALL(*scriptLoader1, execute()).WillOnce(Invoke([this] {
310 m_order.push_back(1);
311 }));
312 EXPECT_CALL(*scriptLoader2, execute()).WillOnce(Invoke([this] {
313 m_order.push_back(2);
314 }));
315 EXPECT_CALL(*scriptLoader3, execute()).WillOnce(Invoke([this] {
316 m_order.push_back(3);
317 }));
318 EXPECT_CALL(*scriptLoader4, execute()).WillOnce(Invoke([this] {
319 m_order.push_back(4);
320 }));
321 EXPECT_CALL(*scriptLoader5, execute()).WillOnce(Invoke([this] {
322 m_order.push_back(5);
323 }));
325 m_platform.runAllTasks();
327 // Make sure the async scripts were run before the in-order ones.
328 EXPECT_THAT(m_order, ElementsAre(4, 5, 1, 2, 3));
331 TEST_F(ScriptRunnerTest, QueueReentrantScript_Async)
333 OwnPtrWillBeRawPtr<MockScriptLoader> scriptLoader1 = MockScriptLoader::create(m_element.get());
334 OwnPtrWillBeRawPtr<MockScriptLoader> scriptLoader2 = MockScriptLoader::create(m_element.get());
335 OwnPtrWillBeRawPtr<MockScriptLoader> scriptLoader3 = MockScriptLoader::create(m_element.get());
337 m_scriptRunner->queueScriptForExecution(scriptLoader1.get(), ScriptRunner::ASYNC_EXECUTION);
338 m_scriptRunner->queueScriptForExecution(scriptLoader2.get(), ScriptRunner::ASYNC_EXECUTION);
339 m_scriptRunner->queueScriptForExecution(scriptLoader3.get(), ScriptRunner::ASYNC_EXECUTION);
340 m_scriptRunner->notifyScriptReady(scriptLoader1.get(), ScriptRunner::ASYNC_EXECUTION);
342 MockScriptLoader* scriptLoader = scriptLoader2.get();
343 EXPECT_CALL(*scriptLoader1, execute()).WillOnce(Invoke([scriptLoader, this] {
344 m_order.push_back(1);
345 m_scriptRunner->notifyScriptReady(scriptLoader, ScriptRunner::ASYNC_EXECUTION);
346 }));
348 scriptLoader = scriptLoader3.get();
349 EXPECT_CALL(*scriptLoader2, execute()).WillOnce(Invoke([scriptLoader, this] {
350 m_order.push_back(2);
351 m_scriptRunner->notifyScriptReady(scriptLoader, ScriptRunner::ASYNC_EXECUTION);
352 }));
354 EXPECT_CALL(*scriptLoader3, execute()).WillOnce(Invoke([this] {
355 m_order.push_back(3);
356 }));
358 // Make sure that re-entrant calls to notifyScriptReady don't cause ScriptRunner::execute to do
359 // more work than expected.
360 m_platform.runSingleTask();
361 EXPECT_THAT(m_order, ElementsAre(1));
363 m_platform.runSingleTask();
364 EXPECT_THAT(m_order, ElementsAre(1, 2));
366 m_platform.runSingleTask();
367 EXPECT_THAT(m_order, ElementsAre(1, 2, 3));
370 TEST_F(ScriptRunnerTest, QueueReentrantScript_InOrder)
372 OwnPtrWillBeRawPtr<MockScriptLoader> scriptLoader1 = MockScriptLoader::create(m_element.get());
373 OwnPtrWillBeRawPtr<MockScriptLoader> scriptLoader2 = MockScriptLoader::create(m_element.get());
374 OwnPtrWillBeRawPtr<MockScriptLoader> scriptLoader3 = MockScriptLoader::create(m_element.get());
376 EXPECT_CALL(*scriptLoader1, isReady()).WillRepeatedly(Return(true));
377 EXPECT_CALL(*scriptLoader2, isReady()).WillRepeatedly(Return(true));
378 EXPECT_CALL(*scriptLoader3, isReady()).WillRepeatedly(Return(true));
380 m_scriptRunner->queueScriptForExecution(scriptLoader1.get(), ScriptRunner::IN_ORDER_EXECUTION);
381 m_scriptRunner->resume();
383 MockScriptLoader* scriptLoader = scriptLoader2.get();
384 EXPECT_CALL(*scriptLoader1, execute()).WillOnce(Invoke([scriptLoader, this] {
385 m_order.push_back(1);
386 m_scriptRunner->queueScriptForExecution(scriptLoader, ScriptRunner::IN_ORDER_EXECUTION);
387 m_scriptRunner->resume();
388 }));
390 scriptLoader = scriptLoader3.get();
391 EXPECT_CALL(*scriptLoader2, execute()).WillOnce(Invoke([scriptLoader, this] {
392 m_order.push_back(2);
393 m_scriptRunner->queueScriptForExecution(scriptLoader, ScriptRunner::IN_ORDER_EXECUTION);
394 m_scriptRunner->resume();
395 }));
397 EXPECT_CALL(*scriptLoader3, execute()).WillOnce(Invoke([this] {
398 m_order.push_back(3);
399 }));
401 // Make sure that re-entrant calls to queueScriptForExecution don't cause ScriptRunner::execute to do
402 // more work than expected.
403 m_platform.runSingleTask();
404 EXPECT_THAT(m_order, ElementsAre(1));
406 m_platform.runSingleTask();
407 EXPECT_THAT(m_order, ElementsAre(1, 2));
409 m_platform.runSingleTask();
410 EXPECT_THAT(m_order, ElementsAre(1, 2, 3));
413 TEST_F(ScriptRunnerTest, ShouldYield_AsyncScripts)
415 OwnPtrWillBeRawPtr<MockScriptLoader> scriptLoader1 = MockScriptLoader::create(m_element.get());
416 OwnPtrWillBeRawPtr<MockScriptLoader> scriptLoader2 = MockScriptLoader::create(m_element.get());
417 OwnPtrWillBeRawPtr<MockScriptLoader> scriptLoader3 = MockScriptLoader::create(m_element.get());
419 m_scriptRunner->queueScriptForExecution(scriptLoader1.get(), ScriptRunner::ASYNC_EXECUTION);
420 m_scriptRunner->queueScriptForExecution(scriptLoader2.get(), ScriptRunner::ASYNC_EXECUTION);
421 m_scriptRunner->queueScriptForExecution(scriptLoader3.get(), ScriptRunner::ASYNC_EXECUTION);
422 m_scriptRunner->notifyScriptReady(scriptLoader1.get(), ScriptRunner::ASYNC_EXECUTION);
423 m_scriptRunner->notifyScriptReady(scriptLoader2.get(), ScriptRunner::ASYNC_EXECUTION);
424 m_scriptRunner->notifyScriptReady(scriptLoader3.get(), ScriptRunner::ASYNC_EXECUTION);
426 EXPECT_CALL(*scriptLoader1, execute()).WillOnce(Invoke([this] {
427 m_order.push_back(1);
428 m_platform.setShouldYield(true);
429 }));
430 EXPECT_CALL(*scriptLoader2, execute()).WillOnce(Invoke([this] {
431 m_order.push_back(2);
432 }));
433 EXPECT_CALL(*scriptLoader3, execute()).WillOnce(Invoke([this] {
434 m_order.push_back(3);
435 }));
437 m_platform.runSingleTask();
438 EXPECT_THAT(m_order, ElementsAre(1));
440 // Make sure the interrupted tasks are executed next 'tick'.
441 m_platform.setShouldYield(false);
442 m_platform.runSingleTask();
443 EXPECT_THAT(m_order, ElementsAre(1, 2, 3));
446 TEST_F(ScriptRunnerTest, QueueReentrantScript_ManyAsyncScripts)
448 OwnPtrWillBeRawPtr<MockScriptLoader> scriptLoaders[20];
449 for (int i = 0; i < 20; i++)
450 scriptLoaders[i] = nullptr;
452 for (int i = 0; i < 20; i++) {
453 scriptLoaders[i] = MockScriptLoader::create(m_element.get());
454 EXPECT_CALL(*scriptLoaders[i], isReady()).WillRepeatedly(Return(true));
456 m_scriptRunner->queueScriptForExecution(scriptLoaders[i].get(), ScriptRunner::ASYNC_EXECUTION);
458 if (i > 0) {
459 EXPECT_CALL(*scriptLoaders[i], execute()).WillOnce(Invoke([this, i] {
460 m_order.push_back(i);
461 }));
465 m_scriptRunner->notifyScriptReady(scriptLoaders[0].get(), ScriptRunner::ASYNC_EXECUTION);
466 m_scriptRunner->notifyScriptReady(scriptLoaders[1].get(), ScriptRunner::ASYNC_EXECUTION);
467 m_scriptRunner->resume();
469 EXPECT_CALL(*scriptLoaders[0], execute()).WillOnce(Invoke([&scriptLoaders, this] {
470 for (int i = 2; i < 20; i++)
471 m_scriptRunner->notifyScriptReady(scriptLoaders[i].get(), ScriptRunner::ASYNC_EXECUTION);
472 m_scriptRunner->resume();
473 m_order.push_back(0);
474 }));
476 m_platform.runAllTasks();
478 int expected[] = {
479 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19
482 EXPECT_THAT(m_order, testing::ElementsAreArray(expected));
485 TEST_F(ScriptRunnerTest, ShouldYield_InOrderScripts)
487 OwnPtrWillBeRawPtr<MockScriptLoader> scriptLoader1 = MockScriptLoader::create(m_element.get());
488 OwnPtrWillBeRawPtr<MockScriptLoader> scriptLoader2 = MockScriptLoader::create(m_element.get());
489 OwnPtrWillBeRawPtr<MockScriptLoader> scriptLoader3 = MockScriptLoader::create(m_element.get());
491 EXPECT_CALL(*scriptLoader1, isReady()).WillRepeatedly(Return(true));
492 EXPECT_CALL(*scriptLoader2, isReady()).WillRepeatedly(Return(true));
493 EXPECT_CALL(*scriptLoader3, isReady()).WillRepeatedly(Return(true));
495 m_scriptRunner->queueScriptForExecution(scriptLoader1.get(), ScriptRunner::IN_ORDER_EXECUTION);
496 m_scriptRunner->queueScriptForExecution(scriptLoader2.get(), ScriptRunner::IN_ORDER_EXECUTION);
497 m_scriptRunner->queueScriptForExecution(scriptLoader3.get(), ScriptRunner::IN_ORDER_EXECUTION);
498 m_scriptRunner->resume();
500 EXPECT_CALL(*scriptLoader1, execute()).WillOnce(Invoke([this] {
501 m_order.push_back(1);
502 m_platform.setShouldYield(true);
503 }));
504 EXPECT_CALL(*scriptLoader2, execute()).WillOnce(Invoke([this] {
505 m_order.push_back(2);
506 }));
507 EXPECT_CALL(*scriptLoader3, execute()).WillOnce(Invoke([this] {
508 m_order.push_back(3);
509 }));
511 m_platform.runSingleTask();
512 EXPECT_THAT(m_order, ElementsAre(1));
514 // Make sure the interrupted tasks are executed next 'tick'.
515 m_platform.setShouldYield(false);
516 m_platform.runSingleTask();
517 EXPECT_THAT(m_order, ElementsAre(1, 2, 3));
520 TEST_F(ScriptRunnerTest, ShouldYield_RunsAtLastOneTask_AsyncScripts)
522 OwnPtrWillBeRawPtr<MockScriptLoader> scriptLoader1 = MockScriptLoader::create(m_element.get());
523 OwnPtrWillBeRawPtr<MockScriptLoader> scriptLoader2 = MockScriptLoader::create(m_element.get());
524 OwnPtrWillBeRawPtr<MockScriptLoader> scriptLoader3 = MockScriptLoader::create(m_element.get());
526 m_scriptRunner->queueScriptForExecution(scriptLoader1.get(), ScriptRunner::ASYNC_EXECUTION);
527 m_scriptRunner->queueScriptForExecution(scriptLoader2.get(), ScriptRunner::ASYNC_EXECUTION);
528 m_scriptRunner->queueScriptForExecution(scriptLoader3.get(), ScriptRunner::ASYNC_EXECUTION);
529 m_scriptRunner->notifyScriptReady(scriptLoader1.get(), ScriptRunner::ASYNC_EXECUTION);
530 m_scriptRunner->notifyScriptReady(scriptLoader2.get(), ScriptRunner::ASYNC_EXECUTION);
531 m_scriptRunner->notifyScriptReady(scriptLoader3.get(), ScriptRunner::ASYNC_EXECUTION);
533 m_platform.setShouldYield(true);
534 EXPECT_CALL(*scriptLoader1, execute()).Times(1);
535 EXPECT_CALL(*scriptLoader2, execute()).Times(0);
536 EXPECT_CALL(*scriptLoader3, execute()).Times(0);
538 m_platform.runSingleTask();
540 // We can't safely distruct ScriptRunner with unexecuted MockScriptLoaders (real ScriptLoader is fine) so drain them.
541 testing::Mock::VerifyAndClear(scriptLoader2.get());
542 testing::Mock::VerifyAndClear(scriptLoader3.get());
543 EXPECT_CALL(*scriptLoader2, execute()).Times(1);
544 EXPECT_CALL(*scriptLoader3, execute()).Times(1);
546 m_platform.runAllTasks();
549 TEST_F(ScriptRunnerTest, ShouldYield_RunsAtLastOneTask_InOrderScripts)
551 OwnPtrWillBeRawPtr<MockScriptLoader> scriptLoader1 = MockScriptLoader::create(m_element.get());
552 OwnPtrWillBeRawPtr<MockScriptLoader> scriptLoader2 = MockScriptLoader::create(m_element.get());
553 OwnPtrWillBeRawPtr<MockScriptLoader> scriptLoader3 = MockScriptLoader::create(m_element.get());
555 EXPECT_CALL(*scriptLoader1, isReady()).WillRepeatedly(Return(true));
556 EXPECT_CALL(*scriptLoader2, isReady()).WillRepeatedly(Return(true));
557 EXPECT_CALL(*scriptLoader3, isReady()).WillRepeatedly(Return(true));
559 m_scriptRunner->queueScriptForExecution(scriptLoader1.get(), ScriptRunner::IN_ORDER_EXECUTION);
560 m_scriptRunner->queueScriptForExecution(scriptLoader2.get(), ScriptRunner::IN_ORDER_EXECUTION);
561 m_scriptRunner->queueScriptForExecution(scriptLoader3.get(), ScriptRunner::IN_ORDER_EXECUTION);
562 m_scriptRunner->resume();
564 m_platform.setShouldYield(true);
565 EXPECT_CALL(*scriptLoader1, execute()).Times(1);
566 EXPECT_CALL(*scriptLoader2, execute()).Times(0);
567 EXPECT_CALL(*scriptLoader3, execute()).Times(0);
569 m_platform.runSingleTask();
571 // We can't safely distruct ScriptRunner with unexecuted MockScriptLoaders (real ScriptLoader is fine) so drain them.
572 testing::Mock::VerifyAndClear(scriptLoader2.get());
573 testing::Mock::VerifyAndClear(scriptLoader3.get());
574 EXPECT_CALL(*scriptLoader2, execute()).Times(1);
575 EXPECT_CALL(*scriptLoader3, execute()).Times(1);
576 EXPECT_CALL(*scriptLoader2, isReady()).WillRepeatedly(Return(true));
577 EXPECT_CALL(*scriptLoader3, isReady()).WillRepeatedly(Return(true));
578 m_platform.runAllTasks();
581 } // namespace blink