jest-watch-typeahead 2.2.0 → 2.2.2
Sign up to get free protection for your applications and to get access to all the features.
- package/build/file_name_plugin/plugin.js +0 -5
- package/build/file_name_plugin/prompt.js +0 -13
- package/build/lib/pattern_mode_helpers.js +0 -3
- package/build/lib/scroll.js +0 -4
- package/build/lib/utils.js +6 -26
- package/build/test_name_plugin/plugin.js +0 -5
- package/build/test_name_plugin/prompt.js +0 -14
- package/package.json +10 -7
@@ -15,7 +15,6 @@ export default class FileNamePlugin {
|
|
15
15
|
prompt: config.prompt || 'filter by a filename regex pattern'
|
16
16
|
};
|
17
17
|
}
|
18
|
-
|
19
18
|
apply(jestHooks) {
|
20
19
|
jestHooks.onFileChange(({
|
21
20
|
projects
|
@@ -23,11 +22,9 @@ export default class FileNamePlugin {
|
|
23
22
|
this._projects = projects;
|
24
23
|
});
|
25
24
|
}
|
26
|
-
|
27
25
|
onKey(key) {
|
28
26
|
this._prompt.put(key);
|
29
27
|
}
|
30
|
-
|
31
28
|
run(globalConfig, updateConfigAndRun) {
|
32
29
|
const p = new FileNamePatternPrompt(this._stdout, this._prompt);
|
33
30
|
p.updateSearchSources(this._projects);
|
@@ -41,9 +38,7 @@ export default class FileNamePlugin {
|
|
41
38
|
}, rej);
|
42
39
|
});
|
43
40
|
}
|
44
|
-
|
45
41
|
getUsageInfo() {
|
46
42
|
return this._usageInfo;
|
47
43
|
}
|
48
|
-
|
49
44
|
}
|
@@ -12,22 +12,17 @@ export default class FileNamePatternPrompt extends PatternPrompt {
|
|
12
12
|
this._entityName = 'filenames';
|
13
13
|
this._searchSources = [];
|
14
14
|
}
|
15
|
-
|
16
15
|
_onChange(pattern, options) {
|
17
16
|
super._onChange(pattern, options);
|
18
|
-
|
19
17
|
this._printTypeahead(pattern, options);
|
20
18
|
}
|
21
|
-
|
22
19
|
_printTypeahead(pattern, options) {
|
23
20
|
const matchedTests = this._getMatchedTests(pattern);
|
24
|
-
|
25
21
|
const total = matchedTests.length;
|
26
22
|
const pipe = this._pipe;
|
27
23
|
const prompt = this._prompt;
|
28
24
|
printPatternCaret(pattern, pipe);
|
29
25
|
pipe.write(ansiEscapes.cursorLeft);
|
30
|
-
|
31
26
|
if (pattern) {
|
32
27
|
printPatternMatches(total, 'file', pipe);
|
33
28
|
const prefix = ` ${chalk.dim('\u203A')} `;
|
@@ -46,26 +41,21 @@ export default class FileNamePatternPrompt extends PatternPrompt {
|
|
46
41
|
const filePath = trimAndFormatPath(padding, context.config, path, width);
|
47
42
|
return highlight(path, filePath, pattern);
|
48
43
|
}).map((item, i) => formatTypeaheadSelection(item, i, index, prompt)).forEach(item => printTypeaheadItem(item, pipe));
|
49
|
-
|
50
44
|
if (total > end) {
|
51
45
|
printMore('file', pipe, total - end);
|
52
46
|
}
|
53
47
|
} else {
|
54
48
|
printStartTyping('filename', pipe);
|
55
49
|
}
|
56
|
-
|
57
50
|
printRestoredPatternCaret(pattern, this._currentUsageRows, pipe);
|
58
51
|
}
|
59
|
-
|
60
52
|
_getMatchedTests(pattern) {
|
61
53
|
let regex;
|
62
|
-
|
63
54
|
try {
|
64
55
|
regex = new RegExp(pattern, 'i');
|
65
56
|
} catch (e) {
|
66
57
|
return [];
|
67
58
|
}
|
68
|
-
|
69
59
|
return this._searchSources.reduce((tests, {
|
70
60
|
testPaths,
|
71
61
|
config
|
@@ -78,15 +68,12 @@ export default class FileNamePatternPrompt extends PatternPrompt {
|
|
78
68
|
})));
|
79
69
|
}, []);
|
80
70
|
}
|
81
|
-
|
82
71
|
updateSearchSources(searchSources) {
|
83
72
|
this._searchSources = searchSources;
|
84
73
|
}
|
85
|
-
|
86
74
|
run(onSuccess, onCancel, options) {
|
87
75
|
super.run(value => {
|
88
76
|
onSuccess(removeTrimmingDots(value).split('/').map(escapeStrForRegex).join('/'));
|
89
77
|
}, onCancel, options);
|
90
78
|
}
|
91
|
-
|
92
79
|
}
|
@@ -1,8 +1,6 @@
|
|
1
1
|
import chalk from 'chalk';
|
2
2
|
import stripAnsi from 'strip-ansi';
|
3
|
-
|
4
3
|
const pluralize = (count, text) => count === 1 ? text : `${text}s`;
|
5
|
-
|
6
4
|
export const printPatternMatches = (count, entity, pipe, extraText = '') => {
|
7
5
|
const pluralized = pluralize(count, entity);
|
8
6
|
const result = count ? `\n\n Pattern matches ${count} ${pluralized}` : `\n\n Pattern matches no ${pluralized}`;
|
@@ -22,6 +20,5 @@ export const formatTypeaheadSelection = (item, index, activeIndex, prompt) => {
|
|
22
20
|
prompt.setPromptSelection(stripAnsi(item));
|
23
21
|
return chalk.black.bgYellow(stripAnsi(item));
|
24
22
|
}
|
25
|
-
|
26
23
|
return item;
|
27
24
|
};
|
package/build/lib/scroll.js
CHANGED
@@ -5,22 +5,18 @@ const scroll = (size, {
|
|
5
5
|
let start = 0;
|
6
6
|
let index = Math.min(offset, size);
|
7
7
|
const halfScreen = max / 2;
|
8
|
-
|
9
8
|
if (index <= halfScreen) {
|
10
9
|
start = 0;
|
11
10
|
} else {
|
12
11
|
if (size >= max) {
|
13
12
|
start = Math.min(index - halfScreen - 1, size - max);
|
14
13
|
}
|
15
|
-
|
16
14
|
index = Math.min(index - start, size);
|
17
15
|
}
|
18
|
-
|
19
16
|
return {
|
20
17
|
end: Math.min(size, start + max),
|
21
18
|
index,
|
22
19
|
start
|
23
20
|
};
|
24
21
|
};
|
25
|
-
|
26
22
|
export default scroll;
|
package/build/lib/utils.js
CHANGED
@@ -4,7 +4,6 @@ import slash from 'slash';
|
|
4
4
|
import stripAnsi from 'strip-ansi';
|
5
5
|
const TRIMMING_DOTS = '...';
|
6
6
|
const ENTER = '⏎';
|
7
|
-
|
8
7
|
const relativePath = (config, testPath) => {
|
9
8
|
const relativeTestPath = path.relative(config.cwd || config.rootDir, testPath);
|
10
9
|
const dirname = path.dirname(relativeTestPath);
|
@@ -14,9 +13,7 @@ const relativePath = (config, testPath) => {
|
|
14
13
|
dirname
|
15
14
|
};
|
16
15
|
};
|
17
|
-
|
18
16
|
const colorize = (str, start, end) => chalk.dim(str.slice(0, start)) + chalk.reset(str.slice(start, end)) + chalk.dim(str.slice(end));
|
19
|
-
|
20
17
|
export const trimAndFormatPath = (pad, config, testPath, columns) => {
|
21
18
|
const maxLength = columns - pad;
|
22
19
|
const relative = relativePath(config, testPath);
|
@@ -25,50 +22,43 @@ export const trimAndFormatPath = (pad, config, testPath, columns) => {
|
|
25
22
|
} = relative;
|
26
23
|
let {
|
27
24
|
dirname
|
28
|
-
} = relative;
|
25
|
+
} = relative;
|
29
26
|
|
27
|
+
// length is ok
|
30
28
|
if ((dirname + path.sep + basename).length <= maxLength) {
|
31
29
|
return slash(chalk.dim(dirname + path.sep) + chalk.bold(basename));
|
32
|
-
}
|
33
|
-
|
30
|
+
}
|
34
31
|
|
32
|
+
// we can fit trimmed dirname and full basename
|
35
33
|
const basenameLength = basename.length;
|
36
|
-
|
37
34
|
if (basenameLength + 4 < maxLength) {
|
38
35
|
const dirnameLength = maxLength - 4 - basenameLength;
|
39
36
|
dirname = `${TRIMMING_DOTS}${dirname.slice(dirname.length - dirnameLength, dirname.length)}`;
|
40
37
|
return slash(chalk.dim(dirname + path.sep) + chalk.bold(basename));
|
41
38
|
}
|
42
|
-
|
43
39
|
if (basenameLength + 4 === maxLength) {
|
44
40
|
return slash(chalk.dim(`${TRIMMING_DOTS}${path.sep}`) + chalk.bold(basename));
|
45
|
-
}
|
46
|
-
|
47
|
-
|
41
|
+
}
|
42
|
+
// can't fit dirname, but can fit trimmed basename
|
48
43
|
return slash(chalk.bold(`${TRIMMING_DOTS}${basename.slice(-maxLength + 3)}`));
|
49
44
|
};
|
50
45
|
export const getTerminalWidth = (pipe = process.stdout) => pipe.columns;
|
51
46
|
export const highlight = (rawPath, filePath, pattern) => {
|
52
47
|
const relativePathHead = './';
|
53
48
|
let regexp;
|
54
|
-
|
55
49
|
try {
|
56
50
|
regexp = new RegExp(pattern, 'i');
|
57
51
|
} catch (e) {
|
58
52
|
return chalk.dim(filePath);
|
59
53
|
}
|
60
|
-
|
61
54
|
const strippedRawPath = stripAnsi(rawPath);
|
62
55
|
const strippedFilePath = stripAnsi(filePath);
|
63
56
|
const match = strippedRawPath.match(regexp);
|
64
|
-
|
65
57
|
if (!match || match.index == null) {
|
66
58
|
return chalk.dim(strippedFilePath);
|
67
59
|
}
|
68
|
-
|
69
60
|
const offset = strippedRawPath.length - strippedFilePath.length;
|
70
61
|
let trimLength;
|
71
|
-
|
72
62
|
if (strippedFilePath.startsWith(TRIMMING_DOTS)) {
|
73
63
|
trimLength = TRIMMING_DOTS.length;
|
74
64
|
} else if (strippedFilePath.startsWith(relativePathHead)) {
|
@@ -76,7 +66,6 @@ export const highlight = (rawPath, filePath, pattern) => {
|
|
76
66
|
} else {
|
77
67
|
trimLength = 0;
|
78
68
|
}
|
79
|
-
|
80
69
|
const start = match.index - offset;
|
81
70
|
const end = start + match[0].length;
|
82
71
|
return colorize(strippedFilePath, Math.max(start, 0), Math.max(end, trimLength));
|
@@ -84,36 +73,28 @@ export const highlight = (rawPath, filePath, pattern) => {
|
|
84
73
|
export const formatTestNameByPattern = (testName, pattern, width) => {
|
85
74
|
const inlineTestName = testName.replace(/(\r\n|\n|\r)/gm, ENTER);
|
86
75
|
let regexp;
|
87
|
-
|
88
76
|
try {
|
89
77
|
regexp = new RegExp(pattern, 'i');
|
90
78
|
} catch (e) {
|
91
79
|
return chalk.dim(inlineTestName);
|
92
80
|
}
|
93
|
-
|
94
81
|
const match = inlineTestName.match(regexp);
|
95
|
-
|
96
82
|
if (!match || match.index == null) {
|
97
83
|
return chalk.dim(inlineTestName);
|
98
84
|
}
|
99
|
-
|
100
85
|
const startPatternIndex = Math.max(match.index, 0);
|
101
86
|
const endPatternIndex = startPatternIndex + match[0].length;
|
102
87
|
const testNameFitsInTerminal = inlineTestName.length <= width;
|
103
|
-
|
104
88
|
if (testNameFitsInTerminal) {
|
105
89
|
return colorize(inlineTestName, startPatternIndex, endPatternIndex);
|
106
90
|
}
|
107
|
-
|
108
91
|
const numberOfTruncatedChars = TRIMMING_DOTS.length + inlineTestName.length - width;
|
109
92
|
const end = Math.max(endPatternIndex - numberOfTruncatedChars, 0);
|
110
93
|
const truncatedTestName = inlineTestName.slice(numberOfTruncatedChars);
|
111
94
|
const shouldHighlightDots = startPatternIndex <= numberOfTruncatedChars;
|
112
|
-
|
113
95
|
if (shouldHighlightDots) {
|
114
96
|
return colorize(TRIMMING_DOTS + truncatedTestName, 0, end + TRIMMING_DOTS.length);
|
115
97
|
}
|
116
|
-
|
117
98
|
const start = startPatternIndex - numberOfTruncatedChars;
|
118
99
|
return colorize(TRIMMING_DOTS + truncatedTestName, start + TRIMMING_DOTS.length, end + TRIMMING_DOTS.length);
|
119
100
|
};
|
@@ -121,6 +102,5 @@ export const removeTrimmingDots = value => {
|
|
121
102
|
if (value.startsWith(TRIMMING_DOTS)) {
|
122
103
|
return value.slice(TRIMMING_DOTS.length);
|
123
104
|
}
|
124
|
-
|
125
105
|
return value;
|
126
106
|
};
|
@@ -15,7 +15,6 @@ export default class TestNamePlugin {
|
|
15
15
|
prompt: config.prompt || 'filter by a test name regex pattern'
|
16
16
|
};
|
17
17
|
}
|
18
|
-
|
19
18
|
apply(jestHooks) {
|
20
19
|
jestHooks.onTestRunComplete(({
|
21
20
|
testResults
|
@@ -23,11 +22,9 @@ export default class TestNamePlugin {
|
|
23
22
|
this._testResults = testResults;
|
24
23
|
});
|
25
24
|
}
|
26
|
-
|
27
25
|
onKey(key) {
|
28
26
|
this._prompt.put(key);
|
29
27
|
}
|
30
|
-
|
31
28
|
run(globalConfig, updateConfigAndRun) {
|
32
29
|
const p = new TestNamePatternPrompt(this._stdout, this._prompt);
|
33
30
|
p.updateCachedTestResults(this._testResults);
|
@@ -41,9 +38,7 @@ export default class TestNamePlugin {
|
|
41
38
|
}, rej);
|
42
39
|
});
|
43
40
|
}
|
44
|
-
|
45
41
|
getUsageInfo() {
|
46
42
|
return this._usageInfo;
|
47
43
|
}
|
48
|
-
|
49
44
|
}
|
@@ -12,24 +12,18 @@ export default class TestNamePatternPrompt extends PatternPrompt {
|
|
12
12
|
this._cachedTestResults = [];
|
13
13
|
this._offset = -1;
|
14
14
|
}
|
15
|
-
|
16
15
|
_onChange(pattern, options) {
|
17
16
|
super._onChange(pattern, options);
|
18
|
-
|
19
17
|
this._offset = options.offset;
|
20
|
-
|
21
18
|
this._printTypeahead(pattern, options);
|
22
19
|
}
|
23
|
-
|
24
20
|
_printTypeahead(pattern, options) {
|
25
21
|
const matchedTests = this._getMatchedTests(pattern);
|
26
|
-
|
27
22
|
const total = matchedTests.length;
|
28
23
|
const pipe = this._pipe;
|
29
24
|
const prompt = this._prompt;
|
30
25
|
printPatternCaret(pattern, pipe);
|
31
26
|
pipe.write(ansiEscapes.cursorLeft);
|
32
|
-
|
33
27
|
if (pattern) {
|
34
28
|
printPatternMatches(total, 'test', pipe, ` from ${chalk.yellow('cached')} test suites`);
|
35
29
|
const width = getTerminalWidth(pipe);
|
@@ -40,26 +34,21 @@ export default class TestNamePatternPrompt extends PatternPrompt {
|
|
40
34
|
} = scroll(total, options);
|
41
35
|
prompt.setPromptLength(total);
|
42
36
|
matchedTests.slice(start, end).map(name => formatTestNameByPattern(name, pattern, width - 4)).map((item, i) => formatTypeaheadSelection(item, i, index, prompt)).forEach(item => printTypeaheadItem(item, pipe));
|
43
|
-
|
44
37
|
if (total > end) {
|
45
38
|
printMore('test', pipe, total - end);
|
46
39
|
}
|
47
40
|
} else {
|
48
41
|
printStartTyping('test name', pipe);
|
49
42
|
}
|
50
|
-
|
51
43
|
printRestoredPatternCaret(pattern, this._currentUsageRows, pipe);
|
52
44
|
}
|
53
|
-
|
54
45
|
_getMatchedTests(pattern) {
|
55
46
|
let regex;
|
56
|
-
|
57
47
|
try {
|
58
48
|
regex = new RegExp(pattern, 'i');
|
59
49
|
} catch (e) {
|
60
50
|
return [];
|
61
51
|
}
|
62
|
-
|
63
52
|
return this._cachedTestResults.reduce((matchedTests, {
|
64
53
|
testResults
|
65
54
|
}) => {
|
@@ -70,11 +59,9 @@ export default class TestNamePatternPrompt extends PatternPrompt {
|
|
70
59
|
}) => fullName));
|
71
60
|
}, []);
|
72
61
|
}
|
73
|
-
|
74
62
|
updateCachedTestResults(testResults = []) {
|
75
63
|
this._cachedTestResults = testResults;
|
76
64
|
}
|
77
|
-
|
78
65
|
run(onSuccess, onCancel, options) {
|
79
66
|
super.run(value => {
|
80
67
|
const preparedPattern = escapeStrForRegex(removeTrimmingDots(value));
|
@@ -82,5 +69,4 @@ export default class TestNamePatternPrompt extends PatternPrompt {
|
|
82
69
|
onSuccess(useExactMatch ? `^${preparedPattern}$` : preparedPattern);
|
83
70
|
}, onCancel, options);
|
84
71
|
}
|
85
|
-
|
86
72
|
}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "jest-watch-typeahead",
|
3
|
-
"version": "2.2.
|
3
|
+
"version": "2.2.2",
|
4
4
|
"main": "build/index.js",
|
5
5
|
"exports": {
|
6
6
|
".": "./build/index.js",
|
@@ -32,11 +32,11 @@
|
|
32
32
|
"typecheck": "yarn tsc -p ."
|
33
33
|
},
|
34
34
|
"dependencies": {
|
35
|
-
"ansi-escapes": "^
|
36
|
-
"chalk": "^
|
35
|
+
"ansi-escapes": "^6.0.0",
|
36
|
+
"chalk": "^5.2.0",
|
37
37
|
"jest-regex-util": "^29.0.0",
|
38
38
|
"jest-watcher": "^29.0.0",
|
39
|
-
"slash": "^
|
39
|
+
"slash": "^5.0.0",
|
40
40
|
"string-length": "^5.0.1",
|
41
41
|
"strip-ansi": "^7.0.1"
|
42
42
|
},
|
@@ -49,7 +49,7 @@
|
|
49
49
|
"@jest/types": "^29.0.0",
|
50
50
|
"@semantic-release/changelog": "^6.0.1",
|
51
51
|
"@semantic-release/git": "^10.0.1",
|
52
|
-
"@types/node": "^
|
52
|
+
"@types/node": "^14.0.0",
|
53
53
|
"@typescript-eslint/eslint-plugin": "^5.0.0",
|
54
54
|
"@typescript-eslint/parser": "^5.0.0",
|
55
55
|
"babel-jest": "^29.0.0",
|
@@ -65,7 +65,7 @@
|
|
65
65
|
"jest-serializer-ansi-escapes": "^2.0.1",
|
66
66
|
"prettier": "^2.1.1",
|
67
67
|
"rimraf": "^3.0.2",
|
68
|
-
"semantic-release": "^
|
68
|
+
"semantic-release": "^20.0.0",
|
69
69
|
"semver": "^7.3.5",
|
70
70
|
"typescript": "^4.0.2"
|
71
71
|
},
|
@@ -109,5 +109,8 @@
|
|
109
109
|
"@semantic-release/github"
|
110
110
|
]
|
111
111
|
},
|
112
|
-
"packageManager": "yarn@3.
|
112
|
+
"packageManager": "yarn@3.3.1",
|
113
|
+
"resolutions": {
|
114
|
+
"ansi-escapes/type-fest": "^3.0.0"
|
115
|
+
}
|
113
116
|
}
|