From 275af0c52d686138c4b7899ce8e3bb225cecdd82 Mon Sep 17 00:00:00 2001 From: cpojer Date: Mon, 18 Apr 2016 12:11:57 +0900 Subject: [PATCH] Use workers to parse files and extract dependencies properly. --- packages/jest-haste-map/src/index.js | 131 ++++++++++-------- packages/jest-haste-map/src/lib/docblock.js | 51 ++----- .../jest-haste-map/src/lib/extractRequires.js | 52 +++---- packages/jest-haste-map/src/worker.js | 71 ++++++++++ .../__tests__/Runtime-NODE_PATH-test.js | 5 +- .../Runtime-genMockFromModule-test.js | 5 +- .../__tests__/Runtime-getTestEnvData-test.js | 5 +- src/Runtime/__tests__/Runtime-jest-fn.js | 5 +- .../__tests__/Runtime-jsdom-env-test.js | 5 +- src/Runtime/__tests__/Runtime-mock-test.js | 5 +- .../__tests__/Runtime-requireMock-test.js | 5 +- .../__tests__/Runtime-requireModule-test.js | 5 +- .../Runtime-requireModuleOrMock-test.js | 5 +- src/TestRunner.js | 14 +- src/__tests__/TestRunner-fs-test.js | 16 ++- src/__tests__/TestRunner-test.js | 4 +- src/lib/createHasteMap.js | 4 +- src/resolvers/HasteResolver.js | 59 +------- 18 files changed, 232 insertions(+), 215 deletions(-) create mode 100644 packages/jest-haste-map/src/worker.js diff --git a/packages/jest-haste-map/src/index.js b/packages/jest-haste-map/src/index.js index 67004f9e8d82..73fc06da19af 100644 --- a/packages/jest-haste-map/src/index.js +++ b/packages/jest-haste-map/src/index.js @@ -10,7 +10,6 @@ const crypto = require('crypto'); const denodeify = require('denodeify'); -const docblock = require('./lib/docblock'); const execSync = require('child_process').execSync; const fs = require('graceful-fs'); const getPlatformExtension = require('./lib/getPlatformExtension'); @@ -18,15 +17,13 @@ const nodeCrawl = require('./crawlers/node'); const os = require('os'); const path = require('./fastpath'); const watchmanCrawl = require('./crawlers/watchman'); +const worker = require('./worker'); +const workerFarm = require('worker-farm'); -const GENERIC_PLATFORM = 'generic'; +const GENERIC_PLATFORM = 'g'; const NODE_MODULES = path.sep + 'node_modules' + path.sep; -const PACKAGE_JSON = path.sep + 'package.json'; const VERSION = require('../package.json').version; -const readFile = denodeify(fs.readFile); -const writeFile = denodeify(fs.writeFile); - const canUseWatchman = (() => { try { execSync('watchman version', {stdio: 'ignore'}); @@ -42,6 +39,9 @@ class HasteMap { cacheDirectory: options.cacheDirectory || os.tmpDir(), extensions: options.extensions, ignorePattern: options.ignorePattern, + maxWorkers: options.maxWorkers, + mocksPattern: + options.mocksPattern ? new RegExp(options.mocksPattern) : null, platforms: options.platforms, resetCache: options.resetCache, roots: options.roots, @@ -54,14 +54,17 @@ class HasteMap { ? new RegExp('(.+?)' + NODE_MODULES + '(' + list.join('|') + ')(?!' + NODE_MODULES + ')') : null; - this._buildPromise = null; this._cachePath = HasteMap.getCacheFilePath( this._options.cacheDirectory, VERSION, this._options.roots.join(':'), this._options.extensions.join(':'), - this._options.platforms.join(':') + this._options.platforms.join(':'), + options.mocksPattern ); + this._buildPromise = null; + this._workerPromise = null; + this._workerFarm = null; } static getCacheFilePath(tmpdir) { @@ -73,15 +76,12 @@ class HasteMap { build() { if (!this._buildPromise) { this._buildPromise = this._buildFileMap() - .then(data => this._buildHasteMap(data)); + .then(data => this._buildHasteMap(data)) + .then(data => this._persist(data)); } return this._buildPromise; } - persist(data) { - return writeFile(this._cachePath, JSON.stringify(data)).then(() => data); - } - read() { return this._parse(fs.readFileSync(this._cachePath, 'utf-8')); } @@ -101,6 +101,11 @@ class HasteMap { }); } + _persist(data) { + fs.writeFileSync(this._cachePath, JSON.stringify(data), 'utf-8'); + return data; + } + _buildFileMap() { const read = this._options.resetCache ? this._createEmptyMap : this.read; @@ -112,6 +117,9 @@ class HasteMap { _buildHasteMap(data) { const map = Object.create(null); + const mocks = Object.create(null); + const mocksPattern = this._options.mocksPattern; + const promises = []; const setModule = module => { if (!map[module.id]) { map[module.id] = Object.create(null); @@ -129,13 +137,14 @@ class HasteMap { ); } - const fileData = data.files[module.path]; - fileData.id = module.id; moduleMap[platform] = module; }; - const promises = []; for (const filePath in data.files) { + if (mocksPattern && mocksPattern.test(filePath)) { + mocks[path.basename(filePath, path.extname(filePath))] = filePath; + } + if (!this._isNodeModulesDir(filePath)) { const fileData = data.files[filePath]; const moduleData = data.map[fileData.id]; @@ -148,19 +157,60 @@ class HasteMap { } } - fileData.visited = true; - if (filePath.endsWith(PACKAGE_JSON)) { - promises.push(this._processHastePackage(filePath, setModule)); - } else { - promises.push(this._processHasteModule(filePath, setModule)); + promises.push( + this._getWorker()({filePath}).then(data => { + fileData.visited = true; + if (data.module) { + fileData.id = data.module.id; + setModule(data.module); + } + if (data.dependencies) { + fileData.dependencies = data.dependencies; + } + }) + ); + } + } + + return Promise.all(promises) + .then(() => { + if (this._workerFarm) { + workerFarm.end(this._workerFarm); } + this._workerFarm = null; + this._workerPromise = null; + }) + .then(() => { + data.map = map; + data.mocks = mocks; + return data; + }); + } + + _getWorker() { + if (!this._workerPromise) { + if (this._options.maxWorkers === 1) { + this._workerPromise = data => new Promise( + (resolve, reject) => worker(data, (error, data) => { + if (error) { + reject(error); + } else { + resolve(data); + } + }) + ); + } else { + this._workerFarm = workerFarm( + { + maxConcurrentWorkers: this._options.maxWorkers, + }, + require.resolve('./worker') + ); + this._workerPromise = denodeify(this._workerFarm); } } - return Promise.all(promises).then(() => { - data.map = map; - return data; - }); + return this._workerPromise; } _parse(data) { @@ -201,39 +251,10 @@ class HasteMap { clocks: Object.create(null), files: Object.create(null), map: Object.create(null), + mocks: Object.create(null), }; } - _processHastePackage(filePath, setModule) { - return readFile(filePath, 'utf-8') - .then(data => { - data = JSON.parse(data); - if (data.name) { - setModule({ - id: data.name, - path: filePath, - type: 'package', - }); - } - }); - } - - _processHasteModule(filePath, setModule) { - return readFile(filePath, 'utf-8') - .then(data => { - const doc = docblock.parseAsObject(data); - const id = doc.providesModule || doc.provides; - - if (id) { - setModule({ - id, - path: filePath, - type: 'module', - }); - } - }); - } - } HasteMap.GENERIC_PLATFORM = GENERIC_PLATFORM; diff --git a/packages/jest-haste-map/src/lib/docblock.js b/packages/jest-haste-map/src/lib/docblock.js index 205e8db6f2ee..ae9e02c7a03f 100644 --- a/packages/jest-haste-map/src/lib/docblock.js +++ b/packages/jest-haste-map/src/lib/docblock.js @@ -9,32 +9,20 @@ 'use strict'; +const commentEndRe = /\*\/$/; +const commentStartRe = /^\/\*\*/; const docblockRe = /^\s*(\/\*\*(.|\r?\n)*?\*\/)/; - const ltrimRe = /^\s*/; -/** - * @param {String} contents - * @return {String} - */ +const multilineRe = /(?:^|\r?\n) *(@[^\r\n]*?) *\r?\n *([^@\r\n\s][^@\r\n]+?) *\r?\n/g; +const propertyRe = /(?:^|\r?\n) *@(\S+) *([^\r\n]*)/g; +const stringStartRe = /(\r?\n|^) *\*/g; +const wsRe = /[\t ]+/g; + function extract(contents) { const match = contents.match(docblockRe); - if (match) { - return match[0].replace(ltrimRe, '') || ''; - } - return ''; + return match ? match[0].replace(ltrimRe, '') || '' : ''; } -const commentStartRe = /^\/\*\*/; -const commentEndRe = /\*\/$/; -const wsRe = /[\t ]+/g; -const stringStartRe = /(\r?\n|^) *\*/g; -const multilineRe = /(?:^|\r?\n) *(@[^\r\n]*?) *\r?\n *([^@\r\n\s][^@\r\n]+?) *\r?\n/g; -const propertyRe = /(?:^|\r?\n) *@(\S+) *([^\r\n]*)/g; - -/** - * @param {String} contents - * @return {Array} - */ function parse(docblock) { docblock = docblock .replace(commentStartRe, '') @@ -50,32 +38,13 @@ function parse(docblock) { } docblock = docblock.trim(); - const result = []; + const result = Object.create(null); let match; while ((match = propertyRe.exec(docblock))) { - result.push([match[1], match[2]]); - } - - return result; -} - -/** - * Same as parse but returns an object of prop: value instead of array of paris - * If a property appers more than once the last one will be returned - * - * @param {String} contents - * @return {Object} - */ -function parseAsObject(docblock) { - const pairs = parse(docblock); - const result = {}; - for (let i = 0; i < pairs.length; i++) { - result[pairs[i][0]] = pairs[i][1]; + result[match[1]] = match[2]; } return result; } - exports.extract = extract; exports.parse = parse; -exports.parseAsObject = parseAsObject; diff --git a/packages/jest-haste-map/src/lib/extractRequires.js b/packages/jest-haste-map/src/lib/extractRequires.js index 441197251dbe..76115ba6559e 100644 --- a/packages/jest-haste-map/src/lib/extractRequires.js +++ b/packages/jest-haste-map/src/lib/extractRequires.js @@ -8,52 +8,34 @@ */ 'use strict'; +const blockCommentRe = /\/\*[^]*?\*\//g; +const lineCommentRe = /\/\/.*/g; + +/* eslint-disable max-len */ const replacePatterns = { - IMPORT_RE: /(\bimport\s+(?:[^'"]+\s+from\s+)??)(['"])([^'"]+)(\2)/g, EXPORT_RE: /(\bexport\s+(?:[^'"]+\s+from\s+)??)(['"])([^'"]+)(\2)/g, + IMPORT_RE: /(\bimport\s+(?:[^'"]+\s+from\s+)??)(['"])([^'"]+)(\2)/g, + REQUIRE_EXTENSIONS_PATTERN: /(\b(?:require\s*?\.\s*?(?:requireActual|requireMock)|jest\s*?\.\s*?genMockFromModule)\s*?\(\s*?)(['"])([^'"]+)(\2\s*?\))/g, REQUIRE_RE: /(\brequire\s*?\(\s*?)(['"])([^'"]+)(\2\s*?\))/g, }; +/* eslint-enable max-len */ -/** - * Extract all required modules from a `code` string. - */ -const blockCommentRe = /\/\*[^]*?\*\//g; -const lineCommentRe = /\/\/.*/g; function extractRequires(code) { - const cache = Object.create(null); - const deps = { - sync: [], - }; - - const addDependency = dep => { - if (!cache[dep]) { - cache[dep] = true; - deps.sync.push(dep); - } + const dependencies = new Set(); + const addDependency = (match, pre, quot, dep, post) => { + dependencies.add(dep); + return match; }; - code = code + code .replace(blockCommentRe, '') .replace(lineCommentRe, '') - // Parse the sync dependencies this module has. When the module is - // required, all it's sync dependencies will be loaded into memory. - // Sync dependencies can be defined either using `require` or the ES6 - // `import` or `export` syntaxes: - // var dep1 = require('dep1'); - .replace(replacePatterns.IMPORT_RE, (match, pre, quot, dep, post) => { - addDependency(dep); - return match; - }) - .replace(replacePatterns.EXPORT_RE, (match, pre, quot, dep, post) => { - addDependency(dep); - return match; - }) - .replace(replacePatterns.REQUIRE_RE, (match, pre, quot, dep, post) => { - addDependency(dep); - return match; - }); + .replace(replacePatterns.EXPORT_RE, addDependency) + .replace(replacePatterns.IMPORT_RE, addDependency) + .replace(replacePatterns.REQUIRE_EXTENSIONS_PATTERN, addDependency) + .replace(replacePatterns.REQUIRE_RE, addDependency); - return {code, deps}; + return Array.from(dependencies); } module.exports = extractRequires; diff --git a/packages/jest-haste-map/src/worker.js b/packages/jest-haste-map/src/worker.js new file mode 100644 index 000000000000..6ef631152ef4 --- /dev/null +++ b/packages/jest-haste-map/src/worker.js @@ -0,0 +1,71 @@ +/** + * Copyright (c) 2014-present, Facebook, Inc. All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ +'use strict'; + +const docblock = require('./lib/docblock'); +const extractRequires = require('./lib/extractRequires'); +const fs = require('graceful-fs'); +const path = require('./fastpath'); + +const PACKAGE_JSON = path.sep + 'package.json'; + +// Make sure uncaught errors are logged before we exit. +process.on('uncaughtException', err => { + console.error(err.stack); + process.exit(1); +}); + +const formatError = error => { + if (typeof error === 'string') { + return { + stack: null, + message: error, + type: 'Error', + }; + } + + return { + stack: error.stack, + message: error.message, + type: error.type, + }; +}; + +module.exports = (data, callback) => { + try { + const filePath = data.filePath; + const content = fs.readFileSync(filePath, 'utf-8'); + let module; + let dependencies; + + if (filePath.endsWith(PACKAGE_JSON)) { + const fileData = JSON.parse(content); + if (fileData.name) { + module = { + id: fileData.name, + path: filePath, + type: 'package', + }; + } + } else { + const doc = docblock.parse(docblock.extract(content)); + const id = doc.providesModule || doc.provides; + dependencies = extractRequires(content); + if (id) { + module = { + id, + path: filePath, + type: 'module', + }; + } + } + callback(null, {module, dependencies}); + } catch (error) { + callback(formatError(error)); + } +}; diff --git a/src/Runtime/__tests__/Runtime-NODE_PATH-test.js b/src/Runtime/__tests__/Runtime-NODE_PATH-test.js index 3eeeb04261fb..54719da2cca3 100644 --- a/src/Runtime/__tests__/Runtime-NODE_PATH-test.js +++ b/src/Runtime/__tests__/Runtime-NODE_PATH-test.js @@ -30,7 +30,10 @@ describe('Runtime', () => { function buildLoader() { const environment = new JSDOMEnvironment(config); - const resolver = new HasteResolver(config, {resetCache: false}); + const resolver = new HasteResolver(config, { + resetCache: false, + maxWorkers: 1, + }); return resolver.getHasteMap().then( response => new Runtime(config, environment, response) ); diff --git a/src/Runtime/__tests__/Runtime-genMockFromModule-test.js b/src/Runtime/__tests__/Runtime-genMockFromModule-test.js index 9aa8ee4e2dd6..b433af2b7500 100644 --- a/src/Runtime/__tests__/Runtime-genMockFromModule-test.js +++ b/src/Runtime/__tests__/Runtime-genMockFromModule-test.js @@ -30,7 +30,10 @@ describe('nodeRuntime', () => { function buildLoader() { const environment = new JSDOMEnvironment(config); - const resolver = new HasteResolver(config, {resetCache: false}); + const resolver = new HasteResolver(config, { + resetCache: false, + maxWorkers: 1, + }); return resolver.getHasteMap().then( response => new Runtime(config, environment, response) ); diff --git a/src/Runtime/__tests__/Runtime-getTestEnvData-test.js b/src/Runtime/__tests__/Runtime-getTestEnvData-test.js index 180d2f2f3a9e..481043fc6802 100644 --- a/src/Runtime/__tests__/Runtime-getTestEnvData-test.js +++ b/src/Runtime/__tests__/Runtime-getTestEnvData-test.js @@ -31,7 +31,10 @@ describe('Runtime', () => { function buildLoader() { const environment = new JSDOMEnvironment(config); - const resolver = new HasteResolver(config, {resetCache: false}); + const resolver = new HasteResolver(config, { + resetCache: false, + maxWorkers: 1, + }); return resolver.getHasteMap().then( response => new Runtime(config, environment, response) ); diff --git a/src/Runtime/__tests__/Runtime-jest-fn.js b/src/Runtime/__tests__/Runtime-jest-fn.js index 413e8cdfdfde..d9adbf327a46 100644 --- a/src/Runtime/__tests__/Runtime-jest-fn.js +++ b/src/Runtime/__tests__/Runtime-jest-fn.js @@ -30,7 +30,10 @@ describe('Runtime', () => { function buildLoader() { const environment = new JSDOMEnvironment(config); - const resolver = new HasteResolver(config, {resetCache: false}); + const resolver = new HasteResolver(config, { + resetCache: false, + maxWorkers: 1, + }); return resolver.getHasteMap().then( response => new Runtime(config, environment, response) ); diff --git a/src/Runtime/__tests__/Runtime-jsdom-env-test.js b/src/Runtime/__tests__/Runtime-jsdom-env-test.js index cee3c2d349f7..cbc3c3b6539c 100644 --- a/src/Runtime/__tests__/Runtime-jsdom-env-test.js +++ b/src/Runtime/__tests__/Runtime-jsdom-env-test.js @@ -30,7 +30,10 @@ describe('Runtime', () => { function buildLoader() { const environment = new JSDOMEnvironment(config); - const resolver = new HasteResolver(config, {resetCache: false}); + const resolver = new HasteResolver(config, { + resetCache: false, + maxWorkers: 1, + }); return resolver.getHasteMap().then( response => new Runtime(config, environment, response) ); diff --git a/src/Runtime/__tests__/Runtime-mock-test.js b/src/Runtime/__tests__/Runtime-mock-test.js index 0d7dab75b756..f8462c013cdb 100644 --- a/src/Runtime/__tests__/Runtime-mock-test.js +++ b/src/Runtime/__tests__/Runtime-mock-test.js @@ -30,7 +30,10 @@ describe('Runtime', () => { function buildLoader() { const environment = new JSDOMEnvironment(config); - const resolver = new HasteResolver(config, {resetCache: false}); + const resolver = new HasteResolver(config, { + resetCache: false, + maxWorkers: 1, + }); return resolver.getHasteMap().then( response => new Runtime(config, environment, response) ); diff --git a/src/Runtime/__tests__/Runtime-requireMock-test.js b/src/Runtime/__tests__/Runtime-requireMock-test.js index 0f9d19d98f51..dd99299d4b32 100644 --- a/src/Runtime/__tests__/Runtime-requireMock-test.js +++ b/src/Runtime/__tests__/Runtime-requireMock-test.js @@ -30,7 +30,10 @@ describe('Runtime', () => { function buildLoader() { const environment = new JSDOMEnvironment(config); - const resolver = new HasteResolver(config, {resetCache: false}); + const resolver = new HasteResolver(config, { + resetCache: false, + maxWorkers: 1, + }); return resolver.getHasteMap().then( response => new Runtime(config, environment, response) ); diff --git a/src/Runtime/__tests__/Runtime-requireModule-test.js b/src/Runtime/__tests__/Runtime-requireModule-test.js index ae510ca2e0a0..7c143711343b 100644 --- a/src/Runtime/__tests__/Runtime-requireModule-test.js +++ b/src/Runtime/__tests__/Runtime-requireModule-test.js @@ -31,7 +31,10 @@ describe('Runtime', () => { function buildLoader(config) { config = Object.assign({}, baseConfig, config); const environment = new JSDOMEnvironment(config); - const resolver = new HasteResolver(config, {resetCache: false}); + const resolver = new HasteResolver(config, { + resetCache: false, + maxWorkers: 1, + }); return resolver.getHasteMap().then( response => new Runtime(config, environment, response) ); diff --git a/src/Runtime/__tests__/Runtime-requireModuleOrMock-test.js b/src/Runtime/__tests__/Runtime-requireModuleOrMock-test.js index 77a81c28735d..de886bfc5b69 100644 --- a/src/Runtime/__tests__/Runtime-requireModuleOrMock-test.js +++ b/src/Runtime/__tests__/Runtime-requireModuleOrMock-test.js @@ -37,7 +37,10 @@ describe('Runtime', () => { function buildLoader(config) { config = Object.assign({}, baseConfig, config); const environment = new JSDOMEnvironment(config); - const resolver = new HasteResolver(config, {resetCache: false}); + const resolver = new HasteResolver(config, { + resetCache: false, + maxWorkers: 1, + }); return resolver.getHasteMap().then( response => new Runtime(config, environment, response) ); diff --git a/src/TestRunner.js b/src/TestRunner.js index 51a991a713d5..7b00c47fd0aa 100644 --- a/src/TestRunner.js +++ b/src/TestRunner.js @@ -56,6 +56,7 @@ class TestRunner { const Resolver = require(config.moduleResolver); this._resolver = new Resolver(config, { + maxWorkers: options.runInBand ? 1 : this._opts.maxWorkers, resetCache: !config.cache, }); @@ -220,23 +221,12 @@ class TestRunner { }); } -<<<<<<< b46a656a708ebcb95c95f246a0dd658b389dc610 - promiseTestPathsMatching(pathPattern) { - try { - const maybeFile = path.resolve(process.cwd(), pathPattern); - fs.accessSync(maybeFile); - return Promise.resolve([pathPattern].filter(this.isTestFilePath)); - } catch (e) { - return this._getAllTestPaths() - .then(paths => paths.filter(path => new RegExp(pathPattern).test(path))); -======= promiseTestPathsMatching(pattern) { if (pattern && !(pattern instanceof RegExp)) { const maybeFile = path.resolve(process.cwd(), pattern); if (fileExists(maybeFile)) { - return Promise.resolve([pattern].filter(this._isTestFilePath)); + return Promise.resolve([pattern].filter(this.isTestFilePath)); } ->>>>>>> Implement `jest-haste-map` instead of `node-haste` } const paths = this._getAllTestPaths(); diff --git a/src/__tests__/TestRunner-fs-test.js b/src/__tests__/TestRunner-fs-test.js index 26bcf1218e52..267b1cb1e7ef 100644 --- a/src/__tests__/TestRunner-fs-test.js +++ b/src/__tests__/TestRunner-fs-test.js @@ -28,7 +28,9 @@ describe('TestRunner-fs', () => { name, rootDir, testDirectoryName: '__testtests__', - }), {}); + }), { + maxWorkers: 1, + }); return runner.promiseTestPathsMatching(/.*/).then(paths => { const relPaths = paths.map(absPath => path.relative(rootDir, absPath)); expect(relPaths).toEqual([path.normalize('__testtests__/test.js')]); @@ -43,7 +45,9 @@ describe('TestRunner-fs', () => { rootDir, testDirectoryName: '__testtests__', testFileExtensions: ['jsx'], - }), {}); + }), { + maxWorkers: 1, + }); return runner.promiseTestPathsMatching(/.*/).then(paths => { const relPaths = paths.map(absPath => path.relative(rootDir, absPath)); expect(relPaths).toEqual([path.normalize('__testtests__/test.jsx')]); @@ -58,7 +62,9 @@ describe('TestRunner-fs', () => { rootDir, testDirectoryName: '__testtests__', testFileExtensions: ['foobar'], - }), {}); + }), { + maxWorkers: 1, + }); return runner.promiseTestPathsMatching(/.*/).then(paths => { const relPaths = paths.map(absPath => path.relative(rootDir, absPath)); expect(relPaths).toEqual([path.normalize('__testtests__/test.foobar')]); @@ -73,7 +79,9 @@ describe('TestRunner-fs', () => { rootDir, testDirectoryName: '__testtests__', testFileExtensions: ['js', 'jsx'], - }), {}); + }), { + maxWorkers: 1, + }); return runner.promiseTestPathsMatching(/.*/).then(paths => { const relPaths = paths.map(absPath => path.relative(rootDir, absPath)); expect(relPaths.sort()).toEqual([ diff --git a/src/__tests__/TestRunner-test.js b/src/__tests__/TestRunner-test.js index ef8376614bc9..3229d0b87ba5 100644 --- a/src/__tests__/TestRunner-test.js +++ b/src/__tests__/TestRunner-test.js @@ -32,7 +32,9 @@ describe('TestRunner', () => { name, rootDir: '.', testPathDirs: [], - }), {}); + }), { + maxWorkers: 1, + }); }); it('supports ../ paths and unix separators', () => { diff --git a/src/lib/createHasteMap.js b/src/lib/createHasteMap.js index 6d0ee45521ac..72fe9aa14f99 100644 --- a/src/lib/createHasteMap.js +++ b/src/lib/createHasteMap.js @@ -22,8 +22,10 @@ module.exports = function createHasteMap(config, options) { cacheDirectory: config.cacheDirectory, extensions, ignorePattern, - providesModuleNodeModules: config.haste.providesModuleNodeModules, + maxWorkers: options && options.maxWorkers, + mocksPattern: config.mocksPattern, platforms: config.haste.platforms || ['ios', 'android'], + providesModuleNodeModules: config.haste.providesModuleNodeModules, resetCache: options && options.resetCache, roots: config.testPathDirs, useWatchman: config.watchman, diff --git a/src/resolvers/HasteResolver.js b/src/resolvers/HasteResolver.js index 24d4088c18db..f0f83b59b090 100644 --- a/src/resolvers/HasteResolver.js +++ b/src/resolvers/HasteResolver.js @@ -9,45 +9,15 @@ 'use strict'; const createHasteMap = require('../lib/createHasteMap'); -const path = require('path'); - -/* eslint-disable max-len */ -const REQUIRE_EXTENSIONS_PATTERN = /(\b(?:require\s*?\.\s*?(?:requireActual|requireMock)|jest\s*?\.\s*?genMockFromModule)\s*?\(\s*?)(['"])([^'"]+)(\2\s*?\))/g; -/* eslint-enable max-len */ class HasteResolver { constructor(config, options) { this._map = createHasteMap(config, options); this._defaultPlatform = config.haste.defaultPlatform; - this._mocksPattern = new RegExp(config.mocksPattern); - this._mappedModuleNames = Object.create(null); - if (config.moduleNameMapper.length) { - config.moduleNameMapper.forEach( - map => this._mappedModuleNames[map[1]] = new RegExp(map[0]) - ); - } // warm-up and cache mocks - this._hasteMapPromise = this._map.build().then(data => - this._getAllMocks().then(mocks => { - data.mocks = mocks; - return this._map.persist(data); - }) - ); - - /*extractRequires: code => { - const data = HasteMap.extractRequires(code); - data.code = data.code.replace( - REQUIRE_EXTENSIONS_PATTERN, - (match, pre, quot, dep, post) => { - data.deps.sync.push(dep); - return match; - } - ); - - return this._updateModuleMappings(data); - },*/ + this._map.build(); } matchFiles(pattern) { @@ -70,32 +40,7 @@ class HasteResolver { } getHasteMap() { - return this._hasteMapPromise; - } - - _getAllMocks() { - const mocks = Object.create(null); - return this._map - .matchFiles(this._mocksPattern) - .then(files => files.forEach( - file => mocks[path.basename(file, path.extname(file))] = file - )) - .then(() => mocks); - } - - _updateModuleMappings(data) { - const nameMapper = this._mappedModuleNames; - const updateMapping = (moduleName, index, array) => { - for (const mappedModuleName in nameMapper) { - const regex = nameMapper[mappedModuleName]; - if (regex.test(moduleName)) { - array[index] = mappedModuleName; - return; - } - } - }; - data.deps.sync.forEach(updateMapping); - return data; + return this._map.build(); } }