forked from jest-community/jest-watch-select-projects
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
124 lines (101 loc) · 3.34 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
const chalk = require('chalk');
const prompts = require('prompts');
const ansiEscapes = require('ansi-escapes');
const { readConfig } = require('jest-config');
const path = require('path');
class JestPluginProjects {
constructor() {
this._activeProjects = {};
this._projectNames = [];
}
apply(jestHook) {
jestHook.onFileChange(({ projects }) => this._setProjects(projects));
jestHook.shouldRunTestSuite(({ testPath, config }) => {
const name = this._getDisplayName(config) || this._getBasename(config);
return (
this._activeProjects[name] === undefined || this._activeProjects[name]
);
});
}
onKey() {}
_getDisplayName(config) {
const { displayName } = config;
return typeof displayName === 'object' ? displayName.name : displayName;
}
_getBasename(config) {
const { rootDir } = config;
return path.basename(rootDir);
}
_setProjects(projects) {
if (!this._projectNames.length) {
const projectNameSet = projects.reduce((state, p) => {
const displayName = this._getDisplayName(p.config);
const basename = this._getBasename(p.config);
if (state.has(displayName)) {
throw new Error(`
Found multiple projects with the same \`displayName\`: "${displayName}"
Change the \`displayName\` on at least one of them to prevent name collision.
- More info: https://facebook.github.io/jest/docs/en/configuration.html#projects-array-string-projectconfig
`);
}
if (state.has(basename)) {
throw new Error(`
Found multiple projects with the same directory basename: "${basename}"
Add a \`displayName\` to at least one of them to prevent name collision.
- More info: https://facebook.github.io/jest/docs/en/configuration.html#projects-array-string-projectconfig
`);
}
return new Set([...state, displayName || basename]);
}, new Set());
this._projectNames = [...projectNameSet];
this._setActiveProjects(this._projectNames);
}
}
_setActiveProjects(activeProjects) {
this._numActiveProjects = activeProjects.length;
this._activeProjects = this._projectNames.reduce((memo, name) => {
memo[name] = activeProjects.includes(name);
return memo;
}, {});
}
run(globalConfig) {
console.log(ansiEscapes.clearScreen);
return prompts([
{
type: 'multiselect',
name: 'activeProjects',
message: 'Select projects',
choices: this._projectNames.map(value => ({
value,
selected: this._activeProjects[value],
})),
},
]).then(({ activeProjects }) => {
process.stdin.setRawMode(true);
process.stdin.resume();
if (activeProjects !== undefined) {
this._setActiveProjects(activeProjects);
return true;
}
return Promise.reject();
});
}
_getActiveProjectsText() {
const numProjects = this._projectNames.length;
if (this._numActiveProjects === numProjects) {
return '(all selected)';
} else if (this._numActiveProjects === 0) {
return '(zero selected)';
} else {
return `(${this._numActiveProjects}/${numProjects} selected)`;
}
return;
}
getUsageInfo() {
return {
key: 'P',
prompt: `select projects ${chalk.italic(this._getActiveProjectsText())}`,
};
}
}
module.exports = JestPluginProjects;