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 "core/dom/Document.h" | 7 #include "core/dom/Document.h" |
8 #include "core/dom/Element.h" | |
9 #include "core/dom/ScriptLoader.h" | 8 #include "core/dom/ScriptLoader.h" |
10 #include "platform/heap/Handle.h" | 9 #include "platform/heap/Handle.h" |
11 #include "platform/testing/TestingPlatformSupport.h" | 10 #include "platform/testing/TestingPlatformSupport.h" |
12 #include "public/platform/Platform.h" | 11 #include "public/platform/Platform.h" |
13 #include "public/platform/WebViewScheduler.h" | 12 #include "public/platform/WebViewScheduler.h" |
14 #include "testing/gmock/include/gmock/gmock.h" | 13 #include "testing/gmock/include/gmock/gmock.h" |
15 #include "testing/gtest/include/gtest/gtest.h" | 14 #include "testing/gtest/include/gtest/gtest.h" |
16 | 15 |
17 using ::testing::Invoke; | 16 using ::testing::Invoke; |
18 using ::testing::ElementsAre; | 17 using ::testing::ElementsAre; |
19 using ::testing::Return; | 18 using ::testing::Return; |
20 using ::testing::WhenSorted; | 19 using ::testing::WhenSorted; |
21 using ::testing::ElementsAreArray; | 20 using ::testing::ElementsAreArray; |
22 | 21 |
23 namespace blink { | 22 namespace blink { |
24 | 23 |
25 class MockScriptLoader final : public ScriptLoader { | 24 class MockScriptLoader final : public ScriptLoader { |
26 public: | 25 public: |
27 static MockScriptLoader* create(Element* element) { | 26 static MockScriptLoader* create() { return new MockScriptLoader(); } |
28 return new MockScriptLoader(element); | |
29 } | |
30 ~MockScriptLoader() override {} | 27 ~MockScriptLoader() override {} |
31 | 28 |
32 MOCK_METHOD0(execute, void()); | 29 MOCK_METHOD0(execute, void()); |
33 MOCK_CONST_METHOD0(isReady, bool()); | 30 MOCK_CONST_METHOD0(isReady, bool()); |
34 | 31 |
35 private: | 32 private: |
36 explicit MockScriptLoader(Element* element) | 33 // ScriptLoader is given a nullptr ScriptLoaderClient here, since |
37 : ScriptLoader(element, false, false, false) {} | 34 // ScriptRunner doesn't appear to depend on it or the associated element. |
hiroshige
2017/03/01 00:58:14
Instead of nullptr ScriptLoaderClient, how about s
Nate Chapin
2017/03/01 21:34:59
Done.
| |
35 explicit MockScriptLoader() : ScriptLoader(nullptr, false, false, false) {} | |
38 }; | 36 }; |
39 | 37 |
40 class ScriptRunnerTest : public testing::Test { | 38 class ScriptRunnerTest : public testing::Test { |
41 public: | 39 public: |
42 ScriptRunnerTest() | 40 ScriptRunnerTest() : m_document(Document::create()) {} |
43 : m_document(Document::create()), | |
44 m_element(m_document->createElement("foo")) {} | |
45 | 41 |
46 void SetUp() override { | 42 void SetUp() override { |
47 // We have to create ScriptRunner after initializing platform, because we | 43 // We have to create ScriptRunner after initializing platform, because we |
48 // need Platform::current()->currentThread()->scheduler()-> | 44 // need Platform::current()->currentThread()->scheduler()-> |
49 // loadingTaskRunner() to be initialized before creating ScriptRunner to | 45 // loadingTaskRunner() to be initialized before creating ScriptRunner to |
50 // save it in constructor. | 46 // save it in constructor. |
51 m_scriptRunner = ScriptRunner::create(m_document.get()); | 47 m_scriptRunner = ScriptRunner::create(m_document.get()); |
52 } | 48 } |
53 void TearDown() override { m_scriptRunner.release(); } | 49 void TearDown() override { m_scriptRunner.release(); } |
54 | 50 |
55 protected: | 51 protected: |
56 Persistent<Document> m_document; | 52 Persistent<Document> m_document; |
57 Persistent<Element> m_element; | |
58 Persistent<ScriptRunner> m_scriptRunner; | 53 Persistent<ScriptRunner> m_scriptRunner; |
59 WTF::Vector<int> m_order; | 54 WTF::Vector<int> m_order; |
60 ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler> | 55 ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler> |
61 m_platform; | 56 m_platform; |
62 }; | 57 }; |
63 | 58 |
64 TEST_F(ScriptRunnerTest, QueueSingleScript_Async) { | 59 TEST_F(ScriptRunnerTest, QueueSingleScript_Async) { |
65 MockScriptLoader* scriptLoader = MockScriptLoader::create(m_element.get()); | 60 MockScriptLoader* scriptLoader = MockScriptLoader::create(); |
66 m_scriptRunner->queueScriptForExecution(scriptLoader, ScriptRunner::Async); | 61 m_scriptRunner->queueScriptForExecution(scriptLoader, ScriptRunner::Async); |
67 m_scriptRunner->notifyScriptReady(scriptLoader, ScriptRunner::Async); | 62 m_scriptRunner->notifyScriptReady(scriptLoader, ScriptRunner::Async); |
68 | 63 |
69 EXPECT_CALL(*scriptLoader, execute()); | 64 EXPECT_CALL(*scriptLoader, execute()); |
70 m_platform->runUntilIdle(); | 65 m_platform->runUntilIdle(); |
71 } | 66 } |
72 | 67 |
73 TEST_F(ScriptRunnerTest, QueueSingleScript_InOrder) { | 68 TEST_F(ScriptRunnerTest, QueueSingleScript_InOrder) { |
74 MockScriptLoader* scriptLoader = MockScriptLoader::create(m_element.get()); | 69 MockScriptLoader* scriptLoader = MockScriptLoader::create(); |
75 m_scriptRunner->queueScriptForExecution(scriptLoader, ScriptRunner::InOrder); | 70 m_scriptRunner->queueScriptForExecution(scriptLoader, ScriptRunner::InOrder); |
76 | 71 |
77 EXPECT_CALL(*scriptLoader, isReady()).WillOnce(Return(true)); | 72 EXPECT_CALL(*scriptLoader, isReady()).WillOnce(Return(true)); |
78 EXPECT_CALL(*scriptLoader, execute()); | 73 EXPECT_CALL(*scriptLoader, execute()); |
79 | 74 |
80 m_scriptRunner->notifyScriptReady(scriptLoader, ScriptRunner::InOrder); | 75 m_scriptRunner->notifyScriptReady(scriptLoader, ScriptRunner::InOrder); |
81 | 76 |
82 m_platform->runUntilIdle(); | 77 m_platform->runUntilIdle(); |
83 } | 78 } |
84 | 79 |
85 TEST_F(ScriptRunnerTest, QueueMultipleScripts_InOrder) { | 80 TEST_F(ScriptRunnerTest, QueueMultipleScripts_InOrder) { |
86 MockScriptLoader* scriptLoader1 = MockScriptLoader::create(m_element.get()); | 81 MockScriptLoader* scriptLoader1 = MockScriptLoader::create(); |
87 MockScriptLoader* scriptLoader2 = MockScriptLoader::create(m_element.get()); | 82 MockScriptLoader* scriptLoader2 = MockScriptLoader::create(); |
88 MockScriptLoader* scriptLoader3 = MockScriptLoader::create(m_element.get()); | 83 MockScriptLoader* scriptLoader3 = MockScriptLoader::create(); |
89 | 84 |
90 HeapVector<Member<MockScriptLoader>> scriptLoaders; | 85 HeapVector<Member<MockScriptLoader>> scriptLoaders; |
91 scriptLoaders.push_back(scriptLoader1); | 86 scriptLoaders.push_back(scriptLoader1); |
92 scriptLoaders.push_back(scriptLoader2); | 87 scriptLoaders.push_back(scriptLoader2); |
93 scriptLoaders.push_back(scriptLoader3); | 88 scriptLoaders.push_back(scriptLoader3); |
94 | 89 |
95 for (ScriptLoader* scriptLoader : scriptLoaders) { | 90 for (ScriptLoader* scriptLoader : scriptLoaders) { |
96 m_scriptRunner->queueScriptForExecution(scriptLoader, | 91 m_scriptRunner->queueScriptForExecution(scriptLoader, |
97 ScriptRunner::InOrder); | 92 ScriptRunner::InOrder); |
98 } | 93 } |
(...skipping 16 matching lines...) Expand all Loading... | |
115 isReady[i] = true; | 110 isReady[i] = true; |
116 m_scriptRunner->notifyScriptReady(scriptLoaders[i], ScriptRunner::InOrder); | 111 m_scriptRunner->notifyScriptReady(scriptLoaders[i], ScriptRunner::InOrder); |
117 m_platform->runUntilIdle(); | 112 m_platform->runUntilIdle(); |
118 } | 113 } |
119 | 114 |
120 // But ensure the scripts were run in the expected order. | 115 // But ensure the scripts were run in the expected order. |
121 EXPECT_THAT(m_order, ElementsAre(1, 2, 3)); | 116 EXPECT_THAT(m_order, ElementsAre(1, 2, 3)); |
122 } | 117 } |
123 | 118 |
124 TEST_F(ScriptRunnerTest, QueueMixedScripts) { | 119 TEST_F(ScriptRunnerTest, QueueMixedScripts) { |
125 MockScriptLoader* scriptLoader1 = MockScriptLoader::create(m_element.get()); | 120 MockScriptLoader* scriptLoader1 = MockScriptLoader::create(); |
126 MockScriptLoader* scriptLoader2 = MockScriptLoader::create(m_element.get()); | 121 MockScriptLoader* scriptLoader2 = MockScriptLoader::create(); |
127 MockScriptLoader* scriptLoader3 = MockScriptLoader::create(m_element.get()); | 122 MockScriptLoader* scriptLoader3 = MockScriptLoader::create(); |
128 MockScriptLoader* scriptLoader4 = MockScriptLoader::create(m_element.get()); | 123 MockScriptLoader* scriptLoader4 = MockScriptLoader::create(); |
129 MockScriptLoader* scriptLoader5 = MockScriptLoader::create(m_element.get()); | 124 MockScriptLoader* scriptLoader5 = MockScriptLoader::create(); |
130 | 125 |
131 m_scriptRunner->queueScriptForExecution(scriptLoader1, ScriptRunner::InOrder); | 126 m_scriptRunner->queueScriptForExecution(scriptLoader1, ScriptRunner::InOrder); |
132 m_scriptRunner->queueScriptForExecution(scriptLoader2, ScriptRunner::InOrder); | 127 m_scriptRunner->queueScriptForExecution(scriptLoader2, ScriptRunner::InOrder); |
133 m_scriptRunner->queueScriptForExecution(scriptLoader3, ScriptRunner::InOrder); | 128 m_scriptRunner->queueScriptForExecution(scriptLoader3, ScriptRunner::InOrder); |
134 m_scriptRunner->queueScriptForExecution(scriptLoader4, ScriptRunner::Async); | 129 m_scriptRunner->queueScriptForExecution(scriptLoader4, ScriptRunner::Async); |
135 m_scriptRunner->queueScriptForExecution(scriptLoader5, ScriptRunner::Async); | 130 m_scriptRunner->queueScriptForExecution(scriptLoader5, ScriptRunner::Async); |
136 | 131 |
137 EXPECT_CALL(*scriptLoader1, isReady()).WillRepeatedly(Return(true)); | 132 EXPECT_CALL(*scriptLoader1, isReady()).WillRepeatedly(Return(true)); |
138 EXPECT_CALL(*scriptLoader2, isReady()).WillRepeatedly(Return(false)); | 133 EXPECT_CALL(*scriptLoader2, isReady()).WillRepeatedly(Return(false)); |
139 m_scriptRunner->notifyScriptReady(scriptLoader1, ScriptRunner::InOrder); | 134 m_scriptRunner->notifyScriptReady(scriptLoader1, ScriptRunner::InOrder); |
(...skipping 24 matching lines...) Expand all Loading... | |
164 m_order.push_back(5); | 159 m_order.push_back(5); |
165 })); | 160 })); |
166 | 161 |
167 m_platform->runUntilIdle(); | 162 m_platform->runUntilIdle(); |
168 | 163 |
169 // Async tasks are expected to run first. | 164 // Async tasks are expected to run first. |
170 EXPECT_THAT(m_order, ElementsAre(4, 5, 1, 2, 3)); | 165 EXPECT_THAT(m_order, ElementsAre(4, 5, 1, 2, 3)); |
171 } | 166 } |
172 | 167 |
173 TEST_F(ScriptRunnerTest, QueueReentrantScript_Async) { | 168 TEST_F(ScriptRunnerTest, QueueReentrantScript_Async) { |
174 MockScriptLoader* scriptLoader1 = MockScriptLoader::create(m_element.get()); | 169 MockScriptLoader* scriptLoader1 = MockScriptLoader::create(); |
175 MockScriptLoader* scriptLoader2 = MockScriptLoader::create(m_element.get()); | 170 MockScriptLoader* scriptLoader2 = MockScriptLoader::create(); |
176 MockScriptLoader* scriptLoader3 = MockScriptLoader::create(m_element.get()); | 171 MockScriptLoader* scriptLoader3 = MockScriptLoader::create(); |
177 | 172 |
178 m_scriptRunner->queueScriptForExecution(scriptLoader1, ScriptRunner::Async); | 173 m_scriptRunner->queueScriptForExecution(scriptLoader1, ScriptRunner::Async); |
179 m_scriptRunner->queueScriptForExecution(scriptLoader2, ScriptRunner::Async); | 174 m_scriptRunner->queueScriptForExecution(scriptLoader2, ScriptRunner::Async); |
180 m_scriptRunner->queueScriptForExecution(scriptLoader3, ScriptRunner::Async); | 175 m_scriptRunner->queueScriptForExecution(scriptLoader3, ScriptRunner::Async); |
181 m_scriptRunner->notifyScriptReady(scriptLoader1, ScriptRunner::Async); | 176 m_scriptRunner->notifyScriptReady(scriptLoader1, ScriptRunner::Async); |
182 | 177 |
183 MockScriptLoader* scriptLoader = scriptLoader2; | 178 MockScriptLoader* scriptLoader = scriptLoader2; |
184 EXPECT_CALL(*scriptLoader1, execute()).WillOnce(Invoke([scriptLoader, this] { | 179 EXPECT_CALL(*scriptLoader1, execute()).WillOnce(Invoke([scriptLoader, this] { |
185 m_order.push_back(1); | 180 m_order.push_back(1); |
186 m_scriptRunner->notifyScriptReady(scriptLoader, ScriptRunner::Async); | 181 m_scriptRunner->notifyScriptReady(scriptLoader, ScriptRunner::Async); |
(...skipping 15 matching lines...) Expand all Loading... | |
202 EXPECT_THAT(m_order, ElementsAre(1)); | 197 EXPECT_THAT(m_order, ElementsAre(1)); |
203 | 198 |
204 m_platform->runSingleTask(); | 199 m_platform->runSingleTask(); |
205 EXPECT_THAT(m_order, ElementsAre(1, 2)); | 200 EXPECT_THAT(m_order, ElementsAre(1, 2)); |
206 | 201 |
207 m_platform->runSingleTask(); | 202 m_platform->runSingleTask(); |
208 EXPECT_THAT(m_order, ElementsAre(1, 2, 3)); | 203 EXPECT_THAT(m_order, ElementsAre(1, 2, 3)); |
209 } | 204 } |
210 | 205 |
211 TEST_F(ScriptRunnerTest, QueueReentrantScript_InOrder) { | 206 TEST_F(ScriptRunnerTest, QueueReentrantScript_InOrder) { |
212 MockScriptLoader* scriptLoader1 = MockScriptLoader::create(m_element.get()); | 207 MockScriptLoader* scriptLoader1 = MockScriptLoader::create(); |
213 MockScriptLoader* scriptLoader2 = MockScriptLoader::create(m_element.get()); | 208 MockScriptLoader* scriptLoader2 = MockScriptLoader::create(); |
214 MockScriptLoader* scriptLoader3 = MockScriptLoader::create(m_element.get()); | 209 MockScriptLoader* scriptLoader3 = MockScriptLoader::create(); |
215 | 210 |
216 EXPECT_CALL(*scriptLoader1, isReady()).WillRepeatedly(Return(true)); | 211 EXPECT_CALL(*scriptLoader1, isReady()).WillRepeatedly(Return(true)); |
217 EXPECT_CALL(*scriptLoader2, isReady()).WillRepeatedly(Return(true)); | 212 EXPECT_CALL(*scriptLoader2, isReady()).WillRepeatedly(Return(true)); |
218 EXPECT_CALL(*scriptLoader3, isReady()).WillRepeatedly(Return(true)); | 213 EXPECT_CALL(*scriptLoader3, isReady()).WillRepeatedly(Return(true)); |
219 | 214 |
220 m_scriptRunner->queueScriptForExecution(scriptLoader1, ScriptRunner::InOrder); | 215 m_scriptRunner->queueScriptForExecution(scriptLoader1, ScriptRunner::InOrder); |
221 m_scriptRunner->notifyScriptReady(scriptLoader1, ScriptRunner::InOrder); | 216 m_scriptRunner->notifyScriptReady(scriptLoader1, ScriptRunner::InOrder); |
222 | 217 |
223 MockScriptLoader* scriptLoader = scriptLoader2; | 218 MockScriptLoader* scriptLoader = scriptLoader2; |
224 EXPECT_CALL(*scriptLoader1, execute()) | 219 EXPECT_CALL(*scriptLoader1, execute()) |
(...skipping 28 matching lines...) Expand all Loading... | |
253 m_platform->runSingleTask(); | 248 m_platform->runSingleTask(); |
254 EXPECT_THAT(m_order, ElementsAre(1, 2, 3)); | 249 EXPECT_THAT(m_order, ElementsAre(1, 2, 3)); |
255 } | 250 } |
256 | 251 |
257 TEST_F(ScriptRunnerTest, QueueReentrantScript_ManyAsyncScripts) { | 252 TEST_F(ScriptRunnerTest, QueueReentrantScript_ManyAsyncScripts) { |
258 MockScriptLoader* scriptLoaders[20]; | 253 MockScriptLoader* scriptLoaders[20]; |
259 for (int i = 0; i < 20; i++) | 254 for (int i = 0; i < 20; i++) |
260 scriptLoaders[i] = nullptr; | 255 scriptLoaders[i] = nullptr; |
261 | 256 |
262 for (int i = 0; i < 20; i++) { | 257 for (int i = 0; i < 20; i++) { |
263 scriptLoaders[i] = MockScriptLoader::create(m_element.get()); | 258 scriptLoaders[i] = MockScriptLoader::create(); |
264 EXPECT_CALL(*scriptLoaders[i], isReady()).WillRepeatedly(Return(true)); | 259 EXPECT_CALL(*scriptLoaders[i], isReady()).WillRepeatedly(Return(true)); |
265 | 260 |
266 m_scriptRunner->queueScriptForExecution(scriptLoaders[i], | 261 m_scriptRunner->queueScriptForExecution(scriptLoaders[i], |
267 ScriptRunner::Async); | 262 ScriptRunner::Async); |
268 | 263 |
269 if (i > 0) { | 264 if (i > 0) { |
270 EXPECT_CALL(*scriptLoaders[i], execute()).WillOnce(Invoke([this, i] { | 265 EXPECT_CALL(*scriptLoaders[i], execute()).WillOnce(Invoke([this, i] { |
271 m_order.push_back(i); | 266 m_order.push_back(i); |
272 })); | 267 })); |
273 } | 268 } |
(...skipping 12 matching lines...) Expand all Loading... | |
286 | 281 |
287 m_platform->runUntilIdle(); | 282 m_platform->runUntilIdle(); |
288 | 283 |
289 int expected[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, | 284 int expected[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, |
290 10, 11, 12, 13, 14, 15, 16, 17, 18, 19}; | 285 10, 11, 12, 13, 14, 15, 16, 17, 18, 19}; |
291 | 286 |
292 EXPECT_THAT(m_order, testing::ElementsAreArray(expected)); | 287 EXPECT_THAT(m_order, testing::ElementsAreArray(expected)); |
293 } | 288 } |
294 | 289 |
295 TEST_F(ScriptRunnerTest, ResumeAndSuspend_InOrder) { | 290 TEST_F(ScriptRunnerTest, ResumeAndSuspend_InOrder) { |
296 MockScriptLoader* scriptLoader1 = MockScriptLoader::create(m_element.get()); | 291 MockScriptLoader* scriptLoader1 = MockScriptLoader::create(); |
297 MockScriptLoader* scriptLoader2 = MockScriptLoader::create(m_element.get()); | 292 MockScriptLoader* scriptLoader2 = MockScriptLoader::create(); |
298 MockScriptLoader* scriptLoader3 = MockScriptLoader::create(m_element.get()); | 293 MockScriptLoader* scriptLoader3 = MockScriptLoader::create(); |
299 | 294 |
300 m_scriptRunner->queueScriptForExecution(scriptLoader1, ScriptRunner::InOrder); | 295 m_scriptRunner->queueScriptForExecution(scriptLoader1, ScriptRunner::InOrder); |
301 m_scriptRunner->queueScriptForExecution(scriptLoader2, ScriptRunner::InOrder); | 296 m_scriptRunner->queueScriptForExecution(scriptLoader2, ScriptRunner::InOrder); |
302 m_scriptRunner->queueScriptForExecution(scriptLoader3, ScriptRunner::InOrder); | 297 m_scriptRunner->queueScriptForExecution(scriptLoader3, ScriptRunner::InOrder); |
303 | 298 |
304 EXPECT_CALL(*scriptLoader1, execute()).WillOnce(Invoke([this] { | 299 EXPECT_CALL(*scriptLoader1, execute()).WillOnce(Invoke([this] { |
305 m_order.push_back(1); | 300 m_order.push_back(1); |
306 })); | 301 })); |
307 EXPECT_CALL(*scriptLoader2, execute()).WillOnce(Invoke([this] { | 302 EXPECT_CALL(*scriptLoader2, execute()).WillOnce(Invoke([this] { |
308 m_order.push_back(2); | 303 m_order.push_back(2); |
(...skipping 19 matching lines...) Expand all Loading... | |
328 m_platform->runSingleTask(); | 323 m_platform->runSingleTask(); |
329 m_scriptRunner->suspend(); | 324 m_scriptRunner->suspend(); |
330 m_scriptRunner->resume(); | 325 m_scriptRunner->resume(); |
331 m_platform->runUntilIdle(); | 326 m_platform->runUntilIdle(); |
332 | 327 |
333 // Make sure elements are correct and in right order. | 328 // Make sure elements are correct and in right order. |
334 EXPECT_THAT(m_order, ElementsAre(1, 2, 3)); | 329 EXPECT_THAT(m_order, ElementsAre(1, 2, 3)); |
335 } | 330 } |
336 | 331 |
337 TEST_F(ScriptRunnerTest, ResumeAndSuspend_Async) { | 332 TEST_F(ScriptRunnerTest, ResumeAndSuspend_Async) { |
338 MockScriptLoader* scriptLoader1 = MockScriptLoader::create(m_element.get()); | 333 MockScriptLoader* scriptLoader1 = MockScriptLoader::create(); |
339 MockScriptLoader* scriptLoader2 = MockScriptLoader::create(m_element.get()); | 334 MockScriptLoader* scriptLoader2 = MockScriptLoader::create(); |
340 MockScriptLoader* scriptLoader3 = MockScriptLoader::create(m_element.get()); | 335 MockScriptLoader* scriptLoader3 = MockScriptLoader::create(); |
341 | 336 |
342 m_scriptRunner->queueScriptForExecution(scriptLoader1, ScriptRunner::Async); | 337 m_scriptRunner->queueScriptForExecution(scriptLoader1, ScriptRunner::Async); |
343 m_scriptRunner->queueScriptForExecution(scriptLoader2, ScriptRunner::Async); | 338 m_scriptRunner->queueScriptForExecution(scriptLoader2, ScriptRunner::Async); |
344 m_scriptRunner->queueScriptForExecution(scriptLoader3, ScriptRunner::Async); | 339 m_scriptRunner->queueScriptForExecution(scriptLoader3, ScriptRunner::Async); |
345 | 340 |
346 m_scriptRunner->notifyScriptReady(scriptLoader1, ScriptRunner::Async); | 341 m_scriptRunner->notifyScriptReady(scriptLoader1, ScriptRunner::Async); |
347 m_scriptRunner->notifyScriptReady(scriptLoader2, ScriptRunner::Async); | 342 m_scriptRunner->notifyScriptReady(scriptLoader2, ScriptRunner::Async); |
348 m_scriptRunner->notifyScriptReady(scriptLoader3, ScriptRunner::Async); | 343 m_scriptRunner->notifyScriptReady(scriptLoader3, ScriptRunner::Async); |
349 | 344 |
350 EXPECT_CALL(*scriptLoader1, execute()).WillOnce(Invoke([this] { | 345 EXPECT_CALL(*scriptLoader1, execute()).WillOnce(Invoke([this] { |
351 m_order.push_back(1); | 346 m_order.push_back(1); |
352 })); | 347 })); |
353 EXPECT_CALL(*scriptLoader2, execute()).WillOnce(Invoke([this] { | 348 EXPECT_CALL(*scriptLoader2, execute()).WillOnce(Invoke([this] { |
354 m_order.push_back(2); | 349 m_order.push_back(2); |
355 })); | 350 })); |
356 EXPECT_CALL(*scriptLoader3, execute()).WillOnce(Invoke([this] { | 351 EXPECT_CALL(*scriptLoader3, execute()).WillOnce(Invoke([this] { |
357 m_order.push_back(3); | 352 m_order.push_back(3); |
358 })); | 353 })); |
359 | 354 |
360 m_platform->runSingleTask(); | 355 m_platform->runSingleTask(); |
361 m_scriptRunner->suspend(); | 356 m_scriptRunner->suspend(); |
362 m_scriptRunner->resume(); | 357 m_scriptRunner->resume(); |
363 m_platform->runUntilIdle(); | 358 m_platform->runUntilIdle(); |
364 | 359 |
365 // Make sure elements are correct. | 360 // Make sure elements are correct. |
366 EXPECT_THAT(m_order, WhenSorted(ElementsAre(1, 2, 3))); | 361 EXPECT_THAT(m_order, WhenSorted(ElementsAre(1, 2, 3))); |
367 } | 362 } |
368 | 363 |
369 TEST_F(ScriptRunnerTest, LateNotifications) { | 364 TEST_F(ScriptRunnerTest, LateNotifications) { |
370 MockScriptLoader* scriptLoader1 = MockScriptLoader::create(m_element.get()); | 365 MockScriptLoader* scriptLoader1 = MockScriptLoader::create(); |
371 MockScriptLoader* scriptLoader2 = MockScriptLoader::create(m_element.get()); | 366 MockScriptLoader* scriptLoader2 = MockScriptLoader::create(); |
372 | 367 |
373 EXPECT_CALL(*scriptLoader1, isReady()).WillRepeatedly(Return(true)); | 368 EXPECT_CALL(*scriptLoader1, isReady()).WillRepeatedly(Return(true)); |
374 EXPECT_CALL(*scriptLoader2, isReady()).WillRepeatedly(Return(true)); | 369 EXPECT_CALL(*scriptLoader2, isReady()).WillRepeatedly(Return(true)); |
375 | 370 |
376 m_scriptRunner->queueScriptForExecution(scriptLoader1, ScriptRunner::InOrder); | 371 m_scriptRunner->queueScriptForExecution(scriptLoader1, ScriptRunner::InOrder); |
377 m_scriptRunner->queueScriptForExecution(scriptLoader2, ScriptRunner::InOrder); | 372 m_scriptRunner->queueScriptForExecution(scriptLoader2, ScriptRunner::InOrder); |
378 | 373 |
379 EXPECT_CALL(*scriptLoader1, execute()).WillOnce(Invoke([this] { | 374 EXPECT_CALL(*scriptLoader1, execute()).WillOnce(Invoke([this] { |
380 m_order.push_back(1); | 375 m_order.push_back(1); |
381 })); | 376 })); |
382 EXPECT_CALL(*scriptLoader2, execute()).WillOnce(Invoke([this] { | 377 EXPECT_CALL(*scriptLoader2, execute()).WillOnce(Invoke([this] { |
383 m_order.push_back(2); | 378 m_order.push_back(2); |
384 })); | 379 })); |
385 | 380 |
386 m_scriptRunner->notifyScriptReady(scriptLoader1, ScriptRunner::InOrder); | 381 m_scriptRunner->notifyScriptReady(scriptLoader1, ScriptRunner::InOrder); |
387 m_platform->runUntilIdle(); | 382 m_platform->runUntilIdle(); |
388 | 383 |
389 // At this moment all tasks can be already executed. Make sure that we do not | 384 // At this moment all tasks can be already executed. Make sure that we do not |
390 // crash here. | 385 // crash here. |
391 m_scriptRunner->notifyScriptReady(scriptLoader2, ScriptRunner::InOrder); | 386 m_scriptRunner->notifyScriptReady(scriptLoader2, ScriptRunner::InOrder); |
392 m_platform->runUntilIdle(); | 387 m_platform->runUntilIdle(); |
393 | 388 |
394 EXPECT_THAT(m_order, ElementsAre(1, 2)); | 389 EXPECT_THAT(m_order, ElementsAre(1, 2)); |
395 } | 390 } |
396 | 391 |
397 TEST_F(ScriptRunnerTest, TasksWithDeadScriptRunner) { | 392 TEST_F(ScriptRunnerTest, TasksWithDeadScriptRunner) { |
398 Persistent<MockScriptLoader> scriptLoader1 = | 393 Persistent<MockScriptLoader> scriptLoader1 = MockScriptLoader::create(); |
399 MockScriptLoader::create(m_element.get()); | 394 Persistent<MockScriptLoader> scriptLoader2 = MockScriptLoader::create(); |
400 Persistent<MockScriptLoader> scriptLoader2 = | |
401 MockScriptLoader::create(m_element.get()); | |
402 | 395 |
403 EXPECT_CALL(*scriptLoader1, isReady()).WillRepeatedly(Return(true)); | 396 EXPECT_CALL(*scriptLoader1, isReady()).WillRepeatedly(Return(true)); |
404 EXPECT_CALL(*scriptLoader2, isReady()).WillRepeatedly(Return(true)); | 397 EXPECT_CALL(*scriptLoader2, isReady()).WillRepeatedly(Return(true)); |
405 | 398 |
406 m_scriptRunner->queueScriptForExecution(scriptLoader1, ScriptRunner::Async); | 399 m_scriptRunner->queueScriptForExecution(scriptLoader1, ScriptRunner::Async); |
407 m_scriptRunner->queueScriptForExecution(scriptLoader2, ScriptRunner::Async); | 400 m_scriptRunner->queueScriptForExecution(scriptLoader2, ScriptRunner::Async); |
408 | 401 |
409 m_scriptRunner->notifyScriptReady(scriptLoader1, ScriptRunner::Async); | 402 m_scriptRunner->notifyScriptReady(scriptLoader1, ScriptRunner::Async); |
410 m_scriptRunner->notifyScriptReady(scriptLoader2, ScriptRunner::Async); | 403 m_scriptRunner->notifyScriptReady(scriptLoader2, ScriptRunner::Async); |
411 | 404 |
412 m_scriptRunner.release(); | 405 m_scriptRunner.release(); |
413 | 406 |
414 ThreadState::current()->collectAllGarbage(); | 407 ThreadState::current()->collectAllGarbage(); |
415 | 408 |
416 // m_scriptRunner is gone. We need to make sure that ScriptRunner::Task do not | 409 // m_scriptRunner is gone. We need to make sure that ScriptRunner::Task do not |
417 // access dead object. | 410 // access dead object. |
418 EXPECT_CALL(*scriptLoader1, execute()).Times(0); | 411 EXPECT_CALL(*scriptLoader1, execute()).Times(0); |
419 EXPECT_CALL(*scriptLoader2, execute()).Times(0); | 412 EXPECT_CALL(*scriptLoader2, execute()).Times(0); |
420 | 413 |
421 m_platform->runUntilIdle(); | 414 m_platform->runUntilIdle(); |
422 } | 415 } |
423 | 416 |
424 } // namespace blink | 417 } // namespace blink |
OLD | NEW |