| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "core/dom/ScriptRunner.h" | 5 #include "core/dom/ScriptRunner.h" |
| 6 | 6 |
| 7 #include "bindings/core/v8/HTMLScriptElementOrSVGScriptElement.h" |
| 7 #include "core/dom/Document.h" | 8 #include "core/dom/Document.h" |
| 8 #include "core/dom/Element.h" | |
| 9 #include "core/dom/ScriptLoader.h" | 9 #include "core/dom/ScriptLoader.h" |
| 10 #include "platform/heap/Handle.h" | 10 #include "platform/heap/Handle.h" |
| 11 #include "platform/testing/TestingPlatformSupport.h" | 11 #include "platform/testing/TestingPlatformSupport.h" |
| 12 #include "public/platform/Platform.h" | 12 #include "public/platform/Platform.h" |
| 13 #include "public/platform/WebViewScheduler.h" | 13 #include "public/platform/WebViewScheduler.h" |
| 14 #include "testing/gmock/include/gmock/gmock.h" | 14 #include "testing/gmock/include/gmock/gmock.h" |
| 15 #include "testing/gtest/include/gtest/gtest.h" | 15 #include "testing/gtest/include/gtest/gtest.h" |
| 16 | 16 |
| 17 using ::testing::Invoke; | 17 using ::testing::Invoke; |
| 18 using ::testing::ElementsAre; | 18 using ::testing::ElementsAre; |
| 19 using ::testing::Return; | 19 using ::testing::Return; |
| 20 using ::testing::WhenSorted; | 20 using ::testing::WhenSorted; |
| 21 using ::testing::ElementsAreArray; | 21 using ::testing::ElementsAreArray; |
| 22 | 22 |
| 23 namespace blink { | 23 namespace blink { |
| 24 | 24 |
| 25 class MockScriptElementBase |
| 26 : public GarbageCollectedFinalized<MockScriptElementBase>, |
| 27 public ScriptElementBase { |
| 28 USING_GARBAGE_COLLECTED_MIXIN(MockScriptElementBase); |
| 29 |
| 30 public: |
| 31 static MockScriptElementBase* create() { |
| 32 return new testing::StrictMock<MockScriptElementBase>(); |
| 33 } |
| 34 |
| 35 MOCK_METHOD0(dispatchLoadEvent, void()); |
| 36 MOCK_METHOD0(dispatchErrorEvent, void()); |
| 37 MOCK_CONST_METHOD0(asyncAttributeValue, bool()); |
| 38 MOCK_CONST_METHOD0(charsetAttributeValue, String()); |
| 39 MOCK_CONST_METHOD0(crossOriginAttributeValue, String()); |
| 40 MOCK_CONST_METHOD0(deferAttributeValue, bool()); |
| 41 MOCK_CONST_METHOD0(eventAttributeValue, String()); |
| 42 MOCK_CONST_METHOD0(forAttributeValue, String()); |
| 43 MOCK_CONST_METHOD0(integrityAttributeValue, String()); |
| 44 MOCK_CONST_METHOD0(languageAttributeValue, String()); |
| 45 MOCK_CONST_METHOD0(sourceAttributeValue, String()); |
| 46 MOCK_CONST_METHOD0(typeAttributeValue, String()); |
| 47 |
| 48 MOCK_METHOD0(textFromChildren, String()); |
| 49 MOCK_CONST_METHOD0(textContent, String()); |
| 50 MOCK_CONST_METHOD0(hasSourceAttribute, bool()); |
| 51 MOCK_CONST_METHOD0(isConnected, bool()); |
| 52 MOCK_CONST_METHOD0(hasChildren, bool()); |
| 53 MOCK_CONST_METHOD0(isNonceableElement, bool()); |
| 54 MOCK_CONST_METHOD0(initiatorName, AtomicString()); |
| 55 MOCK_METHOD3(allowInlineScriptForCSP, |
| 56 bool(const AtomicString&, |
| 57 const WTF::OrdinalNumber&, |
| 58 const String&)); |
| 59 MOCK_CONST_METHOD0(document, Document&()); |
| 60 MOCK_METHOD1(setScriptElementForBinding, |
| 61 void(HTMLScriptElementOrSVGScriptElement&)); |
| 62 |
| 63 DEFINE_INLINE_VIRTUAL_TRACE() { ScriptElementBase::trace(visitor); } |
| 64 }; |
| 65 |
| 25 class MockScriptLoader final : public ScriptLoader { | 66 class MockScriptLoader final : public ScriptLoader { |
| 26 public: | 67 public: |
| 27 static MockScriptLoader* create(Element* element) { | 68 static MockScriptLoader* create() { return new MockScriptLoader(); } |
| 28 return new MockScriptLoader(element); | |
| 29 } | |
| 30 ~MockScriptLoader() override {} | 69 ~MockScriptLoader() override {} |
| 31 | 70 |
| 32 MOCK_METHOD0(execute, void()); | 71 MOCK_METHOD0(execute, void()); |
| 33 MOCK_CONST_METHOD0(isReady, bool()); | 72 MOCK_CONST_METHOD0(isReady, bool()); |
| 34 | 73 |
| 35 private: | 74 private: |
| 36 explicit MockScriptLoader(Element* element) | 75 explicit MockScriptLoader() |
| 37 : ScriptLoader(element, false, false, false) {} | 76 : ScriptLoader(MockScriptElementBase::create(), false, false, false) {} |
| 38 }; | 77 }; |
| 39 | 78 |
| 40 class ScriptRunnerTest : public testing::Test { | 79 class ScriptRunnerTest : public testing::Test { |
| 41 public: | 80 public: |
| 42 ScriptRunnerTest() | 81 ScriptRunnerTest() : m_document(Document::create()) {} |
| 43 : m_document(Document::create()), | |
| 44 m_element(m_document->createElement("foo")) {} | |
| 45 | 82 |
| 46 void SetUp() override { | 83 void SetUp() override { |
| 47 // We have to create ScriptRunner after initializing platform, because we | 84 // We have to create ScriptRunner after initializing platform, because we |
| 48 // need Platform::current()->currentThread()->scheduler()-> | 85 // need Platform::current()->currentThread()->scheduler()-> |
| 49 // loadingTaskRunner() to be initialized before creating ScriptRunner to | 86 // loadingTaskRunner() to be initialized before creating ScriptRunner to |
| 50 // save it in constructor. | 87 // save it in constructor. |
| 51 m_scriptRunner = ScriptRunner::create(m_document.get()); | 88 m_scriptRunner = ScriptRunner::create(m_document.get()); |
| 52 } | 89 } |
| 53 void TearDown() override { m_scriptRunner.release(); } | 90 void TearDown() override { m_scriptRunner.release(); } |
| 54 | 91 |
| 55 protected: | 92 protected: |
| 56 Persistent<Document> m_document; | 93 Persistent<Document> m_document; |
| 57 Persistent<Element> m_element; | |
| 58 Persistent<ScriptRunner> m_scriptRunner; | 94 Persistent<ScriptRunner> m_scriptRunner; |
| 59 WTF::Vector<int> m_order; | 95 WTF::Vector<int> m_order; |
| 60 ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler> | 96 ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler> |
| 61 m_platform; | 97 m_platform; |
| 62 }; | 98 }; |
| 63 | 99 |
| 64 TEST_F(ScriptRunnerTest, QueueSingleScript_Async) { | 100 TEST_F(ScriptRunnerTest, QueueSingleScript_Async) { |
| 65 MockScriptLoader* scriptLoader = MockScriptLoader::create(m_element.get()); | 101 MockScriptLoader* scriptLoader = MockScriptLoader::create(); |
| 66 m_scriptRunner->queueScriptForExecution(scriptLoader, ScriptRunner::Async); | 102 m_scriptRunner->queueScriptForExecution(scriptLoader, ScriptRunner::Async); |
| 67 m_scriptRunner->notifyScriptReady(scriptLoader, ScriptRunner::Async); | 103 m_scriptRunner->notifyScriptReady(scriptLoader, ScriptRunner::Async); |
| 68 | 104 |
| 69 EXPECT_CALL(*scriptLoader, execute()); | 105 EXPECT_CALL(*scriptLoader, execute()); |
| 70 m_platform->runUntilIdle(); | 106 m_platform->runUntilIdle(); |
| 71 } | 107 } |
| 72 | 108 |
| 73 TEST_F(ScriptRunnerTest, QueueSingleScript_InOrder) { | 109 TEST_F(ScriptRunnerTest, QueueSingleScript_InOrder) { |
| 74 MockScriptLoader* scriptLoader = MockScriptLoader::create(m_element.get()); | 110 MockScriptLoader* scriptLoader = MockScriptLoader::create(); |
| 75 m_scriptRunner->queueScriptForExecution(scriptLoader, ScriptRunner::InOrder); | 111 m_scriptRunner->queueScriptForExecution(scriptLoader, ScriptRunner::InOrder); |
| 76 | 112 |
| 77 EXPECT_CALL(*scriptLoader, isReady()).WillOnce(Return(true)); | 113 EXPECT_CALL(*scriptLoader, isReady()).WillOnce(Return(true)); |
| 78 EXPECT_CALL(*scriptLoader, execute()); | 114 EXPECT_CALL(*scriptLoader, execute()); |
| 79 | 115 |
| 80 m_scriptRunner->notifyScriptReady(scriptLoader, ScriptRunner::InOrder); | 116 m_scriptRunner->notifyScriptReady(scriptLoader, ScriptRunner::InOrder); |
| 81 | 117 |
| 82 m_platform->runUntilIdle(); | 118 m_platform->runUntilIdle(); |
| 83 } | 119 } |
| 84 | 120 |
| 85 TEST_F(ScriptRunnerTest, QueueMultipleScripts_InOrder) { | 121 TEST_F(ScriptRunnerTest, QueueMultipleScripts_InOrder) { |
| 86 MockScriptLoader* scriptLoader1 = MockScriptLoader::create(m_element.get()); | 122 MockScriptLoader* scriptLoader1 = MockScriptLoader::create(); |
| 87 MockScriptLoader* scriptLoader2 = MockScriptLoader::create(m_element.get()); | 123 MockScriptLoader* scriptLoader2 = MockScriptLoader::create(); |
| 88 MockScriptLoader* scriptLoader3 = MockScriptLoader::create(m_element.get()); | 124 MockScriptLoader* scriptLoader3 = MockScriptLoader::create(); |
| 89 | 125 |
| 90 HeapVector<Member<MockScriptLoader>> scriptLoaders; | 126 HeapVector<Member<MockScriptLoader>> scriptLoaders; |
| 91 scriptLoaders.push_back(scriptLoader1); | 127 scriptLoaders.push_back(scriptLoader1); |
| 92 scriptLoaders.push_back(scriptLoader2); | 128 scriptLoaders.push_back(scriptLoader2); |
| 93 scriptLoaders.push_back(scriptLoader3); | 129 scriptLoaders.push_back(scriptLoader3); |
| 94 | 130 |
| 95 for (ScriptLoader* scriptLoader : scriptLoaders) { | 131 for (ScriptLoader* scriptLoader : scriptLoaders) { |
| 96 m_scriptRunner->queueScriptForExecution(scriptLoader, | 132 m_scriptRunner->queueScriptForExecution(scriptLoader, |
| 97 ScriptRunner::InOrder); | 133 ScriptRunner::InOrder); |
| 98 } | 134 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 115 isReady[i] = true; | 151 isReady[i] = true; |
| 116 m_scriptRunner->notifyScriptReady(scriptLoaders[i], ScriptRunner::InOrder); | 152 m_scriptRunner->notifyScriptReady(scriptLoaders[i], ScriptRunner::InOrder); |
| 117 m_platform->runUntilIdle(); | 153 m_platform->runUntilIdle(); |
| 118 } | 154 } |
| 119 | 155 |
| 120 // But ensure the scripts were run in the expected order. | 156 // But ensure the scripts were run in the expected order. |
| 121 EXPECT_THAT(m_order, ElementsAre(1, 2, 3)); | 157 EXPECT_THAT(m_order, ElementsAre(1, 2, 3)); |
| 122 } | 158 } |
| 123 | 159 |
| 124 TEST_F(ScriptRunnerTest, QueueMixedScripts) { | 160 TEST_F(ScriptRunnerTest, QueueMixedScripts) { |
| 125 MockScriptLoader* scriptLoader1 = MockScriptLoader::create(m_element.get()); | 161 MockScriptLoader* scriptLoader1 = MockScriptLoader::create(); |
| 126 MockScriptLoader* scriptLoader2 = MockScriptLoader::create(m_element.get()); | 162 MockScriptLoader* scriptLoader2 = MockScriptLoader::create(); |
| 127 MockScriptLoader* scriptLoader3 = MockScriptLoader::create(m_element.get()); | 163 MockScriptLoader* scriptLoader3 = MockScriptLoader::create(); |
| 128 MockScriptLoader* scriptLoader4 = MockScriptLoader::create(m_element.get()); | 164 MockScriptLoader* scriptLoader4 = MockScriptLoader::create(); |
| 129 MockScriptLoader* scriptLoader5 = MockScriptLoader::create(m_element.get()); | 165 MockScriptLoader* scriptLoader5 = MockScriptLoader::create(); |
| 130 | 166 |
| 131 m_scriptRunner->queueScriptForExecution(scriptLoader1, ScriptRunner::InOrder); | 167 m_scriptRunner->queueScriptForExecution(scriptLoader1, ScriptRunner::InOrder); |
| 132 m_scriptRunner->queueScriptForExecution(scriptLoader2, ScriptRunner::InOrder); | 168 m_scriptRunner->queueScriptForExecution(scriptLoader2, ScriptRunner::InOrder); |
| 133 m_scriptRunner->queueScriptForExecution(scriptLoader3, ScriptRunner::InOrder); | 169 m_scriptRunner->queueScriptForExecution(scriptLoader3, ScriptRunner::InOrder); |
| 134 m_scriptRunner->queueScriptForExecution(scriptLoader4, ScriptRunner::Async); | 170 m_scriptRunner->queueScriptForExecution(scriptLoader4, ScriptRunner::Async); |
| 135 m_scriptRunner->queueScriptForExecution(scriptLoader5, ScriptRunner::Async); | 171 m_scriptRunner->queueScriptForExecution(scriptLoader5, ScriptRunner::Async); |
| 136 | 172 |
| 137 EXPECT_CALL(*scriptLoader1, isReady()).WillRepeatedly(Return(true)); | 173 EXPECT_CALL(*scriptLoader1, isReady()).WillRepeatedly(Return(true)); |
| 138 EXPECT_CALL(*scriptLoader2, isReady()).WillRepeatedly(Return(false)); | 174 EXPECT_CALL(*scriptLoader2, isReady()).WillRepeatedly(Return(false)); |
| 139 m_scriptRunner->notifyScriptReady(scriptLoader1, ScriptRunner::InOrder); | 175 m_scriptRunner->notifyScriptReady(scriptLoader1, ScriptRunner::InOrder); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 164 m_order.push_back(5); | 200 m_order.push_back(5); |
| 165 })); | 201 })); |
| 166 | 202 |
| 167 m_platform->runUntilIdle(); | 203 m_platform->runUntilIdle(); |
| 168 | 204 |
| 169 // Async tasks are expected to run first. | 205 // Async tasks are expected to run first. |
| 170 EXPECT_THAT(m_order, ElementsAre(4, 5, 1, 2, 3)); | 206 EXPECT_THAT(m_order, ElementsAre(4, 5, 1, 2, 3)); |
| 171 } | 207 } |
| 172 | 208 |
| 173 TEST_F(ScriptRunnerTest, QueueReentrantScript_Async) { | 209 TEST_F(ScriptRunnerTest, QueueReentrantScript_Async) { |
| 174 MockScriptLoader* scriptLoader1 = MockScriptLoader::create(m_element.get()); | 210 MockScriptLoader* scriptLoader1 = MockScriptLoader::create(); |
| 175 MockScriptLoader* scriptLoader2 = MockScriptLoader::create(m_element.get()); | 211 MockScriptLoader* scriptLoader2 = MockScriptLoader::create(); |
| 176 MockScriptLoader* scriptLoader3 = MockScriptLoader::create(m_element.get()); | 212 MockScriptLoader* scriptLoader3 = MockScriptLoader::create(); |
| 177 | 213 |
| 178 m_scriptRunner->queueScriptForExecution(scriptLoader1, ScriptRunner::Async); | 214 m_scriptRunner->queueScriptForExecution(scriptLoader1, ScriptRunner::Async); |
| 179 m_scriptRunner->queueScriptForExecution(scriptLoader2, ScriptRunner::Async); | 215 m_scriptRunner->queueScriptForExecution(scriptLoader2, ScriptRunner::Async); |
| 180 m_scriptRunner->queueScriptForExecution(scriptLoader3, ScriptRunner::Async); | 216 m_scriptRunner->queueScriptForExecution(scriptLoader3, ScriptRunner::Async); |
| 181 m_scriptRunner->notifyScriptReady(scriptLoader1, ScriptRunner::Async); | 217 m_scriptRunner->notifyScriptReady(scriptLoader1, ScriptRunner::Async); |
| 182 | 218 |
| 183 MockScriptLoader* scriptLoader = scriptLoader2; | 219 MockScriptLoader* scriptLoader = scriptLoader2; |
| 184 EXPECT_CALL(*scriptLoader1, execute()).WillOnce(Invoke([scriptLoader, this] { | 220 EXPECT_CALL(*scriptLoader1, execute()).WillOnce(Invoke([scriptLoader, this] { |
| 185 m_order.push_back(1); | 221 m_order.push_back(1); |
| 186 m_scriptRunner->notifyScriptReady(scriptLoader, ScriptRunner::Async); | 222 m_scriptRunner->notifyScriptReady(scriptLoader, ScriptRunner::Async); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 202 EXPECT_THAT(m_order, ElementsAre(1)); | 238 EXPECT_THAT(m_order, ElementsAre(1)); |
| 203 | 239 |
| 204 m_platform->runSingleTask(); | 240 m_platform->runSingleTask(); |
| 205 EXPECT_THAT(m_order, ElementsAre(1, 2)); | 241 EXPECT_THAT(m_order, ElementsAre(1, 2)); |
| 206 | 242 |
| 207 m_platform->runSingleTask(); | 243 m_platform->runSingleTask(); |
| 208 EXPECT_THAT(m_order, ElementsAre(1, 2, 3)); | 244 EXPECT_THAT(m_order, ElementsAre(1, 2, 3)); |
| 209 } | 245 } |
| 210 | 246 |
| 211 TEST_F(ScriptRunnerTest, QueueReentrantScript_InOrder) { | 247 TEST_F(ScriptRunnerTest, QueueReentrantScript_InOrder) { |
| 212 MockScriptLoader* scriptLoader1 = MockScriptLoader::create(m_element.get()); | 248 MockScriptLoader* scriptLoader1 = MockScriptLoader::create(); |
| 213 MockScriptLoader* scriptLoader2 = MockScriptLoader::create(m_element.get()); | 249 MockScriptLoader* scriptLoader2 = MockScriptLoader::create(); |
| 214 MockScriptLoader* scriptLoader3 = MockScriptLoader::create(m_element.get()); | 250 MockScriptLoader* scriptLoader3 = MockScriptLoader::create(); |
| 215 | 251 |
| 216 EXPECT_CALL(*scriptLoader1, isReady()).WillRepeatedly(Return(true)); | 252 EXPECT_CALL(*scriptLoader1, isReady()).WillRepeatedly(Return(true)); |
| 217 EXPECT_CALL(*scriptLoader2, isReady()).WillRepeatedly(Return(true)); | 253 EXPECT_CALL(*scriptLoader2, isReady()).WillRepeatedly(Return(true)); |
| 218 EXPECT_CALL(*scriptLoader3, isReady()).WillRepeatedly(Return(true)); | 254 EXPECT_CALL(*scriptLoader3, isReady()).WillRepeatedly(Return(true)); |
| 219 | 255 |
| 220 m_scriptRunner->queueScriptForExecution(scriptLoader1, ScriptRunner::InOrder); | 256 m_scriptRunner->queueScriptForExecution(scriptLoader1, ScriptRunner::InOrder); |
| 221 m_scriptRunner->notifyScriptReady(scriptLoader1, ScriptRunner::InOrder); | 257 m_scriptRunner->notifyScriptReady(scriptLoader1, ScriptRunner::InOrder); |
| 222 | 258 |
| 223 MockScriptLoader* scriptLoader = scriptLoader2; | 259 MockScriptLoader* scriptLoader = scriptLoader2; |
| 224 EXPECT_CALL(*scriptLoader1, execute()) | 260 EXPECT_CALL(*scriptLoader1, execute()) |
| (...skipping 28 matching lines...) Expand all Loading... |
| 253 m_platform->runSingleTask(); | 289 m_platform->runSingleTask(); |
| 254 EXPECT_THAT(m_order, ElementsAre(1, 2, 3)); | 290 EXPECT_THAT(m_order, ElementsAre(1, 2, 3)); |
| 255 } | 291 } |
| 256 | 292 |
| 257 TEST_F(ScriptRunnerTest, QueueReentrantScript_ManyAsyncScripts) { | 293 TEST_F(ScriptRunnerTest, QueueReentrantScript_ManyAsyncScripts) { |
| 258 MockScriptLoader* scriptLoaders[20]; | 294 MockScriptLoader* scriptLoaders[20]; |
| 259 for (int i = 0; i < 20; i++) | 295 for (int i = 0; i < 20; i++) |
| 260 scriptLoaders[i] = nullptr; | 296 scriptLoaders[i] = nullptr; |
| 261 | 297 |
| 262 for (int i = 0; i < 20; i++) { | 298 for (int i = 0; i < 20; i++) { |
| 263 scriptLoaders[i] = MockScriptLoader::create(m_element.get()); | 299 scriptLoaders[i] = MockScriptLoader::create(); |
| 264 EXPECT_CALL(*scriptLoaders[i], isReady()).WillRepeatedly(Return(true)); | 300 EXPECT_CALL(*scriptLoaders[i], isReady()).WillRepeatedly(Return(true)); |
| 265 | 301 |
| 266 m_scriptRunner->queueScriptForExecution(scriptLoaders[i], | 302 m_scriptRunner->queueScriptForExecution(scriptLoaders[i], |
| 267 ScriptRunner::Async); | 303 ScriptRunner::Async); |
| 268 | 304 |
| 269 if (i > 0) { | 305 if (i > 0) { |
| 270 EXPECT_CALL(*scriptLoaders[i], execute()).WillOnce(Invoke([this, i] { | 306 EXPECT_CALL(*scriptLoaders[i], execute()).WillOnce(Invoke([this, i] { |
| 271 m_order.push_back(i); | 307 m_order.push_back(i); |
| 272 })); | 308 })); |
| 273 } | 309 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 286 | 322 |
| 287 m_platform->runUntilIdle(); | 323 m_platform->runUntilIdle(); |
| 288 | 324 |
| 289 int expected[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, | 325 int expected[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, |
| 290 10, 11, 12, 13, 14, 15, 16, 17, 18, 19}; | 326 10, 11, 12, 13, 14, 15, 16, 17, 18, 19}; |
| 291 | 327 |
| 292 EXPECT_THAT(m_order, testing::ElementsAreArray(expected)); | 328 EXPECT_THAT(m_order, testing::ElementsAreArray(expected)); |
| 293 } | 329 } |
| 294 | 330 |
| 295 TEST_F(ScriptRunnerTest, ResumeAndSuspend_InOrder) { | 331 TEST_F(ScriptRunnerTest, ResumeAndSuspend_InOrder) { |
| 296 MockScriptLoader* scriptLoader1 = MockScriptLoader::create(m_element.get()); | 332 MockScriptLoader* scriptLoader1 = MockScriptLoader::create(); |
| 297 MockScriptLoader* scriptLoader2 = MockScriptLoader::create(m_element.get()); | 333 MockScriptLoader* scriptLoader2 = MockScriptLoader::create(); |
| 298 MockScriptLoader* scriptLoader3 = MockScriptLoader::create(m_element.get()); | 334 MockScriptLoader* scriptLoader3 = MockScriptLoader::create(); |
| 299 | 335 |
| 300 m_scriptRunner->queueScriptForExecution(scriptLoader1, ScriptRunner::InOrder); | 336 m_scriptRunner->queueScriptForExecution(scriptLoader1, ScriptRunner::InOrder); |
| 301 m_scriptRunner->queueScriptForExecution(scriptLoader2, ScriptRunner::InOrder); | 337 m_scriptRunner->queueScriptForExecution(scriptLoader2, ScriptRunner::InOrder); |
| 302 m_scriptRunner->queueScriptForExecution(scriptLoader3, ScriptRunner::InOrder); | 338 m_scriptRunner->queueScriptForExecution(scriptLoader3, ScriptRunner::InOrder); |
| 303 | 339 |
| 304 EXPECT_CALL(*scriptLoader1, execute()).WillOnce(Invoke([this] { | 340 EXPECT_CALL(*scriptLoader1, execute()).WillOnce(Invoke([this] { |
| 305 m_order.push_back(1); | 341 m_order.push_back(1); |
| 306 })); | 342 })); |
| 307 EXPECT_CALL(*scriptLoader2, execute()).WillOnce(Invoke([this] { | 343 EXPECT_CALL(*scriptLoader2, execute()).WillOnce(Invoke([this] { |
| 308 m_order.push_back(2); | 344 m_order.push_back(2); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 328 m_platform->runSingleTask(); | 364 m_platform->runSingleTask(); |
| 329 m_scriptRunner->suspend(); | 365 m_scriptRunner->suspend(); |
| 330 m_scriptRunner->resume(); | 366 m_scriptRunner->resume(); |
| 331 m_platform->runUntilIdle(); | 367 m_platform->runUntilIdle(); |
| 332 | 368 |
| 333 // Make sure elements are correct and in right order. | 369 // Make sure elements are correct and in right order. |
| 334 EXPECT_THAT(m_order, ElementsAre(1, 2, 3)); | 370 EXPECT_THAT(m_order, ElementsAre(1, 2, 3)); |
| 335 } | 371 } |
| 336 | 372 |
| 337 TEST_F(ScriptRunnerTest, ResumeAndSuspend_Async) { | 373 TEST_F(ScriptRunnerTest, ResumeAndSuspend_Async) { |
| 338 MockScriptLoader* scriptLoader1 = MockScriptLoader::create(m_element.get()); | 374 MockScriptLoader* scriptLoader1 = MockScriptLoader::create(); |
| 339 MockScriptLoader* scriptLoader2 = MockScriptLoader::create(m_element.get()); | 375 MockScriptLoader* scriptLoader2 = MockScriptLoader::create(); |
| 340 MockScriptLoader* scriptLoader3 = MockScriptLoader::create(m_element.get()); | 376 MockScriptLoader* scriptLoader3 = MockScriptLoader::create(); |
| 341 | 377 |
| 342 m_scriptRunner->queueScriptForExecution(scriptLoader1, ScriptRunner::Async); | 378 m_scriptRunner->queueScriptForExecution(scriptLoader1, ScriptRunner::Async); |
| 343 m_scriptRunner->queueScriptForExecution(scriptLoader2, ScriptRunner::Async); | 379 m_scriptRunner->queueScriptForExecution(scriptLoader2, ScriptRunner::Async); |
| 344 m_scriptRunner->queueScriptForExecution(scriptLoader3, ScriptRunner::Async); | 380 m_scriptRunner->queueScriptForExecution(scriptLoader3, ScriptRunner::Async); |
| 345 | 381 |
| 346 m_scriptRunner->notifyScriptReady(scriptLoader1, ScriptRunner::Async); | 382 m_scriptRunner->notifyScriptReady(scriptLoader1, ScriptRunner::Async); |
| 347 m_scriptRunner->notifyScriptReady(scriptLoader2, ScriptRunner::Async); | 383 m_scriptRunner->notifyScriptReady(scriptLoader2, ScriptRunner::Async); |
| 348 m_scriptRunner->notifyScriptReady(scriptLoader3, ScriptRunner::Async); | 384 m_scriptRunner->notifyScriptReady(scriptLoader3, ScriptRunner::Async); |
| 349 | 385 |
| 350 EXPECT_CALL(*scriptLoader1, execute()).WillOnce(Invoke([this] { | 386 EXPECT_CALL(*scriptLoader1, execute()).WillOnce(Invoke([this] { |
| 351 m_order.push_back(1); | 387 m_order.push_back(1); |
| 352 })); | 388 })); |
| 353 EXPECT_CALL(*scriptLoader2, execute()).WillOnce(Invoke([this] { | 389 EXPECT_CALL(*scriptLoader2, execute()).WillOnce(Invoke([this] { |
| 354 m_order.push_back(2); | 390 m_order.push_back(2); |
| 355 })); | 391 })); |
| 356 EXPECT_CALL(*scriptLoader3, execute()).WillOnce(Invoke([this] { | 392 EXPECT_CALL(*scriptLoader3, execute()).WillOnce(Invoke([this] { |
| 357 m_order.push_back(3); | 393 m_order.push_back(3); |
| 358 })); | 394 })); |
| 359 | 395 |
| 360 m_platform->runSingleTask(); | 396 m_platform->runSingleTask(); |
| 361 m_scriptRunner->suspend(); | 397 m_scriptRunner->suspend(); |
| 362 m_scriptRunner->resume(); | 398 m_scriptRunner->resume(); |
| 363 m_platform->runUntilIdle(); | 399 m_platform->runUntilIdle(); |
| 364 | 400 |
| 365 // Make sure elements are correct. | 401 // Make sure elements are correct. |
| 366 EXPECT_THAT(m_order, WhenSorted(ElementsAre(1, 2, 3))); | 402 EXPECT_THAT(m_order, WhenSorted(ElementsAre(1, 2, 3))); |
| 367 } | 403 } |
| 368 | 404 |
| 369 TEST_F(ScriptRunnerTest, LateNotifications) { | 405 TEST_F(ScriptRunnerTest, LateNotifications) { |
| 370 MockScriptLoader* scriptLoader1 = MockScriptLoader::create(m_element.get()); | 406 MockScriptLoader* scriptLoader1 = MockScriptLoader::create(); |
| 371 MockScriptLoader* scriptLoader2 = MockScriptLoader::create(m_element.get()); | 407 MockScriptLoader* scriptLoader2 = MockScriptLoader::create(); |
| 372 | 408 |
| 373 EXPECT_CALL(*scriptLoader1, isReady()).WillRepeatedly(Return(true)); | 409 EXPECT_CALL(*scriptLoader1, isReady()).WillRepeatedly(Return(true)); |
| 374 EXPECT_CALL(*scriptLoader2, isReady()).WillRepeatedly(Return(true)); | 410 EXPECT_CALL(*scriptLoader2, isReady()).WillRepeatedly(Return(true)); |
| 375 | 411 |
| 376 m_scriptRunner->queueScriptForExecution(scriptLoader1, ScriptRunner::InOrder); | 412 m_scriptRunner->queueScriptForExecution(scriptLoader1, ScriptRunner::InOrder); |
| 377 m_scriptRunner->queueScriptForExecution(scriptLoader2, ScriptRunner::InOrder); | 413 m_scriptRunner->queueScriptForExecution(scriptLoader2, ScriptRunner::InOrder); |
| 378 | 414 |
| 379 EXPECT_CALL(*scriptLoader1, execute()).WillOnce(Invoke([this] { | 415 EXPECT_CALL(*scriptLoader1, execute()).WillOnce(Invoke([this] { |
| 380 m_order.push_back(1); | 416 m_order.push_back(1); |
| 381 })); | 417 })); |
| 382 EXPECT_CALL(*scriptLoader2, execute()).WillOnce(Invoke([this] { | 418 EXPECT_CALL(*scriptLoader2, execute()).WillOnce(Invoke([this] { |
| 383 m_order.push_back(2); | 419 m_order.push_back(2); |
| 384 })); | 420 })); |
| 385 | 421 |
| 386 m_scriptRunner->notifyScriptReady(scriptLoader1, ScriptRunner::InOrder); | 422 m_scriptRunner->notifyScriptReady(scriptLoader1, ScriptRunner::InOrder); |
| 387 m_platform->runUntilIdle(); | 423 m_platform->runUntilIdle(); |
| 388 | 424 |
| 389 // At this moment all tasks can be already executed. Make sure that we do not | 425 // At this moment all tasks can be already executed. Make sure that we do not |
| 390 // crash here. | 426 // crash here. |
| 391 m_scriptRunner->notifyScriptReady(scriptLoader2, ScriptRunner::InOrder); | 427 m_scriptRunner->notifyScriptReady(scriptLoader2, ScriptRunner::InOrder); |
| 392 m_platform->runUntilIdle(); | 428 m_platform->runUntilIdle(); |
| 393 | 429 |
| 394 EXPECT_THAT(m_order, ElementsAre(1, 2)); | 430 EXPECT_THAT(m_order, ElementsAre(1, 2)); |
| 395 } | 431 } |
| 396 | 432 |
| 397 TEST_F(ScriptRunnerTest, TasksWithDeadScriptRunner) { | 433 TEST_F(ScriptRunnerTest, TasksWithDeadScriptRunner) { |
| 398 Persistent<MockScriptLoader> scriptLoader1 = | 434 Persistent<MockScriptLoader> scriptLoader1 = MockScriptLoader::create(); |
| 399 MockScriptLoader::create(m_element.get()); | 435 Persistent<MockScriptLoader> scriptLoader2 = MockScriptLoader::create(); |
| 400 Persistent<MockScriptLoader> scriptLoader2 = | |
| 401 MockScriptLoader::create(m_element.get()); | |
| 402 | 436 |
| 403 EXPECT_CALL(*scriptLoader1, isReady()).WillRepeatedly(Return(true)); | 437 EXPECT_CALL(*scriptLoader1, isReady()).WillRepeatedly(Return(true)); |
| 404 EXPECT_CALL(*scriptLoader2, isReady()).WillRepeatedly(Return(true)); | 438 EXPECT_CALL(*scriptLoader2, isReady()).WillRepeatedly(Return(true)); |
| 405 | 439 |
| 406 m_scriptRunner->queueScriptForExecution(scriptLoader1, ScriptRunner::Async); | 440 m_scriptRunner->queueScriptForExecution(scriptLoader1, ScriptRunner::Async); |
| 407 m_scriptRunner->queueScriptForExecution(scriptLoader2, ScriptRunner::Async); | 441 m_scriptRunner->queueScriptForExecution(scriptLoader2, ScriptRunner::Async); |
| 408 | 442 |
| 409 m_scriptRunner->notifyScriptReady(scriptLoader1, ScriptRunner::Async); | 443 m_scriptRunner->notifyScriptReady(scriptLoader1, ScriptRunner::Async); |
| 410 m_scriptRunner->notifyScriptReady(scriptLoader2, ScriptRunner::Async); | 444 m_scriptRunner->notifyScriptReady(scriptLoader2, ScriptRunner::Async); |
| 411 | 445 |
| 412 m_scriptRunner.release(); | 446 m_scriptRunner.release(); |
| 413 | 447 |
| 414 ThreadState::current()->collectAllGarbage(); | 448 ThreadState::current()->collectAllGarbage(); |
| 415 | 449 |
| 416 // m_scriptRunner is gone. We need to make sure that ScriptRunner::Task do not | 450 // m_scriptRunner is gone. We need to make sure that ScriptRunner::Task do not |
| 417 // access dead object. | 451 // access dead object. |
| 418 EXPECT_CALL(*scriptLoader1, execute()).Times(0); | 452 EXPECT_CALL(*scriptLoader1, execute()).Times(0); |
| 419 EXPECT_CALL(*scriptLoader2, execute()).Times(0); | 453 EXPECT_CALL(*scriptLoader2, execute()).Times(0); |
| 420 | 454 |
| 421 m_platform->runUntilIdle(); | 455 m_platform->runUntilIdle(); |
| 422 } | 456 } |
| 423 | 457 |
| 424 } // namespace blink | 458 } // namespace blink |
| OLD | NEW |