packager: DependencyGraph-test: go through fs.watch mock rather than manual API
Reviewed By: davidaurelio Differential Revision: D4628593 fbshipit-source-id: 43ccdb038bd387e87096f2a7020c98d915fa5bba
This commit is contained in:
parent
e44730cb63
commit
04f42ab075
|
@ -8,6 +8,7 @@
|
|||
*/
|
||||
'use strict';
|
||||
|
||||
const {EventEmitter} = require('events');
|
||||
const {dirname} = require.requireActual('path');
|
||||
const fs = jest.genMockFromModule('fs');
|
||||
const path = require('path');
|
||||
|
@ -96,7 +97,12 @@ fs.readFileSync.mockImplementation(function(filepath, encoding) {
|
|||
function makeStatResult(node) {
|
||||
const isSymlink = node != null && node.SYMLINK != null;
|
||||
return {
|
||||
isBlockDevice: () => false,
|
||||
isCharacterDevice: () => false,
|
||||
isDirectory: () => node != null && typeof node === 'object' && !isSymlink,
|
||||
isFIFO: () => false,
|
||||
isFile: () => node != null && typeof node === 'string',
|
||||
isSocket: () => false,
|
||||
isSymbolicLink: () => isSymlink,
|
||||
mtime,
|
||||
};
|
||||
|
@ -242,6 +248,34 @@ fs.createWriteStream.mock.returned = [];
|
|||
|
||||
fs.__setMockFilesystem = object => (filesystem = object);
|
||||
|
||||
const watcherListByPath = new Map();
|
||||
|
||||
fs.watch.mockImplementation((filename, options, listener) => {
|
||||
if (options.recursive) {
|
||||
throw new Error('recursive watch not implemented');
|
||||
}
|
||||
let watcherList = watcherListByPath.get(filename);
|
||||
if (watcherList == null) {
|
||||
watcherList = [];
|
||||
watcherListByPath.set(filename, watcherList);
|
||||
}
|
||||
const fsWatcher = new EventEmitter();
|
||||
fsWatcher.on('change', listener);
|
||||
fsWatcher.close = () => {
|
||||
watcherList.splice(watcherList.indexOf(fsWatcher), 1);
|
||||
fsWatcher.close = () => { throw new Error('FSWatcher is already closed'); };
|
||||
};
|
||||
watcherList.push(fsWatcher);
|
||||
});
|
||||
|
||||
fs.__triggerWatchEvent = (eventType, filename) => {
|
||||
const directWatchers = watcherListByPath.get(filename) || [];
|
||||
directWatchers.forEach(wtc => wtc.emit('change', eventType));
|
||||
const dirPath = path.dirname(filename);
|
||||
const dirWatchers = watcherListByPath.get(dirPath) || [];
|
||||
dirWatchers.forEach(wtc => wtc.emit('change', eventType, path.relative(dirPath, filename)));
|
||||
};
|
||||
|
||||
function getToNode(filepath) {
|
||||
// Ignore the drive for Windows paths.
|
||||
if (filepath.match(/^[a-zA-Z]:\\/)) {
|
||||
|
|
|
@ -130,7 +130,7 @@ describe('DependencyGraph', function() {
|
|||
},
|
||||
getTransformCacheKey: () => 'abcdef',
|
||||
reporter: require('../../lib/reporting').nullReporter,
|
||||
watch: false,
|
||||
watch: true,
|
||||
};
|
||||
});
|
||||
|
||||
|
@ -3111,70 +3111,74 @@ describe('DependencyGraph', function() {
|
|||
filesystem.root['index.js'] = filesystem.root['index.js']
|
||||
.replace('require("dontWork")', '')
|
||||
.replace('require("wontWork")', '');
|
||||
dgraph.processFileChange('change', root + '/index.js', mockStat);
|
||||
return getOrderedDependenciesAsJSON(dgraph, '/root/index.js')
|
||||
.then(deps => {
|
||||
expect(deps).toEqual([
|
||||
{
|
||||
id: 'index',
|
||||
path: '/root/index.js',
|
||||
dependencies: [
|
||||
'shouldWork',
|
||||
'ember',
|
||||
'internalVendoredPackage',
|
||||
'anotherIndex',
|
||||
],
|
||||
isAsset: false,
|
||||
isJSON: false,
|
||||
isPolyfill: false,
|
||||
resolution: undefined,
|
||||
},
|
||||
{
|
||||
id: 'shouldWork',
|
||||
path: '/root/node_modules/react-haste/main.js',
|
||||
dependencies: ['submodule'],
|
||||
isAsset: false,
|
||||
isJSON: false,
|
||||
isPolyfill: false,
|
||||
resolution: undefined,
|
||||
},
|
||||
{
|
||||
id: 'submodule/main.js',
|
||||
path: '/root/node_modules/react-haste/node_modules/submodule/main.js',
|
||||
dependencies: [],
|
||||
isAsset: false,
|
||||
isJSON: false,
|
||||
isPolyfill: false,
|
||||
resolution: undefined,
|
||||
},
|
||||
{
|
||||
id: 'ember/main.js',
|
||||
path: '/root/node_modules/ember/main.js',
|
||||
dependencies: [],
|
||||
isAsset: false,
|
||||
isJSON: false,
|
||||
isPolyfill: false,
|
||||
resolution: undefined,
|
||||
},
|
||||
{
|
||||
id: 'internalVendoredPackage',
|
||||
path: '/root/vendored_modules/a-vendored-package/main.js',
|
||||
dependencies: [],
|
||||
isAsset: false,
|
||||
isJSON: false,
|
||||
isPolyfill: false,
|
||||
resolution: undefined,
|
||||
},
|
||||
{
|
||||
id: 'anotherIndex',
|
||||
path: '/anotherRoot/index.js',
|
||||
dependencies: [],
|
||||
isAsset: false,
|
||||
isJSON: false,
|
||||
isPolyfill: false,
|
||||
resolution: undefined,
|
||||
},
|
||||
]);
|
||||
triggerWatchEvent('change', root + '/index.js');
|
||||
return new Promise(resolve => {
|
||||
dgraph.once('change', () => {
|
||||
return resolve(getOrderedDependenciesAsJSON(dgraph, '/root/index.js')
|
||||
.then(deps => {
|
||||
expect(deps).toEqual([
|
||||
{
|
||||
id: 'index',
|
||||
path: '/root/index.js',
|
||||
dependencies: [
|
||||
'shouldWork',
|
||||
'ember',
|
||||
'internalVendoredPackage',
|
||||
'anotherIndex',
|
||||
],
|
||||
isAsset: false,
|
||||
isJSON: false,
|
||||
isPolyfill: false,
|
||||
resolution: undefined,
|
||||
},
|
||||
{
|
||||
id: 'shouldWork',
|
||||
path: '/root/node_modules/react-haste/main.js',
|
||||
dependencies: ['submodule'],
|
||||
isAsset: false,
|
||||
isJSON: false,
|
||||
isPolyfill: false,
|
||||
resolution: undefined,
|
||||
},
|
||||
{
|
||||
id: 'submodule/main.js',
|
||||
path: '/root/node_modules/react-haste/node_modules/submodule/main.js',
|
||||
dependencies: [],
|
||||
isAsset: false,
|
||||
isJSON: false,
|
||||
isPolyfill: false,
|
||||
resolution: undefined,
|
||||
},
|
||||
{
|
||||
id: 'ember/main.js',
|
||||
path: '/root/node_modules/ember/main.js',
|
||||
dependencies: [],
|
||||
isAsset: false,
|
||||
isJSON: false,
|
||||
isPolyfill: false,
|
||||
resolution: undefined,
|
||||
},
|
||||
{
|
||||
id: 'internalVendoredPackage',
|
||||
path: '/root/vendored_modules/a-vendored-package/main.js',
|
||||
dependencies: [],
|
||||
isAsset: false,
|
||||
isJSON: false,
|
||||
isPolyfill: false,
|
||||
resolution: undefined,
|
||||
},
|
||||
{
|
||||
id: 'anotherIndex',
|
||||
path: '/anotherRoot/index.js',
|
||||
dependencies: [],
|
||||
isAsset: false,
|
||||
isJSON: false,
|
||||
isPolyfill: false,
|
||||
resolution: undefined,
|
||||
},
|
||||
]);
|
||||
}));
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -5455,4 +5459,8 @@ describe('DependencyGraph', function() {
|
|||
function setMockFileSystem(object) {
|
||||
return require('graceful-fs').__setMockFilesystem(object);
|
||||
}
|
||||
|
||||
function triggerWatchEvent(eventType, filename) {
|
||||
return require('graceful-fs').__triggerWatchEvent(eventType, filename);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -36,6 +36,7 @@ const {
|
|||
createActionStartEntry,
|
||||
log,
|
||||
} = require('../Logger');
|
||||
const {EventEmitter} = require('events');
|
||||
|
||||
import type {Options as TransformOptions} from '../JSTransformer/worker/worker';
|
||||
import type GlobalTransformCache from '../lib/GlobalTransformCache';
|
||||
|
@ -72,7 +73,7 @@ type Options = {
|
|||
watch: boolean,
|
||||
};
|
||||
|
||||
class DependencyGraph {
|
||||
class DependencyGraph extends EventEmitter {
|
||||
_opts: Options;
|
||||
_haste: JestHasteMap;
|
||||
_hasteFS: HasteFS;
|
||||
|
@ -84,6 +85,7 @@ class DependencyGraph {
|
|||
_loading: Promise<void>;
|
||||
|
||||
constructor(opts: Options) {
|
||||
super();
|
||||
this._opts = {...opts};
|
||||
this._helpers = new DependencyGraphHelpers(this._opts);
|
||||
this.load();
|
||||
|
@ -154,6 +156,7 @@ class DependencyGraph {
|
|||
eventsQueue.forEach(({type, filePath, stat}) =>
|
||||
this.processFileChange(type, filePath, stat)
|
||||
);
|
||||
this.emit('change');
|
||||
});
|
||||
|
||||
const buildingHasteMapLogEntry =
|
||||
|
|
Loading…
Reference in New Issue