Skip to content

Commit

Permalink
Make watch mode work with multiple projects.
Browse files Browse the repository at this point in the history
  • Loading branch information
cpojer committed Apr 12, 2017
1 parent 79063e8 commit d6b4e2e
Show file tree
Hide file tree
Showing 10 changed files with 157 additions and 154 deletions.
20 changes: 5 additions & 15 deletions packages/jest-cli/src/SearchSource.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,6 @@ const {
replacePathSepForRegex,
} = require('jest-regex-util');

type SearchSourceConfig = {
roots: Array<Path>,
testMatch: Array<Glob>,
testRegex: string,
testPathIgnorePatterns: Array<string>,
};

type SearchResult = {|
noSCM?: boolean,
paths: Array<Path>,
Expand Down Expand Up @@ -83,7 +76,6 @@ const regexToMatcher = (testRegex: string) => {

class SearchSource {
_context: Context;
_config: SearchSourceConfig;
_options: ResolveModuleConfig;
_rootPattern: RegExp;
_testIgnorePattern: ?RegExp;
Expand All @@ -94,13 +86,9 @@ class SearchSource {
testPathIgnorePatterns: (path: Path) => boolean,
};

constructor(
context: Context,
config: SearchSourceConfig,
options?: ResolveModuleConfig,
) {
constructor(context: Context, options?: ResolveModuleConfig) {
const {config} = context;
this._context = context;
this._config = config;
this._options = options || {
skipNodeResolution: false,
};
Expand Down Expand Up @@ -199,7 +187,9 @@ class SearchSource {
}

findChangedTests(options: Options): Promise<SearchResult> {
return Promise.all(this._config.roots.map(determineSCM)).then(repos => {
return Promise.all(
this._context.config.roots.map(determineSCM),
).then(repos => {
if (!repos.every(([gitRepo, hgRepo]) => gitRepo || hgRepo)) {
return {
noSCM: true,
Expand Down
49 changes: 28 additions & 21 deletions packages/jest-cli/src/TestPathPatternPrompt.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,22 @@
'use strict';

import type {Context} from 'types/Context';
import type {Config, Path} from 'types/Config';
import type {Test} from 'types/TestRunner';
import type SearchSource from './SearchSource';

const ansiEscapes = require('ansi-escapes');
const chalk = require('chalk');
const {getTerminalWidth} = require('./lib/terminalUtils');
const highlight = require('./lib/highlight');
const stringLength = require('string-length');
const {trimAndFormatPath} = require('./reporters/utils');
const SearchSource = require('./SearchSource');
const Prompt = require('./lib/Prompt');

type SearchSources = Array<{|
context: Context,
searchSource: SearchSource,
|}>;

const pluralizeFile = (total: number) => total === 1 ? 'file' : 'files';

const usage = () =>
Expand All @@ -34,17 +39,11 @@ const usage = () =>
const usageRows = usage().split('\n').length;

module.exports = class TestPathPatternPrompt {
_config: Config;
_pipe: stream$Writable | tty$WriteStream;
_prompt: Prompt;
_searchSource: SearchSource;

constructor(
config: Config,
pipe: stream$Writable | tty$WriteStream,
prompt: Prompt,
) {
this._config = config;
_searchSources: SearchSources;

constructor(pipe: stream$Writable | tty$WriteStream, prompt: Prompt) {
this._pipe = pipe;
this._prompt = prompt;
}
Expand All @@ -65,16 +64,24 @@ module.exports = class TestPathPatternPrompt {
regex = new RegExp(pattern, 'i');
} catch (e) {}

const paths = regex
? this._searchSource.findMatchingTests(pattern).paths
: [];
let paths = [];
if (regex) {
this._searchSources.forEach(({searchSource, context}) => {
paths = paths.concat(
searchSource.findMatchingTests(pattern).paths.map(path => ({
context,
path,
})),
);
});
}

this._pipe.write(ansiEscapes.eraseLine);
this._pipe.write(ansiEscapes.cursorLeft);
this._printTypeahead(pattern, paths, 10);
}

_printTypeahead(pattern: string, allResults: Array<Path>, max: number) {
_printTypeahead(pattern: string, allResults: Array<Test>, max: number) {
const total = allResults.length;
const results = allResults.slice(0, max);
const inputText = `${chalk.dim(' pattern \u203A')} ${pattern}`;
Expand All @@ -97,14 +104,14 @@ module.exports = class TestPathPatternPrompt {
const padding = stringLength(prefix) + 2;

results
.map(rawPath => {
.map(({path, context}) => {
const filePath = trimAndFormatPath(
padding,
this._config,
rawPath,
context.config,
path,
width,
);
return highlight(rawPath, filePath, pattern, this._config.rootDir);
return highlight(path, filePath, pattern, context.config.rootDir);
})
.forEach(filePath =>
this._pipe.write(`\n ${chalk.dim('\u203A')} ${filePath}`));
Expand All @@ -129,7 +136,7 @@ module.exports = class TestPathPatternPrompt {
this._pipe.write(ansiEscapes.cursorRestorePosition);
}

updateSearchSource(context: Context) {
this._searchSource = new SearchSource(context, this._config);
updateSearchSources(searchSources: SearchSources) {
this._searchSources = searchSources;
}
};
23 changes: 11 additions & 12 deletions packages/jest-cli/src/__tests__/SearchSource-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,14 @@ describe('SearchSource', () => {
rootDir: '.',
roots: [],
}).config;
return Runtime.createContext(config, {maxWorkers}).then(hasteMap => {
searchSource = new SearchSource(hasteMap, config);
return Runtime.createContext(config, {maxWorkers}).then(context => {
searchSource = new SearchSource(context);
});
});

// micromatch doesn't support '..' through the globstar ('**') to avoid
// infinite recursion.

it('supports ../ paths and unix separators via textRegex', () => {
it('supports ../ paths and unix separators via testRegex', () => {
if (process.platform !== 'win32') {
config = normalizeConfig({
name,
Expand All @@ -64,8 +63,8 @@ describe('SearchSource', () => {
}).config;
return Runtime.createContext(config, {
maxWorkers,
}).then(hasteMap => {
searchSource = new SearchSource(hasteMap, config);
}).then(context => {
searchSource = new SearchSource(context);

const path = '/path/to/__tests__/foo/bar/baz/../../../test.js';
expect(searchSource.isTestFilePath(path)).toEqual(true);
Expand Down Expand Up @@ -95,8 +94,8 @@ describe('SearchSource', () => {
findMatchingTests = config =>
Runtime.createContext(config, {
maxWorkers,
}).then(hasteMap =>
new SearchSource(hasteMap, config).findMatchingTests());
}).then(context =>
new SearchSource(context).findMatchingTests());
});

it('finds tests matching a pattern via testRegex', () => {
Expand Down Expand Up @@ -309,8 +308,8 @@ describe('SearchSource', () => {
name: 'SearchSource-findRelatedTests-tests',
rootDir,
});
Runtime.createContext(config, {maxWorkers}).then(hasteMap => {
searchSource = new SearchSource(hasteMap, config);
Runtime.createContext(config, {maxWorkers}).then(context => {
searchSource = new SearchSource(context);
done();
});
});
Expand Down Expand Up @@ -342,8 +341,8 @@ describe('SearchSource', () => {
rootDir,
testMatch,
});
Runtime.createContext(config, {maxWorkers}).then(hasteMap => {
searchSource = new SearchSource(hasteMap, config);
Runtime.createContext(config, {maxWorkers}).then(context => {
searchSource = new SearchSource(context);
done();
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,25 +80,23 @@ afterEach(runJestMock.mockReset);

describe('Watch mode flows', () => {
let pipe;
let hasteMap;
let hasteMapInstances;
let argv;
let context;
let config;
let contexts;
let stdin;

beforeEach(() => {
terminalWidth = 80;
pipe = {write: jest.fn()};
hasteMap = {on: () => {}};
hasteMapInstances = [{on: () => {}}];
argv = {};
context = {};
config = {};
contexts = [{config: {}}];
stdin = new MockStdin();
});

it('Pressing "P" enters pattern mode', () => {
config = {rootDir: ''};
watch(config, pipe, argv, hasteMap, context, stdin);
contexts[0].config = {rootDir: ''};
watch(contexts, argv, pipe, hasteMapInstances, stdin);

// Write a enter pattern mode
stdin.emit(KEYS.P);
Expand Down Expand Up @@ -134,8 +132,8 @@ describe('Watch mode flows', () => {
});

it('Results in pattern mode get truncated appropriately', () => {
config = {rootDir: ''};
watch(config, pipe, argv, hasteMap, context, stdin);
contexts[0].config = {rootDir: ''};
watch(contexts, argv, pipe, hasteMapInstances, stdin);

stdin.emit(KEYS.P);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,25 +104,23 @@ afterEach(runJestMock.mockReset);

describe('Watch mode flows', () => {
let pipe;
let hasteMap;
let hasteMapInstances;
let argv;
let context;
let config;
let contexts;
let stdin;

beforeEach(() => {
terminalWidth = 80;
pipe = {write: jest.fn()};
hasteMap = {on: () => {}};
hasteMapInstances = [{on: () => {}}];
argv = {};
context = {};
config = {};
contexts = [{config: {}}];
stdin = new MockStdin();
});

it('Pressing "T" enters pattern mode', () => {
config = {rootDir: ''};
watch(config, pipe, argv, hasteMap, context, stdin);
contexts[0].config = {rootDir: ''};
watch(contexts, argv, pipe, hasteMapInstances, stdin);

// Write a enter pattern mode
stdin.emit(KEYS.T);
Expand Down Expand Up @@ -158,8 +156,8 @@ describe('Watch mode flows', () => {
});

it('Results in pattern mode get truncated appropriately', () => {
config = {rootDir: ''};
watch(config, pipe, argv, hasteMap, context, stdin);
contexts[0].config = {rootDir: ''};
watch(contexts, argv, pipe, hasteMapInstances, stdin);

stdin.emit(KEYS.T);

Expand Down
Loading

0 comments on commit d6b4e2e

Please sign in to comment.