Fix issue in the delta bundler when both a file and one of its dependencies have been deleted

Reviewed By: mjesun

Differential Revision: D8037251

fbshipit-source-id: 3b9f2153ad1f21bbd2e35d9b31c84e276543efae
This commit is contained in:
Rafael Oleza 2018-05-17 08:35:59 -07:00 committed by Facebook Github Bot
parent 814182edb1
commit 68807f0a56
2 changed files with 49 additions and 2 deletions

View File

@ -203,7 +203,13 @@ class DeltaCalculator<T> extends EventEmitter {
const module = this._graph.dependencies.get(filePath); const module = this._graph.dependencies.get(filePath);
if (module) { if (module) {
module.inverseDependencies.forEach(path => modifiedFiles.add(path)); module.inverseDependencies.forEach(path => {
// Only mark the inverse dependency as modified if it's not already
// marked as deleted (in that case we can just ignore it).
if (!deletedFiles.has(path)) {
modifiedFiles.add(path);
}
});
} }
}); });

View File

@ -27,6 +27,7 @@ describe('DeltaCalculator', () => {
let fooModule; let fooModule;
let barModule; let barModule;
let bazModule; let bazModule;
let quxModule;
let deltaCalculator; let deltaCalculator;
let fileWatcher; let fileWatcher;
@ -69,7 +70,7 @@ describe('DeltaCalculator', () => {
path: '/bundle', path: '/bundle',
}; };
fooModule = { fooModule = {
dependencies: new Map(), dependencies: new Map([['qux', '/qux']]),
inverseDependencies: ['/bundle'], inverseDependencies: ['/bundle'],
output: { output: {
name: 'foo', name: 'foo',
@ -92,11 +93,20 @@ describe('DeltaCalculator', () => {
}, },
path: '/baz', path: '/baz',
}; };
quxModule = {
dependencies: new Map(),
inverseDependencies: ['/foo'],
output: {
name: 'qux',
},
path: '/qux',
};
graph.dependencies.set('/bundle', entryModule); graph.dependencies.set('/bundle', entryModule);
graph.dependencies.set('/foo', fooModule); graph.dependencies.set('/foo', fooModule);
graph.dependencies.set('/bar', barModule); graph.dependencies.set('/bar', barModule);
graph.dependencies.set('/baz', bazModule); graph.dependencies.set('/baz', bazModule);
graph.dependencies.set('/qux', quxModule);
return { return {
added: new Map([ added: new Map([
@ -104,6 +114,7 @@ describe('DeltaCalculator', () => {
['/foo', fooModule], ['/foo', fooModule],
['/bar', barModule], ['/bar', barModule],
['/baz', bazModule], ['/baz', bazModule],
['/qux', quxModule],
]), ]),
deleted: new Set(), deleted: new Set(),
}; };
@ -142,6 +153,7 @@ describe('DeltaCalculator', () => {
['/foo', fooModule], ['/foo', fooModule],
['/bar', barModule], ['/bar', barModule],
['/baz', bazModule], ['/baz', bazModule],
['/qux', quxModule],
]), ]),
deleted: new Set(), deleted: new Set(),
reset: true, reset: true,
@ -173,6 +185,7 @@ describe('DeltaCalculator', () => {
['/foo', fooModule], ['/foo', fooModule],
['/bar', barModule], ['/bar', barModule],
['/baz', bazModule], ['/baz', bazModule],
['/qux', quxModule],
]), ]),
deleted: new Set(), deleted: new Set(),
reset: true, reset: true,
@ -326,6 +339,34 @@ describe('DeltaCalculator', () => {
expect(traverseDependencies.mock.calls[0][0]).toEqual(['/bundle']); expect(traverseDependencies.mock.calls[0][0]).toEqual(['/bundle']);
}); });
it('does not traverse a file after deleting it and one of its dependencies', async () => {
await deltaCalculator.getDelta({reset: false});
// Delete a file
fileWatcher.emit('change', {
eventsQueue: [{type: 'delete', filePath: '/foo'}],
});
// Delete a dependency of the deleted file
fileWatcher.emit('change', {
eventsQueue: [{type: 'delete', filePath: '/qux'}],
});
traverseDependencies.mockReturnValue(
Promise.resolve({
added: new Map([['/bundle', entryModule]]),
deleted: new Set(['/foo']),
}),
);
await deltaCalculator.getDelta({reset: false});
// Only the /bundle module should have been traversed (since it's an
// inverse dependency of /foo).
expect(traverseDependencies).toHaveBeenCalledTimes(1);
expect(traverseDependencies.mock.calls[0][0]).toEqual(['/bundle']);
});
it('should not do unnecessary work when adding a file after deleting it', async () => { it('should not do unnecessary work when adding a file after deleting it', async () => {
await deltaCalculator.getDelta({reset: false}); await deltaCalculator.getDelta({reset: false});