Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(414)

Side by Side Diff: third_party/WebKit/Source/core/dom/ModuleMapTest.cpp

Issue 2704323002: [ES6 modules] Introduce ModuleMap (Closed)
Patch Set: no core expor Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "core/dom/ModuleMap.h"
6
7 #include "core/dom/Document.h"
8 #include "core/dom/Modulator.h"
9 #include "core/dom/ModuleScript.h"
10 #include "core/dom/ScriptModuleResolver.h"
11 #include "core/loader/modulescript/ModuleScriptFetchRequest.h"
12 #include "core/loader/modulescript/ModuleScriptLoaderClient.h"
13 #include "core/testing/DummyModulator.h"
14 #include "core/testing/DummyPageHolder.h"
15 #include "platform/heap/Handle.h"
16 #include "platform/testing/TestingPlatformSupport.h"
17 #include "public/platform/Platform.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19
20 namespace blink {
21
22 namespace {
23
24 class TestSingleModuleClient final
25 : public GarbageCollectedFinalized<TestSingleModuleClient>,
26 public SingleModuleClient {
27 USING_GARBAGE_COLLECTED_MIXIN(TestSingleModuleClient);
28
29 public:
30 TestSingleModuleClient() = default;
31 virtual ~TestSingleModuleClient() {}
32
33 DEFINE_INLINE_TRACE() { visitor->trace(m_moduleScript); }
34
35 void notifyModuleLoadFinished(ModuleScript* moduleScript) override {
36 m_wasNotifyFinished = true;
37 m_moduleScript = moduleScript;
38 }
39
40 bool wasNotifyFinished() const { return m_wasNotifyFinished; }
41 ModuleScript* moduleScript() { return m_moduleScript; }
42
43 private:
44 bool m_wasNotifyFinished = false;
45 Member<ModuleScript> m_moduleScript;
46 };
47
48 class TestScriptModuleResolver final : public ScriptModuleResolver {
49 public:
50 TestScriptModuleResolver() {}
51
52 int registerModuleScriptCallCount() const {
53 return m_registerModuleScriptCallCount;
54 }
55
56 void registerModuleScript(ModuleScript*) override {
57 m_registerModuleScriptCallCount++;
58 }
59
60 ScriptModule resolve(const String& specifier,
61 const ScriptModule& referrer,
62 ExceptionState&) override {
63 NOTREACHED();
64 return ScriptModule();
65 }
66
67 private:
68 int m_registerModuleScriptCallCount = 0;
69 };
70
71 } // namespace
72
73 class ModuleMapTestModulator final : public DummyModulator {
74 public:
75 ModuleMapTestModulator();
76 virtual ~ModuleMapTestModulator() {}
77
78 DECLARE_TRACE();
79
80 TestScriptModuleResolver* testScriptModuleResolver() {
81 return m_resolver.get();
82 }
83 void resolveFetches();
84
85 private:
86 // Implements Modulator:
87
88 ScriptModuleResolver* scriptModuleResolver() override {
89 return m_resolver.get();
90 }
91
92 WebTaskRunner* taskRunner() override {
93 return Platform::current()->currentThread()->getWebTaskRunner();
94 };
95
96 void fetchNewSingleModule(const ModuleScriptFetchRequest&,
97 ModuleGraphLevel,
98 ModuleScriptLoaderClient*) override;
99
100 struct TestRequest : public GarbageCollectedFinalized<TestRequest> {
101 KURL url;
102 String nonce;
103 Member<ModuleScriptLoaderClient> client;
104
105 DEFINE_INLINE_TRACE() { visitor->trace(client); }
106 };
107 HeapVector<Member<TestRequest>> m_testRequests;
108
109 Member<TestScriptModuleResolver> m_resolver;
110 };
111
112 ModuleMapTestModulator::ModuleMapTestModulator()
113 : m_resolver(new TestScriptModuleResolver) {}
114
115 DEFINE_TRACE(ModuleMapTestModulator) {
116 visitor->trace(m_testRequests);
117 visitor->trace(m_resolver);
118 DummyModulator::trace(visitor);
119 }
120
121 void ModuleMapTestModulator::fetchNewSingleModule(
122 const ModuleScriptFetchRequest& request,
123 ModuleGraphLevel,
124 ModuleScriptLoaderClient* client) {
125 TestRequest* testRequest = new TestRequest;
126 testRequest->url = request.url();
127 testRequest->nonce = request.nonce();
128 testRequest->client = client;
129 m_testRequests.push_back(testRequest);
130 }
131
132 void ModuleMapTestModulator::resolveFetches() {
133 for (const auto& testRequest : m_testRequests) {
134 ModuleScript* moduleScript = ModuleScript::create(
135 ScriptModule(), testRequest->url, testRequest->nonce, ParserInserted,
136 WebURLRequest::FetchCredentialsModeOmit);
137 taskRunner()->postTask(
138 BLINK_FROM_HERE,
139 WTF::bind(&ModuleScriptLoaderClient::notifyNewSingleModuleFinished,
140 wrapPersistent(testRequest->client.get()),
141 wrapPersistent(moduleScript)));
142 }
143 m_testRequests.clear();
144 }
145
146 class ModuleMapTest : public testing::Test {
147 public:
148 void SetUp() override;
149
150 ModuleMapTestModulator* modulator() { return m_modulator.get(); }
151 ModuleMap* map() { return m_map; }
152
153 protected:
154 Persistent<ModuleMapTestModulator> m_modulator;
155 Persistent<ModuleMap> m_map;
156 };
157
158 void ModuleMapTest::SetUp() {
159 m_modulator = new ModuleMapTestModulator();
160 m_map = ModuleMap::create(m_modulator.get());
161 }
162
163 TEST_F(ModuleMapTest, sequentialRequests) {
164 ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>
165 platform;
166 platform->advanceClockSeconds(1.); // For non-zero DocumentParserTimings
167
168 KURL url(KURL(), "https://example.com/foo.js");
169 ModuleScriptFetchRequest moduleRequest(
170 url, String(), ParserInserted, WebURLRequest::FetchCredentialsModeOmit);
171
172 // First request
173 TestSingleModuleClient* client = new TestSingleModuleClient;
174 map()->fetchSingleModuleScript(moduleRequest,
175 ModuleGraphLevel::TopLevelModuleFetch, client);
176 modulator()->resolveFetches();
177 EXPECT_FALSE(client->wasNotifyFinished())
178 << "fetchSingleModuleScript shouldn't complete synchronously";
179 platform->runUntilIdle();
180
181 EXPECT_EQ(
182 modulator()->testScriptModuleResolver()->registerModuleScriptCallCount(),
183 1);
184 EXPECT_TRUE(client->wasNotifyFinished());
185 EXPECT_TRUE(client->moduleScript());
186 EXPECT_EQ(client->moduleScript()->instantiationState(),
187 ModuleInstantiationState::Uninstantiated);
188
189 // Secondary request
190 TestSingleModuleClient* client2 = new TestSingleModuleClient;
191 map()->fetchSingleModuleScript(
192 moduleRequest, ModuleGraphLevel::TopLevelModuleFetch, client2);
193 modulator()->resolveFetches();
194 EXPECT_FALSE(client2->wasNotifyFinished())
195 << "fetchSingleModuleScript shouldn't complete synchronously";
196 platform->runUntilIdle();
197
198 EXPECT_EQ(
199 modulator()->testScriptModuleResolver()->registerModuleScriptCallCount(),
200 1)
201 << "registerModuleScript sholudn't be called in secondary request.";
202 EXPECT_TRUE(client2->wasNotifyFinished());
203 EXPECT_TRUE(client2->moduleScript());
204 EXPECT_EQ(client2->moduleScript()->instantiationState(),
205 ModuleInstantiationState::Uninstantiated);
206 }
207
208 TEST_F(ModuleMapTest, concurrentRequestsShouldJoin) {
209 ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>
210 platform;
211 platform->advanceClockSeconds(1.); // For non-zero DocumentParserTimings
212
213 KURL url(KURL(), "https://example.com/foo.js");
214 ModuleScriptFetchRequest moduleRequest(
215 url, String(), ParserInserted, WebURLRequest::FetchCredentialsModeOmit);
216
217 // First request
218 TestSingleModuleClient* client = new TestSingleModuleClient;
219 map()->fetchSingleModuleScript(moduleRequest,
220 ModuleGraphLevel::TopLevelModuleFetch, client);
221
222 // Secondary request (which should join the first request)
223 TestSingleModuleClient* client2 = new TestSingleModuleClient;
224 map()->fetchSingleModuleScript(
225 moduleRequest, ModuleGraphLevel::TopLevelModuleFetch, client2);
226
227 modulator()->resolveFetches();
228 EXPECT_FALSE(client->wasNotifyFinished())
229 << "fetchSingleModuleScript shouldn't complete synchronously";
230 EXPECT_FALSE(client2->wasNotifyFinished())
231 << "fetchSingleModuleScript shouldn't complete synchronously";
232 platform->runUntilIdle();
233
234 EXPECT_EQ(
235 modulator()->testScriptModuleResolver()->registerModuleScriptCallCount(),
236 1);
237
238 EXPECT_TRUE(client->wasNotifyFinished());
239 EXPECT_TRUE(client->moduleScript());
240 EXPECT_EQ(client->moduleScript()->instantiationState(),
241 ModuleInstantiationState::Uninstantiated);
242 EXPECT_TRUE(client2->wasNotifyFinished());
243 EXPECT_TRUE(client2->moduleScript());
244 EXPECT_EQ(client2->moduleScript()->instantiationState(),
245 ModuleInstantiationState::Uninstantiated);
246 }
247
248 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/dom/ModuleMap.cpp ('k') | third_party/WebKit/Source/core/dom/ScriptModuleResolver.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698