From 6302ed63be720331058d4fa09449372b75cf3bbd Mon Sep 17 00:00:00 2001 From: Mihail Bodrov Date: Sat, 6 Jul 2019 02:25:22 +0300 Subject: [PATCH 01/15] Clear resolved modules cache before runJest in watch mode :bug: --- e2e/__tests__/__snapshots__/moduleNameMapper.test.ts.snap | 2 +- .../__snapshots__/resolveNoFileExtensions.test.ts.snap | 2 +- packages/jest-core/package.json | 1 + packages/jest-core/src/watch.ts | 4 ++++ packages/jest-resolve/src/defaultResolver.ts | 4 ++++ packages/jest-resolve/src/index.ts | 6 +++++- 6 files changed, 16 insertions(+), 3 deletions(-) diff --git a/e2e/__tests__/__snapshots__/moduleNameMapper.test.ts.snap b/e2e/__tests__/__snapshots__/moduleNameMapper.test.ts.snap index 18ccc60fbe68..a3759f42c96f 100644 --- a/e2e/__tests__/__snapshots__/moduleNameMapper.test.ts.snap +++ b/e2e/__tests__/__snapshots__/moduleNameMapper.test.ts.snap @@ -30,6 +30,6 @@ FAIL __tests__/index.js 12 | module.exports = () => 'test'; 13 | - at createNoMappedModuleFoundError (../../packages/jest-resolve/build/index.js:472:17) + at createNoMappedModuleFoundError (../../packages/jest-resolve/build/index.js:501:17) at Object.require (index.js:10:1) `; diff --git a/e2e/__tests__/__snapshots__/resolveNoFileExtensions.test.ts.snap b/e2e/__tests__/__snapshots__/resolveNoFileExtensions.test.ts.snap index f88d38ad9041..7a66f6098b01 100644 --- a/e2e/__tests__/__snapshots__/resolveNoFileExtensions.test.ts.snap +++ b/e2e/__tests__/__snapshots__/resolveNoFileExtensions.test.ts.snap @@ -33,6 +33,6 @@ FAIL __tests__/test.js | ^ 4 | - at Resolver.resolveModule (../../packages/jest-resolve/build/index.js:230:17) + at Resolver.resolveModule (../../packages/jest-resolve/build/index.js:259:17) at Object.require (index.js:3:18) `; diff --git a/packages/jest-core/package.json b/packages/jest-core/package.json index 9f980af3c53d..a63d9f48fb08 100644 --- a/packages/jest-core/package.json +++ b/packages/jest-core/package.json @@ -19,6 +19,7 @@ "jest-haste-map": "^24.8.0", "jest-message-util": "^24.8.0", "jest-regex-util": "^24.3.0", + "jest-resolve": "^24.3.0", "jest-resolve-dependencies": "^24.8.0", "jest-runner": "^24.8.0", "jest-runtime": "^24.8.0", diff --git a/packages/jest-core/src/watch.ts b/packages/jest-core/src/watch.ts index 5b97d1623709..3cbf0444d86c 100644 --- a/packages/jest-core/src/watch.ts +++ b/packages/jest-core/src/watch.ts @@ -15,6 +15,7 @@ import {formatExecError} from 'jest-message-util'; import {isInteractive, preRunMessage, specialChars} from 'jest-util'; import {ValidationError} from 'jest-validate'; import {Context} from 'jest-runtime'; +import Resolver from 'jest-resolve'; import {Config} from '@jest/types'; import { AllowedConfigOptions, @@ -275,6 +276,9 @@ export default function watch( isRunning = true; const configs = contexts.map(context => context.config); const changedFilesPromise = getChangedFilesPromise(globalConfig, configs); + // Clear cache for required modules + Resolver.clearCache(); + return runJest({ changedFilesPromise, contexts, diff --git a/packages/jest-resolve/src/defaultResolver.ts b/packages/jest-resolve/src/defaultResolver.ts index 42a0d31ee939..40e7949b12e4 100644 --- a/packages/jest-resolve/src/defaultResolver.ts +++ b/packages/jest-resolve/src/defaultResolver.ts @@ -44,6 +44,10 @@ export default function defaultResolver( }); } +export const clearResolverCache = () => { + checkedPaths.clear(); +}; + const REGEX_RELATIVE_IMPORT = /^(?:\.\.?(?:\/|$)|\/|([A-Za-z]:)?[\\\/])/; function resolveSync( diff --git a/packages/jest-resolve/src/index.ts b/packages/jest-resolve/src/index.ts index a3e09432dde2..b607ed8db450 100644 --- a/packages/jest-resolve/src/index.ts +++ b/packages/jest-resolve/src/index.ts @@ -12,7 +12,7 @@ import {sync as realpath} from 'realpath-native'; import chalk from 'chalk'; import nodeModulesPaths from './nodeModulesPaths'; import isBuiltinModule from './isBuiltinModule'; -import defaultResolver from './defaultResolver'; +import defaultResolver, {clearResolverCache} from './defaultResolver'; import {ResolverConfig} from './types'; type FindNodeModuleConfig = { @@ -79,6 +79,10 @@ class Resolver { this._modulePathCache = new Map(); } + static clearCache() { + clearResolverCache(); + } + static findNodeModule( path: Config.Path, options: FindNodeModuleConfig, From b508cfee4d46daddf32f3837f490b4e38a6ea6b4 Mon Sep 17 00:00:00 2001 From: Mihail Bodrov Date: Wed, 10 Jul 2019 01:06:54 +0300 Subject: [PATCH 02/15] Add mini test for checking clearCache emit --- packages/jest-core/package.json | 2 +- .../jest-core/src/__tests__/watch.test.js | 64 +++++++++++++++++++ 2 files changed, 65 insertions(+), 1 deletion(-) diff --git a/packages/jest-core/package.json b/packages/jest-core/package.json index a63d9f48fb08..60bf1868942f 100644 --- a/packages/jest-core/package.json +++ b/packages/jest-core/package.json @@ -19,7 +19,7 @@ "jest-haste-map": "^24.8.0", "jest-message-util": "^24.8.0", "jest-regex-util": "^24.3.0", - "jest-resolve": "^24.3.0", + "jest-resolve": "^24.8.0", "jest-resolve-dependencies": "^24.8.0", "jest-runner": "^24.8.0", "jest-runtime": "^24.8.0", diff --git a/packages/jest-core/src/__tests__/watch.test.js b/packages/jest-core/src/__tests__/watch.test.js index 358446807c64..290490f79b1e 100644 --- a/packages/jest-core/src/__tests__/watch.test.js +++ b/packages/jest-core/src/__tests__/watch.test.js @@ -11,6 +11,8 @@ import chalk from 'chalk'; import TestWatcher from '../TestWatcher'; import {JestHook, KEYS} from 'jest-watcher'; +import HasteMap from 'jest-haste-map'; +import fs from 'fs'; const runJestMock = jest.fn(); const watchPluginPath = `${__dirname}/__fixtures__/watch_plugin`; @@ -109,6 +111,10 @@ describe('Watch mode flows', () => { jest.doMock('jest-util/build/isInteractive', () => isInteractive); watch = require('../watch').default; const config = { + haste: { + defaultPlatform: 'android', + }, + moduleFileExtensions: ['js', 'jsx', 'ts', 'tsx', 'json'], rootDir: __dirname, roots: [], testPathIgnorePatterns: [], @@ -576,6 +582,64 @@ describe('Watch mode flows', () => { }); }); + describe('check clear cache modules', () => { + const fileTargetPath = `${__dirname}/__fixtures__/hey.test.js`; + let hasteMapInstance; + let Resolver; + let originalClearCache; + + beforeEach(() => { + Resolver = require('jest-resolve'); + originalClearCache = Resolver.clearCache; + }); + + afterEach(() => { + Resolver.clearCache = originalClearCache; + hasteMapInstance.end(); + try { + fs.unlinkSync(fileTargetPath); + } catch (e) {} + }); + + it('should correct require new files without legacy cache', async () => { + hasteMapInstance = new HasteMap({ + computeSha1: false, + extensions: ['js'], + forceNodeFilesystemAPI: false, + maxWorkers: 2, + name: 'tmp_' + Date.now(), + platforms: [], + retainAllFiles: true, + rootDir: __dirname, + roots: [__dirname], + throwOnModuleCollision: true, + useWatchman: true, + watch: true, + }); + + await hasteMapInstance.build(); + + await watch( + { + ...globalConfig, + rootDir: __dirname, + watchPlugins: [], + }, + contexts, + pipe, + [hasteMapInstance], + stdin, + ); + + Resolver.clearCache = jest.fn(); + + fs.writeFileSync(fileTargetPath, '', {encoding: 'utf-8'}); + + await new Promise(resolve => setTimeout(resolve, 100)); + expect(Resolver.clearCache).toHaveBeenCalledTimes(1); + }); + }); + it('makes watch plugin initialization errors look nice', async () => { const pluginPath = `${__dirname}/__fixtures__/watch_plugin_throws`; From 5fa4548e5ab288e2bf683fb963d44b4121b6d312 Mon Sep 17 00:00:00 2001 From: Mihail Bodrov Date: Wed, 10 Jul 2019 20:30:58 +0300 Subject: [PATCH 03/15] Add good test for watcher :white_check_mark: --- .../src/__tests__/watch-file-changes.test.js | 179 ++++++++++++++++++ .../jest-core/src/__tests__/watch.test.js | 64 ------- packages/jest-core/src/watch.ts | 2 +- packages/jest-resolve/src/defaultResolver.ts | 2 +- packages/jest-resolve/src/index.ts | 6 +- 5 files changed, 184 insertions(+), 69 deletions(-) create mode 100644 packages/jest-core/src/__tests__/watch-file-changes.test.js diff --git a/packages/jest-core/src/__tests__/watch-file-changes.test.js b/packages/jest-core/src/__tests__/watch-file-changes.test.js new file mode 100644 index 000000000000..fc5f242e83c1 --- /dev/null +++ b/packages/jest-core/src/__tests__/watch-file-changes.test.js @@ -0,0 +1,179 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + +'use strict'; + +import {JestHook} from 'jest-watcher'; +import Runtime from 'jest-runtime'; +import {normalize} from 'jest-config'; +import path from 'path'; +import fs from 'fs'; + +describe('Watch mode flows with changed files', () => { + let watch; + let pipe; + let stdin; + const fileTargetPath = `${__dirname}/__fixtures__/hey.js`; + const fileTargetPath2 = `${__dirname}/__fixtures__/heyhey.test.js`; + const cacheDirectory = `${__dirname}/tmp${Math.random()}`; + let hasteMapInstance; + const deleteFolderRecursive = pathname => { + if (fs.existsSync(pathname)) { + fs.readdirSync(pathname).forEach((file, index) => { + const curPath = path.resolve(pathname, file); + if (fs.lstatSync(curPath).isDirectory()) { + // recurse + deleteFolderRecursive(curPath); + } else { + // delete file + fs.unlinkSync(curPath); + } + }); + fs.rmdirSync(pathname); + } + }; + + beforeEach(() => { + watch = require('../watch').default; + pipe = {write: jest.fn()}; + stdin = new MockStdin(); + }); + + afterEach(() => { + jest.resetModules(); + hasteMapInstance.end(); + [fileTargetPath2, fileTargetPath].forEach(file => { + try { + fs.unlinkSync(file); + } catch (e) {} + }); + deleteFolderRecursive(cacheDirectory); + }); + + it('should correct require new files without legacy cache', async () => { + fs.writeFileSync( + fileTargetPath2, + ` + require('${fileTargetPath}'); + describe('Fake test', () => { + it('Hey', () => { + + }); + }); + `, + { + encoding: 'utf-8', + }, + ); + + fs.mkdirSync(cacheDirectory); + const config = normalize( + { + automock: false, + cache: false, + cacheDirectory, + coverageReporters: [], + maxConcurrency: 1, + maxWorkers: 1, + moduleDirectories: ['node_modules'], + moduleFileExtensions: ['js', 'jsx', 'ts', 'tsx', 'json'], + modulePathIgnorePatterns: [], + onlyChanged: false, + reporters: [], + rootDir: __dirname, + roots: [__dirname], + testPathIgnorePatterns: ['/node_modules/'], + testRegex: ['hey\\.test\\.js$'], + watch: false, + watchman: false, + }, + [], + ).options; + + hasteMapInstance = await Runtime.createHasteMap(config, { + maxWorkers: 1, + resetCache: true, + retainAllFiles: true, + watch: true, + watchman: true, + }); + + const realContext = await hasteMapInstance.build().then( + hasteMap => ({ + config, + hasteFS: hasteMap.hasteFS, + moduleMap: hasteMap.moduleMap, + resolver: Runtime.createResolver(config, hasteMap.moduleMap), + }), + error => { + throw error; + }, + ); + + const hook = new JestHook(); + await watch( + { + ...config, + watchPlugins: [], + }, + [realContext], + pipe, + [hasteMapInstance], + stdin, + hook, + ); + + await new Promise(resolve => setTimeout(resolve, 300)); + + fs.writeFileSync( + fileTargetPath, + ` + describe('Fake group', () => { + it('Fake 1', () => {}); + it('Fake 2', () => {}); + it('Fake 3', () => {}); + }); + `, + {encoding: 'utf-8'}, + ); + + const resultReport = await new Promise(resolve => { + hook.getSubscriber().onTestRunComplete(result => { + resolve({ + numFailedTests: result.numFailedTests, + numPassedTests: result.numPassedTests, + }); + }); + }); + + expect(resultReport).toEqual({ + numFailedTests: 0, + numPassedTests: 4, + }); + }); +}); + +class MockStdin { + constructor() { + this._callbacks = []; + } + + setRawMode() {} + + resume() {} + + setEncoding() {} + + on(evt, callback) { + this._callbacks.push(callback); + } + + emit(key) { + this._callbacks.forEach(cb => cb(key)); + } +} diff --git a/packages/jest-core/src/__tests__/watch.test.js b/packages/jest-core/src/__tests__/watch.test.js index 290490f79b1e..358446807c64 100644 --- a/packages/jest-core/src/__tests__/watch.test.js +++ b/packages/jest-core/src/__tests__/watch.test.js @@ -11,8 +11,6 @@ import chalk from 'chalk'; import TestWatcher from '../TestWatcher'; import {JestHook, KEYS} from 'jest-watcher'; -import HasteMap from 'jest-haste-map'; -import fs from 'fs'; const runJestMock = jest.fn(); const watchPluginPath = `${__dirname}/__fixtures__/watch_plugin`; @@ -111,10 +109,6 @@ describe('Watch mode flows', () => { jest.doMock('jest-util/build/isInteractive', () => isInteractive); watch = require('../watch').default; const config = { - haste: { - defaultPlatform: 'android', - }, - moduleFileExtensions: ['js', 'jsx', 'ts', 'tsx', 'json'], rootDir: __dirname, roots: [], testPathIgnorePatterns: [], @@ -582,64 +576,6 @@ describe('Watch mode flows', () => { }); }); - describe('check clear cache modules', () => { - const fileTargetPath = `${__dirname}/__fixtures__/hey.test.js`; - let hasteMapInstance; - let Resolver; - let originalClearCache; - - beforeEach(() => { - Resolver = require('jest-resolve'); - originalClearCache = Resolver.clearCache; - }); - - afterEach(() => { - Resolver.clearCache = originalClearCache; - hasteMapInstance.end(); - try { - fs.unlinkSync(fileTargetPath); - } catch (e) {} - }); - - it('should correct require new files without legacy cache', async () => { - hasteMapInstance = new HasteMap({ - computeSha1: false, - extensions: ['js'], - forceNodeFilesystemAPI: false, - maxWorkers: 2, - name: 'tmp_' + Date.now(), - platforms: [], - retainAllFiles: true, - rootDir: __dirname, - roots: [__dirname], - throwOnModuleCollision: true, - useWatchman: true, - watch: true, - }); - - await hasteMapInstance.build(); - - await watch( - { - ...globalConfig, - rootDir: __dirname, - watchPlugins: [], - }, - contexts, - pipe, - [hasteMapInstance], - stdin, - ); - - Resolver.clearCache = jest.fn(); - - fs.writeFileSync(fileTargetPath, '', {encoding: 'utf-8'}); - - await new Promise(resolve => setTimeout(resolve, 100)); - expect(Resolver.clearCache).toHaveBeenCalledTimes(1); - }); - }); - it('makes watch plugin initialization errors look nice', async () => { const pluginPath = `${__dirname}/__fixtures__/watch_plugin_throws`; diff --git a/packages/jest-core/src/watch.ts b/packages/jest-core/src/watch.ts index 3cbf0444d86c..483983a34aa0 100644 --- a/packages/jest-core/src/watch.ts +++ b/packages/jest-core/src/watch.ts @@ -277,7 +277,7 @@ export default function watch( const configs = contexts.map(context => context.config); const changedFilesPromise = getChangedFilesPromise(globalConfig, configs); // Clear cache for required modules - Resolver.clearCache(); + Resolver.clearDefaultResolverCache(); return runJest({ changedFilesPromise, diff --git a/packages/jest-resolve/src/defaultResolver.ts b/packages/jest-resolve/src/defaultResolver.ts index 40e7949b12e4..8422ebcfc519 100644 --- a/packages/jest-resolve/src/defaultResolver.ts +++ b/packages/jest-resolve/src/defaultResolver.ts @@ -44,7 +44,7 @@ export default function defaultResolver( }); } -export const clearResolverCache = () => { +export const clearDefaultResolverCache = () => { checkedPaths.clear(); }; diff --git a/packages/jest-resolve/src/index.ts b/packages/jest-resolve/src/index.ts index b607ed8db450..9e21e5faa806 100644 --- a/packages/jest-resolve/src/index.ts +++ b/packages/jest-resolve/src/index.ts @@ -12,7 +12,7 @@ import {sync as realpath} from 'realpath-native'; import chalk from 'chalk'; import nodeModulesPaths from './nodeModulesPaths'; import isBuiltinModule from './isBuiltinModule'; -import defaultResolver, {clearResolverCache} from './defaultResolver'; +import defaultResolver, {clearDefaultResolverCache} from './defaultResolver'; import {ResolverConfig} from './types'; type FindNodeModuleConfig = { @@ -79,8 +79,8 @@ class Resolver { this._modulePathCache = new Map(); } - static clearCache() { - clearResolverCache(); + static clearDefaultResolverCache() { + clearDefaultResolverCache(); } static findNodeModule( From 461b527c24b1485596e206a5ba43bda8804e1160 Mon Sep 17 00:00:00 2001 From: Mihail Bodrov Date: Fri, 12 Jul 2019 00:18:08 +0300 Subject: [PATCH 04/15] Add some minor improvments for tests --- .../src/__tests__/watch-file-changes.test.js | 37 +++++++++++++------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/packages/jest-core/src/__tests__/watch-file-changes.test.js b/packages/jest-core/src/__tests__/watch-file-changes.test.js index fc5f242e83c1..3a2866733df9 100644 --- a/packages/jest-core/src/__tests__/watch-file-changes.test.js +++ b/packages/jest-core/src/__tests__/watch-file-changes.test.js @@ -18,8 +18,8 @@ describe('Watch mode flows with changed files', () => { let watch; let pipe; let stdin; - const fileTargetPath = `${__dirname}/__fixtures__/hey.js`; - const fileTargetPath2 = `${__dirname}/__fixtures__/heyhey.test.js`; + const fileTargetPath = `${__dirname}/__fixtures__/lost-file.js`; + const fileTargetPath2 = `${__dirname}/__fixtures__/watch-test.test.js`; const cacheDirectory = `${__dirname}/tmp${Math.random()}`; let hasteMapInstance; const deleteFolderRecursive = pathname => { @@ -88,7 +88,7 @@ describe('Watch mode flows with changed files', () => { rootDir: __dirname, roots: [__dirname], testPathIgnorePatterns: ['/node_modules/'], - testRegex: ['hey\\.test\\.js$'], + testRegex: ['watch-test\\.test\\.js$'], watch: false, watchman: false, }, @@ -129,7 +129,7 @@ describe('Watch mode flows with changed files', () => { ); await new Promise(resolve => setTimeout(resolve, 300)); - + // Create lost file fs.writeFileSync( fileTargetPath, ` @@ -142,18 +142,31 @@ describe('Watch mode flows with changed files', () => { {encoding: 'utf-8'}, ); - const resultReport = await new Promise(resolve => { - hook.getSubscriber().onTestRunComplete(result => { - resolve({ - numFailedTests: result.numFailedTests, - numPassedTests: result.numPassedTests, - }); - }); + const resultSuccessReport = await new Promise(resolve => { + hook.getSubscriber().onTestRunComplete(resolve); }); - expect(resultReport).toEqual({ + expect(resultSuccessReport).toMatchObject({ + numFailedTestSuites: 0, numFailedTests: 0, numPassedTests: 4, + numRuntimeErrorTestSuites: 0, + wasInterrupted: false, + }); + + // Remove again to ensure about no legacy cache + fs.unlinkSync(fileTargetPath); + + const resultErrorReport = await new Promise(resolve => { + hook.getSubscriber().onTestRunComplete(resolve); + }); + + // After remove file we have to fail tests + expect(resultErrorReport).toMatchObject({ + numFailedTestSuites: 1, + numPassedTests: 0, + numRuntimeErrorTestSuites: 1, + wasInterrupted: false, }); }); }); From e0240d1c6d1ffa9315aea28f2d4e3b0699863361 Mon Sep 17 00:00:00 2001 From: Mihail Bodrov Date: Fri, 12 Jul 2019 00:44:42 +0300 Subject: [PATCH 05/15] Use ts instead of js for test :art: --- ...ges.test.js => watch-file-changes.test.ts} | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) rename packages/jest-core/src/__tests__/{watch-file-changes.test.js => watch-file-changes.test.ts} (93%) diff --git a/packages/jest-core/src/__tests__/watch-file-changes.test.js b/packages/jest-core/src/__tests__/watch-file-changes.test.ts similarity index 93% rename from packages/jest-core/src/__tests__/watch-file-changes.test.js rename to packages/jest-core/src/__tests__/watch-file-changes.test.ts index 3a2866733df9..475d228cf69f 100644 --- a/packages/jest-core/src/__tests__/watch-file-changes.test.js +++ b/packages/jest-core/src/__tests__/watch-file-changes.test.ts @@ -8,20 +8,21 @@ 'use strict'; +import path from 'path'; +import fs from 'fs'; import {JestHook} from 'jest-watcher'; import Runtime from 'jest-runtime'; import {normalize} from 'jest-config'; -import path from 'path'; -import fs from 'fs'; +import HasteMap from 'jest-haste-map'; describe('Watch mode flows with changed files', () => { - let watch; - let pipe; - let stdin; + let watch: any; + let pipe: NodeJS.ReadStream; + let stdin: MockStdin; const fileTargetPath = `${__dirname}/__fixtures__/lost-file.js`; const fileTargetPath2 = `${__dirname}/__fixtures__/watch-test.test.js`; const cacheDirectory = `${__dirname}/tmp${Math.random()}`; - let hasteMapInstance; + let hasteMapInstance: HasteMap; const deleteFolderRecursive = pathname => { if (fs.existsSync(pathname)) { fs.readdirSync(pathname).forEach((file, index) => { @@ -40,7 +41,7 @@ describe('Watch mode flows with changed files', () => { beforeEach(() => { watch = require('../watch').default; - pipe = {write: jest.fn()}; + pipe = {write: jest.fn()} as any; stdin = new MockStdin(); }); @@ -92,13 +93,12 @@ describe('Watch mode flows with changed files', () => { watch: false, watchman: false, }, - [], + {} as any, ).options; hasteMapInstance = await Runtime.createHasteMap(config, { maxWorkers: 1, resetCache: true, - retainAllFiles: true, watch: true, watchman: true, }); @@ -172,6 +172,8 @@ describe('Watch mode flows with changed files', () => { }); class MockStdin { + private _callbacks: Array; + constructor() { this._callbacks = []; } @@ -182,11 +184,11 @@ class MockStdin { setEncoding() {} - on(evt, callback) { + on(_: any, callback: any) { this._callbacks.push(callback); } - emit(key) { + emit(key: string) { this._callbacks.forEach(cb => cb(key)); } } From 3c3e3d63bd5e53cf2fc59c89c422bf6b3ccea536 Mon Sep 17 00:00:00 2001 From: Mihail Bodrov Date: Fri, 12 Jul 2019 01:29:32 +0300 Subject: [PATCH 06/15] Fix lint error :shirt: --- .../jest-core/src/__tests__/watch-file-changes.test.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/jest-core/src/__tests__/watch-file-changes.test.ts b/packages/jest-core/src/__tests__/watch-file-changes.test.ts index 475d228cf69f..d18136d654c8 100644 --- a/packages/jest-core/src/__tests__/watch-file-changes.test.ts +++ b/packages/jest-core/src/__tests__/watch-file-changes.test.ts @@ -25,7 +25,7 @@ describe('Watch mode flows with changed files', () => { let hasteMapInstance: HasteMap; const deleteFolderRecursive = pathname => { if (fs.existsSync(pathname)) { - fs.readdirSync(pathname).forEach((file, index) => { + fs.readdirSync(pathname).forEach(file => { const curPath = path.resolve(pathname, file); if (fs.lstatSync(curPath).isDirectory()) { // recurse @@ -88,7 +88,6 @@ describe('Watch mode flows with changed files', () => { reporters: [], rootDir: __dirname, roots: [__dirname], - testPathIgnorePatterns: ['/node_modules/'], testRegex: ['watch-test\\.test\\.js$'], watch: false, watchman: false, @@ -100,7 +99,7 @@ describe('Watch mode flows with changed files', () => { maxWorkers: 1, resetCache: true, watch: true, - watchman: true, + watchman: false, }); const realContext = await hasteMapInstance.build().then( @@ -128,7 +127,10 @@ describe('Watch mode flows with changed files', () => { hook, ); - await new Promise(resolve => setTimeout(resolve, 300)); + await new Promise(resolve => { + hook.getSubscriber().onTestRunComplete(resolve); + }); + // Create lost file fs.writeFileSync( fileTargetPath, From 6b7091cf374c8b1e4b584a8a2de43c43f9d68dc1 Mon Sep 17 00:00:00 2001 From: Mihail Bodrov Date: Fri, 12 Jul 2019 02:05:29 +0300 Subject: [PATCH 07/15] Fix paths in test for Window :white_check_mark: --- .../src/__tests__/watch-file-changes.test.ts | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/packages/jest-core/src/__tests__/watch-file-changes.test.ts b/packages/jest-core/src/__tests__/watch-file-changes.test.ts index d18136d654c8..e53db46b121f 100644 --- a/packages/jest-core/src/__tests__/watch-file-changes.test.ts +++ b/packages/jest-core/src/__tests__/watch-file-changes.test.ts @@ -19,9 +19,17 @@ describe('Watch mode flows with changed files', () => { let watch: any; let pipe: NodeJS.ReadStream; let stdin: MockStdin; - const fileTargetPath = `${__dirname}/__fixtures__/lost-file.js`; - const fileTargetPath2 = `${__dirname}/__fixtures__/watch-test.test.js`; - const cacheDirectory = `${__dirname}/tmp${Math.random()}`; + const fileTargetPath = path.resolve( + __dirname, + '__fixtures__', + 'lost-file.js', + ); + const fileTargetPath2 = path.resolve( + __dirname, + '__fixtures__', + 'watch-test.test.js', + ); + const cacheDirectory = path.resolve(__dirname, `tmp${Math.random()}`); let hasteMapInstance: HasteMap; const deleteFolderRecursive = pathname => { if (fs.existsSync(pathname)) { From 56582f5c69aa9499892de2b94e649d053d727f8c Mon Sep 17 00:00:00 2001 From: Mihail Bodrov Date: Fri, 12 Jul 2019 09:55:11 +0300 Subject: [PATCH 08/15] Add more information to report --- .../src/__tests__/watch-file-changes.test.ts | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/packages/jest-core/src/__tests__/watch-file-changes.test.ts b/packages/jest-core/src/__tests__/watch-file-changes.test.ts index e53db46b121f..48c093c49f2b 100644 --- a/packages/jest-core/src/__tests__/watch-file-changes.test.ts +++ b/packages/jest-core/src/__tests__/watch-file-changes.test.ts @@ -14,6 +14,7 @@ import {JestHook} from 'jest-watcher'; import Runtime from 'jest-runtime'; import {normalize} from 'jest-config'; import HasteMap from 'jest-haste-map'; +import {AggregatedResult} from '@jest/test-result'; describe('Watch mode flows with changed files', () => { let watch: any; @@ -96,6 +97,7 @@ describe('Watch mode flows with changed files', () => { reporters: [], rootDir: __dirname, roots: [__dirname], + silent: true, testRegex: ['watch-test\\.test\\.js$'], watch: false, watchman: false, @@ -152,7 +154,7 @@ describe('Watch mode flows with changed files', () => { {encoding: 'utf-8'}, ); - const resultSuccessReport = await new Promise(resolve => { + const resultSuccessReport: AggregatedResult = await new Promise(resolve => { hook.getSubscriber().onTestRunComplete(resolve); }); @@ -161,13 +163,17 @@ describe('Watch mode flows with changed files', () => { numFailedTests: 0, numPassedTests: 4, numRuntimeErrorTestSuites: 0, + success: true, wasInterrupted: false, }); + expect(resultSuccessReport.testResults[0]).toMatchObject({ + failureMessage: null, + }); // Remove again to ensure about no legacy cache fs.unlinkSync(fileTargetPath); - const resultErrorReport = await new Promise(resolve => { + const resultErrorReport: AggregatedResult = await new Promise(resolve => { hook.getSubscriber().onTestRunComplete(resolve); }); @@ -176,6 +182,7 @@ describe('Watch mode flows with changed files', () => { numFailedTestSuites: 1, numPassedTests: 0, numRuntimeErrorTestSuites: 1, + success: false, wasInterrupted: false, }); }); @@ -188,8 +195,6 @@ class MockStdin { this._callbacks = []; } - setRawMode() {} - resume() {} setEncoding() {} From f673fd96cde1061fe2795716d05d5072bedafb6a Mon Sep 17 00:00:00 2001 From: Mihail Bodrov Date: Fri, 12 Jul 2019 22:40:52 +0300 Subject: [PATCH 09/15] Fix failed test in Windows. Clear code :art: :white_check_mark: --- .../src/__tests__/watch-file-changes.test.ts | 39 ++++--------------- 1 file changed, 7 insertions(+), 32 deletions(-) diff --git a/packages/jest-core/src/__tests__/watch-file-changes.test.ts b/packages/jest-core/src/__tests__/watch-file-changes.test.ts index 48c093c49f2b..f23ae43c0419 100644 --- a/packages/jest-core/src/__tests__/watch-file-changes.test.ts +++ b/packages/jest-core/src/__tests__/watch-file-changes.test.ts @@ -14,44 +14,23 @@ import {JestHook} from 'jest-watcher'; import Runtime from 'jest-runtime'; import {normalize} from 'jest-config'; import HasteMap from 'jest-haste-map'; +import rimraf from 'rimraf'; import {AggregatedResult} from '@jest/test-result'; describe('Watch mode flows with changed files', () => { let watch: any; let pipe: NodeJS.ReadStream; let stdin: MockStdin; - const fileTargetPath = path.resolve( - __dirname, - '__fixtures__', - 'lost-file.js', - ); - const fileTargetPath2 = path.resolve( - __dirname, - '__fixtures__', - 'watch-test.test.js', - ); + const fileTargetPath = path.resolve(__dirname, 'lost-file.js'); + const fileTargetPath2 = path.resolve(__dirname, 'watch-test-fake.test.js'); const cacheDirectory = path.resolve(__dirname, `tmp${Math.random()}`); let hasteMapInstance: HasteMap; - const deleteFolderRecursive = pathname => { - if (fs.existsSync(pathname)) { - fs.readdirSync(pathname).forEach(file => { - const curPath = path.resolve(pathname, file); - if (fs.lstatSync(curPath).isDirectory()) { - // recurse - deleteFolderRecursive(curPath); - } else { - // delete file - fs.unlinkSync(curPath); - } - }); - fs.rmdirSync(pathname); - } - }; beforeEach(() => { watch = require('../watch').default; pipe = {write: jest.fn()} as any; stdin = new MockStdin(); + fs.mkdirSync(cacheDirectory); }); afterEach(() => { @@ -62,14 +41,14 @@ describe('Watch mode flows with changed files', () => { fs.unlinkSync(file); } catch (e) {} }); - deleteFolderRecursive(cacheDirectory); + rimraf.sync(cacheDirectory); }); it('should correct require new files without legacy cache', async () => { fs.writeFileSync( fileTargetPath2, ` - require('${fileTargetPath}'); + require('./lost-file.js'); describe('Fake test', () => { it('Hey', () => { @@ -81,24 +60,20 @@ describe('Watch mode flows with changed files', () => { }, ); - fs.mkdirSync(cacheDirectory); const config = normalize( { - automock: false, cache: false, cacheDirectory, coverageReporters: [], maxConcurrency: 1, maxWorkers: 1, moduleDirectories: ['node_modules'], - moduleFileExtensions: ['js', 'jsx', 'ts', 'tsx', 'json'], - modulePathIgnorePatterns: [], onlyChanged: false, reporters: [], rootDir: __dirname, roots: [__dirname], silent: true, - testRegex: ['watch-test\\.test\\.js$'], + testRegex: ['watch-test-fake\\.test\\.js$'], watch: false, watchman: false, }, From 17a35a5eb0861f78ad6c7e0e6c75e4cb39f0f59b Mon Sep 17 00:00:00 2001 From: Mihail Bodrov Date: Fri, 12 Jul 2019 23:17:18 +0300 Subject: [PATCH 10/15] Use os.tmpdir :shirt: --- packages/jest-core/src/__tests__/watch-file-changes.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/jest-core/src/__tests__/watch-file-changes.test.ts b/packages/jest-core/src/__tests__/watch-file-changes.test.ts index f23ae43c0419..dae9a1ef6516 100644 --- a/packages/jest-core/src/__tests__/watch-file-changes.test.ts +++ b/packages/jest-core/src/__tests__/watch-file-changes.test.ts @@ -10,6 +10,7 @@ import path from 'path'; import fs from 'fs'; +import os from 'os'; import {JestHook} from 'jest-watcher'; import Runtime from 'jest-runtime'; import {normalize} from 'jest-config'; @@ -23,7 +24,7 @@ describe('Watch mode flows with changed files', () => { let stdin: MockStdin; const fileTargetPath = path.resolve(__dirname, 'lost-file.js'); const fileTargetPath2 = path.resolve(__dirname, 'watch-test-fake.test.js'); - const cacheDirectory = path.resolve(__dirname, `tmp${Math.random()}`); + const cacheDirectory = path.resolve(os.tmpdir(), `tmp${Math.random()}`); let hasteMapInstance: HasteMap; beforeEach(() => { From a560aa0b7717c10f916b65b0c4e4ac32315baf18 Mon Sep 17 00:00:00 2001 From: Mihail Bodrov Date: Fri, 12 Jul 2019 23:28:54 +0300 Subject: [PATCH 11/15] Fix infinity llop in watch mode :bug: --- .../src/__tests__/watch-file-changes.test.ts | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/packages/jest-core/src/__tests__/watch-file-changes.test.ts b/packages/jest-core/src/__tests__/watch-file-changes.test.ts index dae9a1ef6516..f49f055499cf 100644 --- a/packages/jest-core/src/__tests__/watch-file-changes.test.ts +++ b/packages/jest-core/src/__tests__/watch-file-changes.test.ts @@ -22,8 +22,12 @@ describe('Watch mode flows with changed files', () => { let watch: any; let pipe: NodeJS.ReadStream; let stdin: MockStdin; - const fileTargetPath = path.resolve(__dirname, 'lost-file.js'); - const fileTargetPath2 = path.resolve(__dirname, 'watch-test-fake.test.js'); + const testDirectory = path.resolve(os.tmpdir(), 'jest-tmp'); + const fileTargetPath = path.resolve(testDirectory, 'lost-file.js'); + const fileTargetPath2 = path.resolve( + testDirectory, + 'watch-test-fake.test.js', + ); const cacheDirectory = path.resolve(os.tmpdir(), `tmp${Math.random()}`); let hasteMapInstance: HasteMap; @@ -31,18 +35,22 @@ describe('Watch mode flows with changed files', () => { watch = require('../watch').default; pipe = {write: jest.fn()} as any; stdin = new MockStdin(); + fs.mkdirSync(testDirectory); fs.mkdirSync(cacheDirectory); }); afterEach(() => { jest.resetModules(); - hasteMapInstance.end(); + if (hasteMapInstance) { + hasteMapInstance.end(); + } [fileTargetPath2, fileTargetPath].forEach(file => { try { fs.unlinkSync(file); } catch (e) {} }); rimraf.sync(cacheDirectory); + rimraf.sync(testDirectory); }); it('should correct require new files without legacy cache', async () => { @@ -71,8 +79,8 @@ describe('Watch mode flows with changed files', () => { moduleDirectories: ['node_modules'], onlyChanged: false, reporters: [], - rootDir: __dirname, - roots: [__dirname], + rootDir: testDirectory, + roots: [testDirectory], silent: true, testRegex: ['watch-test-fake\\.test\\.js$'], watch: false, From b5f09ebcdbc6286b9b2a58f8478d8ab5ac36a354 Mon Sep 17 00:00:00 2001 From: Mihail Bodrov Date: Sat, 13 Jul 2019 00:04:08 +0300 Subject: [PATCH 12/15] Refactored promises to avoid possible fs stream concurrency --- .../src/__tests__/watch-file-changes.test.ts | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/packages/jest-core/src/__tests__/watch-file-changes.test.ts b/packages/jest-core/src/__tests__/watch-file-changes.test.ts index f49f055499cf..0511bd715bc1 100644 --- a/packages/jest-core/src/__tests__/watch-file-changes.test.ts +++ b/packages/jest-core/src/__tests__/watch-file-changes.test.ts @@ -35,6 +35,8 @@ describe('Watch mode flows with changed files', () => { watch = require('../watch').default; pipe = {write: jest.fn()} as any; stdin = new MockStdin(); + rimraf.sync(cacheDirectory); + rimraf.sync(testDirectory); fs.mkdirSync(testDirectory); fs.mkdirSync(cacheDirectory); }); @@ -44,11 +46,6 @@ describe('Watch mode flows with changed files', () => { if (hasteMapInstance) { hasteMapInstance.end(); } - [fileTargetPath2, fileTargetPath].forEach(file => { - try { - fs.unlinkSync(file); - } catch (e) {} - }); rimraf.sync(cacheDirectory); rimraf.sync(testDirectory); }); @@ -109,6 +106,9 @@ describe('Watch mode flows with changed files', () => { ); const hook = new JestHook(); + const firstErrorPromise = new Promise(resolve => { + hook.getSubscriber().onTestRunComplete(resolve); + }); await watch( { ...config, @@ -121,7 +121,9 @@ describe('Watch mode flows with changed files', () => { hook, ); - await new Promise(resolve => { + await firstErrorPromise; + + const successPromise: Promise = new Promise(resolve => { hook.getSubscriber().onTestRunComplete(resolve); }); @@ -138,9 +140,7 @@ describe('Watch mode flows with changed files', () => { {encoding: 'utf-8'}, ); - const resultSuccessReport: AggregatedResult = await new Promise(resolve => { - hook.getSubscriber().onTestRunComplete(resolve); - }); + const resultSuccessReport: AggregatedResult = await successPromise; expect(resultSuccessReport).toMatchObject({ numFailedTestSuites: 0, @@ -154,12 +154,14 @@ describe('Watch mode flows with changed files', () => { failureMessage: null, }); + const errorPromise: Promise = new Promise(resolve => { + hook.getSubscriber().onTestRunComplete(resolve); + }); + // Remove again to ensure about no legacy cache fs.unlinkSync(fileTargetPath); - const resultErrorReport: AggregatedResult = await new Promise(resolve => { - hook.getSubscriber().onTestRunComplete(resolve); - }); + const resultErrorReport: AggregatedResult = await errorPromise; // After remove file we have to fail tests expect(resultErrorReport).toMatchObject({ From 4d4c09c4bf4cfab4796143b288296853d382ae75 Mon Sep 17 00:00:00 2001 From: Mihail Bodrov Date: Sat, 13 Jul 2019 02:32:33 +0300 Subject: [PATCH 13/15] Try to solve strange error in ci mac os --- .../src/__tests__/watch-file-changes.test.ts | 20 ++++++++----------- 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/packages/jest-core/src/__tests__/watch-file-changes.test.ts b/packages/jest-core/src/__tests__/watch-file-changes.test.ts index 0511bd715bc1..5ca4016380c3 100644 --- a/packages/jest-core/src/__tests__/watch-file-changes.test.ts +++ b/packages/jest-core/src/__tests__/watch-file-changes.test.ts @@ -19,6 +19,8 @@ import rimraf from 'rimraf'; import {AggregatedResult} from '@jest/test-result'; describe('Watch mode flows with changed files', () => { + jest.resetModules(); + let watch: any; let pipe: NodeJS.ReadStream; let stdin: MockStdin; @@ -77,7 +79,6 @@ describe('Watch mode flows with changed files', () => { onlyChanged: false, reporters: [], rootDir: testDirectory, - roots: [testDirectory], silent: true, testRegex: ['watch-test-fake\\.test\\.js$'], watch: false, @@ -93,17 +94,12 @@ describe('Watch mode flows with changed files', () => { watchman: false, }); - const realContext = await hasteMapInstance.build().then( - hasteMap => ({ - config, - hasteFS: hasteMap.hasteFS, - moduleMap: hasteMap.moduleMap, - resolver: Runtime.createResolver(config, hasteMap.moduleMap), - }), - error => { - throw error; - }, - ); + const realContext = await hasteMapInstance.build().then(hasteMap => ({ + config, + hasteFS: hasteMap.hasteFS, + moduleMap: hasteMap.moduleMap, + resolver: Runtime.createResolver(config, hasteMap.moduleMap), + })); const hook = new JestHook(); const firstErrorPromise = new Promise(resolve => { From 3a5abc2d7da467f7217205bd1aca13cb2b9d0cb9 Mon Sep 17 00:00:00 2001 From: Mihail Bodrov Date: Sun, 14 Jul 2019 13:09:31 +0300 Subject: [PATCH 14/15] Remove needless param for fs --- .../jest-core/src/__tests__/watch-file-changes.test.ts | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/packages/jest-core/src/__tests__/watch-file-changes.test.ts b/packages/jest-core/src/__tests__/watch-file-changes.test.ts index 5ca4016380c3..9bc34eb0ac2e 100644 --- a/packages/jest-core/src/__tests__/watch-file-changes.test.ts +++ b/packages/jest-core/src/__tests__/watch-file-changes.test.ts @@ -63,9 +63,6 @@ describe('Watch mode flows with changed files', () => { }); }); `, - { - encoding: 'utf-8', - }, ); const config = normalize( @@ -133,10 +130,9 @@ describe('Watch mode flows with changed files', () => { it('Fake 3', () => {}); }); `, - {encoding: 'utf-8'}, ); - const resultSuccessReport: AggregatedResult = await successPromise; + const resultSuccessReport = await successPromise; expect(resultSuccessReport).toMatchObject({ numFailedTestSuites: 0, @@ -157,7 +153,7 @@ describe('Watch mode flows with changed files', () => { // Remove again to ensure about no legacy cache fs.unlinkSync(fileTargetPath); - const resultErrorReport: AggregatedResult = await errorPromise; + const resultErrorReport = await errorPromise; // After remove file we have to fail tests expect(resultErrorReport).toMatchObject({ From 16fb41eeb3f156a19bec900a68a045781090fffa Mon Sep 17 00:00:00 2001 From: Mihail Bodrov Date: Sun, 14 Jul 2019 16:40:18 +0300 Subject: [PATCH 15/15] Optimize promise --- packages/jest-core/src/__tests__/watch-file-changes.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/jest-core/src/__tests__/watch-file-changes.test.ts b/packages/jest-core/src/__tests__/watch-file-changes.test.ts index 9bc34eb0ac2e..ac19096f1b00 100644 --- a/packages/jest-core/src/__tests__/watch-file-changes.test.ts +++ b/packages/jest-core/src/__tests__/watch-file-changes.test.ts @@ -116,7 +116,7 @@ describe('Watch mode flows with changed files', () => { await firstErrorPromise; - const successPromise: Promise = new Promise(resolve => { + const successPromise = new Promise(resolve => { hook.getSubscriber().onTestRunComplete(resolve); }); @@ -146,7 +146,7 @@ describe('Watch mode flows with changed files', () => { failureMessage: null, }); - const errorPromise: Promise = new Promise(resolve => { + const errorPromise = new Promise(resolve => { hook.getSubscriber().onTestRunComplete(resolve); });