Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add path case-insensitivity if onlyChanged option is active, fixes #4644 #4730

Merged
merged 10 commits into from
Nov 17, 2017
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
## master

### Fixes

* `[expect]` fix .toThrow for promises
([#4884](https://github.com/facebook/jest/pull/4884))
* `[jest-docblock]` pragmas should preserve urls
Expand Down Expand Up @@ -44,6 +43,9 @@
thrown by pretty-format ([#4787](https://github.com/facebook/jest/pull/4787))
* `[jest-environment-jsdom]` Fix asynchronous test will fail due to timeout
issue. ([#4669](https://github.com/facebook/jest/pull/4669))
* `[jest-cli]` Fix `--onlyChanged` path case sensitivity on Windows platform
([#4730](https://github.com/facebook/jest/pull/4730))


### Features

Expand Down
86 changes: 60 additions & 26 deletions integration_tests/__tests__/only_changed.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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));

Expand All @@ -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', () => {});`,
Expand All @@ -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);
Expand All @@ -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', () => {
Expand All @@ -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', () => {});`,
Expand All @@ -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);
Expand All @@ -123,22 +120,22 @@ 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, {
'file2.js': 'module.exports = {modified: true}',
});

({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 () => {
Expand Down Expand Up @@ -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);
Expand All @@ -183,10 +180,47 @@ 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/);
});

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');

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);

const {stdout} = runJest(incorrectModifiedDIR, ['-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')`,
});

const {stderr} = runJest(incorrectModifiedDIR, ['-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/);
});
2 changes: 1 addition & 1 deletion integration_tests/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +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 => {
const filePath = fileOrPath.split(path.sep); // ['tmp', 'a.js']
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we do const filePath = fileOrPath.split(path.posix.sep); here? (or just fileOrPath.split('/'))

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for suggestion. Changed to const filePath = fileOrPath.split('/')

const filePath = fileOrPath.split('/'); // ['tmp', 'a.js']
const filename = filePath.pop(); // filepath becomes dirPath (no filename)

if (filePath.length) {
Expand Down
10 changes: 10 additions & 0 deletions packages/jest-cli/src/cli/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,16 @@ const getProjectListFromCLIArgs = (argv, project: ?Path) => {
projects.push(project);
}

if (!projects.length && process.platform === 'win32') {
try {
// $FlowFixMe
projects.push(process.binding('fs').realpath(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());
}
Expand Down