jest-watch-typeahead 0.3.0 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- package/CHANGELOG.md +7 -1
- package/build/file_name_pattern_prompt.js +105 -0
- package/build/file_name_plugin.js +53 -0
- package/build/index.js +10 -0
- package/build/shared/pattern_mode_helpers.js +45 -0
- package/build/shared/scroll.js +30 -0
- package/build/test_name_pattern_prompt.js +91 -0
- package/build/test_name_plugin.js +53 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
@@ -0,0 +1,105 @@
|
|
1
|
+
'use strict';
|
2
|
+
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
4
|
+
value: true
|
5
|
+
});
|
6
|
+
|
7
|
+
var _chalk = require('chalk');
|
8
|
+
|
9
|
+
var _chalk2 = _interopRequireDefault(_chalk);
|
10
|
+
|
11
|
+
var _stringLength = require('string-length');
|
12
|
+
|
13
|
+
var _stringLength2 = _interopRequireDefault(_stringLength);
|
14
|
+
|
15
|
+
var _jestWatcher = require('jest-watcher');
|
16
|
+
|
17
|
+
var _utils = require('./lib/utils');
|
18
|
+
|
19
|
+
var _pattern_mode_helpers = require('./shared/pattern_mode_helpers');
|
20
|
+
|
21
|
+
var _scroll2 = require('./shared/scroll');
|
22
|
+
|
23
|
+
var _scroll3 = _interopRequireDefault(_scroll2);
|
24
|
+
|
25
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
26
|
+
|
27
|
+
class FileNamePatternPrompt extends _jestWatcher.PatternPrompt {
|
28
|
+
|
29
|
+
constructor(pipe, prompt) {
|
30
|
+
super(pipe, prompt);
|
31
|
+
this._entityName = 'filenames';
|
32
|
+
this._searchSources = [];
|
33
|
+
}
|
34
|
+
|
35
|
+
_onChange(pattern, options) {
|
36
|
+
super._onChange(pattern, options);
|
37
|
+
this._printTypeahead(pattern, options);
|
38
|
+
}
|
39
|
+
|
40
|
+
_printTypeahead(pattern, options) {
|
41
|
+
const matchedTests = this._getMatchedTests(pattern);
|
42
|
+
const total = matchedTests.length;
|
43
|
+
const pipe = this._pipe;
|
44
|
+
const prompt = this._prompt;
|
45
|
+
|
46
|
+
(0, _jestWatcher.printPatternCaret)(pattern, pipe);
|
47
|
+
|
48
|
+
if (pattern) {
|
49
|
+
(0, _pattern_mode_helpers.printPatternMatches)(total, 'file', pipe);
|
50
|
+
|
51
|
+
const prefix = ` ${_chalk2.default.dim('\u203A')} `;
|
52
|
+
const padding = (0, _stringLength2.default)(prefix) + 2;
|
53
|
+
const width = (0, _utils.getTerminalWidth)();
|
54
|
+
|
55
|
+
var _scroll = (0, _scroll3.default)(total, options);
|
56
|
+
|
57
|
+
const start = _scroll.start,
|
58
|
+
end = _scroll.end,
|
59
|
+
index = _scroll.index;
|
60
|
+
|
61
|
+
|
62
|
+
prompt.setPromptLength(total);
|
63
|
+
|
64
|
+
matchedTests.slice(start, end).map(({ path, context }) => {
|
65
|
+
const filePath = (0, _utils.trimAndFormatPath)(padding, context.config, path, width);
|
66
|
+
return (0, _utils.highlight)(path, filePath, pattern, context.config.rootDir);
|
67
|
+
}).map((item, i) => (0, _pattern_mode_helpers.formatTypeaheadSelection)(item, i, index, prompt)).forEach(item => (0, _pattern_mode_helpers.printTypeaheadItem)(item, pipe));
|
68
|
+
|
69
|
+
if (total > end) {
|
70
|
+
(0, _pattern_mode_helpers.printMore)('file', pipe, total - end);
|
71
|
+
}
|
72
|
+
} else {
|
73
|
+
(0, _pattern_mode_helpers.printStartTyping)('filename', pipe);
|
74
|
+
}
|
75
|
+
|
76
|
+
(0, _jestWatcher.printRestoredPatternCaret)(pattern, this._currentUsageRows, pipe);
|
77
|
+
}
|
78
|
+
|
79
|
+
_getMatchedTests(pattern) {
|
80
|
+
let regex;
|
81
|
+
|
82
|
+
try {
|
83
|
+
regex = new RegExp(pattern, 'i');
|
84
|
+
} catch (e) {
|
85
|
+
regex = null;
|
86
|
+
}
|
87
|
+
|
88
|
+
let tests = [];
|
89
|
+
if (regex) {
|
90
|
+
this._searchSources.forEach(({ testPaths, config }) => {
|
91
|
+
tests = tests.concat(testPaths.filter(testPath => testPath.match(pattern)).map(path => ({
|
92
|
+
path,
|
93
|
+
context: { config }
|
94
|
+
})));
|
95
|
+
});
|
96
|
+
}
|
97
|
+
|
98
|
+
return tests;
|
99
|
+
}
|
100
|
+
|
101
|
+
updateSearchSources(searchSources) {
|
102
|
+
this._searchSources = searchSources;
|
103
|
+
}
|
104
|
+
}
|
105
|
+
exports.default = FileNamePatternPrompt;
|
@@ -0,0 +1,53 @@
|
|
1
|
+
'use strict';
|
2
|
+
|
3
|
+
var _jestWatcher = require('jest-watcher');
|
4
|
+
|
5
|
+
var _file_name_pattern_prompt = require('./file_name_pattern_prompt');
|
6
|
+
|
7
|
+
var _file_name_pattern_prompt2 = _interopRequireDefault(_file_name_pattern_prompt);
|
8
|
+
|
9
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
10
|
+
|
11
|
+
class FileNamePlugin {
|
12
|
+
|
13
|
+
constructor({
|
14
|
+
stdin,
|
15
|
+
stdout
|
16
|
+
}) {
|
17
|
+
this._stdin = stdin;
|
18
|
+
this._stdout = stdout;
|
19
|
+
this._prompt = new _jestWatcher.Prompt();
|
20
|
+
this._projects = [];
|
21
|
+
}
|
22
|
+
|
23
|
+
apply(jestHooks) {
|
24
|
+
jestHooks.onFileChange(({ projects }) => {
|
25
|
+
this._projects = projects;
|
26
|
+
});
|
27
|
+
}
|
28
|
+
|
29
|
+
onKey(key) {
|
30
|
+
this._prompt.put(key);
|
31
|
+
}
|
32
|
+
|
33
|
+
run(globalConfig, updateConfigAndRun) {
|
34
|
+
const p = new _file_name_pattern_prompt2.default(this._stdout, this._prompt);
|
35
|
+
p.updateSearchSources(this._projects);
|
36
|
+
return new Promise((res, rej) => {
|
37
|
+
p.run(value => {
|
38
|
+
updateConfigAndRun({ mode: 'watch', testPathPattern: value });
|
39
|
+
res();
|
40
|
+
}, rej);
|
41
|
+
});
|
42
|
+
}
|
43
|
+
|
44
|
+
// eslint-disable-next-line class-methods-use-this
|
45
|
+
getUsageInfo() {
|
46
|
+
return {
|
47
|
+
key: 'p',
|
48
|
+
prompt: 'filter by a filename regex pattern'
|
49
|
+
};
|
50
|
+
}
|
51
|
+
}
|
52
|
+
|
53
|
+
module.exports = FileNamePlugin;
|
package/build/index.js
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
"use strict";
|
2
|
+
|
3
|
+
throw new Error(`
|
4
|
+
jest-watch-typeahead includes two watch plugins: The filename plugin and the testname plugin.
|
5
|
+
Please configure Jest as follows:
|
6
|
+
"watchPlugins": [
|
7
|
+
"jest-watch-typeahead/filename",
|
8
|
+
"jest-watch-typeahead/testname"
|
9
|
+
]
|
10
|
+
`);
|
@@ -0,0 +1,45 @@
|
|
1
|
+
'use strict';
|
2
|
+
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
4
|
+
value: true
|
5
|
+
});
|
6
|
+
exports.formatTypeaheadSelection = exports.printTypeaheadItem = exports.printMore = exports.printStartTyping = exports.printPatternMatches = undefined;
|
7
|
+
|
8
|
+
var _chalk = require('chalk');
|
9
|
+
|
10
|
+
var _chalk2 = _interopRequireDefault(_chalk);
|
11
|
+
|
12
|
+
var _stripAnsi = require('strip-ansi');
|
13
|
+
|
14
|
+
var _stripAnsi2 = _interopRequireDefault(_stripAnsi);
|
15
|
+
|
16
|
+
var _jestWatcher = require('jest-watcher');
|
17
|
+
|
18
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
19
|
+
|
20
|
+
const pluralize = (count, text) => count === 1 ? text : `${text}s`;
|
21
|
+
|
22
|
+
const printPatternMatches = exports.printPatternMatches = (count, entity, pipe, extraText = '') => {
|
23
|
+
const pluralized = pluralize(count, entity);
|
24
|
+
const result = count ? `\n\n Pattern matches ${count} ${pluralized}` : `\n\n Pattern matches no ${pluralized}`;
|
25
|
+
|
26
|
+
pipe.write(result + extraText);
|
27
|
+
};
|
28
|
+
|
29
|
+
const printStartTyping = exports.printStartTyping = (entity, pipe) => {
|
30
|
+
pipe.write(`\n\n ${_chalk2.default.italic.yellow(`Start typing to filter by a ${entity} regex pattern.`)}`);
|
31
|
+
};
|
32
|
+
|
33
|
+
const printMore = exports.printMore = (entity, pipe, more) => {
|
34
|
+
pipe.write(`\n ${_chalk2.default.dim(`...and ${more} more ${pluralize(more, entity)}`)}`);
|
35
|
+
};
|
36
|
+
|
37
|
+
const printTypeaheadItem = exports.printTypeaheadItem = (item, pipe) => pipe.write(`\n ${_chalk2.default.dim('\u203A')} ${item}`);
|
38
|
+
|
39
|
+
const formatTypeaheadSelection = exports.formatTypeaheadSelection = (item, index, activeIndex, prompt) => {
|
40
|
+
if (index === activeIndex) {
|
41
|
+
prompt.setPromptSelection((0, _stripAnsi2.default)(item));
|
42
|
+
return _chalk2.default.black.bgYellow((0, _stripAnsi2.default)(item));
|
43
|
+
}
|
44
|
+
return item;
|
45
|
+
};
|
@@ -0,0 +1,30 @@
|
|
1
|
+
"use strict";
|
2
|
+
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
4
|
+
value: true
|
5
|
+
});
|
6
|
+
|
7
|
+
|
8
|
+
const scroll = (size, { offset, max }) => {
|
9
|
+
let start = 0;
|
10
|
+
let index = Math.min(offset, size);
|
11
|
+
|
12
|
+
const halfScreen = max / 2;
|
13
|
+
|
14
|
+
if (index <= halfScreen) {
|
15
|
+
start = 0;
|
16
|
+
} else {
|
17
|
+
if (size >= max) {
|
18
|
+
start = Math.min(index - halfScreen - 1, size - max);
|
19
|
+
}
|
20
|
+
index = Math.min(index - start, size);
|
21
|
+
}
|
22
|
+
|
23
|
+
return {
|
24
|
+
end: Math.min(size, start + max),
|
25
|
+
index,
|
26
|
+
start
|
27
|
+
};
|
28
|
+
};
|
29
|
+
|
30
|
+
exports.default = scroll;
|
@@ -0,0 +1,91 @@
|
|
1
|
+
'use strict';
|
2
|
+
|
3
|
+
var _chalk = require('chalk');
|
4
|
+
|
5
|
+
var _chalk2 = _interopRequireDefault(_chalk);
|
6
|
+
|
7
|
+
var _jestWatcher = require('jest-watcher');
|
8
|
+
|
9
|
+
var _scroll2 = require('./shared/scroll');
|
10
|
+
|
11
|
+
var _scroll3 = _interopRequireDefault(_scroll2);
|
12
|
+
|
13
|
+
var _utils = require('./lib/utils');
|
14
|
+
|
15
|
+
var _pattern_mode_helpers = require('./shared/pattern_mode_helpers');
|
16
|
+
|
17
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
18
|
+
|
19
|
+
class TestNamePatternPrompt extends _jestWatcher.PatternPrompt {
|
20
|
+
|
21
|
+
constructor(pipe, prompt) {
|
22
|
+
super(pipe, prompt);
|
23
|
+
this._entityName = 'tests';
|
24
|
+
this._cachedTestResults = [];
|
25
|
+
}
|
26
|
+
|
27
|
+
_onChange(pattern, options) {
|
28
|
+
super._onChange(pattern, options);
|
29
|
+
this._printTypeahead(pattern, options);
|
30
|
+
}
|
31
|
+
|
32
|
+
_printTypeahead(pattern, options) {
|
33
|
+
const matchedTests = this._getMatchedTests(pattern);
|
34
|
+
const total = matchedTests.length;
|
35
|
+
const pipe = this._pipe;
|
36
|
+
const prompt = this._prompt;
|
37
|
+
|
38
|
+
(0, _jestWatcher.printPatternCaret)(pattern, pipe);
|
39
|
+
|
40
|
+
if (pattern) {
|
41
|
+
(0, _pattern_mode_helpers.printPatternMatches)(total, 'test', pipe, ` from ${_chalk2.default.yellow('cached')} test suites`);
|
42
|
+
|
43
|
+
const width = (0, _utils.getTerminalWidth)();
|
44
|
+
|
45
|
+
var _scroll = (0, _scroll3.default)(total, options);
|
46
|
+
|
47
|
+
const start = _scroll.start,
|
48
|
+
end = _scroll.end,
|
49
|
+
index = _scroll.index;
|
50
|
+
|
51
|
+
|
52
|
+
prompt.setPromptLength(total);
|
53
|
+
|
54
|
+
matchedTests.slice(start, end).map(name => (0, _utils.formatTestNameByPattern)(name, pattern, width - 4)).map((item, i) => (0, _pattern_mode_helpers.formatTypeaheadSelection)(item, i, index, prompt)).forEach(item => (0, _pattern_mode_helpers.printTypeaheadItem)(item, pipe));
|
55
|
+
|
56
|
+
if (total > end) {
|
57
|
+
(0, _pattern_mode_helpers.printMore)('test', pipe, total - end);
|
58
|
+
}
|
59
|
+
} else {
|
60
|
+
(0, _pattern_mode_helpers.printStartTyping)('test name', pipe);
|
61
|
+
}
|
62
|
+
|
63
|
+
(0, _jestWatcher.printRestoredPatternCaret)(pattern, this._currentUsageRows, pipe);
|
64
|
+
}
|
65
|
+
|
66
|
+
_getMatchedTests(pattern) {
|
67
|
+
let regex;
|
68
|
+
|
69
|
+
try {
|
70
|
+
regex = new RegExp(pattern, 'i');
|
71
|
+
} catch (e) {
|
72
|
+
return [];
|
73
|
+
}
|
74
|
+
|
75
|
+
const matchedTests = [];
|
76
|
+
|
77
|
+
this._cachedTestResults.forEach(({ testResults }) => testResults.forEach(({ title }) => {
|
78
|
+
if (regex.test(title)) {
|
79
|
+
matchedTests.push(title);
|
80
|
+
}
|
81
|
+
}));
|
82
|
+
|
83
|
+
return matchedTests;
|
84
|
+
}
|
85
|
+
|
86
|
+
updateCachedTestResults(testResults = []) {
|
87
|
+
this._cachedTestResults = testResults;
|
88
|
+
}
|
89
|
+
}
|
90
|
+
|
91
|
+
module.exports = TestNamePatternPrompt;
|
@@ -0,0 +1,53 @@
|
|
1
|
+
'use strict';
|
2
|
+
|
3
|
+
var _jestWatcher = require('jest-watcher');
|
4
|
+
|
5
|
+
var _test_name_pattern_prompt = require('./test_name_pattern_prompt');
|
6
|
+
|
7
|
+
var _test_name_pattern_prompt2 = _interopRequireDefault(_test_name_pattern_prompt);
|
8
|
+
|
9
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
10
|
+
|
11
|
+
class TestNamePlugin {
|
12
|
+
|
13
|
+
constructor({
|
14
|
+
stdin,
|
15
|
+
stdout
|
16
|
+
}) {
|
17
|
+
this._stdin = stdin;
|
18
|
+
this._stdout = stdout;
|
19
|
+
this._prompt = new _jestWatcher.Prompt();
|
20
|
+
this._testResults = [];
|
21
|
+
}
|
22
|
+
|
23
|
+
apply(jestHooks) {
|
24
|
+
jestHooks.onTestRunComplete(({ testResults }) => {
|
25
|
+
this._testResults = testResults;
|
26
|
+
});
|
27
|
+
}
|
28
|
+
|
29
|
+
onKey(key) {
|
30
|
+
this._prompt.put(key);
|
31
|
+
}
|
32
|
+
|
33
|
+
run(globalConfig, updateConfigAndRun) {
|
34
|
+
const p = new _test_name_pattern_prompt2.default(this._stdout, this._prompt);
|
35
|
+
p.updateCachedTestResults(this._testResults);
|
36
|
+
return new Promise((res, rej) => {
|
37
|
+
p.run(value => {
|
38
|
+
updateConfigAndRun({ mode: 'watch', testNamePattern: value });
|
39
|
+
res();
|
40
|
+
}, rej);
|
41
|
+
});
|
42
|
+
}
|
43
|
+
|
44
|
+
// eslint-disable-next-line class-methods-use-this
|
45
|
+
getUsageInfo() {
|
46
|
+
return {
|
47
|
+
key: 't',
|
48
|
+
prompt: 'filter by a test name regex pattern'
|
49
|
+
};
|
50
|
+
}
|
51
|
+
}
|
52
|
+
|
53
|
+
module.exports = TestNamePlugin;
|