poku 1.9.4 → 1.10.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/lib/@types/background-process.d.ts +2 -1
- package/lib/@types/poku.d.ts +6 -0
- package/lib/bin/index.js +2 -0
- package/lib/modules/create-service.d.ts +4 -6
- package/lib/modules/create-service.js +125 -91
- package/lib/modules/exit.js +5 -6
- package/lib/modules/poku.js +33 -19
- package/lib/services/pid.d.ts +8 -0
- package/lib/services/pid.js +74 -0
- package/lib/services/run-tests.js +27 -11
- package/package.json +10 -9
|
@@ -16,7 +16,7 @@ type BackgroundProcessOptions = {
|
|
|
16
16
|
*/
|
|
17
17
|
startAfter?: string | number;
|
|
18
18
|
/**
|
|
19
|
-
* Stops the service after:
|
|
19
|
+
* Stops the service for neither success nor failure after:
|
|
20
20
|
* @default 60000
|
|
21
21
|
*/
|
|
22
22
|
timeout?: number;
|
|
@@ -43,4 +43,5 @@ export type StartServiceOptions = {
|
|
|
43
43
|
*/
|
|
44
44
|
readonly platform?: Configs['platform'];
|
|
45
45
|
} & BackgroundProcessOptions;
|
|
46
|
+
export type End = (port?: number) => Promise<void>;
|
|
46
47
|
export {};
|
package/lib/@types/poku.d.ts
CHANGED
|
@@ -50,6 +50,12 @@ export type Configs = {
|
|
|
50
50
|
* @default 'node'
|
|
51
51
|
*/
|
|
52
52
|
platform?: 'node' | 'bun' | 'deno';
|
|
53
|
+
/**
|
|
54
|
+
* Stops the tests at the first failure.
|
|
55
|
+
*
|
|
56
|
+
* @default false
|
|
57
|
+
*/
|
|
58
|
+
failFast?: boolean;
|
|
53
59
|
/**
|
|
54
60
|
* You can use this option to run a **callback** or a **file** before each test file on your suite.
|
|
55
61
|
*
|
package/lib/bin/index.js
CHANGED
|
@@ -17,6 +17,7 @@ const exclude = (0, get_arg_js_1.getArg)('exclude');
|
|
|
17
17
|
const parallel = (0, get_arg_js_1.hasArg)('parallel');
|
|
18
18
|
const quiet = (0, get_arg_js_1.hasArg)('quiet');
|
|
19
19
|
const debug = (0, get_arg_js_1.hasArg)('debug');
|
|
20
|
+
const failFast = (0, get_arg_js_1.hasArg)('fail-fast');
|
|
20
21
|
if ((0, get_arg_js_1.hasArg)('log-success'))
|
|
21
22
|
console.log(`The flag ${format_js_1.format.bold('--log-success')} is deprecated. Use ${format_js_1.format.bold('--debug')} instead.`);
|
|
22
23
|
(0, index_js_1.poku)(dirs, {
|
|
@@ -26,5 +27,6 @@ if ((0, get_arg_js_1.hasArg)('log-success'))
|
|
|
26
27
|
parallel,
|
|
27
28
|
quiet,
|
|
28
29
|
debug,
|
|
30
|
+
failFast,
|
|
29
31
|
});
|
|
30
32
|
/* c8 ignore stop */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { StartScriptOptions, StartServiceOptions } from '../@types/background-process.js';
|
|
1
|
+
import { End, StartScriptOptions, StartServiceOptions } from '../@types/background-process.js';
|
|
2
2
|
/**
|
|
3
3
|
*
|
|
4
4
|
* Starts a file in a background process
|
|
@@ -6,7 +6,7 @@ import { StartScriptOptions, StartServiceOptions } from '../@types/background-pr
|
|
|
6
6
|
* Useful for servers, APIs, etc.
|
|
7
7
|
*/
|
|
8
8
|
export declare const startService: (file: string, options?: StartServiceOptions) => Promise<{
|
|
9
|
-
end:
|
|
9
|
+
end: End;
|
|
10
10
|
}>;
|
|
11
11
|
/**
|
|
12
12
|
*
|
|
@@ -18,10 +18,8 @@ export declare const startService: (file: string, options?: StartServiceOptions)
|
|
|
18
18
|
*
|
|
19
19
|
* ---
|
|
20
20
|
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* - See: https://github.com/wellwelwel/poku/issues/143
|
|
21
|
+
* For **Bun**, please see https://github.com/oven-sh/bun/issues/11055
|
|
24
22
|
*/
|
|
25
23
|
export declare const startScript: (script: string, options?: StartScriptOptions) => Promise<{
|
|
26
|
-
end:
|
|
24
|
+
end: End;
|
|
27
25
|
}>;
|
|
@@ -18,97 +18,137 @@ const node_child_process_1 = require("child_process");
|
|
|
18
18
|
const runner_js_1 = require("../helpers/runner.js");
|
|
19
19
|
const node_path_1 = __importDefault(require("path"));
|
|
20
20
|
const list_files_js_1 = require("./list-files.js");
|
|
21
|
-
const
|
|
22
|
-
const
|
|
21
|
+
const pid_js_1 = require("../services/pid.js");
|
|
22
|
+
const runningProcesses = new Map();
|
|
23
23
|
/* c8 ignore start */
|
|
24
|
-
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
});
|
|
24
|
+
node_process_1.default.once('SIGINT', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
25
|
+
for (const { end, port } of runningProcesses.values()) {
|
|
26
|
+
yield end(port);
|
|
27
|
+
}
|
|
28
|
+
}));
|
|
30
29
|
/* c8 ignore stop */
|
|
31
30
|
const backgroundProcess = (runtime, args, file, options) => new Promise((resolve, reject) => {
|
|
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
|
-
|
|
31
|
+
try {
|
|
32
|
+
let isResolved = false;
|
|
33
|
+
const service = (0, node_child_process_1.spawn)(runtime, args, {
|
|
34
|
+
stdio: ['inherit', 'pipe', 'pipe'],
|
|
35
|
+
/* c8 ignore next */
|
|
36
|
+
shell: runner_js_1.isWindows,
|
|
37
|
+
cwd: (options === null || options === void 0 ? void 0 : options.cwd)
|
|
38
|
+
? (0, list_files_js_1.sanitizePath)(node_path_1.default.normalize(options.cwd))
|
|
39
|
+
: undefined,
|
|
40
|
+
env: node_process_1.default.env,
|
|
41
|
+
/* c8 ignore next */
|
|
42
|
+
detached: !runner_js_1.isWindows,
|
|
43
|
+
/* c8 ignore next */
|
|
44
|
+
windowsHide: runner_js_1.isWindows,
|
|
45
|
+
timeout: options === null || options === void 0 ? void 0 : options.timeout,
|
|
46
|
+
});
|
|
47
|
+
const PID = service.pid;
|
|
48
|
+
let portBackup;
|
|
49
|
+
/* c8 ignore start */
|
|
50
|
+
const end = (port) => new Promise((resolve) => {
|
|
51
|
+
try {
|
|
52
|
+
runningProcesses.delete(PID);
|
|
53
|
+
if (runner_js_1.isWindows) {
|
|
54
|
+
pid_js_1.killPID.windows(PID);
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
if (['bun', 'deno'].includes(runtime) ||
|
|
58
|
+
['bun', 'deno'].includes(String(options === null || options === void 0 ? void 0 : options.runner))) {
|
|
59
|
+
node_process_1.default.kill(PID);
|
|
60
|
+
}
|
|
61
|
+
else
|
|
62
|
+
node_process_1.default.kill(-PID, 'SIGKILL');
|
|
63
|
+
if (port && ['bun', 'deno'].includes(runtime)) {
|
|
64
|
+
setTimeout(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
65
|
+
const PIDs = runner_js_1.isWindows
|
|
66
|
+
? yield pid_js_1.findPID.windows(port)
|
|
67
|
+
: yield pid_js_1.findPID.unix(port);
|
|
68
|
+
for (const subPID of PIDs) {
|
|
69
|
+
if (!subPID)
|
|
70
|
+
continue;
|
|
71
|
+
runner_js_1.isWindows
|
|
72
|
+
? yield pid_js_1.killPID.windows(subPID)
|
|
73
|
+
: yield pid_js_1.killPID.unix(subPID);
|
|
74
|
+
}
|
|
75
|
+
resolve(undefined);
|
|
76
|
+
return;
|
|
77
|
+
}));
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
resolve(undefined);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
72
83
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
const stringData = JSON.stringify(String(data));
|
|
79
|
-
if (typeof (options === null || options === void 0 ? void 0 : options.startAfter) === 'undefined' ||
|
|
80
|
-
(typeof (options === null || options === void 0 ? void 0 : options.startAfter) === 'string' &&
|
|
81
|
-
stringData.includes(options === null || options === void 0 ? void 0 : options.startAfter))) {
|
|
82
|
-
resolve({ end });
|
|
83
|
-
clearTimeout(timeout);
|
|
84
|
-
isResolved = true;
|
|
84
|
+
catch (_a) {
|
|
85
|
+
{
|
|
86
|
+
resolve(undefined);
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
85
89
|
}
|
|
86
|
-
}
|
|
87
|
-
(
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
90
|
+
});
|
|
91
|
+
runningProcesses.set(PID, { end, port: portBackup });
|
|
92
|
+
/* c8 ignore stop */
|
|
93
|
+
/* c8 ignore start */
|
|
94
|
+
service.stdout.on('data', (data) => {
|
|
95
|
+
if (!isResolved && typeof (options === null || options === void 0 ? void 0 : options.startAfter) !== 'number') {
|
|
96
|
+
const stringData = JSON.stringify(String(data));
|
|
97
|
+
if (typeof (options === null || options === void 0 ? void 0 : options.startAfter) === 'undefined' ||
|
|
98
|
+
(typeof (options === null || options === void 0 ? void 0 : options.startAfter) === 'string' &&
|
|
99
|
+
stringData.includes(options === null || options === void 0 ? void 0 : options.startAfter))) {
|
|
100
|
+
resolve({ end });
|
|
101
|
+
clearTimeout(timeout);
|
|
102
|
+
isResolved = true;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
(options === null || options === void 0 ? void 0 : options.verbose) && console.log(String(data));
|
|
106
|
+
});
|
|
107
|
+
/* c8 ignore stop */
|
|
108
|
+
/* c8 ignore start */
|
|
109
|
+
service.stderr.on('data', (data) => {
|
|
110
|
+
if (!isResolved && typeof (options === null || options === void 0 ? void 0 : options.startAfter) !== 'number') {
|
|
111
|
+
const stringData = JSON.stringify(String(data));
|
|
112
|
+
if (typeof (options === null || options === void 0 ? void 0 : options.startAfter) === 'undefined' ||
|
|
113
|
+
(typeof (options === null || options === void 0 ? void 0 : options.startAfter) === 'string' &&
|
|
114
|
+
stringData.includes(options === null || options === void 0 ? void 0 : options.startAfter))) {
|
|
115
|
+
resolve({ end });
|
|
116
|
+
clearTimeout(timeout);
|
|
117
|
+
isResolved = true;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
(options === null || options === void 0 ? void 0 : options.verbose) && console.log(String(data));
|
|
121
|
+
});
|
|
122
|
+
/* c8 ignore stop */
|
|
123
|
+
/* c8 ignore stop */
|
|
124
|
+
service.on('error', (err) => {
|
|
125
|
+
end(portBackup);
|
|
126
|
+
reject(`Service failed to start: ${err}`);
|
|
127
|
+
});
|
|
128
|
+
/* c8 ignore stop */
|
|
129
|
+
/* c8 ignore start */
|
|
130
|
+
service.on('close', (code) => {
|
|
131
|
+
if (code !== 0)
|
|
132
|
+
reject(`Service exited with code ${code}`);
|
|
133
|
+
});
|
|
134
|
+
/* c8 ignore stop */
|
|
135
|
+
const timeout = setTimeout(() => {
|
|
105
136
|
if (!isResolved) {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
isResolved = true;
|
|
137
|
+
end(portBackup);
|
|
138
|
+
reject(`createService: Timeout\nFile: ${file}`);
|
|
109
139
|
}
|
|
110
|
-
}, options.
|
|
140
|
+
}, (options === null || options === void 0 ? void 0 : options.timeout) || 60000);
|
|
141
|
+
if (typeof (options === null || options === void 0 ? void 0 : options.startAfter) === 'number') {
|
|
142
|
+
setTimeout(() => {
|
|
143
|
+
if (!isResolved) {
|
|
144
|
+
resolve({ end });
|
|
145
|
+
clearTimeout(timeout);
|
|
146
|
+
isResolved = true;
|
|
147
|
+
}
|
|
148
|
+
}, options.startAfter);
|
|
149
|
+
}
|
|
111
150
|
}
|
|
151
|
+
catch (_a) { }
|
|
112
152
|
});
|
|
113
153
|
/**
|
|
114
154
|
*
|
|
@@ -133,19 +173,13 @@ exports.startService = startService;
|
|
|
133
173
|
*
|
|
134
174
|
* ---
|
|
135
175
|
*
|
|
136
|
-
*
|
|
137
|
-
*
|
|
138
|
-
* - See: https://github.com/wellwelwel/poku/issues/143
|
|
176
|
+
* For **Bun**, please see https://github.com/oven-sh/bun/issues/11055
|
|
139
177
|
*/
|
|
140
178
|
const startScript = (script, options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
141
179
|
const runner = (options === null || options === void 0 ? void 0 : options.runner) || 'npm';
|
|
142
180
|
const runtimeOptions = (0, runner_js_1.scriptRunner)(runner);
|
|
143
181
|
const runtime = runtimeOptions.shift();
|
|
144
182
|
const runtimeArgs = [...runtimeOptions, script];
|
|
145
|
-
|
|
146
|
-
if (['bun', 'deno'].includes(runner))
|
|
147
|
-
throw new Error(`${format_js_1.format.bold('startScript')} currently doesn't works for Bun and Deno.${node_os_1.EOL}See: https://github.com/wellwelwel/poku/issues/143`);
|
|
148
|
-
/* c8 ignore stop */
|
|
149
|
-
return yield backgroundProcess(runtime, runtimeArgs, script, Object.assign(Object.assign({}, options), { isScript: true, runner }));
|
|
183
|
+
return yield backgroundProcess(runtime, runtimeArgs, script, Object.assign(Object.assign({}, options), { runner }));
|
|
150
184
|
});
|
|
151
185
|
exports.startScript = startScript;
|
package/lib/modules/exit.js
CHANGED
|
@@ -13,15 +13,14 @@ const exit = (code, quiet) => {
|
|
|
13
13
|
const isPoku = run_tests_js_1.results.success > 0 || run_tests_js_1.results.fail > 0;
|
|
14
14
|
!quiet &&
|
|
15
15
|
node_process_1.default.on('exit', (code) => {
|
|
16
|
-
isPoku
|
|
16
|
+
if (isPoku) {
|
|
17
|
+
(0, hr_js_1.hr)();
|
|
17
18
|
console.log(format_js_1.format.bg(42, `PASS › ${run_tests_js_1.results.success}`), format_js_1.format.bg(run_tests_js_1.results.fail === 0 ? 100 : 41, `FAIL › ${run_tests_js_1.results.fail}`));
|
|
18
|
-
|
|
19
|
+
(0, hr_js_1.hr)();
|
|
20
|
+
}
|
|
19
21
|
console.log(`${format_js_1.format.dim('Exited with code')} ${format_js_1.format.bold(format_js_1.format === null || format_js_1.format === void 0 ? void 0 : format_js_1.format[code === 0 ? 'success' : 'fail'](String(code)))}`);
|
|
20
22
|
});
|
|
21
|
-
|
|
22
|
-
if (code !== 0)
|
|
23
|
-
node_process_1.default.exit(1);
|
|
24
|
-
node_process_1.default.exit(0);
|
|
23
|
+
node_process_1.default.exit(code === 0 ? 0 : 1);
|
|
25
24
|
};
|
|
26
25
|
exports.exit = exit;
|
|
27
26
|
node_process_1.default.on('unhandledRejection', (reason) => {
|
package/lib/modules/poku.js
CHANGED
|
@@ -29,33 +29,47 @@ function poku(targetPaths, configs) {
|
|
|
29
29
|
const prepareDirs = (0, force_array_js_1.forceArray)(targetPaths);
|
|
30
30
|
const dirs = prepareDirs.length > 0 ? prepareDirs : ['./'];
|
|
31
31
|
const showLogs = !(0, logs_js_1.isQuiet)(configs);
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
// Sequential
|
|
33
|
+
if (!(configs === null || configs === void 0 ? void 0 : configs.parallel)) {
|
|
34
|
+
for (const dir of dirs) {
|
|
35
|
+
const result = yield (0, run_tests_js_1.runTests)(dir, configs);
|
|
36
|
+
if (!result) {
|
|
37
|
+
code = 1;
|
|
38
|
+
if (configs === null || configs === void 0 ? void 0 : configs.failFast)
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
36
41
|
}
|
|
37
|
-
const concurrency = yield Promise.all(dirs.map((dir) => (0, run_tests_js_1.runTestsParallel)(dir, configs)));
|
|
38
|
-
if (concurrency.some((result) => !result))
|
|
39
|
-
code = 1;
|
|
40
|
-
showLogs && (0, hr_js_1.hr)();
|
|
41
|
-
if (showLogs && run_test_file_js_1.fileResults.success.length > 0)
|
|
42
|
-
console.log(run_test_file_js_1.fileResults.success
|
|
43
|
-
.map((current) => `${indentation_js_1.indentation.test}${format_js_1.format.success('✔')} ${format_js_1.format.dim(current)}`)
|
|
44
|
-
.join(node_os_1.EOL));
|
|
45
|
-
if (showLogs && run_test_file_js_1.fileResults.fail.length > 0)
|
|
46
|
-
console.log(run_test_file_js_1.fileResults.fail
|
|
47
|
-
.map((current) => `${indentation_js_1.indentation.test}${format_js_1.format.fail('✘')} ${current}`)
|
|
48
|
-
.join(node_os_1.EOL));
|
|
49
42
|
if (configs === null || configs === void 0 ? void 0 : configs.noExit)
|
|
50
43
|
return code;
|
|
51
44
|
(0, exit_js_1.exit)(code, configs === null || configs === void 0 ? void 0 : configs.quiet);
|
|
52
45
|
return;
|
|
53
46
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
47
|
+
// Parallel
|
|
48
|
+
if (showLogs) {
|
|
49
|
+
(0, hr_js_1.hr)();
|
|
50
|
+
console.log(`${format_js_1.format.bold('Running the Test Suite in Parallel')}${node_os_1.EOL}`);
|
|
51
|
+
}
|
|
52
|
+
try {
|
|
53
|
+
const promises = dirs.map((dir) => __awaiter(this, void 0, void 0, function* () {
|
|
54
|
+
const result = yield (0, run_tests_js_1.runTestsParallel)(dir, configs);
|
|
55
|
+
if (!result && (configs === null || configs === void 0 ? void 0 : configs.failFast))
|
|
56
|
+
throw '';
|
|
57
|
+
return result;
|
|
58
|
+
}));
|
|
59
|
+
const concurrency = yield Promise.all(promises);
|
|
60
|
+
if (concurrency.some((result) => !result))
|
|
57
61
|
code = 1;
|
|
58
62
|
}
|
|
63
|
+
catch (_a) { }
|
|
64
|
+
showLogs && (0, hr_js_1.hr)();
|
|
65
|
+
if (showLogs && run_test_file_js_1.fileResults.success.length > 0)
|
|
66
|
+
console.log(run_test_file_js_1.fileResults.success
|
|
67
|
+
.map((current) => `${indentation_js_1.indentation.test}${format_js_1.format.success('✔')} ${format_js_1.format.dim(current)}`)
|
|
68
|
+
.join(node_os_1.EOL));
|
|
69
|
+
if (showLogs && run_test_file_js_1.fileResults.fail.length > 0)
|
|
70
|
+
console.log(run_test_file_js_1.fileResults.fail
|
|
71
|
+
.map((current) => `${indentation_js_1.indentation.test}${format_js_1.format.fail('✘')} ${current}`)
|
|
72
|
+
.join(node_os_1.EOL));
|
|
59
73
|
if (configs === null || configs === void 0 ? void 0 : configs.noExit)
|
|
60
74
|
return code;
|
|
61
75
|
(0, exit_js_1.exit)(code, configs === null || configs === void 0 ? void 0 : configs.quiet);
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* c8 ignore start */
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.findPID = exports.killPID = void 0;
|
|
5
|
+
const node_child_process_1 = require("child_process");
|
|
6
|
+
const node_os_1 = require("os");
|
|
7
|
+
exports.killPID = {
|
|
8
|
+
unix: (PID) => new Promise((resolve) => {
|
|
9
|
+
try {
|
|
10
|
+
const service = (0, node_child_process_1.spawn)('kill', ['-9', String(PID)]);
|
|
11
|
+
service.on('close', () => {
|
|
12
|
+
resolve(undefined);
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
catch (_a) {
|
|
16
|
+
resolve(undefined);
|
|
17
|
+
}
|
|
18
|
+
}),
|
|
19
|
+
windows: (PID) => new Promise((resolve) => {
|
|
20
|
+
try {
|
|
21
|
+
const service = (0, node_child_process_1.spawn)('taskkill', ['/F', '/T', '/PID', String(PID)]);
|
|
22
|
+
service.on('close', () => {
|
|
23
|
+
resolve(undefined);
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
catch (_a) {
|
|
27
|
+
resolve(undefined);
|
|
28
|
+
}
|
|
29
|
+
}),
|
|
30
|
+
};
|
|
31
|
+
exports.findPID = {
|
|
32
|
+
unix: (port) => new Promise((resolve) => {
|
|
33
|
+
try {
|
|
34
|
+
const PIDs = new Set();
|
|
35
|
+
const service = (0, node_child_process_1.spawn)('lsof', ['-t', '-i', `:${Number(port)}`]);
|
|
36
|
+
service.stdout.on('data', (data) => {
|
|
37
|
+
const output = data.toString().trim().split(node_os_1.EOL);
|
|
38
|
+
output.forEach((pid) => {
|
|
39
|
+
if (pid)
|
|
40
|
+
PIDs.add(Number(pid));
|
|
41
|
+
});
|
|
42
|
+
service.on('close', () => {
|
|
43
|
+
resolve(Array.from(PIDs));
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
catch (_a) { }
|
|
48
|
+
}),
|
|
49
|
+
windows: (port) => new Promise((resolve) => {
|
|
50
|
+
try {
|
|
51
|
+
const PIDs = new Set();
|
|
52
|
+
const service = (0, node_child_process_1.spawn)('cmd.exe', [
|
|
53
|
+
'/c',
|
|
54
|
+
`netstat -aon | findstr :${Number(port)}`,
|
|
55
|
+
]);
|
|
56
|
+
service.stdout.on('data', (data) => {
|
|
57
|
+
const output = data.toString().trim();
|
|
58
|
+
const lines = output.trim().split(node_os_1.EOL);
|
|
59
|
+
lines.map((line) => {
|
|
60
|
+
const tokens = line.trim().split(/\s+/);
|
|
61
|
+
PIDs.add(Number(tokens[4]));
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
service.on('close', () => {
|
|
65
|
+
resolve(Array.from(PIDs));
|
|
66
|
+
});
|
|
67
|
+
service.stderr.on('data', (data) => {
|
|
68
|
+
console.error(`Erro: ${data}`);
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
catch (_a) { }
|
|
72
|
+
}),
|
|
73
|
+
};
|
|
74
|
+
/* c8 ignore stop */
|
|
@@ -59,6 +59,11 @@ const runTests = (dir, configs) => __awaiter(void 0, void 0, void 0, function* (
|
|
|
59
59
|
showLogs &&
|
|
60
60
|
console.log(`${indentation_js_1.indentation.test}${format_js_1.format.fail('✘')} ${log}`, nextLine);
|
|
61
61
|
passed = false;
|
|
62
|
+
if (configs === null || configs === void 0 ? void 0 : configs.failFast) {
|
|
63
|
+
(0, hr_js_1.hr)();
|
|
64
|
+
console.log(` ${format_js_1.format.fail('ℹ')} ${format_js_1.format.bold('fail-fast')} is enabled`);
|
|
65
|
+
break;
|
|
66
|
+
}
|
|
62
67
|
}
|
|
63
68
|
}
|
|
64
69
|
return passed;
|
|
@@ -68,16 +73,27 @@ const runTestsParallel = (dir, configs) => __awaiter(void 0, void 0, void 0, fun
|
|
|
68
73
|
const cwd = node_process_1.default.cwd();
|
|
69
74
|
const testDir = node_path_1.default.join(cwd, dir);
|
|
70
75
|
const files = (0, list_files_js_1.isFile)(dir) ? [dir] : (0, list_files_js_1.listFiles)(testDir, undefined, configs);
|
|
71
|
-
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
76
|
+
try {
|
|
77
|
+
const promises = files.map((filePath) => __awaiter(void 0, void 0, void 0, function* () {
|
|
78
|
+
if ((configs === null || configs === void 0 ? void 0 : configs.failFast) && exports.results.fail > 0)
|
|
79
|
+
return;
|
|
80
|
+
const testPassed = yield (0, run_test_file_js_1.runTestFile)(filePath, configs);
|
|
81
|
+
if (!testPassed) {
|
|
82
|
+
++exports.results.fail;
|
|
83
|
+
if (configs === null || configs === void 0 ? void 0 : configs.failFast)
|
|
84
|
+
throw ` ${format_js_1.format.fail('ℹ')} ${format_js_1.format.bold('fail-fast')} is enabled`;
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
++exports.results.success;
|
|
88
|
+
return true;
|
|
89
|
+
}));
|
|
90
|
+
const concurrency = yield Promise.all(promises);
|
|
91
|
+
return concurrency.every((result) => result);
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
(0, hr_js_1.hr)();
|
|
95
|
+
console.log(error);
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
82
98
|
});
|
|
83
99
|
exports.runTestsParallel = runTestsParallel;
|
package/package.json
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "poku",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.10.1",
|
|
4
4
|
"description": "🐷 Poku makes testing easy for Node.js, Bun & Deno at the same time.",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
6
|
"scripts": {
|
|
7
|
-
"test": "tsx src/bin/index.ts --parallel --debug test/unit,test/integration,test/e2e",
|
|
7
|
+
"test": "tsx src/bin/index.ts --parallel --debug --include=\"test/unit,test/integration,test/e2e\"",
|
|
8
|
+
"test:bun": "bun src/bin/index.ts --parallel --platform=bun --debug --include=\"test/unit,test/integration,test/e2e\"",
|
|
8
9
|
"test:c8": "c8 npm run test",
|
|
9
10
|
"test:ci": "tsx ./test/ci.test.ts",
|
|
10
|
-
"test:node": "FILTER='node-' npm run test:ci",
|
|
11
|
-
"test:
|
|
12
|
-
"test:
|
|
11
|
+
"test:ci:node": "FILTER='node-' npm run test:ci",
|
|
12
|
+
"test:ci:bun": "FILTER='bun-' npm run test:ci",
|
|
13
|
+
"test:ci:deno": "FILTER='deno-' npm run test:ci",
|
|
13
14
|
"predocker:deno": "docker compose -f ./test/docker/playground/deno/docker-compose.yml down",
|
|
14
15
|
"docker:deno": "docker compose -f ./test/docker/playground/deno/docker-compose.yml up --build",
|
|
15
16
|
"clear": "shx rm -rf ./lib ./ci ./coverage",
|
|
@@ -22,7 +23,7 @@
|
|
|
22
23
|
"lint:fix": "npm run eslint:fix && npm run prettier:fix",
|
|
23
24
|
"prettier:checker": "prettier --check .",
|
|
24
25
|
"prettier:fix": "prettier --write .github/workflows/*.yml .",
|
|
25
|
-
"update": "npu && npm i && npm run lint:fix && npm audit"
|
|
26
|
+
"update": "npu --minor && npm i && npm run lint:fix && npm audit"
|
|
26
27
|
},
|
|
27
28
|
"license": "MIT",
|
|
28
29
|
"repository": {
|
|
@@ -102,9 +103,9 @@
|
|
|
102
103
|
],
|
|
103
104
|
"type": "commonjs",
|
|
104
105
|
"devDependencies": {
|
|
105
|
-
"@types/node": "^20.12.
|
|
106
|
-
"@typescript-eslint/eslint-plugin": "^7.
|
|
107
|
-
"@typescript-eslint/parser": "^7.
|
|
106
|
+
"@types/node": "^20.12.11",
|
|
107
|
+
"@typescript-eslint/eslint-plugin": "^7.8.0",
|
|
108
|
+
"@typescript-eslint/parser": "^7.8.0",
|
|
108
109
|
"c8": "^9.1.0",
|
|
109
110
|
"eslint": "^8.57.0",
|
|
110
111
|
"eslint-config-prettier": "^9.1.0",
|