Use current DependencyGraph tests as integration tests for the traverseDependency logic

Reviewed By: davidaurelio

Differential Revision: D6284627

fbshipit-source-id: 7e3f21c53142238f7d50444627c417388a4c1d1d
This commit is contained in:
Rafael Oleza 2017-11-13 16:23:54 -08:00 committed by Facebook Github Bot
parent f1728e4c7b
commit 860dcc4867
4 changed files with 181 additions and 132 deletions

View File

@ -0,0 +1,105 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`traverseDependencies Progress updates increases the number of discover/finished modules in steps of one 1`] = `
Array [
Array [
0,
1,
],
Array [
0,
2,
],
Array [
0,
3,
],
Array [
0,
4,
],
Array [
0,
5,
],
Array [
0,
6,
],
Array [
0,
7,
],
Array [
1,
7,
],
Array [
2,
7,
],
Array [
3,
7,
],
Array [
3,
8,
],
Array [
4,
8,
],
Array [
5,
8,
],
Array [
6,
8,
],
Array [
7,
8,
],
Array [
8,
8,
],
]
`;
exports[`traverseDependencies file watch updating should recover from multiple modules with the same name 1`] = `
Array [
Object {
"dependencies": Array [
"a",
"b",
],
"id": "index",
"isAsset": false,
"isJSON": false,
"isPolyfill": false,
"path": "/root/index.js",
"resolution": undefined,
},
Object {
"dependencies": Array [],
"id": "a",
"isAsset": false,
"isJSON": false,
"isPolyfill": false,
"path": "/root/a.js",
"resolution": undefined,
},
Object {
"dependencies": Array [],
"id": "b",
"isAsset": false,
"isJSON": false,
"isPolyfill": false,
"path": "/root/b.js",
"resolution": undefined,
},
]
`;

View File

@ -47,50 +47,55 @@ beforeEach(() => {
jest.mock('path', () => require.requireActual('path')); jest.mock('path', () => require.requireActual('path'));
}); });
describe('DependencyGraph', function() { describe('traverseDependencies', function() {
let Module; let Module;
let ResolutionRequest; let traverseDependencies;
let defaults; let defaults;
let emptyTransformOptions; let emptyTransformOptions;
function getOrderedDependenciesAsJSON( async function getOrderedDependenciesAsJSON(
dgraphPromise, dgraphPromise,
entryPath, entryPath,
platform, platform,
recursive = true, recursive = true,
) { ) {
return Promise.resolve(dgraphPromise) const dgraph = await dgraphPromise;
.then(dgraph =>
dgraph.getDependencies({ const edges = new Map();
entryPath, const {added} = await traverseDependencies.initialTraverseDependencies(
options: emptyTransformOptions, entryPath,
platform, dgraph,
recursive, {...emptyTransformOptions, platform},
}), edges,
) );
.then(response => response.finalize())
.then(({dependencies}) => const dependencies = recursive
Promise.all( ? added
dependencies.map(dep => : edges.get(entryPath).dependencies.values();
dep.getDependencies().then(moduleDependencies => ({
path: dep.path, return await Promise.all(
isJSON: dep.isJSON(), [entryPath, ...dependencies].map(async path => {
isAsset: dep.isAsset(), const dep = dgraph.getModuleForPath(path);
isPolyfill: dep.isPolyfill(), const moduleDependencies = await dep.getDependencies();
resolution: dep.resolution,
id: dep.getName(), return {
dependencies: moduleDependencies, path: dep.path,
})), isJSON: dep.isJSON(),
), isAsset: dep.isAsset(),
), isPolyfill: dep.isPolyfill(),
); resolution: dep.resolution,
id: dep.getName(),
dependencies: moduleDependencies,
};
}),
);
} }
beforeEach(function() { beforeEach(function() {
jest.resetModules(); jest.resetModules();
Module = require('../Module'); Module = require('../../node-haste/Module');
ResolutionRequest = require('../DependencyGraph/ResolutionRequest'); traverseDependencies = require('../traverseDependencies');
emptyTransformOptions = {transformer: {transform: {}}}; emptyTransformOptions = {transformer: {transform: {}}};
defaults = { defaults = {
@ -132,7 +137,7 @@ describe('DependencyGraph', function() {
const realPlatform = process.platform; const realPlatform = process.platform;
beforeEach(function() { beforeEach(function() {
process.platform = 'linux'; process.platform = 'linux';
DependencyGraph = require('../DependencyGraph'); DependencyGraph = require('../../node-haste/DependencyGraph');
processDgraph = processDgraphFor.bind(null, DependencyGraph); processDgraph = processDgraphFor.bind(null, DependencyGraph);
}); });
@ -199,31 +204,6 @@ describe('DependencyGraph', function() {
}); });
}); });
it('should resolve relative entry path', async () => {
var root = '/root';
setMockFileSystem({
root: {
'index.js': ['/**', ' * @providesModule index', ' */'].join('\n'),
},
});
const opts = {...defaults, roots: [root]};
await processDgraph(opts, async dgraph => {
const deps = await getOrderedDependenciesAsJSON(dgraph, 'index.js');
expect(deps).toEqual([
{
id: 'index',
path: '/root/index.js',
dependencies: [],
isAsset: false,
isJSON: false,
isPolyfill: false,
resolution: undefined,
},
]);
});
});
it('should get shallow dependencies', async function() { it('should get shallow dependencies', async function() {
var root = '/root'; var root = '/root';
setMockFileSystem({ setMockFileSystem({
@ -1947,7 +1927,7 @@ describe('DependencyGraph', function() {
it( it(
'should support browser exclude of a package ("' + fieldName + '")', 'should support browser exclude of a package ("' + fieldName + '")',
async () => { async () => {
require('../DependencyGraph/ModuleResolution').ModuleResolver.EMPTY_MODULE = require('../../node-haste/DependencyGraph/ModuleResolution').ModuleResolver.EMPTY_MODULE =
'/root/emptyModule.js'; '/root/emptyModule.js';
var root = '/root'; var root = '/root';
setMockFileSystem({ setMockFileSystem({
@ -2024,7 +2004,7 @@ describe('DependencyGraph', function() {
it( it(
'should support browser exclude of a file ("' + fieldName + '")', 'should support browser exclude of a file ("' + fieldName + '")',
async () => { async () => {
require('../DependencyGraph/ModuleResolution').ModuleResolver.EMPTY_MODULE = require('../../node-haste/DependencyGraph/ModuleResolution').ModuleResolver.EMPTY_MODULE =
'/root/emptyModule.js'; '/root/emptyModule.js';
var root = '/root'; var root = '/root';
@ -2531,7 +2511,7 @@ describe('DependencyGraph', function() {
// reload path module // reload path module
jest.resetModules(); jest.resetModules();
jest.mock('path', () => require.requireActual('path').win32); jest.mock('path', () => require.requireActual('path').win32);
DependencyGraph = require('../DependencyGraph'); DependencyGraph = require('../../node-haste/DependencyGraph');
processDgraph = processDgraphFor.bind(null, DependencyGraph); processDgraph = processDgraphFor.bind(null, DependencyGraph);
}); });
@ -2714,7 +2694,7 @@ describe('DependencyGraph', function() {
beforeEach(function() { beforeEach(function() {
process.platform = 'linux'; process.platform = 'linux';
DependencyGraph = require('../DependencyGraph'); DependencyGraph = require('../../node-haste/DependencyGraph');
processDgraph = processDgraphFor.bind(null, DependencyGraph); processDgraph = processDgraphFor.bind(null, DependencyGraph);
}); });
@ -2842,6 +2822,7 @@ describe('DependencyGraph', function() {
const deps = await getOrderedDependenciesAsJSON( const deps = await getOrderedDependenciesAsJSON(
dgraph, dgraph,
'/root/index.ios.js', '/root/index.ios.js',
'ios',
); );
expect(deps).toEqual([ expect(deps).toEqual([
{ {
@ -3438,6 +3419,7 @@ describe('DependencyGraph', function() {
const deps = await getOrderedDependenciesAsJSON( const deps = await getOrderedDependenciesAsJSON(
dgraph, dgraph,
'/root/index.ios.js', '/root/index.ios.js',
'ios',
); );
expect(deps).toEqual([ expect(deps).toEqual([
{ {
@ -3544,6 +3526,7 @@ describe('DependencyGraph', function() {
const deps = await getOrderedDependenciesAsJSON( const deps = await getOrderedDependenciesAsJSON(
dgraph, dgraph,
'/root/index.ios.js', '/root/index.ios.js',
'ios',
); );
expect(deps).toEqual([ expect(deps).toEqual([
{ {
@ -3697,7 +3680,7 @@ describe('DependencyGraph', function() {
// reload path module // reload path module
jest.resetModules(); jest.resetModules();
jest.mock('path', () => require.requireActual('path').win32); jest.mock('path', () => require.requireActual('path').win32);
DependencyGraph = require('../DependencyGraph'); DependencyGraph = require('../../node-haste/DependencyGraph');
processDgraph = processDgraphFor.bind(null, DependencyGraph); processDgraph = processDgraphFor.bind(null, DependencyGraph);
}); });
@ -3825,6 +3808,7 @@ describe('DependencyGraph', function() {
const deps = await getOrderedDependenciesAsJSON( const deps = await getOrderedDependenciesAsJSON(
dgraph, dgraph,
'C:\\root\\index.ios.js', 'C:\\root\\index.ios.js',
'ios',
); );
expect(deps).toEqual([ expect(deps).toEqual([
{ {
@ -4420,6 +4404,7 @@ describe('DependencyGraph', function() {
const deps = await getOrderedDependenciesAsJSON( const deps = await getOrderedDependenciesAsJSON(
dgraph, dgraph,
'C:\\root\\index.ios.js', 'C:\\root\\index.ios.js',
'ios',
); );
expect(deps).toEqual([ expect(deps).toEqual([
{ {
@ -4522,6 +4507,7 @@ describe('DependencyGraph', function() {
const deps = await getOrderedDependenciesAsJSON( const deps = await getOrderedDependenciesAsJSON(
dgraph, dgraph,
'C:\\root\\index.ios.js', 'C:\\root\\index.ios.js',
'ios',
); );
expect(deps).toEqual([ expect(deps).toEqual([
{ {
@ -4630,7 +4616,7 @@ describe('DependencyGraph', function() {
beforeEach(function() { beforeEach(function() {
process.platform = 'linux'; process.platform = 'linux';
DependencyGraph = require('../DependencyGraph'); DependencyGraph = require('../../node-haste/DependencyGraph');
processDgraph = processDgraphFor.bind(null, DependencyGraph); processDgraph = processDgraphFor.bind(null, DependencyGraph);
}); });
@ -5296,7 +5282,7 @@ describe('DependencyGraph', function() {
} catch (error) { } catch (error) {
const { const {
AmbiguousModuleResolutionError, AmbiguousModuleResolutionError,
} = require('../DependencyGraph/ResolutionRequest'); } = require('../../node-haste/DependencyGraph/ResolutionRequest');
if (!(error instanceof AmbiguousModuleResolutionError)) { if (!(error instanceof AmbiguousModuleResolutionError)) {
throw error; throw error;
} }
@ -5319,7 +5305,7 @@ describe('DependencyGraph', function() {
beforeEach(function() { beforeEach(function() {
process.platform = 'linux'; process.platform = 'linux';
DependencyGraph = require('../DependencyGraph'); DependencyGraph = require('../../node-haste/DependencyGraph');
processDgraph = processDgraphFor.bind(null, DependencyGraph); processDgraph = processDgraphFor.bind(null, DependencyGraph);
}); });
@ -5344,8 +5330,6 @@ describe('DependencyGraph', function() {
const opts = {...defaults, roots: [root], sourceExts: ['jsx', 'coffee']}; const opts = {...defaults, roots: [root], sourceExts: ['jsx', 'coffee']};
await processDgraph(opts, async dgraph => { await processDgraph(opts, async dgraph => {
const files = await dgraph.matchFilesByPattern('.*');
expect(files).toEqual(['/root/index.jsx', '/root/a.coffee']);
const entryPath = '/root/index.jsx'; const entryPath = '/root/index.jsx';
const deps = await getOrderedDependenciesAsJSON(dgraph, entryPath); const deps = await getOrderedDependenciesAsJSON(dgraph, entryPath);
expect(deps).toEqual([ expect(deps).toEqual([
@ -5383,8 +5367,6 @@ describe('DependencyGraph', function() {
const opts = {...defaults, roots: [root], sourceExts: ['jsx', 'coffee']}; const opts = {...defaults, roots: [root], sourceExts: ['jsx', 'coffee']};
await processDgraph(opts, async dgraph => { await processDgraph(opts, async dgraph => {
const files = await dgraph.matchFilesByPattern('.*');
expect(files).toEqual(['/root/index.jsx', '/root/a.coffee']);
const deps = await getOrderedDependenciesAsJSON( const deps = await getOrderedDependenciesAsJSON(
dgraph, dgraph,
'/root/index.jsx', '/root/index.jsx',
@ -5424,8 +5406,6 @@ describe('DependencyGraph', function() {
const opts = {...defaults, roots: [root]}; const opts = {...defaults, roots: [root]};
await processDgraph(opts, async dgraph => { await processDgraph(opts, async dgraph => {
const files = await dgraph.matchFilesByPattern('.*');
expect(files).toEqual(['/root/X.js']);
try { try {
await getOrderedDependenciesAsJSON(dgraph, '/root/index.jsx'); await getOrderedDependenciesAsJSON(dgraph, '/root/index.jsx');
throw Error('should be unreachable'); throw Error('should be unreachable');
@ -5450,11 +5430,13 @@ describe('DependencyGraph', function() {
} }
function getDependencies() { function getDependencies() {
return dependencyGraph.getDependencies({ return traverseDependencies.initialTraverseDependencies(
entryPath: '/root/index.js', '/root/index.js',
dependencyGraph,
emptyTransformOptions,
new Map(),
onProgress, onProgress,
options: emptyTransformOptions, );
});
} }
beforeEach(function() { beforeEach(function() {
@ -5471,7 +5453,7 @@ describe('DependencyGraph', function() {
'g.js': makeModule('g'), 'g.js': makeModule('g'),
}, },
}); });
const DependencyGraph = require('../DependencyGraph'); const DependencyGraph = require('../../node-haste/DependencyGraph');
return DependencyGraph.load({ return DependencyGraph.load({
...defaults, ...defaults,
roots: ['/root'], roots: ['/root'],
@ -5484,24 +5466,18 @@ describe('DependencyGraph', function() {
dependencyGraph.end(); dependencyGraph.end();
}); });
it('calls back for each finished module', () => { it('calls back for each finished module', async () => {
return getDependencies().then(() => await getDependencies();
expect(onProgress.mock.calls.length).toBe(8),
); // We get a progress change twice per dependency
// (when we discover it and when we process it).
expect(onProgress.mock.calls.length).toBe(8 * 2);
}); });
it('increases the number of finished modules in steps of one', () => { it('increases the number of discover/finished modules in steps of one', async () => {
return getDependencies().then(() => { await getDependencies();
const increments = onProgress.mock.calls.map(([finished]) => finished);
expect(increments).toEqual([1, 2, 3, 4, 5, 6, 7, 8]);
});
});
it('adds the number of discovered modules to the number of total modules', () => { expect(onProgress.mock.calls).toMatchSnapshot();
return getDependencies().then(() => {
const increments = onProgress.mock.calls.map(([, total]) => total);
expect(increments).toEqual([3, 5, 6, 6, 7, 7, 8, 8]);
});
}); });
}); });
@ -5510,7 +5486,7 @@ describe('DependencyGraph', function() {
let processDgraph; let processDgraph;
beforeEach(() => { beforeEach(() => {
DependencyGraph = require('../DependencyGraph'); DependencyGraph = require('../../node-haste/DependencyGraph');
processDgraph = processDgraphFor.bind(null, DependencyGraph); processDgraph = processDgraphFor.bind(null, DependencyGraph);
}); });
@ -5548,7 +5524,7 @@ describe('DependencyGraph', function() {
beforeEach(() => { beforeEach(() => {
moduleRead = Module.prototype.read; moduleRead = Module.prototype.read;
DependencyGraph = require('../DependencyGraph'); DependencyGraph = require('../../node-haste/DependencyGraph');
setMockFileSystem({ setMockFileSystem({
root: { root: {
'index.js': ` 'index.js': `
@ -5600,7 +5576,7 @@ describe('DependencyGraph', function() {
it('produces a deterministic tree if the "a" module resolves first', () => { it('produces a deterministic tree if the "a" module resolves first', () => {
const dependenciesPromise = getOrderedDependenciesAsJSON( const dependenciesPromise = getOrderedDependenciesAsJSON(
dependencyGraph, dependencyGraph,
'index.js', '/root/index.js',
); );
return Promise.all(callDeferreds.map(deferred => deferred.promise)) return Promise.all(callDeferreds.map(deferred => deferred.promise))
@ -5631,7 +5607,7 @@ describe('DependencyGraph', function() {
it('produces a deterministic tree if the "b" module resolves first', () => { it('produces a deterministic tree if the "b" module resolves first', () => {
const dependenciesPromise = getOrderedDependenciesAsJSON( const dependenciesPromise = getOrderedDependenciesAsJSON(
dependencyGraph, dependencyGraph,
'index.js', '/root/index.js',
); );
return Promise.all(callDeferreds.map(deferred => deferred.promise)) return Promise.all(callDeferreds.map(deferred => deferred.promise))
@ -5674,7 +5650,7 @@ describe('DependencyGraph', function() {
}, },
}); });
DependencyGraph = require('../DependencyGraph'); DependencyGraph = require('../../node-haste/DependencyGraph');
dependencyGraph = await DependencyGraph.load({ dependencyGraph = await DependencyGraph.load({
...defaults, ...defaults,
roots: ['/root'], roots: ['/root'],

View File

@ -122,7 +122,8 @@ async function traverseDependenciesForSingleFile(
const nonNullEdge = edge; const nonNullEdge = edge;
let numProcessed = 0; let numProcessed = 0;
let total = currentDependencies.size; let total = 1;
onProgress(numProcessed, total);
const deleted = Array.from(edge.dependencies.entries()) const deleted = Array.from(edge.dependencies.entries())
.map(([relativePath, absolutePath]) => { .map(([relativePath, absolutePath]) => {
@ -163,6 +164,9 @@ async function traverseDependenciesForSingleFile(
}), }),
); );
numProcessed++;
onProgress(numProcessed, total);
return { return {
added: flatten(reorderDependencies(added, edges)), added: flatten(reorderDependencies(added, edges)),
deleted: flatten(deleted), deleted: flatten(deleted),

View File

@ -1,36 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`DependencyGraph file watch updating should recover from multiple modules with the same name 1`] = `
Array [
Object {
"dependencies": Array [
"a",
"b",
],
"id": "index",
"isAsset": false,
"isJSON": false,
"isPolyfill": false,
"path": "/root/index.js",
"resolution": undefined,
},
Object {
"dependencies": Array [],
"id": "a",
"isAsset": false,
"isJSON": false,
"isPolyfill": false,
"path": "/root/a.js",
"resolution": undefined,
},
Object {
"dependencies": Array [],
"id": "b",
"isAsset": false,
"isJSON": false,
"isPolyfill": false,
"path": "/root/b.js",
"resolution": undefined,
},
]
`;