|
|
|
// @flow strict-local
|
|
|
|
import assert from 'assert';
|
|
|
|
import invariant from 'assert';
|
|
|
|
import nullthrows from 'nullthrows';
|
|
|
|
import AssetGraph, {
|
|
|
|
nodeFromAssetGroup,
|
|
|
|
nodeFromDep,
|
|
|
|
nodeFromEntryFile,
|
|
|
|
nodeFromAsset,
|
|
|
|
} from '../src/AssetGraph';
|
|
|
|
import {createDependency as _createDependency} from '../src/Dependency';
|
|
|
|
import {createAsset as _createAsset} from '../src/assetUtils';
|
|
|
|
import {DEFAULT_ENV, DEFAULT_TARGETS} from './test-utils';
|
|
|
|
import {toProjectPath as _toProjectPath} from '../src/projectPath';
|
|
|
|
|
|
|
|
const stats = {size: 0, time: 0};
|
|
|
|
|
|
|
|
function createAsset(opts) {
|
|
|
|
return _createAsset('/', opts);
|
|
|
|
}
|
|
|
|
|
|
|
|
function createDependency(opts) {
|
|
|
|
return _createDependency('/', opts);
|
|
|
|
}
|
|
|
|
|
|
|
|
function toProjectPath(p) {
|
|
|
|
return _toProjectPath('/', p);
|
|
|
|
}
|
|
|
|
|
|
|
|
describe('AssetGraph', () => {
|
|
|
|
it('initialization should create one root node with edges to entry_specifier nodes for each entry', () => {
|
|
|
|
let graph = new AssetGraph();
|
|
|
|
graph.setRootConnections({
|
|
|
|
entries: [
|
|
|
|
toProjectPath('/path/to/index1'),
|
|
|
|
toProjectPath('/path/to/index2'),
|
|
|
|
],
|
|
|
|
});
|
|
|
|
|
|
|
|
assert(graph.hasNode(nullthrows(graph.rootNodeId)));
|
|
|
|
assert(graph.hasContentKey('entry_specifier:path/to/index1'));
|
|
|
|
assert(graph.hasContentKey('entry_specifier:path/to/index2'));
|
|
|
|
});
|
|
|
|
|
|
|
|
it('resolveEntry should connect an entry_specifier node to entry_file nodes', () => {
|
|
|
|
let graph = new AssetGraph();
|
|
|
|
graph.setRootConnections({
|
|
|
|
entries: [
|
|
|
|
toProjectPath('/path/to/index1'),
|
|
|
|
toProjectPath('/path/to/index2'),
|
|
|
|
],
|
|
|
|
});
|
|
|
|
|
|
|
|
graph.resolveEntry(
|
|
|
|
toProjectPath('/path/to/index1'),
|
|
|
|
[
|
|
|
|
{
|
|
|
|
filePath: toProjectPath('/path/to/index1/src/main.js'),
|
|
|
|
packagePath: toProjectPath('/path/to/index1'),
|
|
|
|
},
|
|
|
|
],
|
|
|
|
'123',
|
|
|
|
);
|
|
|
|
|
|
|
|
assert(
|
|
|
|
graph.hasContentKey(
|
|
|
|
nodeFromEntryFile({
|
|
|
|
filePath: toProjectPath('/path/to/index1/src/main.js'),
|
|
|
|
packagePath: toProjectPath('/path/to/index1'),
|
|
|
|
}).id,
|
|
|
|
),
|
|
|
|
);
|
|
|
|
assert(
|
|
|
|
graph.hasEdge(
|
|
|
|
graph.getNodeIdByContentKey('entry_specifier:path/to/index1'),
|
|
|
|
graph.getNodeIdByContentKey(
|
|
|
|
nodeFromEntryFile({
|
|
|
|
filePath: toProjectPath('/path/to/index1/src/main.js'),
|
|
|
|
packagePath: toProjectPath('/path/to/index1'),
|
|
|
|
}).id,
|
|
|
|
),
|
|
|
|
),
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('resolveTargets should connect an entry_file node to dependencies for each target', () => {
|
|
|
|
let graph = new AssetGraph();
|
|
|
|
graph.setRootConnections({
|
|
|
|
entries: [
|
|
|
|
toProjectPath('/path/to/index1'),
|
|
|
|
toProjectPath('/path/to/index2'),
|
|
|
|
],
|
|
|
|
});
|
|
|
|
|
|
|
|
graph.resolveEntry(
|
|
|
|
toProjectPath('/path/to/index1'),
|
|
|
|
[
|
|
|
|
{
|
|
|
|
filePath: toProjectPath('/path/to/index1/src/main.js'),
|
|
|
|
packagePath: toProjectPath('/path/to/index1'),
|
|
|
|
},
|
|
|
|
],
|
|
|
|
'1',
|
|
|
|
);
|
|
|
|
graph.resolveEntry(
|
|
|
|
toProjectPath('/path/to/index2'),
|
|
|
|
[
|
|
|
|
{
|
|
|
|
filePath: toProjectPath('/path/to/index2/src/main.js'),
|
|
|
|
packagePath: toProjectPath('/path/to/index2'),
|
|
|
|
},
|
|
|
|
],
|
|
|
|
'2',
|
|
|
|
);
|
|
|
|
|
|
|
|
graph.resolveTargets(
|
|
|
|
{
|
|
|
|
filePath: toProjectPath('/path/to/index1/src/main.js'),
|
|
|
|
packagePath: toProjectPath('/path/to/index1'),
|
|
|
|
},
|
|
|
|
DEFAULT_TARGETS,
|
|
|
|
'3',
|
|
|
|
);
|
|
|
|
graph.resolveTargets(
|
|
|
|
{
|
|
|
|
filePath: toProjectPath('/path/to/index2/src/main.js'),
|
|
|
|
packagePath: toProjectPath('/path/to/index2'),
|
|
|
|
},
|
|
|
|
DEFAULT_TARGETS,
|
|
|
|
'4',
|
|
|
|
);
|
|
|
|
|
|
|
|
assert(
|
|
|
|
graph.hasContentKey(
|
|
|
|
createDependency({
|
|
|
|
specifier: 'path/to/index1/src/main.js',
|
|
|
|
specifierType: 'esm',
|
|
|
|
target: DEFAULT_TARGETS[0],
|
|
|
|
env: DEFAULT_ENV,
|
|
|
|
}).id,
|
|
|
|
),
|
|
|
|
);
|
|
|
|
assert(
|
|
|
|
graph.hasContentKey(
|
|
|
|
createDependency({
|
|
|
|
specifier: 'path/to/index2/src/main.js',
|
|
|
|
specifierType: 'esm',
|
|
|
|
target: DEFAULT_TARGETS[0],
|
|
|
|
env: DEFAULT_ENV,
|
|
|
|
}).id,
|
|
|
|
),
|
|
|
|
);
|
|
|
|
assert.deepEqual(graph.getAllEdges(), [
|
|
|
|
{
|
|
|
|
from: graph.rootNodeId,
|
|
|
|
to: graph.getNodeIdByContentKey('entry_specifier:path/to/index1'),
|
|
|
|
type: 1,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
from: graph.rootNodeId,
|
|
|
|
to: graph.getNodeIdByContentKey('entry_specifier:path/to/index2'),
|
|
|
|
type: 1,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
from: graph.getNodeIdByContentKey('entry_specifier:path/to/index1'),
|
|
|
|
to: graph.getNodeIdByContentKey(
|
|
|
|
nodeFromEntryFile({
|
|
|
|
filePath: toProjectPath('/path/to/index1/src/main.js'),
|
|
|
|
packagePath: toProjectPath('/path/to/index1'),
|
|
|
|
}).id,
|
|
|
|
),
|
|
|
|
type: 1,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
from: graph.getNodeIdByContentKey('entry_specifier:path/to/index2'),
|
|
|
|
to: graph.getNodeIdByContentKey(
|
|
|
|
nodeFromEntryFile({
|
|
|
|
filePath: toProjectPath('/path/to/index2/src/main.js'),
|
|
|
|
packagePath: toProjectPath('/path/to/index2'),
|
|
|
|
}).id,
|
|
|
|
),
|
|
|
|
type: 1,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
from: graph.getNodeIdByContentKey(
|
|
|
|
nodeFromEntryFile({
|
|
|
|
filePath: toProjectPath('/path/to/index1/src/main.js'),
|
|
|
|
packagePath: toProjectPath('/path/to/index1'),
|
|
|
|
}).id,
|
|
|
|
),
|
|
|
|
to: graph.getNodeIdByContentKey(
|
|
|
|
createDependency({
|
|
|
|
specifier: 'path/to/index1/src/main.js',
|
|
|
|
specifierType: 'esm',
|
|
|
|
target: DEFAULT_TARGETS[0],
|
|
|
|
env: DEFAULT_ENV,
|
|
|
|
}).id,
|
|
|
|
),
|
|
|
|
type: 1,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
from: graph.getNodeIdByContentKey(
|
|
|
|
nodeFromEntryFile({
|
|
|
|
filePath: toProjectPath('/path/to/index2/src/main.js'),
|
|
|
|
packagePath: toProjectPath('/path/to/index2'),
|
|
|
|
}).id,
|
|
|
|
),
|
|
|
|
to: graph.getNodeIdByContentKey(
|
|
|
|
createDependency({
|
|
|
|
specifier: 'path/to/index2/src/main.js',
|
|
|
|
specifierType: 'esm',
|
|
|
|
target: DEFAULT_TARGETS[0],
|
|
|
|
env: DEFAULT_ENV,
|
|
|
|
}).id,
|
|
|
|
),
|
|
|
|
type: 1,
|
|
|
|
},
|
|
|
|
]);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('resolveDependency should update the file a dependency is connected to', () => {
|
|
|
|
let graph = new AssetGraph();
|
|
|
|
graph.setRootConnections({
|
|
|
|
targets: DEFAULT_TARGETS,
|
|
|
|
entries: [toProjectPath('/path/to/index')],
|
|
|
|
});
|
|
|
|
|
|
|
|
graph.resolveEntry(
|
|
|
|
toProjectPath('/path/to/index'),
|
|
|
|
[
|
|
|
|
{
|
|
|
|
filePath: toProjectPath('/path/to/index/src/main.js'),
|
|
|
|
packagePath: toProjectPath('/path/to/index'),
|
|
|
|
},
|
|
|
|
],
|
|
|
|
'1',
|
|
|
|
);
|
|
|
|
graph.resolveTargets(
|
|
|
|
{
|
|
|
|
filePath: toProjectPath('/path/to/index/src/main.js'),
|
|
|
|
packagePath: toProjectPath('/path/to/index'),
|
|
|
|
},
|
|
|
|
DEFAULT_TARGETS,
|
|
|
|
'2',
|
|
|
|
);
|
|
|
|
|
|
|
|
let dep = createDependency({
|
|
|
|
specifier: 'path/to/index/src/main.js',
|
|
|
|
specifierType: 'esm',
|
|
|
|
target: DEFAULT_TARGETS[0],
|
|
|
|
env: DEFAULT_ENV,
|
|
|
|
});
|
|
|
|
let req = {
|
|
|
|
filePath: toProjectPath('/index.js'),
|
|
|
|
env: DEFAULT_ENV,
|
|
|
|
};
|
|
|
|
|
|
|
|
graph.resolveDependency(dep, req, '3');
|
|
|
|
let assetGroupNodeId = graph.getNodeIdByContentKey(
|
|
|
|
nodeFromAssetGroup(req).id,
|
|
|
|
);
|
|
|
|
let dependencyNodeId = graph.getNodeIdByContentKey(dep.id);
|
|
|
|
assert(graph.nodes.has(assetGroupNodeId));
|
|
|
|
assert(graph.hasEdge(dependencyNodeId, assetGroupNodeId));
|
|
|
|
|
|
|
|
let req2 = {
|
|
|
|
filePath: toProjectPath('/index.jsx'),
|
|
|
|
env: DEFAULT_ENV,
|
|
|
|
};
|
|
|
|
graph.resolveDependency(dep, req2, '4');
|
|
|
|
|
|
|
|
let assetGroupNodeId2 = graph.getNodeIdByContentKey(
|
|
|
|
nodeFromAssetGroup(req2).id,
|
|
|
|
);
|
|
|
|
assert(!graph.nodes.has(assetGroupNodeId));
|
|
|
|
assert(graph.nodes.has(assetGroupNodeId2));
|
|
|
|
assert(graph.hasEdge(dependencyNodeId, assetGroupNodeId2));
|
|
|
|
assert(!graph.hasEdge(dependencyNodeId, assetGroupNodeId));
|
|
|
|
|
|
|
|
graph.resolveDependency(dep, req2, '5');
|
|
|
|
assert(graph.nodes.has(assetGroupNodeId2));
|
|
|
|
assert(graph.hasEdge(dependencyNodeId, assetGroupNodeId2));
|
|
|
|
});
|
|
|
|
|
|
|
|
it('resolveAssetGroup should update the asset and dep nodes a file is connected to', () => {
|
|
|
|
let graph = new AssetGraph();
|
|
|
|
graph.setRootConnections({
|
|
|
|
targets: DEFAULT_TARGETS,
|
|
|
|
entries: [toProjectPath('/path/to/index')],
|
|
|
|
});
|
|
|
|
|
|
|
|
graph.resolveEntry(
|
|
|
|
toProjectPath('/path/to/index'),
|
|
|
|
[
|
|
|
|
{
|
|
|
|
filePath: toProjectPath('/path/to/index/src/main.js'),
|
|
|
|
packagePath: toProjectPath('/path/to/index'),
|
|
|
|
},
|
|
|
|
],
|
|
|
|
'1',
|
|
|
|
);
|
|
|
|
graph.resolveTargets(
|
|
|
|
{
|
|
|
|
filePath: toProjectPath('/path/to/index/src/main.js'),
|
|
|
|
packagePath: toProjectPath('/path/to/index'),
|
|
|
|
},
|
|
|
|
DEFAULT_TARGETS,
|
|
|
|
'2',
|
|
|
|
);
|
|
|
|
|
|
|
|
let dep = createDependency({
|
|
|
|
specifier: 'path/to/index/src/main.js',
|
|
|
|
specifierType: 'esm',
|
|
|
|
target: DEFAULT_TARGETS[0],
|
|
|
|
env: DEFAULT_ENV,
|
|
|
|
sourcePath: '',
|
|
|
|
});
|
|
|
|
let sourcePath = '/index.js';
|
|
|
|
let filePath = toProjectPath(sourcePath);
|
|
|
|
let req = {filePath, env: DEFAULT_ENV};
|
|
|
|
graph.resolveDependency(dep, req, '3');
|
|
|
|
let assets = [
|
|
|
|
createAsset({
|
|
|
|
id: '1',
|
|
|
|
filePath,
|
|
|
|
type: 'js',
|
|
|
|
isSource: true,
|
|
|
|
hash: '#1',
|
|
|
|
stats,
|
|
|
|
dependencies: new Map([
|
|
|
|
[
|
|
|
|
'utils',
|
|
|
|
createDependency({
|
|
|
|
specifier: './utils',
|
|
|
|
specifierType: 'esm',
|
|
|
|
env: DEFAULT_ENV,
|
|
|
|
sourcePath,
|
|
|
|
}),
|
|
|
|
],
|
|
|
|
]),
|
|
|
|
env: DEFAULT_ENV,
|
|
|
|
}),
|
|
|
|
createAsset({
|
|
|
|
id: '2',
|
|
|
|
filePath,
|
|
|
|
type: 'js',
|
|
|
|
isSource: true,
|
|
|
|
hash: '#2',
|
|
|
|
stats,
|
|
|
|
dependencies: new Map([
|
|
|
|
[
|
|
|
|
'styles',
|
|
|
|
createDependency({
|
|
|
|
specifier: './styles',
|
|
|
|
specifierType: 'esm',
|
|
|
|
env: DEFAULT_ENV,
|
|
|
|
sourcePath,
|
|
|
|
}),
|
|
|
|
],
|
|
|
|
]),
|
|
|
|
env: DEFAULT_ENV,
|
|
|
|
}),
|
|
|
|
createAsset({
|
|
|
|
id: '3',
|
|
|
|
filePath,
|
|
|
|
type: 'js',
|
|
|
|
isSource: true,
|
|
|
|
hash: '#3',
|
|
|
|
dependencies: new Map(),
|
|
|
|
env: DEFAULT_ENV,
|
|
|
|
stats,
|
|
|
|
}),
|
|
|
|
];
|
|
|
|
|
|
|
|
graph.resolveAssetGroup(req, assets, '4');
|
|
|
|
|
|
|
|
let nodeId1 = graph.getNodeIdByContentKey('1');
|
|
|
|
let nodeId2 = graph.getNodeIdByContentKey('2');
|
|
|
|
let nodeId3 = graph.getNodeIdByContentKey('3');
|
|
|
|
|
|
|
|
let assetGroupNode = graph.getNodeIdByContentKey(
|
|
|
|
nodeFromAssetGroup(req).id,
|
|
|
|
);
|
|
|
|
|
|
|
|
let dependencyNodeId1 = graph.getNodeIdByContentKey(
|
|
|
|
[...assets[0].dependencies.values()][0].id,
|
|
|
|
);
|
|
|
|
let dependencyNodeId2 = graph.getNodeIdByContentKey(
|
|
|
|
[...assets[1].dependencies.values()][0].id,
|
|
|
|
);
|
|
|
|
|
|
|
|
assert(graph.nodes.has(nodeId1));
|
|
|
|
assert(graph.nodes.has(nodeId2));
|
|
|
|
assert(graph.nodes.has(nodeId3));
|
|
|
|
assert(graph.nodes.has(dependencyNodeId1));
|
|
|
|
assert(graph.nodes.has(dependencyNodeId2));
|
|
|
|
assert(graph.hasEdge(assetGroupNode, nodeId1));
|
|
|
|
assert(graph.hasEdge(assetGroupNode, nodeId2));
|
|
|
|
assert(graph.hasEdge(assetGroupNode, nodeId3));
|
|
|
|
assert(graph.hasEdge(nodeId1, dependencyNodeId1));
|
|
|
|
assert(graph.hasEdge(nodeId2, dependencyNodeId2));
|
|
|
|
|
|
|
|
let assets2 = [
|
|
|
|
createAsset({
|
|
|
|
id: '1',
|
|
|
|
filePath,
|
|
|
|
type: 'js',
|
|
|
|
isSource: true,
|
|
|
|
hash: '#1',
|
|
|
|
stats,
|
|
|
|
dependencies: new Map([
|
|
|
|
[
|
|
|
|
'utils',
|
|
|
|
createDependency({
|
|
|
|
specifier: './utils',
|
|
|
|
specifierType: 'esm',
|
|
|
|
env: DEFAULT_ENV,
|
|
|
|
sourcePath,
|
|
|
|
}),
|
|
|
|
],
|
|
|
|
]),
|
|
|
|
env: DEFAULT_ENV,
|
|
|
|
}),
|
|
|
|
createAsset({
|
|
|
|
id: '2',
|
|
|
|
filePath,
|
|
|
|
type: 'js',
|
|
|
|
isSource: true,
|
|
|
|
hash: '#2',
|
|
|
|
stats,
|
|
|
|
dependencies: new Map(),
|
|
|
|
env: DEFAULT_ENV,
|
|
|
|
}),
|
|
|
|
];
|
|
|
|
|
|
|
|
graph.resolveAssetGroup(req, assets2, '5');
|
|
|
|
|
|
|
|
assert(graph.nodes.has(nodeId1));
|
|
|
|
assert(graph.nodes.has(nodeId2));
|
|
|
|
assert(!graph.nodes.has(nodeId3));
|
|
|
|
assert(graph.nodes.has(dependencyNodeId1));
|
|
|
|
assert(!graph.nodes.has(dependencyNodeId2));
|
|
|
|
assert(graph.hasEdge(assetGroupNode, nodeId1));
|
|
|
|
assert(graph.hasEdge(assetGroupNode, nodeId2));
|
|
|
|
assert(!graph.hasEdge(assetGroupNode, nodeId3));
|
|
|
|
assert(graph.hasEdge(nodeId1, dependencyNodeId1));
|
|
|
|
assert(!graph.hasEdge(nodeId2, dependencyNodeId2));
|
|
|
|
});
|
|
|
|
|
|
|
|
// Assets can define dependent assets in the same asset group by declaring a dependency with a module
|
|
|
|
// specifier that matches the dependent asset's unique key. These dependent assets are then connected
|
|
|
|
// to the asset's dependency instead of the asset group.
|
|
|
|
it('resolveAssetGroup should handle dependent assets in asset groups', () => {
|
|
|
|
let graph = new AssetGraph();
|
|
|
|
graph.setRootConnections({
|
|
|
|
targets: DEFAULT_TARGETS,
|
|
|
|
entries: [toProjectPath('/index')],
|
|
|
|
});
|
|
|
|
|
|
|
|
graph.resolveEntry(
|
|
|
|
toProjectPath('/index'),
|
|
|
|
[
|
|
|
|
{
|
|
|
|
filePath: toProjectPath('/path/to/index/src/main.js'),
|
|
|
|
packagePath: toProjectPath('/path/to/index'),
|
|
|
|
},
|
|
|
|
],
|
|
|
|
'1',
|
|
|
|
);
|
|
|
|
graph.resolveTargets(
|
|
|
|
{
|
|
|
|
filePath: toProjectPath('/path/to/index/src/main.js'),
|
|
|
|
packagePath: toProjectPath('/path/to/index'),
|
|
|
|
},
|
|
|
|
DEFAULT_TARGETS,
|
|
|
|
'2',
|
|
|
|
);
|
|
|
|
|
|
|
|
let dep = createDependency({
|
|
|
|
specifier: 'path/to/index/src/main.js',
|
|
|
|
specifierType: 'esm',
|
|
|
|
env: DEFAULT_ENV,
|
|
|
|
target: DEFAULT_TARGETS[0],
|
|
|
|
});
|
|
|
|
let sourcePath = '/index.js';
|
|
|
|
let filePath = toProjectPath(sourcePath);
|
|
|
|
let req = {filePath, env: DEFAULT_ENV};
|
|
|
|
graph.resolveDependency(dep, req, '123');
|
|
|
|
let dep1 = createDependency({
|
|
|
|
specifier: 'dependent-asset-1',
|
|
|
|
specifierType: 'esm',
|
|
|
|
env: DEFAULT_ENV,
|
|
|
|
sourcePath,
|
|
|
|
});
|
|
|
|
let dep2 = createDependency({
|
|
|
|
specifier: 'dependent-asset-2',
|
|
|
|
specifierType: 'esm',
|
|
|
|
env: DEFAULT_ENV,
|
|
|
|
sourcePath,
|
|
|
|
});
|
|
|
|
let assets = [
|
|
|
|
createAsset({
|
|
|
|
id: '1',
|
|
|
|
filePath,
|
|
|
|
type: 'js',
|
|
|
|
isSource: true,
|
|
|
|
hash: '#1',
|
|
|
|
stats,
|
|
|
|
dependencies: new Map([['dep1', dep1]]),
|
|
|
|
env: DEFAULT_ENV,
|
|
|
|
}),
|
|
|
|
createAsset({
|
|
|
|
id: '2',
|
|
|
|
uniqueKey: 'dependent-asset-1',
|
|
|
|
filePath,
|
|
|
|
type: 'js',
|
|
|
|
isSource: true,
|
|
|
|
hash: '#1',
|
|
|
|
stats,
|
|
|
|
dependencies: new Map([['dep2', dep2]]),
|
|
|
|
env: DEFAULT_ENV,
|
|
|
|
}),
|
|
|
|
createAsset({
|
|
|
|
id: '3',
|
|
|
|
uniqueKey: 'dependent-asset-2',
|
|
|
|
filePath,
|
|
|
|
type: 'js',
|
|
|
|
isSource: true,
|
|
|
|
hash: '#1',
|
|
|
|
stats,
|
|
|
|
env: DEFAULT_ENV,
|
|
|
|
}),
|
|
|
|
];
|
|
|
|
|
|
|
|
graph.resolveAssetGroup(req, assets, '3');
|
|
|
|
|
|
|
|
let nodeId1 = graph.getNodeIdByContentKey('1');
|
|
|
|
let nodeId2 = graph.getNodeIdByContentKey('2');
|
|
|
|
let nodeId3 = graph.getNodeIdByContentKey('3');
|
|
|
|
|
|
|
|
let assetGroupNodeId = graph.getNodeIdByContentKey(
|
|
|
|
nodeFromAssetGroup(req).id,
|
|
|
|
);
|
|
|
|
|
|
|
|
let depNodeId1 = graph.getNodeIdByContentKey(nodeFromDep(dep1).id);
|
|
|
|
let depNodeId2 = graph.getNodeIdByContentKey(nodeFromDep(dep2).id);
|
|
|
|
|
|
|
|
assert(nodeId1);
|
|
|
|
assert(nodeId2);
|
|
|
|
assert(nodeId3);
|
|
|
|
assert(graph.hasEdge(assetGroupNodeId, nodeId1));
|
|
|
|
assert(!graph.hasEdge(assetGroupNodeId, nodeId2));
|
|
|
|
assert(!graph.hasEdge(assetGroupNodeId, nodeId3));
|
|
|
|
assert(graph.hasEdge(nodeId1, depNodeId1));
|
|
|
|
assert(graph.hasEdge(depNodeId1, nodeId2));
|
|
|
|
assert(graph.hasEdge(nodeId2, depNodeId2));
|
|
|
|
assert(graph.hasEdge(depNodeId2, nodeId3));
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should support marking and unmarking all parents with hasDeferred', () => {
|
|
|
|
let graph = new AssetGraph();
|
|
|
|
|
|
|
|
// index
|
|
|
|
let indexAssetGroup = {
|
|
|
|
filePath: toProjectPath('/index.js'),
|
|
|
|
env: DEFAULT_ENV,
|
|
|
|
};
|
|
|
|
graph.setRootConnections({assetGroups: [indexAssetGroup]});
|
|
|
|
let indexFooDep = createDependency({
|
|
|
|
specifier: './foo',
|
|
|
|
specifierType: 'esm',
|
|
|
|
env: DEFAULT_ENV,
|
|
|
|
sourcePath: '/index.js',
|
|
|
|
});
|
|
|
|
let indexBarDep = createDependency({
|
|
|
|
specifier: './bar',
|
|
|
|
specifierType: 'esm',
|
|
|
|
env: DEFAULT_ENV,
|
|
|
|
sourcePath: '/index.js',
|
|
|
|
});
|
|
|
|
let indexAsset = createAsset({
|
|
|
|
id: 'assetIndex',
|
|
|
|
filePath: toProjectPath('/index.js'),
|
|
|
|
type: 'js',
|
|
|
|
isSource: true,
|
|
|
|
hash: '#4',
|
|
|
|
stats,
|
|
|
|
dependencies: new Map([
|
|
|
|
['./foo', indexFooDep],
|
|
|
|
['./bar', indexBarDep],
|
|
|
|
]),
|
|
|
|
env: DEFAULT_ENV,
|
|
|
|
});
|
|
|
|
graph.resolveAssetGroup(indexAssetGroup, [indexAsset], '0');
|
|
|
|
|
|
|
|
// index imports foo
|
|
|
|
let fooAssetGroup = {
|
|
|
|
filePath: toProjectPath('/foo.js'),
|
|
|
|
env: DEFAULT_ENV,
|
|
|
|
};
|
|
|
|
graph.resolveDependency(indexFooDep, fooAssetGroup, '0');
|
|
|
|
let fooAssetGroupNode = nodeFromAssetGroup(fooAssetGroup);
|
|
|
|
let fooUtilsDep = createDependency({
|
|
|
|
specifier: './utils',
|
|
|
|
specifierType: 'esm',
|
|
|
|
env: DEFAULT_ENV,
|
|
|
|
sourcePath: '/foo.js',
|
|
|
|
});
|
|
|
|
let fooUtilsDepNode = nodeFromDep(fooUtilsDep);
|
|
|
|
let fooAsset = createAsset({
|
|
|
|
id: 'assetFoo',
|
|
|
|
filePath: toProjectPath('/foo.js'),
|
|
|
|
type: 'js',
|
|
|
|
isSource: true,
|
|
|
|
hash: '#1',
|
|
|
|
stats,
|
|
|
|
dependencies: new Map([['./utils', fooUtilsDep]]),
|
|
|
|
env: DEFAULT_ENV,
|
|
|
|
});
|
|
|
|
let fooAssetNode = nodeFromAsset(fooAsset);
|
|
|
|
graph.resolveAssetGroup(fooAssetGroup, [fooAsset], '0');
|
|
|
|
let utilsAssetGroup = {
|
|
|
|
filePath: toProjectPath('/utils.js'),
|
|
|
|
env: DEFAULT_ENV,
|
|
|
|
};
|
|
|
|
let utilsAssetGroupNode = nodeFromAssetGroup(utilsAssetGroup);
|
|
|
|
graph.resolveDependency(fooUtilsDep, utilsAssetGroup, '0');
|
|
|
|
|
|
|
|
// foo's dependency is deferred
|
|
|
|
graph.markParentsWithHasDeferred(
|
|
|
|
graph.getNodeIdByContentKey(fooUtilsDepNode.id),
|
|
|
|
);
|
|
|
|
let node = nullthrows(graph.getNodeByContentKey(fooAssetNode.id));
|
|
|
|
invariant(node.type === 'asset');
|
|
|
|
assert(node.hasDeferred);
|
|
|
|
node = nullthrows(graph.getNodeByContentKey(fooAssetGroupNode.id));
|
|
|
|
invariant(node.type === 'asset_group');
|
|
|
|
assert(node.hasDeferred);
|
|
|
|
|
|
|
|
// index also imports bar
|
|
|
|
let barAssetGroup = {
|
|
|
|
filePath: toProjectPath('/bar.js'),
|
|
|
|
env: DEFAULT_ENV,
|
|
|
|
};
|
|
|
|
graph.resolveDependency(indexBarDep, barAssetGroup, '0');
|
|
|
|
let barAssetGroupNode = nodeFromAssetGroup(barAssetGroup);
|
|
|
|
let barUtilsDep = createDependency({
|
|
|
|
specifier: './utils',
|
|
|
|
specifierType: 'esm',
|
|
|
|
env: DEFAULT_ENV,
|
|
|
|
sourcePath: '/bar.js',
|
|
|
|
});
|
|
|
|
let barAsset = createAsset({
|
|
|
|
id: 'assetBar',
|
|
|
|
filePath: toProjectPath('/bar.js'),
|
|
|
|
type: 'js',
|
|
|
|
isSource: true,
|
|
|
|
hash: '#2',
|
|
|
|
stats,
|
|
|
|
dependencies: new Map([['./utils', barUtilsDep]]),
|
|
|
|
env: DEFAULT_ENV,
|
|
|
|
});
|
|
|
|
let barAssetNode = nodeFromAsset(barAsset);
|
|
|
|
graph.resolveAssetGroup(barAssetGroup, [barAsset], '3');
|
|
|
|
graph.resolveDependency(barUtilsDep, utilsAssetGroup, '4');
|
|
|
|
|
|
|
|
// bar undeferres utils
|
|
|
|
graph.unmarkParentsWithHasDeferred(
|
|
|
|
graph.getNodeIdByContentKey(utilsAssetGroupNode.id),
|
|
|
|
);
|
|
|
|
node = nullthrows(graph.getNodeByContentKey(fooUtilsDep.id));
|
|
|
|
invariant(node.type === 'dependency');
|
|
|
|
assert(!node.hasDeferred);
|
|
|
|
node = nullthrows(graph.getNodeByContentKey(fooAssetNode.id));
|
|
|
|
invariant(node.type === 'asset');
|
|
|
|
assert(!node.hasDeferred);
|
|
|
|
node = nullthrows(graph.getNodeByContentKey(fooAssetGroupNode.id));
|
|
|
|
invariant(node.type === 'asset_group');
|
|
|
|
assert(!node.hasDeferred);
|
|
|
|
node = nullthrows(graph.getNodeByContentKey(barUtilsDep.id));
|
|
|
|
invariant(node.type === 'dependency');
|
|
|
|
assert(!node.hasDeferred);
|
|
|
|
node = nullthrows(graph.getNodeByContentKey(barAssetNode.id));
|
|
|
|
invariant(node.type === 'asset');
|
|
|
|
assert(!node.hasDeferred);
|
|
|
|
node = nullthrows(graph.getNodeByContentKey(barAssetGroupNode.id));
|
|
|
|
invariant(node.type === 'asset_group');
|
|
|
|
assert(!node.hasDeferred);
|
|
|
|
});
|
|
|
|
});
|