1 |
|
2 |
|
3 | import assert from 'assert';
|
4 | import AssetGraph, {
|
5 | nodeFromAssetGroup,
|
6 | nodeFromDep,
|
7 | nodeFromEntryFile,
|
8 | } from '../src/AssetGraph';
|
9 | import {createDependency} from '../src/Dependency';
|
10 | import {createAsset} from '../src/InternalAsset';
|
11 | import {createEnvironment} from '../src/Environment';
|
12 |
|
13 | const DEFAULT_ENV = createEnvironment({
|
14 | context: 'browser',
|
15 | engines: {
|
16 | browsers: ['> 1%'],
|
17 | },
|
18 | });
|
19 |
|
20 | const TARGETS = [
|
21 | {
|
22 | name: 'test',
|
23 | distDir: 'dist',
|
24 | distEntry: 'out.js',
|
25 | env: DEFAULT_ENV,
|
26 | publicUrl: null,
|
27 | },
|
28 | ];
|
29 |
|
30 | const stats = {size: 0, time: 0};
|
31 |
|
32 | describe('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 |
|
320 |
|
321 |
|
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 | });
|