mirror of https://github.com/status-im/metro.git
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
556c432260
commit
9aa1215e21
|
@ -8,6 +8,7 @@
|
||||||
*/
|
*/
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
const {EventEmitter} = require('events');
|
||||||
const {dirname} = require.requireActual('path');
|
const {dirname} = require.requireActual('path');
|
||||||
const fs = jest.genMockFromModule('fs');
|
const fs = jest.genMockFromModule('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
@ -96,7 +97,12 @@ fs.readFileSync.mockImplementation(function(filepath, encoding) {
|
||||||
function makeStatResult(node) {
|
function makeStatResult(node) {
|
||||||
const isSymlink = node != null && node.SYMLINK != null;
|
const isSymlink = node != null && node.SYMLINK != null;
|
||||||
return {
|
return {
|
||||||
|
isBlockDevice: () => false,
|
||||||
|
isCharacterDevice: () => false,
|
||||||
isDirectory: () => node != null && typeof node === 'object' && !isSymlink,
|
isDirectory: () => node != null && typeof node === 'object' && !isSymlink,
|
||||||
|
isFIFO: () => false,
|
||||||
|
isFile: () => node != null && typeof node === 'string',
|
||||||
|
isSocket: () => false,
|
||||||
isSymbolicLink: () => isSymlink,
|
isSymbolicLink: () => isSymlink,
|
||||||
mtime,
|
mtime,
|
||||||
};
|
};
|
||||||
|
@ -242,6 +248,34 @@ fs.createWriteStream.mock.returned = [];
|
||||||
|
|
||||||
fs.__setMockFilesystem = object => (filesystem = object);
|
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) {
|
function getToNode(filepath) {
|
||||||
// Ignore the drive for Windows paths.
|
// Ignore the drive for Windows paths.
|
||||||
if (filepath.match(/^[a-zA-Z]:\\/)) {
|
if (filepath.match(/^[a-zA-Z]:\\/)) {
|
||||||
|
|
|
@ -130,7 +130,7 @@ describe('DependencyGraph', function() {
|
||||||
},
|
},
|
||||||
getTransformCacheKey: () => 'abcdef',
|
getTransformCacheKey: () => 'abcdef',
|
||||||
reporter: require('../../lib/reporting').nullReporter,
|
reporter: require('../../lib/reporting').nullReporter,
|
||||||
watch: false,
|
watch: true,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -3111,70 +3111,74 @@ describe('DependencyGraph', function() {
|
||||||
filesystem.root['index.js'] = filesystem.root['index.js']
|
filesystem.root['index.js'] = filesystem.root['index.js']
|
||||||
.replace('require("dontWork")', '')
|
.replace('require("dontWork")', '')
|
||||||
.replace('require("wontWork")', '');
|
.replace('require("wontWork")', '');
|
||||||
dgraph.processFileChange('change', root + '/index.js', mockStat);
|
triggerWatchEvent('change', root + '/index.js');
|
||||||
return getOrderedDependenciesAsJSON(dgraph, '/root/index.js')
|
return new Promise(resolve => {
|
||||||
.then(deps => {
|
dgraph.once('change', () => {
|
||||||
expect(deps).toEqual([
|
return resolve(getOrderedDependenciesAsJSON(dgraph, '/root/index.js')
|
||||||
{
|
.then(deps => {
|
||||||
id: 'index',
|
expect(deps).toEqual([
|
||||||
path: '/root/index.js',
|
{
|
||||||
dependencies: [
|
id: 'index',
|
||||||
'shouldWork',
|
path: '/root/index.js',
|
||||||
'ember',
|
dependencies: [
|
||||||
'internalVendoredPackage',
|
'shouldWork',
|
||||||
'anotherIndex',
|
'ember',
|
||||||
],
|
'internalVendoredPackage',
|
||||||
isAsset: false,
|
'anotherIndex',
|
||||||
isJSON: false,
|
],
|
||||||
isPolyfill: false,
|
isAsset: false,
|
||||||
resolution: undefined,
|
isJSON: false,
|
||||||
},
|
isPolyfill: false,
|
||||||
{
|
resolution: undefined,
|
||||||
id: 'shouldWork',
|
},
|
||||||
path: '/root/node_modules/react-haste/main.js',
|
{
|
||||||
dependencies: ['submodule'],
|
id: 'shouldWork',
|
||||||
isAsset: false,
|
path: '/root/node_modules/react-haste/main.js',
|
||||||
isJSON: false,
|
dependencies: ['submodule'],
|
||||||
isPolyfill: false,
|
isAsset: false,
|
||||||
resolution: undefined,
|
isJSON: false,
|
||||||
},
|
isPolyfill: false,
|
||||||
{
|
resolution: undefined,
|
||||||
id: 'submodule/main.js',
|
},
|
||||||
path: '/root/node_modules/react-haste/node_modules/submodule/main.js',
|
{
|
||||||
dependencies: [],
|
id: 'submodule/main.js',
|
||||||
isAsset: false,
|
path: '/root/node_modules/react-haste/node_modules/submodule/main.js',
|
||||||
isJSON: false,
|
dependencies: [],
|
||||||
isPolyfill: false,
|
isAsset: false,
|
||||||
resolution: undefined,
|
isJSON: false,
|
||||||
},
|
isPolyfill: false,
|
||||||
{
|
resolution: undefined,
|
||||||
id: 'ember/main.js',
|
},
|
||||||
path: '/root/node_modules/ember/main.js',
|
{
|
||||||
dependencies: [],
|
id: 'ember/main.js',
|
||||||
isAsset: false,
|
path: '/root/node_modules/ember/main.js',
|
||||||
isJSON: false,
|
dependencies: [],
|
||||||
isPolyfill: false,
|
isAsset: false,
|
||||||
resolution: undefined,
|
isJSON: false,
|
||||||
},
|
isPolyfill: false,
|
||||||
{
|
resolution: undefined,
|
||||||
id: 'internalVendoredPackage',
|
},
|
||||||
path: '/root/vendored_modules/a-vendored-package/main.js',
|
{
|
||||||
dependencies: [],
|
id: 'internalVendoredPackage',
|
||||||
isAsset: false,
|
path: '/root/vendored_modules/a-vendored-package/main.js',
|
||||||
isJSON: false,
|
dependencies: [],
|
||||||
isPolyfill: false,
|
isAsset: false,
|
||||||
resolution: undefined,
|
isJSON: false,
|
||||||
},
|
isPolyfill: false,
|
||||||
{
|
resolution: undefined,
|
||||||
id: 'anotherIndex',
|
},
|
||||||
path: '/anotherRoot/index.js',
|
{
|
||||||
dependencies: [],
|
id: 'anotherIndex',
|
||||||
isAsset: false,
|
path: '/anotherRoot/index.js',
|
||||||
isJSON: false,
|
dependencies: [],
|
||||||
isPolyfill: false,
|
isAsset: false,
|
||||||
resolution: undefined,
|
isJSON: false,
|
||||||
},
|
isPolyfill: false,
|
||||||
]);
|
resolution: undefined,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
}));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -5455,4 +5459,8 @@ describe('DependencyGraph', function() {
|
||||||
function setMockFileSystem(object) {
|
function setMockFileSystem(object) {
|
||||||
return require('graceful-fs').__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,
|
createActionStartEntry,
|
||||||
log,
|
log,
|
||||||
} = require('../Logger');
|
} = require('../Logger');
|
||||||
|
const {EventEmitter} = require('events');
|
||||||
|
|
||||||
import type {Options as TransformOptions} from '../JSTransformer/worker/worker';
|
import type {Options as TransformOptions} from '../JSTransformer/worker/worker';
|
||||||
import type GlobalTransformCache from '../lib/GlobalTransformCache';
|
import type GlobalTransformCache from '../lib/GlobalTransformCache';
|
||||||
|
@ -72,7 +73,7 @@ type Options = {
|
||||||
watch: boolean,
|
watch: boolean,
|
||||||
};
|
};
|
||||||
|
|
||||||
class DependencyGraph {
|
class DependencyGraph extends EventEmitter {
|
||||||
_opts: Options;
|
_opts: Options;
|
||||||
_haste: JestHasteMap;
|
_haste: JestHasteMap;
|
||||||
_hasteFS: HasteFS;
|
_hasteFS: HasteFS;
|
||||||
|
@ -84,6 +85,7 @@ class DependencyGraph {
|
||||||
_loading: Promise<void>;
|
_loading: Promise<void>;
|
||||||
|
|
||||||
constructor(opts: Options) {
|
constructor(opts: Options) {
|
||||||
|
super();
|
||||||
this._opts = {...opts};
|
this._opts = {...opts};
|
||||||
this._helpers = new DependencyGraphHelpers(this._opts);
|
this._helpers = new DependencyGraphHelpers(this._opts);
|
||||||
this.load();
|
this.load();
|
||||||
|
@ -154,6 +156,7 @@ class DependencyGraph {
|
||||||
eventsQueue.forEach(({type, filePath, stat}) =>
|
eventsQueue.forEach(({type, filePath, stat}) =>
|
||||||
this.processFileChange(type, filePath, stat)
|
this.processFileChange(type, filePath, stat)
|
||||||
);
|
);
|
||||||
|
this.emit('change');
|
||||||
});
|
});
|
||||||
|
|
||||||
const buildingHasteMapLogEntry =
|
const buildingHasteMapLogEntry =
|
||||||
|
|
Loading…
Reference in New Issue