diff --git a/CHANGELOG.md b/CHANGELOG.md index e9e156182742..14de6a026592 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -105,6 +105,8 @@ ### Fixes +* `[jest-cli]` Fix stdin encoding to utf8 for watch plugins. + ([#6253](https://github.com/facebook/jest/issues/6253)) * `[expect]` Better detection of DOM Nodes for equality ([#6246](https://github.com/facebook/jest/pull/6246)) * `[jest-cli]` Fix misleading action description for F key when in "only failed diff --git a/packages/jest-cli/src/__tests__/watch.test.js b/packages/jest-cli/src/__tests__/watch.test.js index 736eb59e17c8..f214d70ab058 100644 --- a/packages/jest-cli/src/__tests__/watch.test.js +++ b/packages/jest-cli/src/__tests__/watch.test.js @@ -65,7 +65,7 @@ jest.doMock( class WatchPlugin1 { getUsageInfo() { return { - key: 's'.codePointAt(0), + key: 's', prompt: 'do nothing', }; } @@ -79,7 +79,7 @@ jest.doMock( class WatchPlugin2 { getUsageInfo() { return { - key: 'u'.codePointAt(0), + key: 'u', prompt: 'do something else', }; } @@ -90,7 +90,6 @@ jest.doMock( const watch = require('../watch').default; const nextTick = () => new Promise(res => process.nextTick(res)); -const toHex = char => Number(char.charCodeAt(0)).toString(16); afterEach(runJestMock.mockReset); @@ -329,7 +328,7 @@ describe('Watch mode flows', () => { } getUsageInfo() { return { - key: 'p'.codePointAt(0), + key: 'p', prompt: 'custom "P" plugin', }; } @@ -352,7 +351,7 @@ describe('Watch mode flows', () => { expect(pipe.write.mock.calls.reverse()[0]).toMatchSnapshot(); - stdin.emit(toHex('p')); + stdin.emit('p'); await nextTick(); expect(run).toHaveBeenCalled(); @@ -405,7 +404,7 @@ describe('Watch mode flows', () => { } getUsageInfo() { return { - key: 's'.codePointAt(0), + key: 's', prompt: 'do nothing', }; } @@ -424,7 +423,7 @@ describe('Watch mode flows', () => { stdin, ); - stdin.emit(Number('s'.charCodeAt(0)).toString(16)); + stdin.emit('s'); await nextTick(); @@ -445,7 +444,7 @@ describe('Watch mode flows', () => { onKey() {} getUsageInfo() { return { - key: 's'.codePointAt(0), + key: 's', prompt: 'do nothing', }; } @@ -465,7 +464,7 @@ describe('Watch mode flows', () => { onKey() {} getUsageInfo() { return { - key: 'z'.codePointAt(0), + key: 'z', prompt: 'also do nothing', }; } @@ -484,14 +483,14 @@ describe('Watch mode flows', () => { stdin, ); - stdin.emit(Number('s'.charCodeAt(0)).toString(16)); + stdin.emit('s'); await nextTick(); expect(run).toHaveBeenCalled(); - stdin.emit(Number('z'.charCodeAt(0)).toString(16)); + stdin.emit('z'); await nextTick(); expect(showPrompt2).not.toHaveBeenCalled(); await resolveShowPrompt(); - stdin.emit(Number('z'.charCodeAt(0)).toString(16)); + stdin.emit('z'); expect(showPrompt2).toHaveBeenCalled(); }); @@ -537,7 +536,7 @@ describe('Watch mode flows', () => { runJestMock.mockReset(); stdin.emit(KEYS.T); - ['t', 'e', 's', 't'].map(toHex).forEach(key => stdin.emit(key)); + ['t', 'e', 's', 't'].forEach(key => stdin.emit(key)); stdin.emit(KEYS.ENTER); await nextTick(); @@ -556,7 +555,7 @@ describe('Watch mode flows', () => { runJestMock.mockReset(); stdin.emit(KEYS.P); - ['f', 'i', 'l', 'e'].map(toHex).forEach(key => stdin.emit(key)); + ['f', 'i', 'l', 'e'].forEach(key => stdin.emit(key)); stdin.emit(KEYS.ENTER); await nextTick(); @@ -575,12 +574,12 @@ describe('Watch mode flows', () => { runJestMock.mockReset(); stdin.emit(KEYS.P); - ['f', 'i', 'l', 'e'].map(toHex).forEach(key => stdin.emit(key)); + ['f', 'i', 'l', 'e'].forEach(key => stdin.emit(key)); stdin.emit(KEYS.ENTER); await nextTick(); stdin.emit(KEYS.T); - ['t', 'e', 's', 't'].map(toHex).forEach(key => stdin.emit(key)); + ['t', 'e', 's', 't'].forEach(key => stdin.emit(key)); stdin.emit(KEYS.ENTER); await nextTick(); diff --git a/packages/jest-cli/src/__tests__/watch_filename_pattern_mode.test.js b/packages/jest-cli/src/__tests__/watch_filename_pattern_mode.test.js index 2d3e8b7d281f..8201e6b72427 100644 --- a/packages/jest-cli/src/__tests__/watch_filename_pattern_mode.test.js +++ b/packages/jest-cli/src/__tests__/watch_filename_pattern_mode.test.js @@ -87,8 +87,6 @@ const watch = require('../watch').default; const nextTick = () => new Promise(res => process.nextTick(res)); -const toHex = char => Number(char.charCodeAt(0)).toString(16); - const globalConfig = {watch: true}; afterEach(runJestMock.mockReset); @@ -122,11 +120,11 @@ describe('Watch mode flows', () => { }; // Write a pattern - ['p', '.', '*', '1', '0'].map(toHex).forEach(assertPattern); + ['p', '.', '*', '1', '0'].forEach(assertPattern); [KEYS.BACKSPACE, KEYS.BACKSPACE].forEach(assertPattern); - ['3'].map(toHex).forEach(assertPattern); + ['3'].forEach(assertPattern); // Runs Jest again runJestMock.mockReset(); @@ -152,17 +150,14 @@ describe('Watch mode flows', () => { await nextTick(); ['p', '.', '*', '1', '0'] - .map(toHex) + .concat(KEYS.ENTER) .forEach(key => stdin.emit(key)); stdin.emit(KEYS.T); await nextTick(); - ['t', 'e', 's', 't'] - .map(toHex) - .concat(KEYS.ENTER) - .forEach(key => stdin.emit(key)); + ['t', 'e', 's', 't'].concat(KEYS.ENTER).forEach(key => stdin.emit(key)); await nextTick(); diff --git a/packages/jest-cli/src/__tests__/watch_test_name_pattern_mode.test.js b/packages/jest-cli/src/__tests__/watch_test_name_pattern_mode.test.js index 3001f4cc37b1..376d89a4b4a0 100644 --- a/packages/jest-cli/src/__tests__/watch_test_name_pattern_mode.test.js +++ b/packages/jest-cli/src/__tests__/watch_test_name_pattern_mode.test.js @@ -99,8 +99,6 @@ jest.doMock('../lib/terminal_utils', () => ({ const watch = require('../watch').default; -const toHex = char => Number(char.charCodeAt(0)).toString(16); - const globalConfig = { watch: true, }; @@ -136,11 +134,11 @@ describe('Watch mode flows', () => { }; // Write a pattern - ['c', 'o', 'n', ' ', '1', '2'].map(toHex).forEach(assertPattern); + ['c', 'o', 'n', ' ', '1', '2'].forEach(assertPattern); [KEYS.BACKSPACE, KEYS.BACKSPACE].forEach(assertPattern); - ['*'].map(toHex).forEach(assertPattern); + ['*'].forEach(assertPattern); // Runs Jest again runJestMock.mockReset(); diff --git a/packages/jest-cli/src/constants.js b/packages/jest-cli/src/constants.js index 0804d3922780..2ceae57dc2b2 100644 --- a/packages/jest-cli/src/constants.js +++ b/packages/jest-cli/src/constants.js @@ -12,28 +12,30 @@ const isWindows = process.platform === 'win32'; export const CLEAR = isWindows ? '\x1B[2J\x1B[0f' : '\x1B[2J\x1B[3J\x1B[H'; export const ARROW = ' \u203A '; export const KEYS = { - A: '61', - ARROW_DOWN: '1b5b42', - ARROW_LEFT: '1b5b44', - ARROW_RIGHT: '1b5b43', - ARROW_UP: '1b5b41', - BACKSPACE: isWindows ? '08' : '7f', - C: '63', - CONTROL_C: '03', - CONTROL_D: '04', - ENTER: '0d', - ESCAPE: '1b', - F: '66', - I: '69', - O: '6f', - P: '70', - Q: '71', - QUESTION_MARK: '3f', - R: '72', - S: '73', - T: '74', - U: '75', - W: '77', + A: 'a', + ARROW_DOWN: '\u001b[B', + ARROW_LEFT: '\u001b[D', + ARROW_RIGHT: '\u001b[C', + ARROW_UP: '\u001b[A', + BACKSPACE: isWindows + ? Buffer.from('08', 'hex').toString() + : Buffer.from('7f', 'hex').toString(), + C: 'c', + CONTROL_C: '\u0003', + CONTROL_D: '\u0004', + ENTER: '\r', + ESCAPE: '\u001b', + F: 'f', + I: 'i', + O: 'o', + P: 'p', + Q: 'q', + QUESTION_MARK: '?', + R: 'r', + S: 's', + T: 't', + U: 'u', + W: 'w', }; export const ICONS = { diff --git a/packages/jest-cli/src/lib/Prompt.js b/packages/jest-cli/src/lib/Prompt.js index 402e0af2898b..cb49d3a1b585 100644 --- a/packages/jest-cli/src/lib/Prompt.js +++ b/packages/jest-cli/src/lib/Prompt.js @@ -84,12 +84,8 @@ export default class Prompt { case KEYS.ARROW_RIGHT: break; default: - const char = new Buffer(key, 'hex').toString(); - this._value = - key === KEYS.BACKSPACE - ? this._value.slice(0, -1) - : this._value + char; + key === KEYS.BACKSPACE ? this._value.slice(0, -1) : this._value + key; this._offset = -1; this._selection = null; this._onChange(); diff --git a/packages/jest-cli/src/lib/__tests__/prompt.test.js b/packages/jest-cli/src/lib/__tests__/prompt.test.js index d3051921c0de..62c7a5cf9220 100644 --- a/packages/jest-cli/src/lib/__tests__/prompt.test.js +++ b/packages/jest-cli/src/lib/__tests__/prompt.test.js @@ -12,8 +12,8 @@ import Prompt from '../Prompt'; import {KEYS} from '../../constants'; const EXTRA_KEYS = Object.assign({}, KEYS, { - E: '65', - S: '73', + E: 'e', + S: 's', }); it('calls handler on change value', () => { diff --git a/packages/jest-cli/src/lib/handle_deprecation_warnings.js b/packages/jest-cli/src/lib/handle_deprecation_warnings.js index a7ad7c612798..e07228b748af 100644 --- a/packages/jest-cli/src/lib/handle_deprecation_warnings.js +++ b/packages/jest-cli/src/lib/handle_deprecation_warnings.js @@ -28,7 +28,7 @@ export default ( // $FlowFixMe stdin.setRawMode(true); stdin.resume(); - stdin.setEncoding('hex'); + stdin.setEncoding('utf8'); stdin.on('data', (key: string) => { if (key === KEYS.ENTER) { resolve(); diff --git a/packages/jest-cli/src/lib/watch_plugins_helpers.js b/packages/jest-cli/src/lib/watch_plugins_helpers.js index 08a7bc21f4b8..af05bc85248d 100644 --- a/packages/jest-cli/src/lib/watch_plugins_helpers.js +++ b/packages/jest-cli/src/lib/watch_plugins_helpers.js @@ -41,7 +41,7 @@ export const getSortedUsageRows = ( const usageInfoB = b.getUsageInfo && b.getUsageInfo(globalConfig); if (usageInfoA && usageInfoB) { - return usageInfoA.key - usageInfoB.key; + return usageInfoA.key.localeCompare(usageInfoB.key); } return 0; diff --git a/packages/jest-cli/src/plugins/quit.js b/packages/jest-cli/src/plugins/quit.js index e9bcc781e7e5..dfcbf8db2f9a 100644 --- a/packages/jest-cli/src/plugins/quit.js +++ b/packages/jest-cli/src/plugins/quit.js @@ -29,7 +29,7 @@ class QuitPlugin extends BaseWatchPlugin { getUsageInfo() { return { - key: 'q'.codePointAt(0), + key: 'q', prompt: 'quit watch mode', }; } diff --git a/packages/jest-cli/src/plugins/test_name_pattern.js b/packages/jest-cli/src/plugins/test_name_pattern.js index a293c5235d6c..4688ffa1ff58 100644 --- a/packages/jest-cli/src/plugins/test_name_pattern.js +++ b/packages/jest-cli/src/plugins/test_name_pattern.js @@ -27,7 +27,7 @@ class TestNamePatternPlugin extends BaseWatchPlugin { getUsageInfo() { return { - key: 't'.codePointAt(0), + key: 't', prompt: 'filter by a test name regex pattern', }; } diff --git a/packages/jest-cli/src/plugins/test_path_pattern.js b/packages/jest-cli/src/plugins/test_path_pattern.js index 2dbb48dc1e31..3de06b7edf55 100644 --- a/packages/jest-cli/src/plugins/test_path_pattern.js +++ b/packages/jest-cli/src/plugins/test_path_pattern.js @@ -28,7 +28,7 @@ class TestPathPatternPlugin extends BaseWatchPlugin { getUsageInfo() { return { - key: 'p'.codePointAt(0), + key: 'p', prompt: 'filter by a filename regex pattern', }; } diff --git a/packages/jest-cli/src/plugins/update_snapshots.js b/packages/jest-cli/src/plugins/update_snapshots.js index f405c1c54ede..8f8d0a40425a 100644 --- a/packages/jest-cli/src/plugins/update_snapshots.js +++ b/packages/jest-cli/src/plugins/update_snapshots.js @@ -39,7 +39,7 @@ class UpdateSnapshotsPlugin extends BaseWatchPlugin { getUsageInfo(globalConfig: GlobalConfig) { if (this._hasSnapshotFailure) { return { - key: 'u'.codePointAt(0), + key: 'u', prompt: 'update failing snapshots', }; } diff --git a/packages/jest-cli/src/plugins/update_snapshots_interactive.js b/packages/jest-cli/src/plugins/update_snapshots_interactive.js index 75c1c020cf15..c05da8a97465 100644 --- a/packages/jest-cli/src/plugins/update_snapshots_interactive.js +++ b/packages/jest-cli/src/plugins/update_snapshots_interactive.js @@ -99,7 +99,7 @@ class UpdateSnapshotInteractivePlugin extends BaseWatchPlugin { this._failedSnapshotTestAssertions.length > 0 ) { return { - key: 'i'.codePointAt(0), + key: 'i', prompt: 'update failing snapshots interactively', }; } diff --git a/packages/jest-cli/src/types.js b/packages/jest-cli/src/types.js index 51ec43e5da94..664065b6c083 100644 --- a/packages/jest-cli/src/types.js +++ b/packages/jest-cli/src/types.js @@ -10,7 +10,7 @@ import type {GlobalConfig} from 'types/Config'; import type {JestHookSubscriber} from './jest_hooks'; export type UsageData = { - key: number, + key: string, prompt: string, }; diff --git a/packages/jest-cli/src/watch.js b/packages/jest-cli/src/watch.js index 89f9ad058965..4279625deaf1 100644 --- a/packages/jest-cli/src/watch.js +++ b/packages/jest-cli/src/watch.js @@ -277,7 +277,7 @@ export default function watch( ).find(plugin => { const usageData = (plugin.getUsageInfo && plugin.getUsageInfo(globalConfig)) || {}; - return usageData.key === parseInt(key, 16); + return usageData.key === key; }); if (matchingWatchPlugin != null) { @@ -359,7 +359,7 @@ export default function watch( if (typeof stdin.setRawMode === 'function') { stdin.setRawMode(true); stdin.resume(); - stdin.setEncoding('hex'); + stdin.setEncoding('utf8'); stdin.on('data', onKeypress); } @@ -405,7 +405,7 @@ const usage = ( plugin => chalk.dim(' \u203A Press') + ' ' + - String.fromCodePoint(plugin.key) + + plugin.key + ' ' + chalk.dim(`to ${plugin.prompt}.`), ),