UNPKG

11.6 kBJavaScriptView Raw
1// @flow
2
3import assert from 'assert';
4import AssetGraph, {
5 nodeFromAssetGroup,
6 nodeFromDep,
7 nodeFromEntryFile,
8} from '../src/AssetGraph';
9import {createDependency} from '../src/Dependency';
10import {createAsset} from '../src/InternalAsset';
11import {createEnvironment} from '../src/Environment';
12
13const DEFAULT_ENV = createEnvironment({
14 context: 'browser',
15 engines: {
16 browsers: ['> 1%'],
17 },
18});
19
20const TARGETS = [
21 {
22 name: 'test',
23 distDir: 'dist',
24 distEntry: 'out.js',
25 env: DEFAULT_ENV,
26 publicUrl: null,
27 },
28];
29
30const stats = {size: 0, time: 0};
31
32describe('AssetGraph', () => {
33 it('initialization should create one root node with edges to entry_specifier nodes for each entry', () => {
34 let graph = new AssetGraph();
35 graph.initialize({
36 entries: ['/path/to/index1', '/path/to/index2'],
37 });
38
39 assert(graph.nodes.has('@@root'));
40 assert(graph.nodes.has('entry_specifier:/path/to/index1'));
41 assert(graph.nodes.has('entry_specifier:/path/to/index2'));
42 });
43
44 it('resolveEntry should connect an entry_specifier node to entry_file nodes', () => {
45 let graph = new AssetGraph();
46 graph.initialize({
47 entries: ['/path/to/index1', '/path/to/index2'],
48 });
49
50 graph.resolveEntry('/path/to/index1', [
51 {filePath: '/path/to/index1/src/main.js'},
52 ]);
53
54 assert(
55 graph.nodes.has(
56 nodeFromEntryFile({filePath: '/path/to/index1/src/main.js'}).id,
57 ),
58 );
59 assert(
60 graph.hasEdge(
61 'entry_specifier:/path/to/index1',
62 nodeFromEntryFile({filePath: '/path/to/index1/src/main.js'}).id,
63 ),
64 );
65 });
66
67 it('resolveTargets should connect an entry_file node to dependencies for each target', () => {
68 let graph = new AssetGraph();
69 graph.initialize({
70 entries: ['/path/to/index1', '/path/to/index2'],
71 });
72
73 graph.resolveEntry('/path/to/index1', [
74 {filePath: '/path/to/index1/src/main.js'},
75 ]);
76 graph.resolveEntry('/path/to/index2', [
77 {filePath: '/path/to/index2/src/main.js'},
78 ]);
79
80 graph.resolveTargets({filePath: '/path/to/index1/src/main.js'}, TARGETS);
81 graph.resolveTargets({filePath: '/path/to/index2/src/main.js'}, TARGETS);
82
83 assert(
84 graph.nodes.has(
85 createDependency({
86 moduleSpecifier: '/path/to/index1/src/main.js',
87 pipeline: 'test',
88 target: TARGETS[0],
89 env: DEFAULT_ENV,
90 }).id,
91 ),
92 );
93 assert(
94 graph.nodes.has(
95 createDependency({
96 moduleSpecifier: '/path/to/index2/src/main.js',
97 pipeline: 'test',
98 target: TARGETS[0],
99 env: DEFAULT_ENV,
100 }).id,
101 ),
102 );
103 assert.deepEqual(graph.getAllEdges(), [
104 {
105 from: '@@root',
106 to: 'entry_specifier:/path/to/index1',
107 type: null,
108 },
109 {
110 from: '@@root',
111 to: 'entry_specifier:/path/to/index2',
112 type: null,
113 },
114 {
115 from: 'entry_specifier:/path/to/index1',
116 to: nodeFromEntryFile({filePath: '/path/to/index1/src/main.js'}).id,
117 type: null,
118 },
119 {
120 from: 'entry_specifier:/path/to/index2',
121 to: nodeFromEntryFile({filePath: '/path/to/index2/src/main.js'}).id,
122 type: null,
123 },
124 {
125 from: nodeFromEntryFile({filePath: '/path/to/index1/src/main.js'}).id,
126 to: createDependency({
127 moduleSpecifier: '/path/to/index1/src/main.js',
128 pipeline: 'test',
129 target: TARGETS[0],
130 env: DEFAULT_ENV,
131 }).id,
132 type: null,
133 },
134 {
135 from: nodeFromEntryFile({filePath: '/path/to/index2/src/main.js'}).id,
136 to: createDependency({
137 moduleSpecifier: '/path/to/index2/src/main.js',
138 pipeline: 'test',
139 target: TARGETS[0],
140 env: DEFAULT_ENV,
141 }).id,
142 type: null,
143 },
144 ]);
145 });
146
147 it('resolveDependency should update the file a dependency is connected to', () => {
148 let graph = new AssetGraph();
149 graph.initialize({
150 targets: TARGETS,
151 entries: ['/path/to/index'],
152 });
153
154 graph.resolveEntry('/path/to/index', [
155 {filePath: '/path/to/index/src/main.js'},
156 ]);
157 graph.resolveTargets({filePath: '/path/to/index/src/main.js'}, TARGETS);
158
159 let dep = createDependency({
160 moduleSpecifier: '/path/to/index/src/main.js',
161 pipeline: 'test',
162 target: TARGETS[0],
163 env: DEFAULT_ENV,
164 });
165 let req = {filePath: '/index.js', env: DEFAULT_ENV};
166
167 graph.resolveDependency(dep, nodeFromAssetGroup(req));
168 assert(graph.nodes.has(nodeFromAssetGroup(req).id));
169 assert(graph.hasEdge(dep.id, nodeFromAssetGroup(req).id));
170
171 let req2 = {filePath: '/index.jsx', env: DEFAULT_ENV};
172 graph.resolveDependency(dep, nodeFromAssetGroup(req2));
173 assert(!graph.nodes.has(nodeFromAssetGroup(req).id));
174 assert(graph.nodes.has(nodeFromAssetGroup(req2).id));
175 assert(graph.hasEdge(dep.id, nodeFromAssetGroup(req2).id));
176 assert(!graph.hasEdge(dep.id, nodeFromAssetGroup(req).id));
177
178 graph.resolveDependency(dep, nodeFromAssetGroup(req2));
179 assert(graph.nodes.has(nodeFromAssetGroup(req2).id));
180 assert(graph.hasEdge(dep.id, nodeFromAssetGroup(req2).id));
181 });
182
183 it('resolveAssetGroup should update the asset and dep nodes a file is connected to', () => {
184 let graph = new AssetGraph();
185 graph.initialize({
186 targets: TARGETS,
187 entries: ['/path/to/index'],
188 });
189
190 graph.resolveEntry('/path/to/index', [
191 {filePath: '/path/to/index/src/main.js'},
192 ]);
193 graph.resolveTargets({filePath: '/path/to/index/src/main.js'}, TARGETS);
194
195 let dep = createDependency({
196 moduleSpecifier: '/path/to/index/src/main.js',
197 pipeline: 'test',
198 target: TARGETS[0],
199 env: DEFAULT_ENV,
200 sourcePath: '',
201 });
202 let filePath = '/index.js';
203 let req = {filePath, env: DEFAULT_ENV};
204 graph.resolveDependency(dep, nodeFromAssetGroup(req));
205 let sourcePath = filePath;
206 let assets = [
207 createAsset({
208 id: '1',
209 filePath,
210 type: 'js',
211 isSource: true,
212 hash: '#1',
213 stats,
214 dependencies: new Map([
215 [
216 'utils',
217 createDependency({
218 moduleSpecifier: './utils',
219 env: DEFAULT_ENV,
220 sourcePath,
221 }),
222 ],
223 ]),
224 env: DEFAULT_ENV,
225 includedFiles: new Map(),
226 }),
227 createAsset({
228 id: '2',
229 filePath,
230 type: 'js',
231 isSource: true,
232 hash: '#2',
233 stats,
234 dependencies: new Map([
235 [
236 'styles',
237 createDependency({
238 moduleSpecifier: './styles',
239 env: DEFAULT_ENV,
240 sourcePath,
241 }),
242 ],
243 ]),
244 env: DEFAULT_ENV,
245 includedFiles: new Map(),
246 }),
247 createAsset({
248 id: '3',
249 filePath,
250 type: 'js',
251 isSource: true,
252 hash: '#3',
253 dependencies: new Map(),
254 env: DEFAULT_ENV,
255 stats,
256 includedFiles: new Map(),
257 }),
258 ];
259
260 graph.resolveAssetGroup(req, assets);
261 assert(graph.nodes.has('1'));
262 assert(graph.nodes.has('2'));
263 assert(graph.nodes.has('3'));
264 assert(graph.nodes.has([...assets[0].dependencies.values()][0].id));
265 assert(graph.nodes.has([...assets[1].dependencies.values()][0].id));
266 assert(graph.hasEdge(nodeFromAssetGroup(req).id, '1'));
267 assert(graph.hasEdge(nodeFromAssetGroup(req).id, '2'));
268 assert(graph.hasEdge(nodeFromAssetGroup(req).id, '3'));
269 assert(graph.hasEdge('1', [...assets[0].dependencies.values()][0].id));
270 assert(graph.hasEdge('2', [...assets[1].dependencies.values()][0].id));
271
272 let assets2 = [
273 createAsset({
274 id: '1',
275 filePath,
276 type: 'js',
277 isSource: true,
278 hash: '#1',
279 stats,
280 dependencies: new Map([
281 [
282 'utils',
283 createDependency({
284 moduleSpecifier: './utils',
285 env: DEFAULT_ENV,
286 sourcePath,
287 }),
288 ],
289 ]),
290 env: DEFAULT_ENV,
291 includedFiles: new Map(),
292 }),
293 createAsset({
294 id: '2',
295 filePath,
296 type: 'js',
297 isSource: true,
298 hash: '#2',
299 stats,
300 dependencies: new Map(),
301 env: DEFAULT_ENV,
302 includedFiles: new Map(),
303 }),
304 ];
305
306 graph.resolveAssetGroup(req, assets2);
307 assert(graph.nodes.has('1'));
308 assert(graph.nodes.has('2'));
309 assert(!graph.nodes.has('3'));
310 assert(graph.nodes.has([...assets[0].dependencies.values()][0].id));
311 assert(!graph.nodes.has([...assets[1].dependencies.values()][0].id));
312 assert(graph.hasEdge(nodeFromAssetGroup(req).id, '1'));
313 assert(graph.hasEdge(nodeFromAssetGroup(req).id, '2'));
314 assert(!graph.hasEdge(nodeFromAssetGroup(req).id, '3'));
315 assert(graph.hasEdge('1', [...assets[0].dependencies.values()][0].id));
316 assert(!graph.hasEdge('2', [...assets[1].dependencies.values()][0].id));
317 });
318
319 // Assets can define dependent assets in the same asset group by declaring a dependency with a module
320 // specifer that matches the dependent asset's unique key. These dependent assets are then connected
321 // to the asset's dependency instead of the asset group.
322 it('resolveAssetGroup should handle dependent assets in asset groups', () => {
323 let graph = new AssetGraph();
324 graph.initialize({targets: TARGETS, entries: ['./index']});
325
326 graph.resolveEntry('./index', [{filePath: '/path/to/index/src/main.js'}]);
327 graph.resolveTargets({filePath: '/path/to/index/src/main.js'}, TARGETS);
328
329 let dep = createDependency({
330 moduleSpecifier: '/path/to/index/src/main.js',
331 pipeline: 'test',
332 env: DEFAULT_ENV,
333 target: TARGETS[0],
334 });
335 let filePath = '/index.js';
336 let req = {filePath, env: DEFAULT_ENV};
337 graph.resolveDependency(dep, nodeFromAssetGroup(req));
338 let sourcePath = filePath;
339 let dep1 = createDependency({
340 moduleSpecifier: 'dependent-asset-1',
341 env: DEFAULT_ENV,
342 sourcePath,
343 });
344 let dep2 = createDependency({
345 moduleSpecifier: 'dependent-asset-2',
346 env: DEFAULT_ENV,
347 sourcePath,
348 });
349 let assets = [
350 createAsset({
351 id: '1',
352 filePath,
353 type: 'js',
354 isSource: true,
355 hash: '#1',
356 stats,
357 dependencies: new Map([['dep1', dep1]]),
358 env: DEFAULT_ENV,
359 }),
360 createAsset({
361 id: '2',
362 uniqueKey: 'dependent-asset-1',
363 filePath,
364 type: 'js',
365 isSource: true,
366 hash: '#1',
367 stats,
368 dependencies: new Map([['dep2', dep2]]),
369 env: DEFAULT_ENV,
370 }),
371 createAsset({
372 id: '3',
373 uniqueKey: 'dependent-asset-2',
374 filePath,
375 type: 'js',
376 isSource: true,
377 hash: '#1',
378 stats,
379 env: DEFAULT_ENV,
380 }),
381 ];
382
383 graph.resolveAssetGroup(req, assets);
384 assert(graph.nodes.has('1'));
385 assert(graph.nodes.has('2'));
386 assert(graph.nodes.has('3'));
387 assert(graph.hasEdge(nodeFromAssetGroup(req).id, '1'));
388 assert(!graph.hasEdge(nodeFromAssetGroup(req).id, '2'));
389 assert(!graph.hasEdge(nodeFromAssetGroup(req).id, '3'));
390 assert(graph.hasEdge('1', nodeFromDep(dep1).id));
391 assert(graph.hasEdge(nodeFromDep(dep1).id, '2'));
392 assert(graph.hasEdge('2', nodeFromDep(dep2).id));
393 assert(graph.hasEdge(nodeFromDep(dep2).id, '3'));
394 });
395});