diff --git a/CHANGELOG.md b/CHANGELOG.md index cac33660b742..826b82934083 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ - `[jest-worker]` [**BREAKING**] Add functionality to call a `setup` method in the worker before the first call and a `teardown` method when ending the farm ([#7014](https://github.com/facebook/jest/pull/7014)). - `[jest-config]` [**BREAKING**] Set default `notifyMode` to `failure-change` ([#7024](https://github.com/facebook/jest/pull/7024)) - `[jest-snapshot]` Enable configurable snapshot paths ([#6143](https://github.com/facebook/jest/pull/6143)) +- `[jest-haste-map]` [**BREAKING**] Remove support for `@providesModule` ([#6104](https://github.com/facebook/jest/pull/6104)) ### Fixes diff --git a/e2e/__tests__/dependency_clash.test.js b/e2e/__tests__/dependency_clash.test.js index bbcdd37b3f33..1303024357bb 100644 --- a/e2e/__tests__/dependency_clash.test.js +++ b/e2e/__tests__/dependency_clash.test.js @@ -59,11 +59,10 @@ test('fails with syntax error on flow types', () => { } `, '__tests__/test.js': ` - const invariant = require('invariant'); + const invariant = require('../invariant'); test('haii', () => expect(invariant(false, 'haii')).toBe('haii')); `, 'invariant.js': `/** - * @providesModule invariant * @flow */ const invariant = (condition: boolean, message: string) => message; diff --git a/e2e/__tests__/multi_project_runner.test.js b/e2e/__tests__/multi_project_runner.test.js index 68090f94ea4b..f1e5c140daa3 100644 --- a/e2e/__tests__/multi_project_runner.test.js +++ b/e2e/__tests__/multi_project_runner.test.js @@ -17,12 +17,7 @@ import {cleanup, extractSummary, writeFiles} from '../Utils'; const DIR = path.resolve(os.tmpdir(), 'multi_project_runner_test'); -const fileContentWithProvidesModule = name => `/* - * @providesModule ${name} - */ - -module.exports = {}; -`; +const SAMPLE_FILE_CONTENT = 'module.exports = {};'; beforeEach(() => cleanup(DIR)); afterEach(() => cleanup(DIR)); @@ -55,29 +50,51 @@ test('--listTests doesnt duplicate the test files', () => { test('can pass projects or global config', () => { writeFiles(DIR, { '.watchmanconfig': '', + 'base_config.js': ` + module.exports = { + haste: { + hasteImplModulePath: '/hasteImpl.js', + }, + }; + `, + 'hasteImpl.js': ` + module.exports = { + getHasteName(path) { + return path + .substr(path.lastIndexOf('/') + 1) + .replace(/\.js$/, ''); + }, + }; + `, 'package.json': '{}', 'project1/__tests__/file1.test.js': ` const file1 = require('file1'); test('file1', () => {}); `, - 'project1/file1.js': fileContentWithProvidesModule('file1'), - 'project1/jest.config.js': `module.exports = {rootDir: './', displayName: 'BACKEND'}`, + 'project1/file1.js': SAMPLE_FILE_CONTENT, + 'project1/jest.config.js': `module.exports = {rootDir: './', displayName: 'BACKEND', haste: { + hasteImplModulePath: '/../hasteImpl.js', + },}`, 'project2/__tests__/file1.test.js': ` const file1 = require('file1'); test('file1', () => {}); `, - 'project2/file1.js': fileContentWithProvidesModule('file1'), - 'project2/jest.config.js': `module.exports = {rootDir: './'}`, + 'project2/file1.js': SAMPLE_FILE_CONTENT, + 'project2/jest.config.js': `module.exports = {rootDir: './', haste: { + hasteImplModulePath: '/../hasteImpl.js', + },}`, 'project3/__tests__/file1.test.js': ` const file1 = require('file1'); test('file1', () => {}); `, - 'project3/file1.js': fileContentWithProvidesModule('file1'), - 'project3/jest.config.js': `module.exports = {rootDir: './', displayName: 'UI'}`, + 'project3/file1.js': SAMPLE_FILE_CONTENT, + 'project3/jest.config.js': `module.exports = {rootDir: './', displayName: 'UI', haste: { + hasteImplModulePath: '/../hasteImpl.js', + },}`, }); let stderr; - ({stderr} = runJest(DIR, ['--no-watchman'])); + ({stderr} = runJest(DIR, ['--no-watchman', '--config', 'base_config.js'])); expect(stderr).toMatch( 'The name `file1` was looked up in the Haste module map. It cannot be resolved, because there exists several different files', ); @@ -88,6 +105,9 @@ test('can pass projects or global config', () => { 'global_config.js': ` module.exports = { projects: ['project1/', 'project2/', 'project3/'], + haste: { + hasteImplModulePath: '/hasteImpl.js', + }, }; `, }); @@ -99,6 +119,8 @@ test('can pass projects or global config', () => { 'project1', 'project2', 'project3', + '--config', + 'base_config.js', ])); const result1 = extractSummary(stderr); @@ -126,16 +148,16 @@ test('"No tests found" message for projects', () => { '.watchmanconfig': '', 'package.json': '{}', 'project1/__tests__/file1.test.js': ` - const file1 = require('file1'); + const file1 = require('../file1'); test('file1', () => {}); `, - 'project1/file1.js': fileContentWithProvidesModule('file1'), + 'project1/file1.js': SAMPLE_FILE_CONTENT, 'project1/jest.config.js': `module.exports = {rootDir: './'}`, 'project2/__tests__/file1.test.js': ` - const file1 = require('file1'); + const file1 = require('../file1'); test('file1', () => {}); `, - 'project2/file1.js': fileContentWithProvidesModule('file1'), + 'project2/file1.js': SAMPLE_FILE_CONTENT, 'project2/jest.config.js': `module.exports = {rootDir: './'}`, }); const {stdout: verboseOutput} = runJest(DIR, [ @@ -170,16 +192,16 @@ test('projects can be workspaces with non-JS/JSON files', () => { 'packages/README.md': '# Packages README', 'packages/project1/README.md': '# Project1 README', 'packages/project1/__tests__/file1.test.js': ` - const file1 = require('file1'); + const file1 = require('../file1'); test('file1', () => {}); `, - 'packages/project1/file1.js': fileContentWithProvidesModule('file1'), + 'packages/project1/file1.js': SAMPLE_FILE_CONTENT, 'packages/project1/package.json': '{}', 'packages/project2/__tests__/file2.test.js': ` - const file2 = require('file2'); + const file2 = require('../file2'); test('file2', () => {}); `, - 'packages/project2/file2.js': fileContentWithProvidesModule('file2'), + 'packages/project2/file2.js': SAMPLE_FILE_CONTENT, 'packages/project2/package.json': '{}', }); diff --git a/packages/jest-cli/src/__tests__/SearchSource.test.js b/packages/jest-cli/src/__tests__/SearchSource.test.js index d3d2e5d1e556..ee88081a6e77 100644 --- a/packages/jest-cli/src/__tests__/SearchSource.test.js +++ b/packages/jest-cli/src/__tests__/SearchSource.test.js @@ -373,6 +373,18 @@ describe('SearchSource', () => { beforeEach(done => { const {options: config} = normalize( { + haste: { + hasteImplModulePath: path.join( + __dirname, + '..', + '..', + '..', + 'jest-haste-map', + 'src', + '__tests__', + 'haste_impl.js', + ), + }, name: 'SearchSource-findRelatedTests-tests', rootDir, }, diff --git a/packages/jest-haste-map/src/__tests__/__snapshots__/index.test.js.snap b/packages/jest-haste-map/src/__tests__/__snapshots__/index.test.js.snap index 8122a04e6413..d86bc28499f3 100644 --- a/packages/jest-haste-map/src/__tests__/__snapshots__/index.test.js.snap +++ b/packages/jest-haste-map/src/__tests__/__snapshots__/index.test.js.snap @@ -3,25 +3,25 @@ exports[`HasteMap file system changes processing recovery from duplicate module IDs recovers when the most recent duplicate is fixed 1`] = ` "The name \`Pear\` was looked up in the Haste module map. It cannot be resolved, because there exists several different files, or packages, that provide a module for that particular name and platform. The platform is generic (no extension). You must delete or blacklist files until there remains only one of these: - * \`/project/fruits/blueberry.js\` (module) - * \`/project/fruits/pear.js\` (module) + * \`/project/fruits/Pear.js\` (module) + * \`/project/fruits/another/Pear.js\` (module) " `; exports[`HasteMap file system changes processing recovery from duplicate module IDs recovers when the oldest version of the duplicates is fixed 1`] = ` "The name \`Pear\` was looked up in the Haste module map. It cannot be resolved, because there exists several different files, or packages, that provide a module for that particular name and platform. The platform is generic (no extension). You must delete or blacklist files until there remains only one of these: - * \`/project/fruits/blueberry.js\` (module) - * \`/project/fruits/pear.js\` (module) + * \`/project/fruits/Pear.js\` (module) + * \`/project/fruits/another/Pear.js\` (module) " `; exports[`HasteMap throws on duplicate module ids if "throwOnModuleCollision" is set to true 1`] = ` -[Error: jest-haste-map: @providesModule naming collision: +[Error: jest-haste-map: Haste module naming collision: Duplicate module name: Strawberry - Paths: /project/fruits/raspberry.js collides with /project/fruits/strawberry.js + Paths: /project/fruits/another/Strawberry.js collides with /project/fruits/Strawberry.js -This error is caused by a @providesModule declaration with the same name across two different files.] +This error is caused by \`hasteImpl\` returning the same name for different files.] `; exports[`HasteMap tries to crawl using node as a fallback 1`] = ` @@ -32,22 +32,22 @@ exports[`HasteMap tries to crawl using node as a fallback 1`] = ` exports[`HasteMap warns on duplicate mock files 1`] = ` "jest-haste-map: duplicate manual mock found: - Module name: subdir/blueberry - Duplicate Mock path: /project/fruits2/__mocks__/subdir/blueberry.js + Module name: subdir/Blueberry + Duplicate Mock path: /project/fruits2/__mocks__/subdir/Blueberry.js This warning is caused by two manual mock files with the same file name. Jest will use the mock file found in: -/project/fruits2/__mocks__/subdir/blueberry.js +/project/fruits2/__mocks__/subdir/Blueberry.js Please delete one of the following two files: - /project/fruits1/__mocks__/subdir/blueberry.js -/project/fruits2/__mocks__/subdir/blueberry.js + /project/fruits1/__mocks__/subdir/Blueberry.js +/project/fruits2/__mocks__/subdir/Blueberry.js " `; exports[`HasteMap warns on duplicate module ids 1`] = ` -"jest-haste-map: @providesModule naming collision: +"jest-haste-map: Haste module naming collision: Duplicate module name: Strawberry - Paths: /project/fruits/raspberry.js collides with /project/fruits/strawberry.js + Paths: /project/fruits/other/Strawberry.js collides with /project/fruits/Strawberry.js -This warning is caused by a @providesModule declaration with the same name across two different files." +This warning is caused by \`hasteImpl\` returning the same name for different files." `; diff --git a/packages/jest-haste-map/src/__tests__/haste_impl.js b/packages/jest-haste-map/src/__tests__/haste_impl.js index 59a10b6912a2..0dc26ac5fac6 100644 --- a/packages/jest-haste-map/src/__tests__/haste_impl.js +++ b/packages/jest-haste-map/src/__tests__/haste_impl.js @@ -8,6 +8,17 @@ module.exports = { getHasteName(path) { - return path.substr(path.lastIndexOf('/') + 1).replace(/\.js$/, ''); + if ( + path.includes('__mocks__') || + path.includes('NoHaste') || + path.includes('/module_dir/') || + path.includes('/sourcemaps/') + ) { + return undefined; + } + + return path + .substr(path.lastIndexOf('/') + 1) + .replace(/(\.(android|ios|native))?\.js$/, ''); }, }; diff --git a/packages/jest-haste-map/src/__tests__/index.test.js b/packages/jest-haste-map/src/__tests__/index.test.js index 0374851082af..b67f5ec3dbaa 100644 --- a/packages/jest-haste-map/src/__tests__/index.test.js +++ b/packages/jest-haste-map/src/__tests__/index.test.js @@ -141,35 +141,25 @@ describe('HasteMap', () => { mockEmitters = Object.create(null); mockFs = object({ - '/project/fruits/__mocks__/Pear.js': [ - 'const Melon = require("Melon");', - ].join('\n'), - '/project/fruits/banana.js': [ - '/**', - ' * @providesModule Banana', - ' */', - 'const Strawberry = require("Strawberry");', - ].join('\n'), - '/project/fruits/kiwi.js': ['/**', ' * @providesModule Kiwi', ' */'].join( - '\n', - ), - '/project/fruits/pear.js': [ - '/**', - ' * @providesModule Pear', - ' */', - 'const Banana = require("Banana");', - 'const Strawberry = require("Strawberry");', - ].join('\n'), - '/project/fruits/strawberry.js': [ - '/**', - ' * @providesModule Strawberry', - ' */', - ].join('\n'), - '/project/vegetables/melon.js': [ - '/**', - ' * @providesModule Melon', - ' */', - ].join('\n'), + '/project/fruits/Banana.js': ` + const Strawberry = require("Strawberry"); + `, + '/project/fruits/Kiwi.js': ` + // Kiwi! + `, + '/project/fruits/Pear.js': ` + const Banana = require("Banana"); + const Strawberry = require("Strawberry"); + `, + '/project/fruits/Strawberry.js': ` + // Strawberry! + `, + '/project/fruits/__mocks__/Pear.js': ` + const Melon = require("Melon"); + `, + '/project/vegetables/Melon.js': ` + // Melon! + `, '/project/video/video.mp4': Buffer.from([ 0xfa, 0xce, @@ -198,7 +188,8 @@ describe('HasteMap', () => { defaultConfig = { extensions: ['js', 'json'], - ignorePattern: /kiwi/, + hasteImplModulePath: require.resolve('./haste_impl.js'), + ignorePattern: /Kiwi/, maxWorkers: 1, name: 'haste-map-test', platforms: ['ios', 'android'], @@ -235,10 +226,10 @@ describe('HasteMap', () => { it('matches files against a pattern', () => new HasteMap(defaultConfig).build().then(({hasteFS}) => { expect(hasteFS.matchFiles(/project\/fruits/)).toEqual([ + '/project/fruits/Banana.js', + '/project/fruits/Pear.js', + '/project/fruits/Strawberry.js', '/project/fruits/__mocks__/Pear.js', - '/project/fruits/banana.js', - '/project/fruits/pear.js', - '/project/fruits/strawberry.js', ]); expect(hasteFS.matchFiles(/__mocks__/)).toEqual([ @@ -248,41 +239,35 @@ describe('HasteMap', () => { it('builds a haste map on a fresh cache', () => { // Include these files in the map - mockFs['/project/fruits/node_modules/react/react.js'] = [ - '/**', - ' * @providesModule React', - ' */', - 'const Component = require("Component");', - ].join('\n'); - mockFs['/project/fruits/node_modules/fbjs/lib/flatMap.js'] = [ - '/**', - ' * @providesModule flatMap', - ' */', - ].join('\n'); + mockFs['/project/fruits/node_modules/react/React.js'] = ` + const Component = require("Component"); + `; + mockFs['/project/fruits/node_modules/fbjs/lib/flatMap.js'] = ` + // flatMap + `; // Ignore these mockFs[ '/project/fruits/node_modules/react/node_modules/fbjs/lib/mapObject.js' - ] = ['/**', ' * @providesModule mapObject', ' */'].join('\n'); - mockFs['/project/fruits/node_modules/react/node_modules/dummy/merge.js'] = [ - '/**', - ' * @providesModule merge', - ' */', - ].join('\n'); + ] = ` + // mapObject + `; + mockFs['/project/fruits/node_modules/react/node_modules/dummy/merge.js'] = ` + // merge + `; mockFs[ '/project/fruits/node_modules/react/node_modules/merge/package.json' - ] = ['{', ' "name": "merge"', '}'].join('\n'); - mockFs['/project/fruits/node_modules/jest/jest.js'] = [ - '/**', - ' * @providesModule Jest', - ' */', - 'const Test = require("Test");', - ].join('\n'); - mockFs['/project/fruits/node_modules/fbjs2/index.js'] = [ - '/**', - ' * @providesModule fbjs2', - ' */', - ].join('\n'); + ] = ` + { + "name": "merge" + } + `; + mockFs['/project/fruits/node_modules/jest/Jest.js'] = ` + const Test = require("Test"); + `; + mockFs['/project/fruits/node_modules/fbjs2/fbjs2.js'] = ` + // fbjs2 + `; const hasteMap = new HasteMap( Object.assign({}, defaultConfig, { @@ -296,8 +281,10 @@ describe('HasteMap', () => { expect(data.files).toEqual( createMap({ + 'fruits/Banana.js': ['Banana', 32, 1, ['Strawberry'], null], + 'fruits/Pear.js': ['Pear', 32, 1, ['Banana', 'Strawberry'], null], + 'fruits/Strawberry.js': ['Strawberry', 32, 1, [], null], 'fruits/__mocks__/Pear.js': ['', 32, 1, ['Melon'], null], - 'fruits/banana.js': ['Banana', 32, 1, ['Strawberry'], null], // node modules 'fruits/node_modules/fbjs/lib/flatMap.js': [ 'flatMap', @@ -306,33 +293,30 @@ describe('HasteMap', () => { [], null, ], - 'fruits/node_modules/react/react.js': [ + 'fruits/node_modules/react/React.js': [ 'React', 32, 1, ['Component'], null, ], - - 'fruits/pear.js': ['Pear', 32, 1, ['Banana', 'Strawberry'], null], - 'fruits/strawberry.js': ['Strawberry', 32, 1, [], null], - 'vegetables/melon.js': ['Melon', 32, 1, [], null], + 'vegetables/Melon.js': ['Melon', 32, 1, [], null], }), ); expect(data.map).toEqual( createMap({ - Banana: {[H.GENERIC_PLATFORM]: ['fruits/banana.js', H.MODULE]}, - Melon: {[H.GENERIC_PLATFORM]: ['vegetables/melon.js', H.MODULE]}, - Pear: {[H.GENERIC_PLATFORM]: ['fruits/pear.js', H.MODULE]}, + Banana: {[H.GENERIC_PLATFORM]: ['fruits/Banana.js', H.MODULE]}, + Melon: {[H.GENERIC_PLATFORM]: ['vegetables/Melon.js', H.MODULE]}, + Pear: {[H.GENERIC_PLATFORM]: ['fruits/Pear.js', H.MODULE]}, React: { [H.GENERIC_PLATFORM]: [ - 'fruits/node_modules/react/react.js', + 'fruits/node_modules/react/React.js', H.MODULE, ], }, Strawberry: { - [H.GENERIC_PLATFORM]: ['fruits/strawberry.js', H.MODULE], + [H.GENERIC_PLATFORM]: ['fruits/Strawberry.js', H.MODULE], }, flatMap: { [H.GENERIC_PLATFORM]: [ @@ -365,11 +349,11 @@ describe('HasteMap', () => { // The node crawler returns "null" for the SHA-1. data.files = createMap({ + 'fruits/Banana.js': ['Banana', 32, 0, ['Strawberry'], null], + 'fruits/Pear.js': ['Pear', 32, 0, ['Banana', 'Strawberry'], null], + 'fruits/Strawberry.js': ['Strawberry', 32, 0, [], null], 'fruits/__mocks__/Pear.js': ['', 32, 0, ['Melon'], null], - 'fruits/banana.js': ['Banana', 32, 0, ['Strawberry'], null], - 'fruits/pear.js': ['Pear', 32, 0, ['Banana', 'Strawberry'], null], - 'fruits/strawberry.js': ['Strawberry', 32, 0, [], null], - 'vegetables/melon.js': ['Melon', 32, 0, [], null], + 'vegetables/Melon.js': ['Melon', 32, 0, [], null], }); return Promise.resolve(data); @@ -387,40 +371,40 @@ describe('HasteMap', () => { expect(data.files).toEqual( createMap({ - 'fruits/__mocks__/Pear.js': [ - '', - 32, - 1, - ['Melon'], - 'a315b7804be2b124b77c1f107205397f45226964', - ], - 'fruits/banana.js': [ + 'fruits/Banana.js': [ 'Banana', 32, 1, ['Strawberry'], - 'f24c6984cce6f032f6d55d771d04ab8dbbe63c8c', + '7772b628e422e8cf59c526be4bb9f44c0898e3d1', ], - 'fruits/pear.js': [ + 'fruits/Pear.js': [ 'Pear', 32, 1, ['Banana', 'Strawberry'], - '211a8ff1e67007b204727d26943c15cf9fd00031', + '89d0c2cc11dcc5e1df50b8af04ab1b597acfba2f', ], - 'fruits/strawberry.js': [ + 'fruits/Strawberry.js': [ 'Strawberry', 32, 1, [], - 'd55d545ad7d997cb2aa10fb412e0cc287d4fbfb3', + 'e8aa38e232b3795f062f1d777731d9240c0f8c25', ], - 'vegetables/melon.js': [ + 'fruits/__mocks__/Pear.js': [ + '', + 32, + 1, + ['Melon'], + '8d40afbb6e2dc78e1ba383b6d02cafad35cceef2', + ], + 'vegetables/Melon.js': [ 'Melon', 32, 1, [], - '45c5d30e29313187829dfd5a16db81c3143fbcc7', + 'f16ccf6f2334ceff2ddb47628a2c5f2d748198ca', ], }), ); @@ -431,12 +415,9 @@ describe('HasteMap', () => { }); it('does not crawl native files even if requested to do so', async () => { - mockFs['/project/video/i-require-a-video.js'] = [ - '/**', - ' * @providesModule IRequireAVideo', - ' */', - 'module.exports = require("./video.mp4");', - ].join('\n'); + mockFs['/project/video/IRequireAVideo.js'] = ` + module.exports = require("./video.mp4"); + `; const hasteMap = new HasteMap( Object.assign({}, defaultConfig, { @@ -453,11 +434,9 @@ describe('HasteMap', () => { }); it('retains all files if `retainAllFiles` is specified', () => { - mockFs['/project/fruits/node_modules/fbjs/index.js'] = [ - '/**', - ' * @providesModule fbjs', - ' */', - ].join('\n'); + mockFs['/project/fruits/node_modules/fbjs/fbjs.js'] = ` + // fbjs! + `; const hasteMap = new HasteMap( Object.assign({}, defaultConfig, { @@ -469,7 +448,7 @@ describe('HasteMap', () => { return hasteMap.build().then(({__hasteMapForTest: data}) => { // Expect the node module to be part of files but make sure it wasn't // read. - expect(data.files.get('fruits/node_modules/fbjs/index.js')).toEqual([ + expect(data.files.get('fruits/node_modules/fbjs/fbjs.js')).toEqual([ '', 32, 0, @@ -486,16 +465,12 @@ describe('HasteMap', () => { it('warns on duplicate mock files', () => { // Duplicate mock files for blueberry - mockFs['/project/fruits1/__mocks__/subdir/blueberry.js'] = [ - '/**', - ' * @providesModule Blueberry1', - ' */', - ].join('\n'); - mockFs['/project/fruits2/__mocks__/subdir/blueberry.js'] = [ - '/**', - ' * @providesModule Blueberry2', - ' */', - ].join('\n'); + mockFs['/project/fruits1/__mocks__/subdir/Blueberry.js'] = ` + // Blueberry + `; + mockFs['/project/fruits2/__mocks__/subdir/Blueberry.js'] = ` + // Blueberry too! + `; return new HasteMap( Object.assign({mocksPattern: '__mocks__'}, defaultConfig), @@ -507,13 +482,9 @@ describe('HasteMap', () => { }); it('warns on duplicate module ids', () => { - // Raspberry thinks it is a Strawberry - mockFs['/project/fruits/raspberry.js'] = [ - '/**', - ' * @providesModule Strawberry', - ' */', - 'const Banana = require("Banana");', - ].join('\n'); + mockFs['/project/fruits/other/Strawberry.js'] = ` + const Banana = require("Banana"); + `; return new HasteMap(defaultConfig) .build() @@ -530,12 +501,9 @@ describe('HasteMap', () => { it('throws on duplicate module ids if "throwOnModuleCollision" is set to true', () => { // Raspberry thinks it is a Strawberry - mockFs['/project/fruits/raspberry.js'] = [ - '/**', - ' * @providesModule Strawberry', - ' */', - 'const Banana = require("Banana");', - ].join('\n'); + mockFs['/project/fruits/another/Strawberry.js'] = ` + const Banana = require("Banana"); + `; return new HasteMap( Object.assign({throwOnModuleCollision: true}, defaultConfig), @@ -548,56 +516,47 @@ describe('HasteMap', () => { it('splits up modules by platform', () => { mockFs = Object.create(null); - mockFs['/project/fruits/strawberry.js'] = [ - '/**', - ' * @providesModule Strawberry', - ' */', - 'const Banana = require("Banana");', - ].join('\n'); - - mockFs['/project/fruits/strawberry.ios.js'] = [ - '/**', - ' * @providesModule Strawberry', - ' */', - 'const Raspberry = require("Raspberry");', - ].join('\n'); - - mockFs['/project/fruits/strawberry.android.js'] = [ - '/**', - ' * @providesModule Strawberry', - ' */', - 'const Blackberry = require("Blackberry");', - ].join('\n'); + mockFs['/project/fruits/Strawberry.js'] = ` + const Banana = require("Banana"); + `; + + mockFs['/project/fruits/Strawberry.ios.js'] = ` + const Raspberry = require("Raspberry"); + `; + + mockFs['/project/fruits/Strawberry.android.js'] = ` + const Blackberry = require("Blackberry"); + `; return new HasteMap(defaultConfig) .build() .then(({__hasteMapForTest: data}) => { expect(data.files).toEqual( createMap({ - 'fruits/strawberry.android.js': [ + 'fruits/Strawberry.android.js': [ 'Strawberry', 32, 1, ['Blackberry'], null, ], - 'fruits/strawberry.ios.js': [ + 'fruits/Strawberry.ios.js': [ 'Strawberry', 32, 1, ['Raspberry'], null, ], - 'fruits/strawberry.js': ['Strawberry', 32, 1, ['Banana'], null], + 'fruits/Strawberry.js': ['Strawberry', 32, 1, ['Banana'], null], }), ); expect(data.map).toEqual( createMap({ Strawberry: { - [H.GENERIC_PLATFORM]: ['fruits/strawberry.js', H.MODULE], - android: ['fruits/strawberry.android.js', H.MODULE], - ios: ['fruits/strawberry.ios.js', H.MODULE], + [H.GENERIC_PLATFORM]: ['fruits/Strawberry.js', H.MODULE], + android: ['fruits/Strawberry.android.js', H.MODULE], + ios: ['fruits/Strawberry.ios.js', H.MODULE], }, }), ); @@ -646,12 +605,9 @@ describe('HasteMap', () => { // Let's assume one JS file has changed. mockChangedFiles = object({ - '/project/fruits/banana.js': [ - '/**', - ' * @providesModule Kiwi', // Identity crisis. - ' */', - 'const Raspberry = require("Raspberry");', - ].join('\n'), + '/project/fruits/Banana.js': ` + const Kiwi = require("Kiwi"); + `, }); // Watchman would give us different clocks for `/project/fruits`. @@ -671,21 +627,18 @@ describe('HasteMap', () => { expect(fs.readFileSync).toBeCalledWith(cacheFilePath, 'utf8'); } expect(fs.readFileSync).toBeCalledWith( - '/project/fruits/banana.js', + '/project/fruits/Banana.js', 'utf8', ); expect(normalizeMap(data.clocks)).toEqual(mockClocks); const files = new Map(initialData.files); - files.set('fruits/banana.js', ['Kiwi', 32, 1, ['Raspberry'], null]); + files.set('fruits/Banana.js', ['Banana', 32, 1, ['Kiwi'], null]); expect(normalizeMap(data.files)).toEqual(files); const map = new Map(initialData.map); - - map.set('Kiwi', map.get('Banana')); - map.delete('Banana'); expect(normalizeMap(data.map)).toEqual(map); }); })); @@ -697,9 +650,9 @@ describe('HasteMap', () => { fs.readFileSync.mockClear(); // Let's assume one JS file was removed. - delete mockFs['/project/fruits/banana.js']; + delete mockFs['/project/fruits/Banana.js']; mockChangedFiles = object({ - '/project/fruits/banana.js': null, + '/project/fruits/Banana.js': null, }); // Watchman would give us different clocks for `/project/fruits`. @@ -712,7 +665,7 @@ describe('HasteMap', () => { .build() .then(({__hasteMapForTest: data}) => { const files = new Map(initialData.files); - files.delete('fruits/banana.js'); + files.delete('fruits/Banana.js'); expect(normalizeMap(data.files)).toEqual(files); const map = new Map(initialData.map); @@ -723,104 +676,83 @@ describe('HasteMap', () => { it('correctly handles platform-specific file additions', async () => { mockFs = Object.create(null); - mockFs['/project/fruits/strawberry.js'] = [ - '/**', - ' * @providesModule Strawberry', - ' */', - 'const Banana = require("Banana");', - ].join('\n'); + mockFs['/project/fruits/Strawberry.js'] = ` + const Banana = require("Banana"); + `; let data; ({__hasteMapForTest: data} = await new HasteMap(defaultConfig).build()); expect(data.map.get('Strawberry')).toEqual({ - g: ['fruits/strawberry.js', 0], + g: ['fruits/Strawberry.js', 0], }); - delete mockFs['/project/fruits/strawberry.ios.js']; + delete mockFs['/project/fruits/Strawberry.ios.js']; mockChangedFiles = object({ - '/project/fruits/strawberry.ios.js': [ - '/**', - ' * @providesModule Strawberry', - ' */', - 'const Raspberry = require("Raspberry");', - ].join('\n'), + '/project/fruits/Strawberry.ios.js': ` + const Raspberry = require("Raspberry"); + `, }); mockClocks = createMap({fruits: 'c:fake-clock:3'}); ({__hasteMapForTest: data} = await new HasteMap(defaultConfig).build()); expect(data.map.get('Strawberry')).toEqual({ - g: ['fruits/strawberry.js', 0], - ios: ['fruits/strawberry.ios.js', 0], + g: ['fruits/Strawberry.js', 0], + ios: ['fruits/Strawberry.ios.js', 0], }); }); it('correctly handles platform-specific file deletions', async () => { mockFs = Object.create(null); - mockFs['/project/fruits/strawberry.js'] = [ - '/**', - ' * @providesModule Strawberry', - ' */', - 'const Banana = require("Banana");', - ].join('\n'); - mockFs['/project/fruits/strawberry.ios.js'] = [ - '/**', - ' * @providesModule Strawberry', - ' */', - 'const Raspberry = require("Raspberry");', - ].join('\n'); + mockFs['/project/fruits/Strawberry.js'] = ` + const Banana = require("Banana"); + `; + mockFs['/project/fruits/Strawberry.ios.js'] = ` + const Raspberry = require("Raspberry"); + `; let data; ({__hasteMapForTest: data} = await new HasteMap(defaultConfig).build()); expect(data.map.get('Strawberry')).toEqual({ - g: ['fruits/strawberry.js', 0], - ios: ['fruits/strawberry.ios.js', 0], + g: ['fruits/Strawberry.js', 0], + ios: ['fruits/Strawberry.ios.js', 0], }); - delete mockFs['/project/fruits/strawberry.ios.js']; - mockChangedFiles = object({'/project/fruits/strawberry.ios.js': null}); + delete mockFs['/project/fruits/Strawberry.ios.js']; + mockChangedFiles = object({'/project/fruits/Strawberry.ios.js': null}); mockClocks = createMap({fruits: 'c:fake-clock:3'}); ({__hasteMapForTest: data} = await new HasteMap(defaultConfig).build()); expect(data.map.get('Strawberry')).toEqual({ - g: ['fruits/strawberry.js', 0], + g: ['fruits/Strawberry.js', 0], }); }); it('correctly handles platform-specific file renames', async () => { mockFs = Object.create(null); - mockFs['/project/fruits/strawberry.ios.js'] = [ - '/**', - ' * @providesModule Strawberry', - ' */', - 'const Raspberry = require("Raspberry");', - ].join('\n'); + mockFs['/project/fruits/Strawberry.ios.js'] = ` + const Raspberry = require("Raspberry"); + `; let data; ({__hasteMapForTest: data} = await new HasteMap(defaultConfig).build()); expect(data.map.get('Strawberry')).toEqual({ - ios: ['fruits/strawberry.ios.js', 0], + ios: ['fruits/Strawberry.ios.js', 0], }); - delete mockFs['/project/fruits/strawberry.ios.js']; + delete mockFs['/project/fruits/Strawberry.ios.js']; mockChangedFiles = object({ - '/project/fruits/strawberry.ios.js': null, - '/project/fruits/strawberry.js': [ - '/**', - ' * @providesModule Strawberry', - ' */', - 'const Banana = require("Banana");', - ].join('\n'), + '/project/fruits/Strawberry.ios.js': null, + '/project/fruits/Strawberry.js': ` + const Banana = require("Banana"); + `, }); mockClocks = createMap({fruits: 'c:fake-clock:3'}); ({__hasteMapForTest: data} = await new HasteMap(defaultConfig).build()); expect(data.map.get('Strawberry')).toEqual({ - g: ['fruits/strawberry.js', 0], + g: ['fruits/Strawberry.js', 0], }); }); describe('duplicate modules', () => { beforeEach(async () => { - mockFs['/project/fruits/another_strawberry.js'] = [ - '/**', - ' * @providesModule Strawberry', - ' */', - 'const Blackberry = require("Blackberry");', - ].join('\n'); + mockFs['/project/fruits/another/Strawberry.js'] = ` + const Blackberry = require("Blackberry"); + `; const {__hasteMapForTest: data} = await new HasteMap( defaultConfig, @@ -828,7 +760,7 @@ describe('HasteMap', () => { expect(normalizeMap(data.duplicates)).toEqual( createMap({ Strawberry: { - g: {'fruits/another_strawberry.js': 0, 'fruits/strawberry.js': 0}, + g: {'fruits/Strawberry.js': 0, 'fruits/another/Strawberry.js': 0}, }, }), ); @@ -836,9 +768,9 @@ describe('HasteMap', () => { }); it('recovers when a duplicate file is deleted', async () => { - delete mockFs['/project/fruits/another_strawberry.js']; + delete mockFs['/project/fruits/another/Strawberry.js']; mockChangedFiles = object({ - '/project/fruits/another_strawberry.js': null, + '/project/fruits/another/Strawberry.js': null, }); mockClocks = createMap({ fruits: 'c:fake-clock:3', @@ -850,20 +782,18 @@ describe('HasteMap', () => { ).build(); expect(normalizeMap(data.duplicates)).toEqual(new Map()); expect(data.map.get('Strawberry')).toEqual({ - g: ['fruits/strawberry.js', 0], + g: ['fruits/Strawberry.js', 0], }); // Make sure the other files are not affected. - expect(data.map.get('Banana')).toEqual({g: ['fruits/banana.js', 0]}); + expect(data.map.get('Banana')).toEqual({g: ['fruits/Banana.js', 0]}); }); it('recovers when a duplicate module is renamed', async () => { mockChangedFiles = object({ - '/project/fruits/another_strawberry.js': [ - '/**', - ' * @providesModule AnotherStrawberry', - ' */', - 'const Blackberry = require("Blackberry");', - ].join('\n'), + '/project/fruits/another/Pineapple.js': ` + const Blackberry = require("Blackberry"); + `, + '/project/fruits/another/Strawberry.js': null, }); mockClocks = createMap({ fruits: 'c:fake-clock:3', @@ -875,13 +805,13 @@ describe('HasteMap', () => { ).build(); expect(normalizeMap(data.duplicates)).toEqual(new Map()); expect(data.map.get('Strawberry')).toEqual({ - g: ['fruits/strawberry.js', 0], + g: ['fruits/Strawberry.js', 0], }); - expect(data.map.get('AnotherStrawberry')).toEqual({ - g: ['fruits/another_strawberry.js', 0], + expect(data.map.get('Pineapple')).toEqual({ + g: ['fruits/another/Pineapple.js', 0], }); // Make sure the other files are not affected. - expect(data.map.get('Banana')).toEqual({g: ['fruits/banana.js', 0]}); + expect(data.map.get('Banana')).toEqual({g: ['fruits/Banana.js', 0]}); }); }); @@ -900,7 +830,7 @@ describe('HasteMap', () => { }); const config = Object.assign({}, defaultConfig, { - ignorePattern: /kiwi|pear/, + ignorePattern: /Kiwi|Pear/, }); return new HasteMap(config).build().then(({moduleMap}) => { expect(moduleMap.getModule('Pear')).toBe(null); @@ -933,6 +863,7 @@ describe('HasteMap', () => { const jestWorker = require('jest-worker'); return new HasteMap( Object.assign({}, defaultConfig, { + hasteImplModulePath: undefined, maxWorkers: 4, }), ) @@ -947,7 +878,7 @@ describe('HasteMap', () => { { computeDependencies: true, computeSha1: false, - filePath: '/project/fruits/__mocks__/Pear.js', + filePath: '/project/fruits/Banana.js', hasteImplModulePath: undefined, rootDir: '/project', }, @@ -956,7 +887,7 @@ describe('HasteMap', () => { { computeDependencies: true, computeSha1: false, - filePath: '/project/fruits/banana.js', + filePath: '/project/fruits/Pear.js', hasteImplModulePath: undefined, rootDir: '/project', }, @@ -965,7 +896,7 @@ describe('HasteMap', () => { { computeDependencies: true, computeSha1: false, - filePath: '/project/fruits/pear.js', + filePath: '/project/fruits/Strawberry.js', hasteImplModulePath: undefined, rootDir: '/project', }, @@ -974,7 +905,7 @@ describe('HasteMap', () => { { computeDependencies: true, computeSha1: false, - filePath: '/project/fruits/strawberry.js', + filePath: '/project/fruits/__mocks__/Pear.js', hasteImplModulePath: undefined, rootDir: '/project', }, @@ -983,7 +914,7 @@ describe('HasteMap', () => { { computeDependencies: true, computeSha1: false, - filePath: '/project/vegetables/melon.js', + filePath: '/project/vegetables/Melon.js', hasteImplModulePath: undefined, rootDir: '/project', }, @@ -1004,7 +935,7 @@ describe('HasteMap', () => { node.mockImplementation(options => { const {data} = options; data.files = createMap({ - 'fruits/banana.js': ['', 32, 0, [], null], + 'fruits/Banana.js': ['', 32, 0, [], null], }); return Promise.resolve(data); }); @@ -1017,7 +948,7 @@ describe('HasteMap', () => { expect(data.files).toEqual( createMap({ - 'fruits/banana.js': ['Banana', 32, 1, ['Strawberry'], null], + 'fruits/Banana.js': ['Banana', 32, 1, ['Strawberry'], null], }), ); @@ -1035,7 +966,7 @@ describe('HasteMap', () => { node.mockImplementation(options => { const {data} = options; data.files = createMap({ - 'fruits/banana.js': ['', 32, 0, [], null], + 'fruits/Banana.js': ['', 32, 0, [], null], }); return Promise.resolve(data); }); @@ -1048,7 +979,7 @@ describe('HasteMap', () => { expect(data.files).toEqual( createMap({ - 'fruits/banana.js': ['Banana', 32, 1, ['Strawberry'], null], + 'fruits/Banana.js': ['Banana', 32, 1, ['Strawberry'], null], }), ); }); @@ -1109,11 +1040,11 @@ describe('HasteMap', () => { hm_it('provides a new set of hasteHS and moduleMap', async hm => { const initialResult = await hm.build(); - const filePath = '/project/fruits/banana.js'; + const filePath = '/project/fruits/Banana.js'; expect(initialResult.hasteFS.getModuleName(filePath)).toBeDefined(); expect(initialResult.moduleMap.getModule('Banana')).toBe(filePath); - mockDeleteFile('/project/fruits', 'banana.js'); - mockDeleteFile('/project/fruits', 'banana.js'); + mockDeleteFile('/project/fruits', 'Banana.js'); + mockDeleteFile('/project/fruits', 'Banana.js'); const {eventsQueue, hasteFS, moduleMap} = await waitForItToChange(hm); expect(eventsQueue).toHaveLength(1); const deletedBanana = {filePath, stat: undefined, type: 'delete'}; @@ -1136,36 +1067,31 @@ describe('HasteMap', () => { }; hm_it('handles several change events at once', async hm => { - mockFs['/project/fruits/tomato.js'] = [ - '/**', - ' * @providesModule Tomato', - ' */', - ].join('\n'); - mockFs['/project/fruits/pear.js'] = [ - '/**', - ' * @providesModule Kiwi', - ' */', - ].join('\n'); + mockFs['/project/fruits/Tomato.js'] = ` + // Tomato! + `; + mockFs['/project/fruits/Pear.js'] = ` + // Pear! + `; const e = mockEmitters['/project/fruits']; - e.emit('all', 'add', 'tomato.js', '/project/fruits', MOCK_STAT_FILE); - e.emit('all', 'change', 'pear.js', '/project/fruits', MOCK_STAT_FILE); + e.emit('all', 'add', 'Tomato.js', '/project/fruits', MOCK_STAT_FILE); + e.emit('all', 'change', 'Pear.js', '/project/fruits', MOCK_STAT_FILE); const {eventsQueue, hasteFS, moduleMap} = await waitForItToChange(hm); expect(eventsQueue).toEqual([ { - filePath: '/project/fruits/tomato.js', + filePath: '/project/fruits/Tomato.js', stat: MOCK_STAT_FILE, type: 'add', }, { - filePath: '/project/fruits/pear.js', + filePath: '/project/fruits/Pear.js', stat: MOCK_STAT_FILE, type: 'change', }, ]); - expect(hasteFS.getModuleName('/project/fruits/tomato.js')).not.toBeNull(); + expect(hasteFS.getModuleName('/project/fruits/Tomato.js')).not.toBeNull(); expect(moduleMap.getModule('Tomato')).toBeDefined(); - expect(moduleMap.getModule('Pear')).toBeNull(); - expect(moduleMap.getModule('Kiwi')).toBe('/project/fruits/pear.js'); + expect(moduleMap.getModule('Pear')).toBe('/project/fruits/Pear.js'); }); hm_it('does not emit duplicate change events', async hm => { @@ -1245,38 +1171,35 @@ describe('HasteMap', () => { }, { mockFs: { - '/project/fruits/Orange.android.js': [ - '/**', - ' * @providesModule Orange', - ' */', - ].join('\n'), - - '/project/fruits/Orange.ios.js': [ - '/**', - ' * @providesModule Orange', - ' */', - ].join('\n'), + '/project/fruits/Orange.android.js': ` + // Orange Android! + `, + '/project/fruits/Orange.ios.js': ` + // Orange iOS! + `, }, }, ); describe('recovery from duplicate module IDs', () => { async function setupDuplicates(hm) { - mockFs['/project/fruits/pear.js'] = [ - '/**', - ' * @providesModule Pear', - ' */', - ].join('\n'); - mockFs['/project/fruits/blueberry.js'] = [ - '/**', - ' * @providesModule Pear', - ' */', - ].join('\n'); + mockFs['/project/fruits/Pear.js'] = ` + // Pear! + `; + mockFs['/project/fruits/another/Pear.js'] = ` + // Pear too! + `; const e = mockEmitters['/project/fruits']; - e.emit('all', 'change', 'pear.js', '/project/fruits', MOCK_STAT_FILE); - e.emit('all', 'add', 'blueberry.js', '/project/fruits', MOCK_STAT_FILE); + e.emit('all', 'change', 'Pear.js', '/project/fruits', MOCK_STAT_FILE); + e.emit( + 'all', + 'add', + 'Pear.js', + '/project/fruits/another', + MOCK_STAT_FILE, + ); const {hasteFS, moduleMap} = await waitForItToChange(hm); - expect(hasteFS.exists('/project/fruits/blueberry.js')).toBe(true); + expect(hasteFS.exists('/project/fruits/another/Pear.js')).toBe(true); try { moduleMap.getModule('Pear'); throw new Error('should be unreachable'); @@ -1289,8 +1212,8 @@ describe('HasteMap', () => { expect(error.platform).toBe('g'); expect(error.supportsNativePlatform).toBe(false); expect(error.duplicatesSet).toEqual({ - '/project/fruits/blueberry.js': 0, - '/project/fruits/pear.js': 0, + '/project/fruits/Pear.js': 0, + '/project/fruits/another/Pear.js': 0, }); expect(error.message).toMatchSnapshot(); } @@ -1300,43 +1223,46 @@ describe('HasteMap', () => { 'recovers when the oldest version of the duplicates is fixed', async hm => { await setupDuplicates(hm); - mockFs['/project/fruits/pear.js'] = [ - '/**', - ' * @providesModule OldPear', - ' */', - ].join('\n'); + mockFs['/project/fruits/Pear.js'] = null; + mockFs['/project/fruits/Pear2.js'] = ` + // Pear! + `; const e = mockEmitters['/project/fruits']; - e.emit('all', 'change', 'pear.js', '/project/fruits', MOCK_STAT_FILE); + e.emit('all', 'delete', 'Pear.js', '/project/fruits', MOCK_STAT_FILE); + e.emit('all', 'add', 'Pear2.js', '/project/fruits', MOCK_STAT_FILE); const {moduleMap} = await waitForItToChange(hm); expect(moduleMap.getModule('Pear')).toBe( - '/project/fruits/blueberry.js', + '/project/fruits/another/Pear.js', ); - expect(moduleMap.getModule('OldPear')).toBe( - '/project/fruits/pear.js', - ); - expect(moduleMap.getModule('Blueberry')).toBe(null); + expect(moduleMap.getModule('Pear2')).toBe('/project/fruits/Pear2.js'); }, ); hm_it('recovers when the most recent duplicate is fixed', async hm => { await setupDuplicates(hm); - mockFs['/project/fruits/blueberry.js'] = [ - '/**', - ' * @providesModule Blueberry', - ' */', - ].join('\n'); + mockFs['/project/fruits/another/Pear.js'] = null; + mockFs['/project/fruits/another/Pear2.js'] = ` + // Pear too! + `; const e = mockEmitters['/project/fruits']; e.emit( 'all', - 'change', - 'blueberry.js', - '/project/fruits', + 'add', + 'Pear2.js', + '/project/fruits/another', + MOCK_STAT_FILE, + ); + e.emit( + 'all', + 'delete', + 'Pear.js', + '/project/fruits/another', MOCK_STAT_FILE, ); const {moduleMap} = await waitForItToChange(hm); - expect(moduleMap.getModule('Pear')).toBe('/project/fruits/pear.js'); - expect(moduleMap.getModule('Blueberry')).toBe( - '/project/fruits/blueberry.js', + expect(moduleMap.getModule('Pear')).toBe('/project/fruits/Pear.js'); + expect(moduleMap.getModule('Pear2')).toBe( + '/project/fruits/another/Pear2.js', ); }); diff --git a/packages/jest-haste-map/src/__tests__/worker.test.js b/packages/jest-haste-map/src/__tests__/worker.test.js index 7ea4645d0222..426502dd3d92 100644 --- a/packages/jest-haste-map/src/__tests__/worker.test.js +++ b/packages/jest-haste-map/src/__tests__/worker.test.js @@ -26,6 +26,16 @@ describe('worker', () => { beforeEach(() => { mockFs = { + '/project/fruits/Banana.js': ` + const Strawberry = require("Strawberry"); + `, + '/project/fruits/Pear.js': ` + const Banana = require("Banana"); + const Strawberry = require('Strawberry'); + `, + '/project/fruits/Strawberry.js': ` + // Strawberry! + `, '/project/fruits/apple.png': Buffer.from([ 137, 80, @@ -36,30 +46,12 @@ describe('worker', () => { 26, 10, ]), - '/project/fruits/banana.js': [ - '/**', - ' * @providesModule Banana', - ' */', - 'const Strawberry = require("Strawberry");', - ].join('\n'), - '/project/fruits/pear.js': [ - '/**', - ' * @providesModule Pear', - ' */', - 'const Banana = require("Banana");', - 'const Strawberry = require(`Strawberry`);', - ].join('\n'), - '/project/fruits/strawberry.js': [ - '/**', - ' * @providesModule Strawberry', - ' */', - ].join('\n'), - '/project/package.json': [ - '{', - ' "name": "haste-package",', - ' "main": "foo.js"', - '}', - ].join('\n'), + '/project/package.json': ` + { + "name": "haste-package", + "main": "foo.js" + } + `, }; readFileSync = fs.readFileSync; @@ -85,44 +77,49 @@ describe('worker', () => { expect( await worker({ computeDependencies: true, - filePath: '/project/fruits/pear.js', + filePath: '/project/fruits/Pear.js', rootDir, }), ).toEqual({ dependencies: ['Banana', 'Strawberry'], - id: 'Pear', - module: ['fruits/pear.js', H.MODULE], }); expect( await worker({ computeDependencies: true, - filePath: '/project/fruits/strawberry.js', + filePath: '/project/fruits/Strawberry.js', rootDir, }), ).toEqual({ dependencies: [], - id: 'Strawberry', - module: ['fruits/strawberry.js', H.MODULE], }); }); it('delegates to hasteImplModulePath for getting the id', async () => { - const moduleData = await worker({ - computeDependencies: true, - filePath: '/project/fruits/strawberry.js', - hasteImplModulePath: path.resolve(__dirname, 'haste_impl.js'), - rootDir, + expect( + await worker({ + computeDependencies: true, + filePath: '/project/fruits/Pear.js', + hasteImplModulePath: require.resolve('./haste_impl.js'), + rootDir, + }), + ).toEqual({ + dependencies: ['Banana', 'Strawberry'], + id: 'Pear', + module: ['fruits/Pear.js', H.MODULE], }); - expect(moduleData.id).toBe('strawberry'); - expect(moduleData).toEqual( - expect.objectContaining({ - dependencies: expect.any(Array), - id: expect.any(String), - module: expect.any(Array), + expect( + await worker({ + computeDependencies: true, + filePath: '/project/fruits/Strawberry.js', + rootDir, }), - ); + ).toEqual({ + dependencies: [], + id: 'Strawberry', + module: ['fruits/Strawberry.js', H.MODULE], + }); }); it('parses package.json files as haste packages', async () => { @@ -163,7 +160,7 @@ describe('worker', () => { expect( await getSha1({ computeSha1: false, - filePath: '/project/fruits/banana.js', + filePath: '/project/fruits/Banana.js', rootDir, }), ).toEqual({sha1: null}); @@ -171,18 +168,18 @@ describe('worker', () => { expect( await getSha1({ computeSha1: true, - filePath: '/project/fruits/banana.js', + filePath: '/project/fruits/Banana.js', rootDir, }), - ).toEqual({sha1: 'f24c6984cce6f032f6d55d771d04ab8dbbe63c8c'}); + ).toEqual({sha1: '7772b628e422e8cf59c526be4bb9f44c0898e3d1'}); expect( await getSha1({ computeSha1: true, - filePath: '/project/fruits/pear.js', + filePath: '/project/fruits/Pear.js', rootDir, }), - ).toEqual({sha1: '1bf6fc618461c19553e27f8b8021c62b13ff614a'}); + ).toEqual({sha1: '0cb0930919e068f146da84d9a0ad0182e4bdb673'}); await expect( getSha1({computeSha1: true, filePath: '/i/dont/exist.js', rootDir}), @@ -193,14 +190,14 @@ describe('worker', () => { expect( await worker({ computeDependencies: false, - filePath: '/project/fruits/pear.js', + filePath: '/project/fruits/Pear.js', hasteImplModulePath: path.resolve(__dirname, 'haste_impl.js'), rootDir, }), ).toEqual({ dependencies: undefined, - id: 'pear', - module: ['fruits/pear.js', H.MODULE], + id: 'Pear', + module: ['fruits/Pear.js', H.MODULE], sha1: undefined, }); diff --git a/packages/jest-haste-map/src/blacklist.js b/packages/jest-haste-map/src/blacklist.js index 6acaeb9b949b..3a7f3795e625 100644 --- a/packages/jest-haste-map/src/blacklist.js +++ b/packages/jest-haste-map/src/blacklist.js @@ -15,8 +15,7 @@ // reflected in the list. Adding "application/" is too risky since some text // file formats (like ".js" and ".json") have an "application/" MIME type. // -// Feel free to add any extensions that cannot contain any "@providesModule" -// annotation. +// Feel free to add any extensions that cannot be a Haste module. const extensions: Set = new Set([ // JSONs are never haste modules, except for "package.json", which is handled. diff --git a/packages/jest-haste-map/src/index.js b/packages/jest-haste-map/src/index.js index 1d2383da5e62..77d7fb17ef99 100644 --- a/packages/jest-haste-map/src/index.js +++ b/packages/jest-haste-map/src/index.js @@ -398,7 +398,7 @@ class HasteMap extends EventEmitter { const existingModule = moduleMap[platform]; if (existingModule && existingModule[H.PATH] !== module[H.PATH]) { const message = - `jest-haste-map: @providesModule naming collision:\n` + + `jest-haste-map: Haste module naming collision:\n` + ` Duplicate module name: ${id}\n` + ` Paths: ${fastPath.resolve( rootDir, @@ -406,8 +406,8 @@ class HasteMap extends EventEmitter { )} collides with ` + `${fastPath.resolve(rootDir, existingModule[H.PATH])}\n\nThis ` + `${this._options.throwOnModuleCollision ? 'error' : 'warning'} ` + - `is caused by a @providesModule declaration ` + - `with the same name across two different files.`; + `is caused by \`hasteImpl\` returning the same name for different` + + ` files.`; if (this._options.throwOnModuleCollision) { throw new Error(message); } diff --git a/packages/jest-haste-map/src/worker.js b/packages/jest-haste-map/src/worker.js index 019622b1caf9..53bc98be296d 100644 --- a/packages/jest-haste-map/src/worker.js +++ b/packages/jest-haste-map/src/worker.js @@ -11,7 +11,6 @@ import type {HasteImpl, WorkerMessage, WorkerMetadata} from './types'; import crypto from 'crypto'; import path from 'path'; -import * as docblock from 'jest-docblock'; import fs from 'graceful-fs'; import blacklist from './blacklist'; import H from './constants'; @@ -75,9 +74,6 @@ export async function worker(data: WorkerMessage): Promise { // Process a random file that is returned as a MODULE. if (hasteImpl) { id = hasteImpl.getHasteName(filePath); - } else { - const doc = docblock.parse(docblock.extract(getContent())); - id = [].concat(doc.providesModule || doc.provides)[0]; } if (computeDependencies) { diff --git a/packages/jest-runtime/src/__mocks__/createRuntime.js b/packages/jest-runtime/src/__mocks__/createRuntime.js index 8c56f2b38010..7300afa587a8 100644 --- a/packages/jest-runtime/src/__mocks__/createRuntime.js +++ b/packages/jest-runtime/src/__mocks__/createRuntime.js @@ -16,6 +16,18 @@ module.exports = function createRuntime(filename, config) { config = normalize( Object.assign( { + haste: { + hasteImplModulePath: path.resolve( + __dirname, + '..', + '..', + '..', + 'jest-haste-map', + 'src', + '__tests__', + 'haste_impl.js', + ), + }, name: 'Runtime-' + filename.replace(/\W/, '-') + '.tests', rootDir: path.resolve(path.dirname(filename), 'test_root'), }, diff --git a/packages/jest-runtime/src/__tests__/runtime_require_mock.test.js b/packages/jest-runtime/src/__tests__/runtime_require_mock.test.js index 5b3539072a0e..796baf311a5e 100644 --- a/packages/jest-runtime/src/__tests__/runtime_require_mock.test.js +++ b/packages/jest-runtime/src/__tests__/runtime_require_mock.test.js @@ -54,7 +54,7 @@ describe('Runtime', () => { expect(exports.getModuleStateValue()).toBe('test value'); })); - it('automocks @providesModule modules without a manual mock', () => + it('automocks haste modules without a manual mock', () => createRuntime(__filename).then(runtime => { const exports = runtime.requireMock( runtime.__mockRootPath, @@ -100,7 +100,7 @@ describe('Runtime', () => { } })); - it('stores and re-uses automocked @providesModule exports', () => + it('stores and re-uses automocked haste exports', () => createRuntime(__filename).then(runtime => { let exports = runtime.requireMock( runtime.__mockRootPath, @@ -130,7 +130,7 @@ describe('Runtime', () => { ).toBeDefined(); })); - it('throws on non-existent @providesModule modules', () => + it('throws on non-existent haste modules', () => createRuntime(__filename).then(runtime => { expect(() => { runtime.requireMock(runtime.__mockRootPath, 'DoesntExist'); diff --git a/packages/jest-runtime/src/__tests__/runtime_require_module.test.js b/packages/jest-runtime/src/__tests__/runtime_require_module.test.js index af8907c08b52..054f5c4a25f0 100644 --- a/packages/jest-runtime/src/__tests__/runtime_require_module.test.js +++ b/packages/jest-runtime/src/__tests__/runtime_require_module.test.js @@ -18,7 +18,7 @@ describe('Runtime requireModule', () => { createRuntime = require('createRuntime'); }); - it('finds @providesModule modules', () => + it('finds haste modules', () => createRuntime(__filename).then(runtime => { const exports = runtime.requireModule( runtime.__mockRootPath, @@ -142,7 +142,7 @@ describe('Runtime requireModule', () => { }); })); - it('throws on non-existent @providesModule modules', () => + it('throws on non-existent haste modules', () => createRuntime(__filename).then(runtime => { expect(() => { runtime.requireModule(runtime.__mockRootPath, 'DoesntExist'); diff --git a/packages/jest-runtime/src/__tests__/test_root/ManuallyMocked.js b/packages/jest-runtime/src/__tests__/test_root/ManuallyMocked.js index 2f5433f9823b..f64a42aaca22 100644 --- a/packages/jest-runtime/src/__tests__/test_root/ManuallyMocked.js +++ b/packages/jest-runtime/src/__tests__/test_root/ManuallyMocked.js @@ -4,7 +4,6 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @providesModule ManuallyMocked */ 'use strict'; diff --git a/packages/jest-runtime/src/__tests__/test_root/ModuleWithSideEffects.js b/packages/jest-runtime/src/__tests__/test_root/ModuleWithSideEffects.js index c4b199463d1f..13d2e706c160 100644 --- a/packages/jest-runtime/src/__tests__/test_root/ModuleWithSideEffects.js +++ b/packages/jest-runtime/src/__tests__/test_root/ModuleWithSideEffects.js @@ -4,7 +4,6 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @providesModule ModuleWithSideEffects */ 'use strict'; diff --git a/packages/jest-runtime/src/__tests__/test_root/OnlyRequiredFromMock.js b/packages/jest-runtime/src/__tests__/test_root/OnlyRequiredFromMock.js index 4deac38e32d3..07eef6272439 100644 --- a/packages/jest-runtime/src/__tests__/test_root/OnlyRequiredFromMock.js +++ b/packages/jest-runtime/src/__tests__/test_root/OnlyRequiredFromMock.js @@ -4,7 +4,6 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @providesModule OnlyRequiredFromMock */ 'use strict'; diff --git a/packages/jest-runtime/src/__tests__/test_root/RegularModule.js b/packages/jest-runtime/src/__tests__/test_root/RegularModule.js index 1370098e928a..e2736f7f9070 100644 --- a/packages/jest-runtime/src/__tests__/test_root/RegularModule.js +++ b/packages/jest-runtime/src/__tests__/test_root/RegularModule.js @@ -4,7 +4,6 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @providesModule RegularModule */ 'use strict'; diff --git a/packages/jest-runtime/src/__tests__/test_root/RelativeImageStub.js b/packages/jest-runtime/src/__tests__/test_root/RelativeImageStub.js index 0bb5d866fa4d..27a59152664b 100644 --- a/packages/jest-runtime/src/__tests__/test_root/RelativeImageStub.js +++ b/packages/jest-runtime/src/__tests__/test_root/RelativeImageStub.js @@ -4,7 +4,6 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @providesModule RelativeImageStub */ 'use strict'; diff --git a/packages/jest-runtime/src/__tests__/test_root/RequireRegularModule.js b/packages/jest-runtime/src/__tests__/test_root/RequireRegularModule.js index 2e988cf606ac..b643a7ec2251 100644 --- a/packages/jest-runtime/src/__tests__/test_root/RequireRegularModule.js +++ b/packages/jest-runtime/src/__tests__/test_root/RequireRegularModule.js @@ -4,7 +4,6 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @providesModule RequireRegularModule */ 'use strict'; diff --git a/packages/jest-runtime/src/__tests__/test_root/global_image_stub.js b/packages/jest-runtime/src/__tests__/test_root/global_image_stub.js index b5c5b7b4d98a..f2aa94927430 100644 --- a/packages/jest-runtime/src/__tests__/test_root/global_image_stub.js +++ b/packages/jest-runtime/src/__tests__/test_root/global_image_stub.js @@ -4,7 +4,6 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @providesModule global_image_stub */ 'use strict'; diff --git a/packages/jest-runtime/src/__tests__/test_root/haste-modules/Foo.react.js b/packages/jest-runtime/src/__tests__/test_root/haste-modules/Foo.react.js index 86600c4f8798..6ef15b0fa5c6 100644 --- a/packages/jest-runtime/src/__tests__/test_root/haste-modules/Foo.react.js +++ b/packages/jest-runtime/src/__tests__/test_root/haste-modules/Foo.react.js @@ -4,7 +4,6 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @providesModule Foo.react */ 'use strict'; diff --git a/packages/jest-runtime/src/__tests__/test_root/haste-modules/FooContainer.react.js b/packages/jest-runtime/src/__tests__/test_root/haste-modules/FooContainer.react.js index 1b245be935dc..59a26d92ee61 100644 --- a/packages/jest-runtime/src/__tests__/test_root/haste-modules/FooContainer.react.js +++ b/packages/jest-runtime/src/__tests__/test_root/haste-modules/FooContainer.react.js @@ -4,7 +4,6 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @providesModule FooContainer.react */ 'use strict'; diff --git a/packages/jest-runtime/src/__tests__/test_root/haste-modules/FooRenderUtil.js b/packages/jest-runtime/src/__tests__/test_root/haste-modules/FooRenderUtil.js index a216b08f2bab..02cc5d6c702a 100644 --- a/packages/jest-runtime/src/__tests__/test_root/haste-modules/FooRenderUtil.js +++ b/packages/jest-runtime/src/__tests__/test_root/haste-modules/FooRenderUtil.js @@ -4,7 +4,6 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @providesModule FooRenderUtil */ 'use strict'; diff --git a/packages/jest-runtime/src/__tests__/test_root/inner_parent_module.js b/packages/jest-runtime/src/__tests__/test_root/inner_parent_module.js index 840e482ca047..b798a006f2a4 100644 --- a/packages/jest-runtime/src/__tests__/test_root/inner_parent_module.js +++ b/packages/jest-runtime/src/__tests__/test_root/inner_parent_module.js @@ -4,7 +4,6 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @providesModule inner_parent_module */ 'use strict'; diff --git a/packages/jest-runtime/src/__tests__/test_root/platform/platform.android.js b/packages/jest-runtime/src/__tests__/test_root/platform/Platform.android.js similarity index 90% rename from packages/jest-runtime/src/__tests__/test_root/platform/platform.android.js rename to packages/jest-runtime/src/__tests__/test_root/platform/Platform.android.js index 20a655e821af..850ce4ab781f 100644 --- a/packages/jest-runtime/src/__tests__/test_root/platform/platform.android.js +++ b/packages/jest-runtime/src/__tests__/test_root/platform/Platform.android.js @@ -4,7 +4,6 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @providesModule Platform */ 'use strict'; diff --git a/packages/jest-runtime/src/__tests__/test_root/platform/platform.ios.js b/packages/jest-runtime/src/__tests__/test_root/platform/Platform.ios.js similarity index 89% rename from packages/jest-runtime/src/__tests__/test_root/platform/platform.ios.js rename to packages/jest-runtime/src/__tests__/test_root/platform/Platform.ios.js index 4caaaed2af20..bc880488f2af 100644 --- a/packages/jest-runtime/src/__tests__/test_root/platform/platform.ios.js +++ b/packages/jest-runtime/src/__tests__/test_root/platform/Platform.ios.js @@ -4,7 +4,6 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @providesModule Platform */ 'use strict'; diff --git a/packages/jest-runtime/src/__tests__/test_root/platform/platform.js b/packages/jest-runtime/src/__tests__/test_root/platform/Platform.js similarity index 90% rename from packages/jest-runtime/src/__tests__/test_root/platform/platform.js rename to packages/jest-runtime/src/__tests__/test_root/platform/Platform.js index 71ded2564ac9..00fee88580ed 100644 --- a/packages/jest-runtime/src/__tests__/test_root/platform/platform.js +++ b/packages/jest-runtime/src/__tests__/test_root/platform/Platform.js @@ -4,7 +4,6 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @providesModule Platform */ 'use strict'; diff --git a/packages/jest-runtime/src/__tests__/test_root/platform/platform.native.js b/packages/jest-runtime/src/__tests__/test_root/platform/Platform.native.js similarity index 90% rename from packages/jest-runtime/src/__tests__/test_root/platform/platform.native.js rename to packages/jest-runtime/src/__tests__/test_root/platform/Platform.native.js index 5ae9a7f6cf9e..e14c4fdf2446 100644 --- a/packages/jest-runtime/src/__tests__/test_root/platform/platform.native.js +++ b/packages/jest-runtime/src/__tests__/test_root/platform/Platform.native.js @@ -4,7 +4,6 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @providesModule Platform */ 'use strict'; diff --git a/packages/jest-runtime/src/__tests__/test_root/root.js b/packages/jest-runtime/src/__tests__/test_root/root.js index 8c2e2309a034..1e0b5acd4974 100644 --- a/packages/jest-runtime/src/__tests__/test_root/root.js +++ b/packages/jest-runtime/src/__tests__/test_root/root.js @@ -4,7 +4,6 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @providesModule root */ 'use strict';