Index: Source/core/dom/ScriptRunnerTest.cpp |
diff --git a/Source/core/dom/ScriptRunnerTest.cpp b/Source/core/dom/ScriptRunnerTest.cpp |
deleted file mode 100644 |
index 6ed5b093bf7590f899900ff5b300c29ac8593d5f..0000000000000000000000000000000000000000 |
--- a/Source/core/dom/ScriptRunnerTest.cpp |
+++ /dev/null |
@@ -1,468 +0,0 @@ |
-// Copyright 2015 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "config.h" |
-#include "core/dom/ScriptRunner.h" |
- |
-#include "core/dom/Document.h" |
-#include "core/dom/ScriptLoader.h" |
-#include "platform/heap/Handle.h" |
-#include "platform/scheduler/Scheduler.h" |
-#include "public/platform/Platform.h" |
-#include "wtf/PassOwnPtr.h" |
-#include <gmock/gmock.h> |
-#include <gtest/gtest.h> |
- |
-using ::testing::Invoke; |
-using ::testing::ElementsAre; |
-using ::testing::Return; |
- |
-namespace blink { |
- |
-class MockScriptLoader: public ScriptLoader { |
-public: |
- explicit MockScriptLoader(Element* element) : ScriptLoader(element, false, false) { } |
- |
- ~MockScriptLoader() override { } |
- |
- MOCK_METHOD0(execute, void()); |
- MOCK_CONST_METHOD0(isReady, bool()); |
-}; |
- |
-class MockPlatform : public Platform, private WebScheduler { |
-public: |
- MockPlatform() : m_shouldYield(false), m_shouldYieldEveryOtherTime(false) { } |
- |
- WebScheduler* scheduler() override |
- { |
- return this; |
- } |
- |
- void postLoadingTask(const WebTraceLocation&, WebThread::Task* task) override |
- { |
- m_tasks.append(adoptPtr(task)); |
- } |
- |
- void cryptographicallyRandomValues(unsigned char* buffer, size_t length) override { } |
- |
- void runSingleTask() |
- { |
- if (m_tasks.isEmpty()) |
- return; |
- m_tasks.takeFirst()->run(); |
- } |
- |
- void runAllTasks() |
- { |
- while (!m_tasks.isEmpty()) |
- m_tasks.takeFirst()->run(); |
- } |
- |
- bool shouldYieldForHighPriorityWork() override |
- { |
- if (m_shouldYieldEveryOtherTime) |
- m_shouldYield = !m_shouldYield; |
- return m_shouldYield; |
- } |
- |
- void setShouldYield(bool shouldYield) |
- { |
- m_shouldYield = shouldYield; |
- } |
- |
- // NOTE if we yield 100% of the time, nothing will get run. |
- void setShouldYieldEveryOtherTime(bool shouldYieldEveryOtherTime) |
- { |
- m_shouldYieldEveryOtherTime = shouldYieldEveryOtherTime; |
- } |
- |
-private: |
- Deque<OwnPtr<WebThread::Task>> m_tasks; |
- bool m_shouldYield; |
- bool m_shouldYieldEveryOtherTime; |
-}; |
- |
-class ScriptRunnerTest : public testing::Test { |
-public: |
- void SetUp() override |
- { |
- m_document = Document::create(); |
- m_element = m_document->createElement("foo", ASSERT_NO_EXCEPTION); |
- |
- m_scriptRunner = ScriptRunner::create(m_document.get()); |
- m_oldPlatform = Platform::current(); |
- Platform::initialize(&m_platform); |
- m_platform.setShouldYield(false); |
- m_platform.setShouldYieldEveryOtherTime(false); |
- } |
- |
- void TearDown() override |
- { |
- m_scriptRunner.release(); |
- Scheduler::shutdown(); |
- Platform::initialize(m_oldPlatform); |
- } |
- |
- RefPtrWillBePersistent<Document> m_document; |
- RefPtrWillBePersistent<Element> m_element; |
- OwnPtrWillBePersistent<ScriptRunner> m_scriptRunner; |
- std::vector<int> m_order; // gmock matchers don't work nicely with WTF::Vector |
- MockPlatform m_platform; |
- Platform* m_oldPlatform; |
-}; |
- |
-TEST_F(ScriptRunnerTest, QueueSingleScript_Async) |
-{ |
- MockScriptLoader scriptLoader(m_element.get()); |
- m_scriptRunner->queueScriptForExecution(&scriptLoader, ScriptRunner::ASYNC_EXECUTION); |
- m_scriptRunner->notifyScriptReady(&scriptLoader, ScriptRunner::ASYNC_EXECUTION); |
- |
- EXPECT_CALL(scriptLoader, execute()); |
- m_platform.runAllTasks(); |
-} |
- |
-TEST_F(ScriptRunnerTest, QueueSingleScript_InOrder) |
-{ |
- MockScriptLoader scriptLoader(m_element.get()); |
- m_scriptRunner->queueScriptForExecution(&scriptLoader, ScriptRunner::IN_ORDER_EXECUTION); |
- m_scriptRunner->resume(); |
- |
- EXPECT_CALL(scriptLoader, isReady()).WillOnce(Return(true)); |
- EXPECT_CALL(scriptLoader, execute()); |
- m_platform.runAllTasks(); |
-} |
- |
-TEST_F(ScriptRunnerTest, QueueMultipleScripts_InOrder) |
-{ |
- MockScriptLoader scriptLoader1(m_element.get()); |
- MockScriptLoader scriptLoader2(m_element.get()); |
- MockScriptLoader scriptLoader3(m_element.get()); |
- |
- m_scriptRunner->queueScriptForExecution(&scriptLoader1, ScriptRunner::IN_ORDER_EXECUTION); |
- m_scriptRunner->queueScriptForExecution(&scriptLoader2, ScriptRunner::IN_ORDER_EXECUTION); |
- m_scriptRunner->queueScriptForExecution(&scriptLoader3, ScriptRunner::IN_ORDER_EXECUTION); |
- |
- EXPECT_CALL(scriptLoader1, execute()).WillOnce(Invoke([this] { |
- m_order.push_back(1); |
- })); |
- EXPECT_CALL(scriptLoader2, execute()).WillOnce(Invoke([this] { |
- m_order.push_back(2); |
- })); |
- EXPECT_CALL(scriptLoader3, execute()).WillOnce(Invoke([this] { |
- m_order.push_back(3); |
- })); |
- |
- // Make the scripts become ready in reverse order. |
- bool isReady[] = { false, false, false }; |
- EXPECT_CALL(scriptLoader1, isReady()).WillRepeatedly(Invoke([&isReady] { |
- return isReady[0]; |
- })); |
- EXPECT_CALL(scriptLoader2, isReady()).WillRepeatedly(Invoke([&isReady] { |
- return isReady[1]; |
- })); |
- EXPECT_CALL(scriptLoader3, isReady()).WillRepeatedly(Invoke([&isReady] { |
- return isReady[2]; |
- })); |
- |
- for (int i = 2; i >= 0; i--) { |
- isReady[i] = true; |
- m_scriptRunner->resume(); |
- m_platform.runAllTasks(); |
- } |
- |
- // But ensure the scripts were run in the expected order. |
- EXPECT_THAT(m_order, ElementsAre(1, 2, 3)); |
-} |
- |
-TEST_F(ScriptRunnerTest, QueueMixedScripts) |
-{ |
- MockScriptLoader scriptLoader1(m_element.get()); |
- MockScriptLoader scriptLoader2(m_element.get()); |
- MockScriptLoader scriptLoader3(m_element.get()); |
- MockScriptLoader scriptLoader4(m_element.get()); |
- MockScriptLoader scriptLoader5(m_element.get()); |
- |
- EXPECT_CALL(scriptLoader1, isReady()).WillRepeatedly(Return(true)); |
- EXPECT_CALL(scriptLoader2, isReady()).WillRepeatedly(Return(true)); |
- EXPECT_CALL(scriptLoader3, isReady()).WillRepeatedly(Return(true)); |
- |
- m_scriptRunner->queueScriptForExecution(&scriptLoader1, ScriptRunner::IN_ORDER_EXECUTION); |
- m_scriptRunner->queueScriptForExecution(&scriptLoader2, ScriptRunner::IN_ORDER_EXECUTION); |
- m_scriptRunner->queueScriptForExecution(&scriptLoader3, ScriptRunner::IN_ORDER_EXECUTION); |
- m_scriptRunner->queueScriptForExecution(&scriptLoader4, ScriptRunner::ASYNC_EXECUTION); |
- m_scriptRunner->queueScriptForExecution(&scriptLoader5, ScriptRunner::ASYNC_EXECUTION); |
- |
- m_scriptRunner->notifyScriptReady(&scriptLoader4, ScriptRunner::ASYNC_EXECUTION); |
- m_scriptRunner->notifyScriptReady(&scriptLoader5, ScriptRunner::ASYNC_EXECUTION); |
- |
- EXPECT_CALL(scriptLoader1, execute()).WillOnce(Invoke([this] { |
- m_order.push_back(1); |
- })); |
- EXPECT_CALL(scriptLoader2, execute()).WillOnce(Invoke([this] { |
- m_order.push_back(2); |
- })); |
- EXPECT_CALL(scriptLoader3, execute()).WillOnce(Invoke([this] { |
- m_order.push_back(3); |
- })); |
- EXPECT_CALL(scriptLoader4, execute()).WillOnce(Invoke([this] { |
- m_order.push_back(4); |
- })); |
- EXPECT_CALL(scriptLoader5, execute()).WillOnce(Invoke([this] { |
- m_order.push_back(5); |
- })); |
- |
- m_platform.runAllTasks(); |
- |
- // Make sure the async scripts were run before the in-order ones. |
- EXPECT_THAT(m_order, ElementsAre(4, 5, 1, 2, 3)); |
-} |
- |
-TEST_F(ScriptRunnerTest, QueueMixedScripts_YieldAfterEveryExecution) |
-{ |
- MockScriptLoader scriptLoader1(m_element.get()); |
- MockScriptLoader scriptLoader2(m_element.get()); |
- MockScriptLoader scriptLoader3(m_element.get()); |
- MockScriptLoader scriptLoader4(m_element.get()); |
- MockScriptLoader scriptLoader5(m_element.get()); |
- |
- m_platform.setShouldYieldEveryOtherTime(true); |
- |
- EXPECT_CALL(scriptLoader1, isReady()).WillRepeatedly(Return(true)); |
- EXPECT_CALL(scriptLoader2, isReady()).WillRepeatedly(Return(true)); |
- EXPECT_CALL(scriptLoader3, isReady()).WillRepeatedly(Return(true)); |
- |
- m_scriptRunner->queueScriptForExecution(&scriptLoader1, ScriptRunner::IN_ORDER_EXECUTION); |
- m_scriptRunner->queueScriptForExecution(&scriptLoader2, ScriptRunner::IN_ORDER_EXECUTION); |
- m_scriptRunner->queueScriptForExecution(&scriptLoader3, ScriptRunner::IN_ORDER_EXECUTION); |
- m_scriptRunner->queueScriptForExecution(&scriptLoader4, ScriptRunner::ASYNC_EXECUTION); |
- m_scriptRunner->queueScriptForExecution(&scriptLoader5, ScriptRunner::ASYNC_EXECUTION); |
- |
- m_scriptRunner->notifyScriptReady(&scriptLoader4, ScriptRunner::ASYNC_EXECUTION); |
- m_scriptRunner->notifyScriptReady(&scriptLoader5, ScriptRunner::ASYNC_EXECUTION); |
- |
- EXPECT_CALL(scriptLoader1, execute()).WillOnce(Invoke([this] { |
- m_order.push_back(1); |
- })); |
- EXPECT_CALL(scriptLoader2, execute()).WillOnce(Invoke([this] { |
- m_order.push_back(2); |
- })); |
- EXPECT_CALL(scriptLoader3, execute()).WillOnce(Invoke([this] { |
- m_order.push_back(3); |
- })); |
- EXPECT_CALL(scriptLoader4, execute()).WillOnce(Invoke([this] { |
- m_order.push_back(4); |
- })); |
- EXPECT_CALL(scriptLoader5, execute()).WillOnce(Invoke([this] { |
- m_order.push_back(5); |
- })); |
- |
- m_platform.runAllTasks(); |
- |
- // Make sure the async scripts were run before the in-order ones. |
- EXPECT_THAT(m_order, ElementsAre(4, 5, 1, 2, 3)); |
-} |
- |
-TEST_F(ScriptRunnerTest, QueueReentrantScript_Async) |
-{ |
- MockScriptLoader scriptLoader1(m_element.get()); |
- MockScriptLoader scriptLoader2(m_element.get()); |
- MockScriptLoader scriptLoader3(m_element.get()); |
- |
- m_scriptRunner->queueScriptForExecution(&scriptLoader1, ScriptRunner::ASYNC_EXECUTION); |
- m_scriptRunner->queueScriptForExecution(&scriptLoader2, ScriptRunner::ASYNC_EXECUTION); |
- m_scriptRunner->queueScriptForExecution(&scriptLoader3, ScriptRunner::ASYNC_EXECUTION); |
- m_scriptRunner->notifyScriptReady(&scriptLoader1, ScriptRunner::ASYNC_EXECUTION); |
- |
- EXPECT_CALL(scriptLoader1, execute()).WillOnce(Invoke([&scriptLoader2, this] { |
- m_order.push_back(1); |
- m_scriptRunner->notifyScriptReady(&scriptLoader2, ScriptRunner::ASYNC_EXECUTION); |
- })); |
- |
- EXPECT_CALL(scriptLoader2, execute()).WillOnce(Invoke([&scriptLoader3, this] { |
- m_order.push_back(2); |
- m_scriptRunner->notifyScriptReady(&scriptLoader3, ScriptRunner::ASYNC_EXECUTION); |
- })); |
- |
- EXPECT_CALL(scriptLoader3, execute()).WillOnce(Invoke([this] { |
- m_order.push_back(3); |
- })); |
- |
- // Make sure that re-entrant calls to notifyScriptReady don't cause ScriptRunner::execute to do |
- // more work than expected. |
- m_platform.runSingleTask(); |
- EXPECT_THAT(m_order, ElementsAre(1)); |
- |
- m_platform.runSingleTask(); |
- EXPECT_THAT(m_order, ElementsAre(1, 2)); |
- |
- m_platform.runSingleTask(); |
- EXPECT_THAT(m_order, ElementsAre(1, 2, 3)); |
-} |
- |
-TEST_F(ScriptRunnerTest, QueueReentrantScript_InOrder) |
-{ |
- MockScriptLoader scriptLoader1(m_element.get()); |
- MockScriptLoader scriptLoader2(m_element.get()); |
- MockScriptLoader scriptLoader3(m_element.get()); |
- |
- EXPECT_CALL(scriptLoader1, isReady()).WillRepeatedly(Return(true)); |
- EXPECT_CALL(scriptLoader2, isReady()).WillRepeatedly(Return(true)); |
- EXPECT_CALL(scriptLoader3, isReady()).WillRepeatedly(Return(true)); |
- |
- m_scriptRunner->queueScriptForExecution(&scriptLoader1, ScriptRunner::IN_ORDER_EXECUTION); |
- m_scriptRunner->resume(); |
- |
- EXPECT_CALL(scriptLoader1, execute()).WillOnce(Invoke([&scriptLoader2, this] { |
- m_order.push_back(1); |
- m_scriptRunner->queueScriptForExecution(&scriptLoader2, ScriptRunner::IN_ORDER_EXECUTION); |
- m_scriptRunner->resume(); |
- })); |
- |
- EXPECT_CALL(scriptLoader2, execute()).WillOnce(Invoke([&scriptLoader3, this] { |
- m_order.push_back(2); |
- m_scriptRunner->queueScriptForExecution(&scriptLoader3, ScriptRunner::IN_ORDER_EXECUTION); |
- m_scriptRunner->resume(); |
- })); |
- |
- EXPECT_CALL(scriptLoader3, execute()).WillOnce(Invoke([this] { |
- m_order.push_back(3); |
- })); |
- |
- // Make sure that re-entrant calls to queueScriptForExecution don't cause ScriptRunner::execute to do |
- // more work than expected. |
- m_platform.runSingleTask(); |
- EXPECT_THAT(m_order, ElementsAre(1)); |
- |
- m_platform.runSingleTask(); |
- EXPECT_THAT(m_order, ElementsAre(1, 2)); |
- |
- m_platform.runSingleTask(); |
- EXPECT_THAT(m_order, ElementsAre(1, 2, 3)); |
-} |
- |
-TEST_F(ScriptRunnerTest, ShouldYield_AsyncScripts) |
-{ |
- MockScriptLoader scriptLoader1(m_element.get()); |
- MockScriptLoader scriptLoader2(m_element.get()); |
- MockScriptLoader scriptLoader3(m_element.get()); |
- |
- m_scriptRunner->queueScriptForExecution(&scriptLoader1, ScriptRunner::ASYNC_EXECUTION); |
- m_scriptRunner->queueScriptForExecution(&scriptLoader2, ScriptRunner::ASYNC_EXECUTION); |
- m_scriptRunner->queueScriptForExecution(&scriptLoader3, ScriptRunner::ASYNC_EXECUTION); |
- m_scriptRunner->notifyScriptReady(&scriptLoader1, ScriptRunner::ASYNC_EXECUTION); |
- m_scriptRunner->notifyScriptReady(&scriptLoader2, ScriptRunner::ASYNC_EXECUTION); |
- m_scriptRunner->notifyScriptReady(&scriptLoader3, ScriptRunner::ASYNC_EXECUTION); |
- |
- EXPECT_CALL(scriptLoader1, execute()).WillOnce(Invoke([this] { |
- m_order.push_back(1); |
- m_platform.setShouldYield(true); |
- })); |
- EXPECT_CALL(scriptLoader2, execute()).WillOnce(Invoke([this] { |
- m_order.push_back(2); |
- })); |
- EXPECT_CALL(scriptLoader3, execute()).WillOnce(Invoke([this] { |
- m_order.push_back(3); |
- })); |
- |
- m_platform.runSingleTask(); |
- EXPECT_THAT(m_order, ElementsAre(1)); |
- |
- // Make sure the interrupted tasks are executed next 'tick'. |
- m_platform.setShouldYield(false); |
- m_platform.runSingleTask(); |
- EXPECT_THAT(m_order, ElementsAre(1, 2, 3)); |
-} |
- |
-TEST_F(ScriptRunnerTest, ShouldYield_InOrderScripts) |
-{ |
- MockScriptLoader scriptLoader1(m_element.get()); |
- MockScriptLoader scriptLoader2(m_element.get()); |
- MockScriptLoader scriptLoader3(m_element.get()); |
- |
- EXPECT_CALL(scriptLoader1, isReady()).WillRepeatedly(Return(true)); |
- EXPECT_CALL(scriptLoader2, isReady()).WillRepeatedly(Return(true)); |
- EXPECT_CALL(scriptLoader3, isReady()).WillRepeatedly(Return(true)); |
- |
- m_scriptRunner->queueScriptForExecution(&scriptLoader1, ScriptRunner::IN_ORDER_EXECUTION); |
- m_scriptRunner->queueScriptForExecution(&scriptLoader2, ScriptRunner::IN_ORDER_EXECUTION); |
- m_scriptRunner->queueScriptForExecution(&scriptLoader3, ScriptRunner::IN_ORDER_EXECUTION); |
- m_scriptRunner->resume(); |
- |
- EXPECT_CALL(scriptLoader1, execute()).WillOnce(Invoke([this] { |
- m_order.push_back(1); |
- m_platform.setShouldYield(true); |
- })); |
- EXPECT_CALL(scriptLoader2, execute()).WillOnce(Invoke([this] { |
- m_order.push_back(2); |
- })); |
- EXPECT_CALL(scriptLoader3, execute()).WillOnce(Invoke([this] { |
- m_order.push_back(3); |
- })); |
- |
- m_platform.runSingleTask(); |
- EXPECT_THAT(m_order, ElementsAre(1)); |
- |
- // Make sure the interrupted tasks are executed next 'tick'. |
- m_platform.setShouldYield(false); |
- m_platform.runSingleTask(); |
- EXPECT_THAT(m_order, ElementsAre(1, 2, 3)); |
-} |
- |
-TEST_F(ScriptRunnerTest, ShouldYield_RunsAtLastOneTask_AsyncScripts) |
-{ |
- MockScriptLoader scriptLoader1(m_element.get()); |
- MockScriptLoader scriptLoader2(m_element.get()); |
- MockScriptLoader scriptLoader3(m_element.get()); |
- |
- m_scriptRunner->queueScriptForExecution(&scriptLoader1, ScriptRunner::ASYNC_EXECUTION); |
- m_scriptRunner->queueScriptForExecution(&scriptLoader2, ScriptRunner::ASYNC_EXECUTION); |
- m_scriptRunner->queueScriptForExecution(&scriptLoader3, ScriptRunner::ASYNC_EXECUTION); |
- m_scriptRunner->notifyScriptReady(&scriptLoader1, ScriptRunner::ASYNC_EXECUTION); |
- m_scriptRunner->notifyScriptReady(&scriptLoader2, ScriptRunner::ASYNC_EXECUTION); |
- m_scriptRunner->notifyScriptReady(&scriptLoader3, ScriptRunner::ASYNC_EXECUTION); |
- |
- m_platform.setShouldYield(true); |
- EXPECT_CALL(scriptLoader1, execute()).Times(1); |
- EXPECT_CALL(scriptLoader2, execute()).Times(0); |
- EXPECT_CALL(scriptLoader3, execute()).Times(0); |
- |
- m_platform.runSingleTask(); |
- |
- // We can't safely distruct ScriptRunner with unexecuted MockScriptLoaders (real ScriptLoader is fine) so drain them. |
- testing::Mock::VerifyAndClear(&scriptLoader2); |
- testing::Mock::VerifyAndClear(&scriptLoader3); |
- m_platform.runAllTasks(); |
-} |
- |
-TEST_F(ScriptRunnerTest, ShouldYield_RunsAtLastOneTask_InOrderScripts) |
-{ |
- MockScriptLoader scriptLoader1(m_element.get()); |
- MockScriptLoader scriptLoader2(m_element.get()); |
- MockScriptLoader scriptLoader3(m_element.get()); |
- |
- EXPECT_CALL(scriptLoader1, isReady()).WillRepeatedly(Return(true)); |
- EXPECT_CALL(scriptLoader2, isReady()).WillRepeatedly(Return(true)); |
- EXPECT_CALL(scriptLoader3, isReady()).WillRepeatedly(Return(true)); |
- |
- m_scriptRunner->queueScriptForExecution(&scriptLoader1, ScriptRunner::IN_ORDER_EXECUTION); |
- m_scriptRunner->queueScriptForExecution(&scriptLoader2, ScriptRunner::IN_ORDER_EXECUTION); |
- m_scriptRunner->queueScriptForExecution(&scriptLoader3, ScriptRunner::IN_ORDER_EXECUTION); |
- m_scriptRunner->resume(); |
- |
- m_platform.setShouldYield(true); |
- EXPECT_CALL(scriptLoader1, execute()).Times(1); |
- EXPECT_CALL(scriptLoader2, execute()).Times(0); |
- EXPECT_CALL(scriptLoader3, execute()).Times(0); |
- |
- m_platform.runSingleTask(); |
- |
- // We can't safely distruct ScriptRunner with unexecuted MockScriptLoaders (real ScriptLoader is fine) so drain them. |
- testing::Mock::VerifyAndClear(&scriptLoader2); |
- testing::Mock::VerifyAndClear(&scriptLoader3); |
- EXPECT_CALL(scriptLoader2, isReady()).WillRepeatedly(Return(true)); |
- EXPECT_CALL(scriptLoader3, isReady()).WillRepeatedly(Return(true)); |
- m_platform.runAllTasks(); |
-} |
- |
-} // namespace blink |