diff --git a/packages/jest-cli/src/TestNamePatternPrompt.js b/packages/jest-cli/src/TestNamePatternPrompt.js index e9dd4cf330da..fd7f0b0db237 100644 --- a/packages/jest-cli/src/TestNamePatternPrompt.js +++ b/packages/jest-cli/src/TestNamePatternPrompt.js @@ -10,7 +10,7 @@ 'use strict'; -import type {Config} from 'types/Config'; +import type {TestResult} from 'types/TestResult'; const ansiEscapes = require('ansi-escapes'); const chalk = require('chalk'); @@ -30,108 +30,105 @@ const usage = () => const usageRows = usage().split('\n').length; -module.exports = ( - config: Config, - pipe: stream$Writable | tty$WriteStream, - prompt: Prompt, -) => { - class TestNamePatternPrompt { - // $FlowFixMe - _cachedTestResults; - - constructor() { - (this: any).onChange = this.onChange.bind(this); - } +module.exports = class TestNamePatternPrompt { + _cachedTestResults: Array; + _pipe: stream$Writable | tty$WriteStream; + _prompt: Prompt; - run(onSuccess: Function, onCancel: Function) { - pipe.write(ansiEscapes.cursorHide); - pipe.write(ansiEscapes.clearScreen); - pipe.write(usage()); - pipe.write(ansiEscapes.cursorShow); + constructor(pipe: stream$Writable | tty$WriteStream, prompt: Prompt) { + this._pipe = pipe; + this._prompt = prompt; + } - prompt.enter(this.onChange, onSuccess, onCancel); - } + run(onSuccess: Function, onCancel: Function) { + this._pipe.write(ansiEscapes.cursorHide); + this._pipe.write(ansiEscapes.clearScreen); + this._pipe.write(usage()); + this._pipe.write(ansiEscapes.cursorShow); - onChange(pattern: string) { - pipe.write(ansiEscapes.eraseLine); - pipe.write(ansiEscapes.cursorLeft); - this.printTypeahead(pattern, 10); - } + this._prompt.enter(this._onChange.bind(this), onSuccess, onCancel); + } - printTypeahead(pattern: string, max: number) { - const matchedTests = this.getMatchedTests(pattern); + _onChange(pattern: string) { + this._pipe.write(ansiEscapes.eraseLine); + this._pipe.write(ansiEscapes.cursorLeft); + this._printTypeahead(pattern, 10); + } - const total = matchedTests.length; - const results = matchedTests.slice(0, max); - const inputText = `${chalk.dim(' pattern \u203A')} ${pattern}`; + _printTypeahead(pattern: string, max: number) { + const matchedTests = this._getMatchedTests(pattern); - pipe.write(ansiEscapes.eraseDown); - pipe.write(inputText); - pipe.write(ansiEscapes.cursorSavePosition); + const total = matchedTests.length; + const results = matchedTests.slice(0, max); + const inputText = `${chalk.dim(' pattern \u203A')} ${pattern}`; - if (pattern) { - if (total) { - pipe.write(`\n\n Pattern matches ${total} ${pluralizeTest(total)}`); - } else { - pipe.write(`\n\n Pattern matches no tests`); - } + this._pipe.write(ansiEscapes.eraseDown); + this._pipe.write(inputText); + this._pipe.write(ansiEscapes.cursorSavePosition); - pipe.write(' from cached test suites.'); + if (pattern) { + if (total) { + this._pipe.write( + `\n\n Pattern matches ${total} ${pluralizeTest(total)}`, + ); + } else { + this._pipe.write(`\n\n Pattern matches no tests`); + } - const width = getTerminalWidth(); + this._pipe.write(' from cached test suites.'); - results.forEach(name => { - const testName = formatTestNameByPattern(name, pattern, width - 4); + const width = getTerminalWidth(); - pipe.write(`\n ${chalk.dim('\u203A')} ${testName}`); - }); + results.forEach(name => { + const testName = formatTestNameByPattern(name, pattern, width - 4); - if (total > max) { - const more = total - max; - pipe.write( - // eslint-disable-next-line max-len - `\n ${chalk.dim(`\u203A and ${more} more ${pluralizeTest(more)}`)}`, - ); - } - } else { - pipe.write( + this._pipe.write(`\n ${chalk.dim('\u203A')} ${testName}`); + }); + + if (total > max) { + const more = total - max; + this._pipe.write( // eslint-disable-next-line max-len - `\n\n ${chalk.italic.yellow('Start typing to filter by a test name regex pattern.')}`, + `\n ${chalk.dim(`\u203A and ${more} more ${pluralizeTest(more)}`)}`, ); } - - pipe.write(ansiEscapes.cursorTo(stringLength(inputText), usageRows - 1)); - pipe.write(ansiEscapes.cursorRestorePosition); + } else { + this._pipe.write( + // eslint-disable-next-line max-len + `\n\n ${chalk.italic.yellow('Start typing to filter by a test name regex pattern.')}`, + ); } - getMatchedTests(pattern: string) { - let regex; + this._pipe.write( + ansiEscapes.cursorTo(stringLength(inputText), usageRows - 1), + ); + this._pipe.write(ansiEscapes.cursorRestorePosition); + } - try { - regex = new RegExp(pattern, 'i'); - } catch (e) { - return []; - } + _getMatchedTests(pattern: string) { + let regex; - const matchedTests = []; + try { + regex = new RegExp(pattern, 'i'); + } catch (e) { + return []; + } - this._cachedTestResults.forEach(({testResults}) => - testResults.forEach(({ - title, - }) => { - if (regex.test(title)) { - matchedTests.push(title); - } - })); + const matchedTests = []; - return matchedTests; - } + this._cachedTestResults.forEach(({testResults}) => + testResults.forEach(({ + title, + }) => { + if (regex.test(title)) { + matchedTests.push(title); + } + })); - // $FlowFixMe - updateCachedTestResults(testResults) { - this._cachedTestResults = testResults || []; - } + return matchedTests; } - return new TestNamePatternPrompt(); + updateCachedTestResults(testResults: Array) { + this._cachedTestResults = testResults || []; + } }; diff --git a/packages/jest-cli/src/TestPathPatternPrompt.js b/packages/jest-cli/src/TestPathPatternPrompt.js index 210262e56a63..86531ba9d805 100644 --- a/packages/jest-cli/src/TestPathPatternPrompt.js +++ b/packages/jest-cli/src/TestPathPatternPrompt.js @@ -33,93 +33,103 @@ const usage = () => const usageRows = usage().split('\n').length; -module.exports = ( - config: Config, - pipe: stream$Writable | tty$WriteStream, - prompt: Prompt, -) => { - class TestPathPatternPrompt { - searchSource: SearchSource; - - constructor() { - (this: any).onChange = this.onChange.bind(this); - } +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; + this._pipe = pipe; + this._prompt = prompt; + } - run(onSuccess: Function, onCancel: Function) { - pipe.write(ansiEscapes.cursorHide); - pipe.write(ansiEscapes.clearScreen); - pipe.write(usage()); - pipe.write(ansiEscapes.cursorShow); + run(onSuccess: Function, onCancel: Function) { + this._pipe.write(ansiEscapes.cursorHide); + this._pipe.write(ansiEscapes.clearScreen); + this._pipe.write(usage()); + this._pipe.write(ansiEscapes.cursorShow); - prompt.enter(this.onChange, onSuccess, onCancel); - } + this._prompt.enter(this._onChange.bind(this), onSuccess, onCancel); + } - onChange(pattern: string) { - let regex; + _onChange(pattern: string) { + let regex; - try { - regex = new RegExp(pattern, 'i'); - } catch (e) {} + try { + regex = new RegExp(pattern, 'i'); + } catch (e) {} - const paths = regex - ? this.searchSource.findMatchingTests(pattern).paths - : []; + const paths = regex + ? this._searchSource.findMatchingTests(pattern).paths + : []; - pipe.write(ansiEscapes.eraseLine); - pipe.write(ansiEscapes.cursorLeft); - this.printTypeahead(pattern, paths, 10); - } + this._pipe.write(ansiEscapes.eraseLine); + this._pipe.write(ansiEscapes.cursorLeft); + this._printTypeahead(pattern, paths, 10); + } - printTypeahead(pattern: string, allResults: Array, max: number) { - const total = allResults.length; - const results = allResults.slice(0, max); - const inputText = `${chalk.dim(' pattern \u203A')} ${pattern}`; - - pipe.write(ansiEscapes.eraseDown); - pipe.write(inputText); - pipe.write(ansiEscapes.cursorSavePosition); - - if (pattern) { - if (total) { - pipe.write(`\n\n Pattern matches ${total} ${pluralizeFile(total)}.`); - } else { - pipe.write(`\n\n Pattern matches no files.`); - } - - const width = getTerminalWidth(); - const prefix = ` ${chalk.dim('\u203A')} `; - const padding = stringLength(prefix) + 2; - - results - .map(rawPath => { - const filePath = trimAndFormatPath(padding, config, rawPath, width); - return highlight(rawPath, filePath, pattern, config.rootDir); - }) - .forEach(filePath => - pipe.write(`\n ${chalk.dim('\u203A')} ${filePath}`)); - - if (total > max) { - const more = total - max; - pipe.write( - // eslint-disable-next-line max-len - `\n ${chalk.dim(`\u203A and ${more} more ${pluralizeFile(more)}`)}`, - ); - } + _printTypeahead(pattern: string, allResults: Array, max: number) { + const total = allResults.length; + const results = allResults.slice(0, max); + const inputText = `${chalk.dim(' pattern \u203A')} ${pattern}`; + + this._pipe.write(ansiEscapes.eraseDown); + this._pipe.write(inputText); + this._pipe.write(ansiEscapes.cursorSavePosition); + + if (pattern) { + if (total) { + this._pipe.write( + `\n\n Pattern matches ${total} ${pluralizeFile(total)}.`, + ); } else { - pipe.write( + this._pipe.write(`\n\n Pattern matches no files.`); + } + + const width = getTerminalWidth(); + const prefix = ` ${chalk.dim('\u203A')} `; + const padding = stringLength(prefix) + 2; + + results + .map(rawPath => { + const filePath = trimAndFormatPath( + padding, + this._config, + rawPath, + width, + ); + return highlight(rawPath, filePath, pattern, this._config.rootDir); + }) + .forEach(filePath => + this._pipe.write(`\n ${chalk.dim('\u203A')} ${filePath}`)); + + if (total > max) { + const more = total - max; + this._pipe.write( // eslint-disable-next-line max-len - `\n\n ${chalk.italic.yellow('Start typing to filter by a filename regex pattern.')}`, + `\n ${chalk.dim(`\u203A and ${more} more ${pluralizeFile(more)}`)}`, ); } - - pipe.write(ansiEscapes.cursorTo(stringLength(inputText), usageRows - 1)); - pipe.write(ansiEscapes.cursorRestorePosition); + } else { + this._pipe.write( + // eslint-disable-next-line max-len + `\n\n ${chalk.italic.yellow('Start typing to filter by a filename regex pattern.')}`, + ); } - updateSearchSource(context: Context) { - this.searchSource = new SearchSource(context, config); - } + this._pipe.write( + ansiEscapes.cursorTo(stringLength(inputText), usageRows - 1), + ); + this._pipe.write(ansiEscapes.cursorRestorePosition); } - return new TestPathPatternPrompt(); + updateSearchSource(context: Context) { + this._searchSource = new SearchSource(context, this._config); + } }; diff --git a/packages/jest-cli/src/watch.js b/packages/jest-cli/src/watch.js index 3064f996ff0d..a6448cfc60cc 100644 --- a/packages/jest-cli/src/watch.js +++ b/packages/jest-cli/src/watch.js @@ -14,7 +14,7 @@ import type {Config} from 'types/Config'; const ansiEscapes = require('ansi-escapes'); const chalk = require('chalk'); -const createTestContext = require('./lib/createContext'); +const createContext = require('./lib/createContext'); const HasteMap = require('jest-haste-map'); const isValidPath = require('./lib/isValidPath'); const preRunMessage = require('./preRunMessage'); @@ -50,8 +50,8 @@ const watch = ( }); const prompt = new Prompt(); - const testPathPatternPrompt = TestPathPatternPrompt(config, pipe, prompt); - const testNamePatternPrompt = TestNamePatternPrompt(config, pipe, prompt); + const testPathPatternPrompt = new TestPathPatternPrompt(config, pipe, prompt); + const testNamePatternPrompt = new TestNamePatternPrompt(pipe, prompt); let hasSnapshotFailure = false; let isRunning = false; let testWatcher; @@ -66,7 +66,7 @@ const watch = ( }); if (validPaths.length) { - hasteContext = createTestContext(config, {hasteFS, moduleMap}); + hasteContext = createContext(config, {hasteFS, moduleMap}); prompt.abort(); testPathPatternPrompt.updateSearchSource(hasteContext); startRun();