From 78dadaea26983385593daa9f8a59b2e9f472b873 Mon Sep 17 00:00:00 2001 From: Peter Danis Date: Fri, 20 Oct 2017 11:24:58 +0200 Subject: [PATCH 1/9] Correct project directory path case on Windows --- packages/jest-cli/src/cli/index.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/jest-cli/src/cli/index.js b/packages/jest-cli/src/cli/index.js index e7a9c02e9ff8..ff6acc5d62ce 100644 --- a/packages/jest-cli/src/cli/index.js +++ b/packages/jest-cli/src/cli/index.js @@ -142,7 +142,11 @@ const getProjectListFromCLIArgs = (argv, project: ?Path) => { } if (!projects.length) { - projects.push(process.cwd()); + if (process.platform === 'win32') { + projects.push(process.binding('fs').realpath(process.cwd())); + } else { + projects.push(process.cwd()); + } } return projects; From c47755fa66993c741dd7d6fdbf5054a8bd5791a0 Mon Sep 17 00:00:00 2001 From: Peter Danis Date: Fri, 20 Oct 2017 13:11:23 +0200 Subject: [PATCH 2/9] fixup! Add try-catch block with fallback --- packages/jest-cli/src/cli/index.js | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/packages/jest-cli/src/cli/index.js b/packages/jest-cli/src/cli/index.js index ff6acc5d62ce..1ce69913790a 100644 --- a/packages/jest-cli/src/cli/index.js +++ b/packages/jest-cli/src/cli/index.js @@ -141,14 +141,19 @@ const getProjectListFromCLIArgs = (argv, project: ?Path) => { projects.push(project); } - if (!projects.length) { - if (process.platform === 'win32') { + if (!projects.length && process.platform === 'win32') { + try { projects.push(process.binding('fs').realpath(process.cwd())); - } else { - projects.push(process.cwd()); + } catch (err) { + // do nothing, just catch error + // process.binding('fs').realpath can throw, e.g. on mapped drives } } + if (!projects.length) { + projects.push(process.cwd()); + } + return projects; }; From af59143539e7ffecb6cd21bd8b2a09ada9dac4d7 Mon Sep 17 00:00:00 2001 From: Peter Danis Date: Tue, 31 Oct 2017 08:23:21 +0100 Subject: [PATCH 3/9] Make only_changed test pass on Windows --- .../__tests__/only_changed.test.js | 49 +++++++++---------- integration_tests/utils.js | 7 ++- 2 files changed, 29 insertions(+), 27 deletions(-) diff --git a/integration_tests/__tests__/only_changed.test.js b/integration_tests/__tests__/only_changed.test.js index 155777e13dd5..6411fd13b62b 100644 --- a/integration_tests/__tests__/only_changed.test.js +++ b/integration_tests/__tests__/only_changed.test.js @@ -14,13 +14,10 @@ import os from 'os'; import path from 'path'; const {cleanup, run, writeFiles} = require('../utils'); -const skipOnWindows = require('../../scripts/skip_on_windows'); const DIR = path.resolve(os.tmpdir(), 'jest_only_changed'); const GIT = 'git -c user.name=jest_test -c user.email=jest_test@test.com'; const HG = 'hg --config ui.username=jest_test'; -skipOnWindows.suite(); - beforeEach(() => cleanup(DIR)); afterEach(() => cleanup(DIR)); @@ -45,7 +42,7 @@ test('run only changed files', () => { expect(stdout).toMatch('No tests found related to files'); ({stderr} = runJest(DIR, ['-o', '--lastCommit'])); - expect(stderr).toMatch('PASS __tests__/file1.test.js'); + expect(stderr).toMatch(/PASS __tests__(\/|\\)file1.test.js/); writeFiles(DIR, { '__tests__/file2.test.js': `require('../file2'); test('file2', () => {});`, @@ -56,9 +53,9 @@ test('run only changed files', () => { ({stderr} = runJest(DIR, ['-o'])); - expect(stderr).not.toMatch('PASS __tests__/file1.test.js'); - expect(stderr).toMatch('PASS __tests__/file2.test.js'); - expect(stderr).toMatch('PASS __tests__/file3.test.js'); + expect(stderr).not.toMatch(/PASS __tests__(\/|\\)file1.test.js/); + expect(stderr).toMatch(/PASS __tests__(\/|\\)file2.test.js/); + expect(stderr).toMatch(/PASS __tests__(\/|\\)file3.test.js/); run(`${GIT} add .`, DIR); run(`${GIT} commit -m "second"`, DIR); @@ -71,9 +68,9 @@ test('run only changed files', () => { }); ({stderr} = runJest(DIR, ['-o'])); - expect(stderr).not.toMatch('PASS __tests__/file1.test.js'); - expect(stderr).toMatch('PASS __tests__/file2.test.js'); - expect(stderr).toMatch('PASS __tests__/file3.test.js'); + expect(stderr).not.toMatch(/PASS __tests__(\/|\\)file1.test.j/); + expect(stderr).toMatch(/PASS __tests__(\/|\\)file2.test.js/); + expect(stderr).toMatch(/PASS __tests__(\/|\\)file3.test.js/); }); test('onlyChanged in config is overwritten by --all or testPathPattern', () => { @@ -100,7 +97,7 @@ test('onlyChanged in config is overwritten by --all or testPathPattern', () => { ); ({stderr} = runJest(DIR, ['--lastCommit'])); - expect(stderr).toMatch('PASS __tests__/file1.test.js'); + expect(stderr).toMatch(/PASS __tests__(\/|\\)file1.test.js/); writeFiles(DIR, { '__tests__/file2.test.js': `require('../file2'); test('file2', () => {});`, @@ -111,9 +108,9 @@ test('onlyChanged in config is overwritten by --all or testPathPattern', () => { ({stderr} = runJest(DIR)); - expect(stderr).not.toMatch('PASS __tests__/file1.test.js'); - expect(stderr).toMatch('PASS __tests__/file2.test.js'); - expect(stderr).toMatch('PASS __tests__/file3.test.js'); + expect(stderr).not.toMatch(/PASS __tests__(\/|\\)file1.test.js/); + expect(stderr).toMatch(/PASS __tests__(\/|\\)file2.test.js/); + expect(stderr).toMatch(/PASS __tests__(\/|\\)file3.test.js/); run(`${GIT} add .`, DIR); run(`${GIT} commit -m "second"`, DIR); @@ -123,7 +120,7 @@ test('onlyChanged in config is overwritten by --all or testPathPattern', () => { ({stderr, stdout} = runJest(DIR, ['file2.test.js'])); expect(stdout).not.toMatch('No tests found related to files'); - expect(stderr).toMatch('PASS __tests__/file2.test.js'); + expect(stderr).toMatch(/PASS __tests__(\/|\\)file2.test.js/); expect(stderr).toMatch('1 total'); writeFiles(DIR, { @@ -131,14 +128,14 @@ test('onlyChanged in config is overwritten by --all or testPathPattern', () => { }); ({stderr} = runJest(DIR)); - expect(stderr).not.toMatch('PASS __tests__/file1.test.js'); - expect(stderr).toMatch('PASS __tests__/file2.test.js'); - expect(stderr).toMatch('PASS __tests__/file3.test.js'); + expect(stderr).not.toMatch(/PASS __tests__(\/|\\)file1.test.js/); + expect(stderr).toMatch(/PASS __tests__(\/|\\)file2.test.js/); + expect(stderr).toMatch(/PASS __tests__(\/|\\)file3.test.js/); ({stderr} = runJest(DIR, ['--all'])); - expect(stderr).toMatch('PASS __tests__/file1.test.js'); - expect(stderr).toMatch('PASS __tests__/file2.test.js'); - expect(stderr).toMatch('PASS __tests__/file3.test.js'); + expect(stderr).toMatch(/PASS __tests__(\/|\\)file1.test.js/); + expect(stderr).toMatch(/PASS __tests__(\/|\\)file2.test.js/); + expect(stderr).toMatch(/PASS __tests__(\/|\\)file3.test.js/); }); test('gets changed files for hg', async () => { @@ -173,7 +170,7 @@ test('gets changed files for hg', async () => { }); ({stdout, stderr} = runJest(DIR, ['-o'])); - expect(stderr).toMatch('PASS __tests__/file2.test.js'); + expect(stderr).toMatch(/PASS __tests__(\/|\\)file2.test.js/); run(`${HG} add .`, DIR); run(`${HG} commit -m "test2"`, DIR); @@ -183,10 +180,10 @@ test('gets changed files for hg', async () => { }); ({stdout, stderr} = runJest(DIR, ['-o'])); - expect(stderr).toMatch('PASS __tests__/file3.test.js'); - expect(stderr).not.toMatch('PASS __tests__/file2.test.js'); + expect(stderr).toMatch(/PASS __tests__(\/|\\)file3.test.js/); + expect(stderr).not.toMatch(/PASS __tests__(\/|\\)file2.test.js/); ({stdout, stderr} = runJest(DIR, ['-o', '--changedFilesWithAncestor'])); - expect(stderr).toMatch('PASS __tests__/file2.test.js'); - expect(stderr).toMatch('PASS __tests__/file3.test.js'); + expect(stderr).toMatch(/PASS __tests__(\/|\\)file2.test.js/); + expect(stderr).toMatch(/PASS __tests__(\/|\\)file3.test.js/); }); diff --git a/integration_tests/utils.js b/integration_tests/utils.js index 87fa132ed1d0..9c2f2de8e25c 100644 --- a/integration_tests/utils.js +++ b/integration_tests/utils.js @@ -82,7 +82,12 @@ const cleanup = (directory: string) => rimraf.sync(directory); const writeFiles = (directory: string, files: {[filename: string]: string}) => { mkdirp.sync(directory); Object.keys(files).forEach(fileOrPath => { - const filePath = fileOrPath.split(path.sep); // ['tmp', 'a.js'] + let filePath; + if (process.platform === 'win32') { + filePath = fileOrPath.replace(/(\/)/g, path.sep).split(path.sep); // ['tmp', 'a.js'] + } else { + filePath = fileOrPath.split(path.sep); // ['tmp', 'a.js'] + } const filename = filePath.pop(); // filepath becomes dirPath (no filename) if (filePath.length) { From b1c3f48b90b65c9d9103dca04119964233280e45 Mon Sep 17 00:00:00 2001 From: Peter Danis Date: Tue, 31 Oct 2017 10:43:13 +0100 Subject: [PATCH 4/9] Add test --- .../__tests__/only_changed.test.js | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/integration_tests/__tests__/only_changed.test.js b/integration_tests/__tests__/only_changed.test.js index 6411fd13b62b..02812d4f5c86 100644 --- a/integration_tests/__tests__/only_changed.test.js +++ b/integration_tests/__tests__/only_changed.test.js @@ -187,3 +187,42 @@ test('gets changed files for hg', async () => { expect(stderr).toMatch(/PASS __tests__(\/|\\)file2.test.js/); expect(stderr).toMatch(/PASS __tests__(\/|\\)file3.test.js/); }); + +test('path on Windows is case-insensitive', () => { + if (process.platform !== 'win32') { + // This test is Windows specific, skip it on other platforms. + return; + } + + const modifiedDIR = path.resolve(DIR, 'outer_dir', 'inner_dir'); + const incorrectModifiedDIR = path.resolve(DIR, 'OUTER_dir', 'inner_dir'); + let stderr; + let stdout; + + writeFiles(modifiedDIR, { + '.watchmanconfig': '', + '__tests__/file1.test.js': `require('../file1'); test('file1', () => {});`, + 'file1.js': 'module.exports = {}', + 'package.json': '{}', + }); + + run(`${GIT} init`, modifiedDIR); + run(`${GIT} add .`, modifiedDIR); + run(`${GIT} commit -m "first"`, modifiedDIR); + + ({stdout} = runJest(modifiedDIR, ['-o'])); + expect(stdout).toMatch('No tests found related to files'); + + writeFiles(modifiedDIR, { + '__tests__/file2.test.js': `require('../file2'); test('file2', () => {});`, + '__tests__/file3.test.js': `require('../file3'); test('file3', () => {});`, + 'file2.js': 'module.exports = {}', + 'file3.js': `require('./file2')`, + }); + + ({stderr} = runJest(modifiedDIR, ['-o'])); + + expect(stderr).not.toMatch(/PASS __tests__(\/|\\)file1.test.js/); + expect(stderr).toMatch(/PASS __tests__(\/|\\)file2.test.js/); + expect(stderr).toMatch(/PASS __tests__(\/|\\)file3.test.js/); +}); From f3f44669f429ac25505ae642c3a67010ba8352ba Mon Sep 17 00:00:00 2001 From: Peter Danis Date: Tue, 31 Oct 2017 10:47:47 +0100 Subject: [PATCH 5/9] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 66c855711fb1..ab5f1361efab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ * `[jest-config]` Include error message for `preset` json ([#4766](https://github.com/facebook/jest/pull/4766)) * `[pretty-format]` Throw `PrettyFormatPluginError` if a plugin halts with an exception ([#4787](https://github.com/facebook/jest/pull/4787)) * `[expect]` Keep the stack trace unchanged when `PrettyFormatPluginError` is thrown by pretty-format ([#4787](https://github.com/facebook/jest/pull/4787)) +* `[jest-cli]` Fix `--onlyChanged` path case sensitivity on Windows platform ([#4730](https://github.com/facebook/jest/pull/4730)) ### Features * `[eslint-plugin-jest]` Add `prefer-to-have-length` lint rule. ([#4771](https://github.com/facebook/jest/pull/4771)) From ed855fce334dde876788ebcd667572035df6765d Mon Sep 17 00:00:00 2001 From: Peter Danis Date: Tue, 31 Oct 2017 12:57:24 +0100 Subject: [PATCH 6/9] fixup! Simplify original writeFiles change --- integration_tests/utils.js | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/integration_tests/utils.js b/integration_tests/utils.js index 9c2f2de8e25c..ebab684b0ee0 100644 --- a/integration_tests/utils.js +++ b/integration_tests/utils.js @@ -82,12 +82,7 @@ const cleanup = (directory: string) => rimraf.sync(directory); const writeFiles = (directory: string, files: {[filename: string]: string}) => { mkdirp.sync(directory); Object.keys(files).forEach(fileOrPath => { - let filePath; - if (process.platform === 'win32') { - filePath = fileOrPath.replace(/(\/)/g, path.sep).split(path.sep); // ['tmp', 'a.js'] - } else { - filePath = fileOrPath.split(path.sep); // ['tmp', 'a.js'] - } + const filePath = fileOrPath.split('/'); // ['tmp', 'a.js'] const filename = filePath.pop(); // filepath becomes dirPath (no filename) if (filePath.length) { From f6350d13d4b075a4dd5c0c8687ac007aa0014a25 Mon Sep 17 00:00:00 2001 From: Peter Danis Date: Tue, 31 Oct 2017 14:54:17 +0100 Subject: [PATCH 7/9] fixup! Ignore process.binding flow error --- packages/jest-cli/src/cli/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/jest-cli/src/cli/index.js b/packages/jest-cli/src/cli/index.js index 1ce69913790a..0943ce068d59 100644 --- a/packages/jest-cli/src/cli/index.js +++ b/packages/jest-cli/src/cli/index.js @@ -143,6 +143,7 @@ const getProjectListFromCLIArgs = (argv, project: ?Path) => { if (!projects.length && process.platform === 'win32') { try { + // $FlowFixMe projects.push(process.binding('fs').realpath(process.cwd())); } catch (err) { // do nothing, just catch error From 4c82bb574a8556a6ecbe9ba3a2257818d4eeb2ad Mon Sep 17 00:00:00 2001 From: Peter Danis Date: Tue, 31 Oct 2017 15:05:20 +0100 Subject: [PATCH 8/9] fixup! Use correct dir --- integration_tests/__tests__/only_changed.test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/integration_tests/__tests__/only_changed.test.js b/integration_tests/__tests__/only_changed.test.js index 02812d4f5c86..fa70846d076c 100644 --- a/integration_tests/__tests__/only_changed.test.js +++ b/integration_tests/__tests__/only_changed.test.js @@ -210,7 +210,7 @@ test('path on Windows is case-insensitive', () => { run(`${GIT} add .`, modifiedDIR); run(`${GIT} commit -m "first"`, modifiedDIR); - ({stdout} = runJest(modifiedDIR, ['-o'])); + ({stdout} = runJest(incorrectModifiedDIR, ['-o'])); expect(stdout).toMatch('No tests found related to files'); writeFiles(modifiedDIR, { @@ -220,7 +220,7 @@ test('path on Windows is case-insensitive', () => { 'file3.js': `require('./file2')`, }); - ({stderr} = runJest(modifiedDIR, ['-o'])); + ({stderr} = runJest(incorrectModifiedDIR, ['-o'])); expect(stderr).not.toMatch(/PASS __tests__(\/|\\)file1.test.js/); expect(stderr).toMatch(/PASS __tests__(\/|\\)file2.test.js/); From aa941c65ca52c0192cfce00dc09983593f4d1a0c Mon Sep 17 00:00:00 2001 From: Peter Danis Date: Tue, 31 Oct 2017 15:20:11 +0100 Subject: [PATCH 9/9] fixup! Fix lint error --- integration_tests/__tests__/only_changed.test.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/integration_tests/__tests__/only_changed.test.js b/integration_tests/__tests__/only_changed.test.js index fa70846d076c..85f326b24ab8 100644 --- a/integration_tests/__tests__/only_changed.test.js +++ b/integration_tests/__tests__/only_changed.test.js @@ -196,8 +196,6 @@ test('path on Windows is case-insensitive', () => { const modifiedDIR = path.resolve(DIR, 'outer_dir', 'inner_dir'); const incorrectModifiedDIR = path.resolve(DIR, 'OUTER_dir', 'inner_dir'); - let stderr; - let stdout; writeFiles(modifiedDIR, { '.watchmanconfig': '', @@ -210,7 +208,7 @@ test('path on Windows is case-insensitive', () => { run(`${GIT} add .`, modifiedDIR); run(`${GIT} commit -m "first"`, modifiedDIR); - ({stdout} = runJest(incorrectModifiedDIR, ['-o'])); + const {stdout} = runJest(incorrectModifiedDIR, ['-o']); expect(stdout).toMatch('No tests found related to files'); writeFiles(modifiedDIR, { @@ -220,7 +218,7 @@ test('path on Windows is case-insensitive', () => { 'file3.js': `require('./file2')`, }); - ({stderr} = runJest(incorrectModifiedDIR, ['-o'])); + const {stderr} = runJest(incorrectModifiedDIR, ['-o']); expect(stderr).not.toMatch(/PASS __tests__(\/|\\)file1.test.js/); expect(stderr).toMatch(/PASS __tests__(\/|\\)file2.test.js/);