jest-watch-typeahead 2.2.0 → 2.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +8 -5
@@ -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.1",
|
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": "^
|
35
|
+
"ansi-escapes": "^6.0.0",
|
36
36
|
"chalk": "^4.0.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",
|
@@ -109,5 +109,8 @@
|
|
109
109
|
"@semantic-release/github"
|
110
110
|
]
|
111
111
|
},
|
112
|
-
"packageManager": "yarn@3.
|
112
|
+
"packageManager": "yarn@3.3.0",
|
113
|
+
"resolutions": {
|
114
|
+
"ansi-escapes/type-fest": "^3.0.0"
|
115
|
+
}
|
113
116
|
}
|