poku 1.4.0 → 1.5.0
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/README.md +47 -51
- package/lib/@types/poku.d.ts +11 -0
- package/lib/bin/index.js +5 -4
- package/lib/helpers/format.d.ts +2 -0
- package/lib/helpers/format.js +10 -3
- package/lib/helpers/hr.js +2 -3
- package/lib/helpers/logs.d.ts +1 -2
- package/lib/helpers/logs.js +3 -5
- package/lib/helpers/parseAsssetion.js +33 -17
- package/lib/helpers/remove-repeats.d.ts +1 -0
- package/lib/helpers/remove-repeats.js +29 -0
- package/lib/modules/assert.js +12 -13
- package/lib/modules/exit.js +9 -8
- package/lib/modules/list-files.js +3 -1
- package/lib/modules/poku.js +24 -3
- package/lib/services/run-test-file.d.ts +6 -0
- package/lib/services/run-test-file.js +58 -20
- package/lib/services/run-tests.d.ts +4 -0
- package/lib/services/run-tests.js +17 -17
- package/package.json +10 -7
package/README.md
CHANGED
|
@@ -4,15 +4,12 @@
|
|
|
4
4
|
[bun-version-image]: https://img.shields.io/badge/Bun->=0.5.3-f471b5
|
|
5
5
|
[deno-version-url]: https://github.com/denoland/deno
|
|
6
6
|
[deno-version-image]: https://img.shields.io/badge/Deno->=1.30.0-70ffaf
|
|
7
|
-
[npm-image]: https://img.shields.io/npm/v/poku.svg?color=3dc1d3
|
|
8
|
-
[npm-url]: https://npmjs.org/package/poku
|
|
9
7
|
[typescript-url]: https://github.com/microsoft/TypeScript
|
|
8
|
+
[typescript-version-image]: https://img.shields.io/badge/TypeScript->=5.0.2-3077c6
|
|
10
9
|
[ci-url]: https://github.com/wellwelwel/poku/actions/workflows/ci.yml?query=branch%3Amain
|
|
11
10
|
[ci-image]: https://img.shields.io/github/actions/workflow/status/wellwelwel/poku/ci.yml?event=push&style=flat&label=CI&branch=main
|
|
12
11
|
[ql-url]: https://github.com/wellwelwel/poku/actions/workflows/codeql.yml?query=branch%3Amain
|
|
13
12
|
[ql-image]: https://img.shields.io/github/actions/workflow/status/wellwelwel/poku/codeql.yml?event=push&style=flat&label=Code%20QL&branch=main
|
|
14
|
-
[license-url]: https://github.com/wellwelwel/poku/blob/main/LICENSE
|
|
15
|
-
[license-image]: https://img.shields.io/npm/l/poku.svg?maxAge=2592000&color=9c88ff
|
|
16
13
|
|
|
17
14
|
# Poku
|
|
18
15
|
|
|
@@ -23,22 +20,23 @@
|
|
|
23
20
|
[![Node.js Version][node-version-image]][node-version-url]
|
|
24
21
|
[![Bun Version][bun-version-image]][bun-version-url]
|
|
25
22
|
[![Deno Version][deno-version-image]][deno-version-url]
|
|
26
|
-
[![
|
|
27
|
-
[![License][license-image]][license-url]
|
|
23
|
+
[![TypeScript Version][typescript-version-image]][typescript-url]
|
|
28
24
|
[![GitHub Workflow Status (with event)][ci-image]][ci-url]
|
|
29
25
|
[![GitHub Workflow Status (with event)][ql-image]][ql-url]
|
|
30
26
|
|
|
31
|
-
Enjoying Poku
|
|
27
|
+
Enjoying **Poku**? Consider giving him a star ⭐️
|
|
32
28
|
|
|
33
29
|
---
|
|
34
30
|
|
|
35
|
-
🐷 [**Documentation Website**](https://poku.dev)
|
|
31
|
+
🐷 [**Documentation Website**](https://poku.dev) • 🔬 [**Compare Poku with the Most Popular Test Runners**](https://poku.dev/docs/comparing)
|
|
36
32
|
|
|
37
33
|
---
|
|
38
34
|
|
|
39
35
|
## Why Poku?
|
|
40
36
|
|
|
41
|
-
|
|
37
|
+
Don't worry about `describe`, `it`, `beforeEach` and everything else 🚀
|
|
38
|
+
|
|
39
|
+
> You don't need to learn what you already know ✨
|
|
42
40
|
|
|
43
41
|
- Supports **ESM** and **CJS**
|
|
44
42
|
- Designed to be highly intuitive
|
|
@@ -47,45 +45,61 @@ Enjoying Poku? Consider giving him a star ⭐️
|
|
|
47
45
|
- Allows both **in-code** and **CLI** usage
|
|
48
46
|
- [**Node.js**][node-version-url], [**Bun**][bun-version-url] and [**Deno**][deno-version-url] compatibility
|
|
49
47
|
- Zero configurations, except you want
|
|
50
|
-
-
|
|
48
|
+
- Poku adapts to your test, not the other way around
|
|
51
49
|
- [**And much more!**](https://poku.dev)
|
|
52
50
|
|
|
53
51
|
---
|
|
54
52
|
|
|
55
|
-
- <img src="https://img.shields.io/bundlephobia/min/poku
|
|
56
|
-
- **Zero** external dependencies
|
|
53
|
+
- <img src="https://img.shields.io/bundlephobia/min/poku">
|
|
54
|
+
- **Zero** external dependencies 🌱
|
|
57
55
|
|
|
58
56
|
---
|
|
59
57
|
|
|
60
58
|
## Documentation
|
|
61
59
|
|
|
62
|
-
- See detailed
|
|
60
|
+
- See detailed usage in [**Documentation**](https://poku.dev/docs/category/documentation) section for **Poku**'s **CLI**, **API (_in-code_)** and **assert**, advanced concepts and much more.
|
|
63
61
|
|
|
64
62
|
---
|
|
65
63
|
|
|
66
64
|
## Overview
|
|
67
65
|
|
|
68
|
-
| Sequential
|
|
69
|
-
|
|
|
70
|
-
|
|
|
71
|
-
|
|
66
|
+
| Sequential | Concurrent |
|
|
67
|
+
| -------------------------------------------------- | ------------------------------------------------ |
|
|
68
|
+
| <img src=".github/assets/readme/sequential.png" /> | <img src=".github/assets/readme/parallel.png" /> |
|
|
69
|
+
|
|
70
|
+
- By default, **Poku**:
|
|
71
|
+
- Searches for all _`.test.`_ and `.spec.` files, but you can customize it using the option [**`filter`**](https://poku.dev/docs/documentation/poku/configs/filter).
|
|
72
|
+
- Uses `sequential` mode.
|
|
73
|
+
- You can use concurrecy by use the flag `--parallel` for **CLI** or the option `parallel` to `true` in **API** (_in-code_) usage.
|
|
72
74
|
|
|
73
|
-
|
|
74
|
-
- The same idea for [**Bun**][bun-version-url] and [**Deno**][deno-version-url] (see bellow).
|
|
75
|
+
> Follow the same idea for [**Bun**][bun-version-url] and [**Deno**][deno-version-url].
|
|
75
76
|
|
|
76
77
|
---
|
|
77
78
|
|
|
78
|
-
**Poku** also includes the `assert` method, keeping everything as it is, but providing human readability
|
|
79
|
+
**Poku** also includes the `assert` method, keeping everything as it is, but providing human readability and automatic `describe` and `it`:
|
|
80
|
+
|
|
81
|
+
> Compatible with **Node.js**, **Bun** and **Deno**.
|
|
79
82
|
|
|
80
83
|
```ts
|
|
81
84
|
import { assert } from 'poku'; // Node and Bun
|
|
82
85
|
import { assert } from 'npm:poku'; // Deno
|
|
83
86
|
|
|
84
|
-
|
|
85
|
-
|
|
87
|
+
const actual = '1';
|
|
88
|
+
|
|
89
|
+
assert(actual, 'My first assert');
|
|
90
|
+
assert.deepStrictEqual(actual, 1, 'My first assert error');
|
|
86
91
|
```
|
|
87
92
|
|
|
88
|
-
|
|
93
|
+
| Using `poku` | Using `node` |
|
|
94
|
+
| --------------------------------------------------- | --------------------------------------------------- |
|
|
95
|
+
| <img src=".github/assets/readme/assert-poku.png" /> | <img src=".github/assets/readme/assert-node.png" /> |
|
|
96
|
+
|
|
97
|
+
- ❌ Both cases finish with `code 1`, as expected
|
|
98
|
+
- 🧑🏻🎓 The `message` param is optional, as it's in **Node.js**
|
|
99
|
+
- 💚 Yes, you can use **Poku**'s `assert` running `node ./my-file.js`
|
|
100
|
+
- 🐷 Unlike most, **Poku** adapts to your test, not the other way around
|
|
101
|
+
|
|
102
|
+
> [**See the complete assert's documentation**](https://poku.dev/docs/documentation/assert).
|
|
89
103
|
|
|
90
104
|
---
|
|
91
105
|
|
|
@@ -93,66 +107,48 @@ assert.deepStrictEqual(1, '1', 'My optional custom message');
|
|
|
93
107
|
|
|
94
108
|
### **Node.js**
|
|
95
109
|
|
|
96
|
-
> <img src=".github/assets/readme/node-js.svg" width="24" />
|
|
97
|
-
|
|
98
110
|
```bash
|
|
99
|
-
npm
|
|
111
|
+
npm i -D poku
|
|
100
112
|
```
|
|
101
113
|
|
|
102
114
|
### TypeScript (Node.js)
|
|
103
115
|
|
|
104
|
-
> <img src=".github/assets/readme/node-js.svg" width="24" />
|
|
105
|
-
> <img src=".github/assets/readme/plus.svg" width="24" />
|
|
106
|
-
> <img src=".github/assets/readme/typescript.svg" width="24" />
|
|
107
|
-
|
|
108
116
|
```bash
|
|
109
|
-
npm
|
|
117
|
+
npm i -D poku tsx
|
|
110
118
|
```
|
|
111
119
|
|
|
112
120
|
### Bun
|
|
113
121
|
|
|
114
|
-
> <img src=".github/assets/readme/bun.svg" width="24" />
|
|
115
|
-
> <img src=".github/assets/readme/plus.svg" width="24" />
|
|
116
|
-
> <img src=".github/assets/readme/typescript.svg" width="24" />
|
|
117
|
-
|
|
118
122
|
```bash
|
|
119
|
-
bun add
|
|
123
|
+
bun add -d poku
|
|
120
124
|
```
|
|
121
125
|
|
|
122
126
|
### **Deno**
|
|
123
127
|
|
|
124
|
-
> <img src=".github/assets/readme/deno.svg" width="24" />
|
|
125
|
-
> <img src=".github/assets/readme/plus.svg" width="24" />
|
|
126
|
-
> <img src=".github/assets/readme/typescript.svg" width="24" />
|
|
127
|
-
|
|
128
128
|
```ts
|
|
129
129
|
import { poku } from 'npm:poku';
|
|
130
130
|
```
|
|
131
131
|
|
|
132
|
-
- **Poku** requires these permissions by default: `--allow-read`, `--allow-env` and `--allow-run`.
|
|
133
|
-
|
|
134
132
|
---
|
|
135
133
|
|
|
136
134
|
## Quick Start
|
|
137
135
|
|
|
138
136
|
### In-code
|
|
139
137
|
|
|
140
|
-
|
|
141
|
-
> <img src=".github/assets/readme/plus.svg" width="24" />
|
|
142
|
-
> <img src=".github/assets/readme/bun.svg" width="24" />
|
|
138
|
+
#### Node.js and Bun
|
|
143
139
|
|
|
144
140
|
```ts
|
|
145
141
|
import { poku } from 'poku';
|
|
146
142
|
|
|
147
|
-
await poku(['
|
|
143
|
+
await poku(['targetDir']);
|
|
148
144
|
```
|
|
149
145
|
|
|
150
|
-
|
|
146
|
+
#### Deno
|
|
151
147
|
|
|
152
148
|
```ts
|
|
153
149
|
import { poku } from 'npm:poku';
|
|
154
150
|
|
|
155
|
-
await poku(['
|
|
151
|
+
await poku(['targetDir']);
|
|
156
152
|
```
|
|
157
153
|
|
|
158
154
|
### CLI
|
|
@@ -160,19 +156,19 @@ await poku(['targetDirA', 'targetDirB']);
|
|
|
160
156
|
> <img src=".github/assets/readme/node-js.svg" width="24" />
|
|
161
157
|
|
|
162
158
|
```bash
|
|
163
|
-
npx poku
|
|
159
|
+
npx poku targetDir
|
|
164
160
|
```
|
|
165
161
|
|
|
166
162
|
> <img src=".github/assets/readme/bun.svg" width="24" />
|
|
167
163
|
|
|
168
164
|
```bash
|
|
169
|
-
bun poku
|
|
165
|
+
bun poku targetDir
|
|
170
166
|
```
|
|
171
167
|
|
|
172
168
|
> <img src=".github/assets/readme/deno.svg" width="24" />
|
|
173
169
|
|
|
174
170
|
```bash
|
|
175
|
-
deno run npm:poku
|
|
171
|
+
deno run npm:poku targetDir
|
|
176
172
|
```
|
|
177
173
|
|
|
178
174
|
---
|
package/lib/@types/poku.d.ts
CHANGED
|
@@ -9,14 +9,19 @@ export type Configs = {
|
|
|
9
9
|
*/
|
|
10
10
|
noExit?: boolean;
|
|
11
11
|
/**
|
|
12
|
+
* @deprecated
|
|
12
13
|
* Customize `stdout` options.
|
|
13
14
|
*/
|
|
14
15
|
log?: {
|
|
15
16
|
/**
|
|
17
|
+
* @deprecated
|
|
18
|
+
*
|
|
16
19
|
* @default false
|
|
17
20
|
*/
|
|
18
21
|
success?: boolean;
|
|
19
22
|
/**
|
|
23
|
+
* @deprecated
|
|
24
|
+
*
|
|
20
25
|
* @default true
|
|
21
26
|
*/
|
|
22
27
|
fail?: boolean;
|
|
@@ -26,6 +31,12 @@ export type Configs = {
|
|
|
26
31
|
*
|
|
27
32
|
* @default false
|
|
28
33
|
*/
|
|
34
|
+
debug?: boolean;
|
|
35
|
+
/**
|
|
36
|
+
* This option overwrites the `debug` settings.
|
|
37
|
+
*
|
|
38
|
+
* @default false
|
|
39
|
+
*/
|
|
29
40
|
quiet?: boolean;
|
|
30
41
|
/**
|
|
31
42
|
* Determines the mode of test execution.
|
package/lib/bin/index.js
CHANGED
|
@@ -6,6 +6,7 @@ const list_files_js_1 = require("../modules/list-files.js");
|
|
|
6
6
|
const get_arg_js_1 = require("../helpers/get-arg.js");
|
|
7
7
|
const index_js_1 = require("../index.js");
|
|
8
8
|
const get_runtime_js_1 = require("../helpers/get-runtime.js");
|
|
9
|
+
const format_js_1 = require("../helpers/format.js");
|
|
9
10
|
const dirs = ((0, get_arg_js_1.hasArg)('include')
|
|
10
11
|
? (_a = (0, get_arg_js_1.getArg)('include')) === null || _a === void 0 ? void 0 : _a.split(',')
|
|
11
12
|
: (_b = (0, get_arg_js_1.getLastParam)()) === null || _b === void 0 ? void 0 : _b.split(',')) || [];
|
|
@@ -14,14 +15,14 @@ const filter = (0, get_arg_js_1.getArg)('filter');
|
|
|
14
15
|
const exclude = (0, get_arg_js_1.getArg)('exclude');
|
|
15
16
|
const parallel = (0, get_arg_js_1.hasArg)('parallel');
|
|
16
17
|
const quiet = (0, get_arg_js_1.hasArg)('quiet');
|
|
17
|
-
const
|
|
18
|
+
const debug = (0, get_arg_js_1.hasArg)('debug');
|
|
19
|
+
if ((0, get_arg_js_1.hasArg)('log-success'))
|
|
20
|
+
console.log(`The flag ${format_js_1.format.bold('--log-success')} is deprecated. Use ${format_js_1.format.bold('--debug')} instead.`);
|
|
18
21
|
(0, index_js_1.poku)(dirs, {
|
|
19
22
|
platform: (0, get_runtime_js_1.platformIsValid)(platform) ? platform : undefined,
|
|
20
23
|
filter: filter ? new RegExp((0, list_files_js_1.escapeRegExp)(filter)) : undefined,
|
|
21
24
|
exclude: exclude ? new RegExp((0, list_files_js_1.escapeRegExp)(exclude)) : undefined,
|
|
22
25
|
parallel,
|
|
23
26
|
quiet,
|
|
24
|
-
|
|
25
|
-
success: logSuccess,
|
|
26
|
-
},
|
|
27
|
+
debug,
|
|
27
28
|
});
|
package/lib/helpers/format.d.ts
CHANGED
package/lib/helpers/format.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.format = void 0;
|
|
3
|
+
exports.getLargestStringLength = exports.format = void 0;
|
|
4
4
|
const pad_js_1 = require("./pad.js");
|
|
5
5
|
exports.format = {
|
|
6
6
|
counter: (current, total, pad = '0') => {
|
|
@@ -10,7 +10,14 @@ exports.format = {
|
|
|
10
10
|
dim: (value) => `\x1b[2m${value}\x1b[0m`,
|
|
11
11
|
bold: (value) => `\x1b[1m${value}\x1b[0m`,
|
|
12
12
|
underline: (value) => `\x1b[4m${value}\x1b[0m`,
|
|
13
|
-
info: (value) => `\x1b[
|
|
13
|
+
info: (value) => `\x1b[94m${value}\x1b[0m`,
|
|
14
14
|
success: (value) => `\x1b[32m${value}\x1b[0m`,
|
|
15
|
-
fail: (value) => `\x1b[
|
|
15
|
+
fail: (value) => `\x1b[91m${value}\x1b[0m`,
|
|
16
|
+
bg: (bg, text) => {
|
|
17
|
+
const padding = ' '.repeat(1);
|
|
18
|
+
const paddedText = `${padding}${text}${padding}`;
|
|
19
|
+
return `\x1b[${bg}m\x1b[1m${paddedText}\x1b[0m`;
|
|
20
|
+
},
|
|
16
21
|
};
|
|
22
|
+
const getLargestStringLength = (arr) => arr.reduce((max, current) => Math.max(max, current.length), 0);
|
|
23
|
+
exports.getLargestStringLength = getLargestStringLength;
|
package/lib/helpers/hr.js
CHANGED
|
@@ -7,8 +7,7 @@ exports.hr = void 0;
|
|
|
7
7
|
const node_os_1 = require("os");
|
|
8
8
|
const node_process_1 = __importDefault(require("process"));
|
|
9
9
|
const hr = () => {
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
console.log(`\x1b[2m${line}\x1b[0m${node_os_1.EOL}`);
|
|
10
|
+
const line = '⎯'.repeat(node_process_1.default.stdout.columns - 10);
|
|
11
|
+
console.log(`${node_os_1.EOL}\x1b[2m\x1b[90m${line}\x1b[0m${node_os_1.EOL}`);
|
|
13
12
|
};
|
|
14
13
|
exports.hr = hr;
|
package/lib/helpers/logs.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
1
|
import { Configs } from '../@types/poku.js';
|
|
2
2
|
export declare const isQuiet: (configs?: Configs) => boolean;
|
|
3
|
-
export declare const
|
|
4
|
-
export declare const showFailures: (configs?: Configs) => boolean;
|
|
3
|
+
export declare const isDebug: (configs?: Configs) => boolean;
|
package/lib/helpers/logs.js
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.isDebug = exports.isQuiet = void 0;
|
|
4
4
|
const isQuiet = (configs) => typeof (configs === null || configs === void 0 ? void 0 : configs.quiet) === 'boolean' && Boolean(configs === null || configs === void 0 ? void 0 : configs.quiet);
|
|
5
5
|
exports.isQuiet = isQuiet;
|
|
6
|
-
const
|
|
7
|
-
exports.
|
|
8
|
-
const showFailures = (configs) => { var _a, _b; return typeof ((_a = configs === null || configs === void 0 ? void 0 : configs.log) === null || _a === void 0 ? void 0 : _a.fail) === 'undefined' || Boolean((_b = configs === null || configs === void 0 ? void 0 : configs.log) === null || _b === void 0 ? void 0 : _b.fail); };
|
|
9
|
-
exports.showFailures = showFailures;
|
|
6
|
+
const isDebug = (configs) => Boolean(configs === null || configs === void 0 ? void 0 : configs.debug);
|
|
7
|
+
exports.isDebug = isDebug;
|
|
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.parseAssertion = void 0;
|
|
7
7
|
const node_process_1 = __importDefault(require("process"));
|
|
8
|
+
const node_path_1 = __importDefault(require("path"));
|
|
8
9
|
const node_assert_1 = __importDefault(require("assert"));
|
|
9
10
|
const node_os_1 = require("os");
|
|
10
11
|
const format_js_1 = require("./format.js");
|
|
@@ -25,35 +26,50 @@ const findFile = (error) => {
|
|
|
25
26
|
}
|
|
26
27
|
return file;
|
|
27
28
|
};
|
|
29
|
+
const formatFail = (str) => format_js_1.format.bold(format_js_1.format.fail(`✘ ${str}`));
|
|
28
30
|
const parseAssertion = (cb, options) => {
|
|
31
|
+
var _a, _b;
|
|
32
|
+
const isPoku = typeof ((_a = node_process_1.default.env) === null || _a === void 0 ? void 0 : _a.FILE) === 'string' && ((_b = node_process_1.default.env) === null || _b === void 0 ? void 0 : _b.FILE.length) > 0;
|
|
33
|
+
const FILE = node_process_1.default.env.FILE;
|
|
29
34
|
try {
|
|
30
35
|
cb();
|
|
36
|
+
if (typeof options.message === 'string') {
|
|
37
|
+
const message = isPoku
|
|
38
|
+
? `${format_js_1.format.bold(format_js_1.format.success(`✔ ${options.message}`))} ${format_js_1.format.dim(format_js_1.format.success(`› ${FILE}`))}`
|
|
39
|
+
: format_js_1.format.bold(format_js_1.format.success(`✔ ${options.message}`));
|
|
40
|
+
console.log(message);
|
|
41
|
+
}
|
|
31
42
|
}
|
|
32
43
|
catch (error) {
|
|
33
44
|
if (error instanceof node_assert_1.default.AssertionError) {
|
|
34
45
|
const { code, actual, expected, operator } = error;
|
|
35
|
-
const
|
|
36
|
-
(
|
|
46
|
+
const absoultePath = findFile(error);
|
|
47
|
+
const file = node_path_1.default.relative(node_path_1.default.resolve(node_process_1.default.cwd()), absoultePath);
|
|
48
|
+
let message = '';
|
|
37
49
|
if (typeof options.message === 'string')
|
|
38
|
-
|
|
50
|
+
message = options.message;
|
|
39
51
|
else if (options.message instanceof Error)
|
|
40
|
-
|
|
52
|
+
message = options.message.message;
|
|
41
53
|
else if (typeof options.defaultMessage === 'string')
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
54
|
+
message = options.defaultMessage;
|
|
55
|
+
const finalMessage = (message === null || message === void 0 ? void 0 : message.trim().length) > 0
|
|
56
|
+
? `${formatFail(message)}`
|
|
57
|
+
: `${formatFail('No Message')}`;
|
|
58
|
+
console.log(isPoku
|
|
59
|
+
? `${finalMessage} ${format_js_1.format.dim(format_js_1.format.fail(`› ${FILE}`))}`
|
|
60
|
+
: finalMessage);
|
|
61
|
+
file && console.log(`${format_js_1.format.dim(' File')} ${file}`);
|
|
62
|
+
console.log(`${format_js_1.format.dim(' Code')} ${code}`);
|
|
63
|
+
console.log(`${format_js_1.format.dim(' Operator')} ${operator}${node_os_1.EOL}`);
|
|
47
64
|
if (!(options === null || options === void 0 ? void 0 : options.hideDiff)) {
|
|
48
|
-
console.log(format_js_1.format.dim(
|
|
65
|
+
console.log(format_js_1.format.dim(` ${(options === null || options === void 0 ? void 0 : options.actual) || 'Actual'}:`));
|
|
49
66
|
console.log(format_js_1.format.bold(typeof actual === 'function' || actual instanceof RegExp
|
|
50
|
-
? String(actual)
|
|
51
|
-
: format_js_1.format.fail(JSON.stringify(actual))));
|
|
52
|
-
console.log(`${node_os_1.EOL}${format_js_1.format.dim(`${(options === null || options === void 0 ? void 0 : options.expected) || 'Expected'}:`)}`);
|
|
53
|
-
console.log(format_js_1.format.bold(typeof expected === 'function' || expected instanceof RegExp
|
|
54
|
-
? String(expected)
|
|
55
|
-
: format_js_1.format.success(JSON.stringify(expected))));
|
|
56
|
-
(0, hr_js_1.hr)();
|
|
67
|
+
? ` ${String(actual)}`
|
|
68
|
+
: ` ${format_js_1.format.fail(JSON.stringify(actual))}`));
|
|
69
|
+
console.log(`${node_os_1.EOL} ${format_js_1.format.dim(`${(options === null || options === void 0 ? void 0 : options.expected) || 'Expected'}:`)}`);
|
|
70
|
+
console.log(format_js_1.format.bold(`${typeof expected === 'function' || expected instanceof RegExp
|
|
71
|
+
? ` ${String(expected)}`
|
|
72
|
+
: ` ${format_js_1.format.success(JSON.stringify(expected))}`}`));
|
|
57
73
|
}
|
|
58
74
|
if (options.throw) {
|
|
59
75
|
console.log(error);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const removeConsecutiveRepeats: (arr: string[], specificItem: RegExp) => string[];
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.removeConsecutiveRepeats = void 0;
|
|
4
|
+
const removeConsecutiveRepeats = (arr, specificItem) => {
|
|
5
|
+
const result = [];
|
|
6
|
+
let consecutiveCount = 0;
|
|
7
|
+
for (let i = 0; i < arr.length; i++) {
|
|
8
|
+
if (specificItem.test(arr[i])) {
|
|
9
|
+
consecutiveCount++;
|
|
10
|
+
if (consecutiveCount <= 2) {
|
|
11
|
+
result.push(arr[i]);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
consecutiveCount = 0;
|
|
16
|
+
result.push(arr[i]);
|
|
17
|
+
}
|
|
18
|
+
// Check if the next item is different or we're at the end of the array
|
|
19
|
+
if (i + 1 === arr.length || !specificItem.test(arr[i + 1])) {
|
|
20
|
+
// If more than two consecutive, remove them from the result
|
|
21
|
+
if (consecutiveCount > 2) {
|
|
22
|
+
result.splice(-consecutiveCount);
|
|
23
|
+
}
|
|
24
|
+
consecutiveCount = 0; // Reset the counter for the next group
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return result;
|
|
28
|
+
};
|
|
29
|
+
exports.removeConsecutiveRepeats = removeConsecutiveRepeats;
|
package/lib/modules/assert.js
CHANGED
|
@@ -35,7 +35,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
35
35
|
exports.assert = void 0;
|
|
36
36
|
const nodeAssert = __importStar(require("assert"));
|
|
37
37
|
const parseAsssetion_js_1 = require("../helpers/parseAsssetion.js");
|
|
38
|
-
const format_js_1 = require("../helpers/format.js");
|
|
39
38
|
const ok = (value, message) => (0, parseAsssetion_js_1.parseAssertion)(() => nodeAssert.ok(value), { message });
|
|
40
39
|
const equal = (actual, expected, message) => (0, parseAsssetion_js_1.parseAssertion)(() => nodeAssert.equal(actual, expected), { message });
|
|
41
40
|
const deepEqual = (actual, expected, message) => (0, parseAsssetion_js_1.parseAssertion)(() => nodeAssert.deepEqual(actual, expected), { message });
|
|
@@ -47,7 +46,7 @@ const doesNotMatch = (value, regExp, message) => (0, parseAsssetion_js_1.parseAs
|
|
|
47
46
|
message,
|
|
48
47
|
actual: 'Value',
|
|
49
48
|
expected: 'RegExp',
|
|
50
|
-
defaultMessage:
|
|
49
|
+
defaultMessage: 'Value should not match regExp',
|
|
51
50
|
});
|
|
52
51
|
function doesNotReject(block, errorOrMessage, message) {
|
|
53
52
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -62,7 +61,7 @@ function doesNotReject(block, errorOrMessage, message) {
|
|
|
62
61
|
throw error;
|
|
63
62
|
}, {
|
|
64
63
|
message,
|
|
65
|
-
defaultMessage:
|
|
64
|
+
defaultMessage: 'Got unwanted rejection',
|
|
66
65
|
hideDiff: true,
|
|
67
66
|
throw: true,
|
|
68
67
|
});
|
|
@@ -77,7 +76,7 @@ function doesNotReject(block, errorOrMessage, message) {
|
|
|
77
76
|
throw error_1;
|
|
78
77
|
}, {
|
|
79
78
|
message: typeof errorOrMessage === 'string' ? errorOrMessage : undefined,
|
|
80
|
-
defaultMessage:
|
|
79
|
+
defaultMessage: 'Got unwanted rejection',
|
|
81
80
|
hideDiff: true,
|
|
82
81
|
throw: true,
|
|
83
82
|
});
|
|
@@ -97,7 +96,7 @@ function doesNotThrow(block, errorOrMessage, message) {
|
|
|
97
96
|
throw error;
|
|
98
97
|
}, {
|
|
99
98
|
message: message,
|
|
100
|
-
defaultMessage:
|
|
99
|
+
defaultMessage: 'Expected function not to throw',
|
|
101
100
|
hideDiff: true,
|
|
102
101
|
throw: true,
|
|
103
102
|
});
|
|
@@ -113,7 +112,7 @@ function doesNotThrow(block, errorOrMessage, message) {
|
|
|
113
112
|
throw error;
|
|
114
113
|
}, {
|
|
115
114
|
message: msg,
|
|
116
|
-
defaultMessage:
|
|
115
|
+
defaultMessage: 'Expected function not to throw',
|
|
117
116
|
hideDiff: true,
|
|
118
117
|
throw: true,
|
|
119
118
|
});
|
|
@@ -132,7 +131,7 @@ function throws(block, errorOrMessage, message) {
|
|
|
132
131
|
throw error;
|
|
133
132
|
}, {
|
|
134
133
|
message: message,
|
|
135
|
-
defaultMessage:
|
|
134
|
+
defaultMessage: 'Expected function to throw',
|
|
136
135
|
hideDiff: true,
|
|
137
136
|
});
|
|
138
137
|
}
|
|
@@ -147,7 +146,7 @@ function throws(block, errorOrMessage, message) {
|
|
|
147
146
|
throw error;
|
|
148
147
|
}, {
|
|
149
148
|
message: msg,
|
|
150
|
-
defaultMessage:
|
|
149
|
+
defaultMessage: 'Expected function to throw',
|
|
151
150
|
hideDiff: true,
|
|
152
151
|
});
|
|
153
152
|
}
|
|
@@ -167,7 +166,7 @@ const match = (value, regExp, message) => (0, parseAsssetion_js_1.parseAssertion
|
|
|
167
166
|
message,
|
|
168
167
|
actual: 'Value',
|
|
169
168
|
expected: 'RegExp',
|
|
170
|
-
defaultMessage:
|
|
169
|
+
defaultMessage: 'Value should match regExp',
|
|
171
170
|
});
|
|
172
171
|
const ifError = (value) => {
|
|
173
172
|
try {
|
|
@@ -177,7 +176,7 @@ const ifError = (value) => {
|
|
|
177
176
|
(0, parseAsssetion_js_1.parseAssertion)(() => {
|
|
178
177
|
throw error;
|
|
179
178
|
}, {
|
|
180
|
-
defaultMessage:
|
|
179
|
+
defaultMessage: 'Expected no error, but received an error',
|
|
181
180
|
hideDiff: true,
|
|
182
181
|
throw: true,
|
|
183
182
|
});
|
|
@@ -192,7 +191,7 @@ const fail = (message) => {
|
|
|
192
191
|
throw error;
|
|
193
192
|
}, {
|
|
194
193
|
message,
|
|
195
|
-
defaultMessage:
|
|
194
|
+
defaultMessage: 'Test failed intentionally',
|
|
196
195
|
hideDiff: true,
|
|
197
196
|
});
|
|
198
197
|
}
|
|
@@ -210,7 +209,7 @@ function rejects(block, errorOrMessage, message) {
|
|
|
210
209
|
throw error;
|
|
211
210
|
}, {
|
|
212
211
|
message,
|
|
213
|
-
defaultMessage:
|
|
212
|
+
defaultMessage: 'Expected promise to be rejected with specified error',
|
|
214
213
|
hideDiff: true,
|
|
215
214
|
});
|
|
216
215
|
}
|
|
@@ -225,7 +224,7 @@ function rejects(block, errorOrMessage, message) {
|
|
|
225
224
|
throw error_1;
|
|
226
225
|
}, {
|
|
227
226
|
message: msg,
|
|
228
|
-
defaultMessage:
|
|
227
|
+
defaultMessage: 'Expected promise to be rejected',
|
|
229
228
|
hideDiff: true,
|
|
230
229
|
});
|
|
231
230
|
}
|
package/lib/modules/exit.js
CHANGED
|
@@ -5,23 +5,24 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.exit = void 0;
|
|
7
7
|
const node_process_1 = __importDefault(require("process"));
|
|
8
|
-
const node_os_1 = require("os");
|
|
9
8
|
const hr_js_1 = require("../helpers/hr.js");
|
|
9
|
+
const run_tests_js_1 = require("../services/run-tests.js");
|
|
10
|
+
const format_js_1 = require("../helpers/format.js");
|
|
10
11
|
const exit = (code, quiet) => {
|
|
12
|
+
const isPoku = run_tests_js_1.results.success > 0 || run_tests_js_1.results.fail > 0;
|
|
11
13
|
!quiet &&
|
|
12
14
|
node_process_1.default.on('exit', (code) => {
|
|
13
|
-
|
|
15
|
+
isPoku &&
|
|
16
|
+
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}`));
|
|
17
|
+
isPoku && (0, hr_js_1.hr)();
|
|
18
|
+
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)))}`);
|
|
14
19
|
});
|
|
15
|
-
!quiet && (0, hr_js_1.hr)();
|
|
16
|
-
if (code !== 0)
|
|
17
|
-
!quiet && console.log('Some tests failed.');
|
|
20
|
+
isPoku && !quiet && (0, hr_js_1.hr)();
|
|
21
|
+
if (code !== 0)
|
|
18
22
|
node_process_1.default.exit(1);
|
|
19
|
-
}
|
|
20
|
-
!quiet && console.log('All tests passed.');
|
|
21
23
|
node_process_1.default.exit(0);
|
|
22
24
|
};
|
|
23
25
|
exports.exit = exit;
|
|
24
|
-
node_process_1.default.stdout.on('resize', hr_js_1.hr);
|
|
25
26
|
node_process_1.default.on('unhandledRejection', (reason) => {
|
|
26
27
|
console.log('unhandledRejection', reason);
|
|
27
28
|
node_process_1.default.exit(1);
|
|
@@ -15,7 +15,7 @@ const envFilter = ((_a = node_process_1.default.env.FILTER) === null || _a === v
|
|
|
15
15
|
: null;
|
|
16
16
|
const listFiles = (dirPath, files = [], configs) => {
|
|
17
17
|
const currentFiles = node_fs_1.default.readdirSync(dirPath);
|
|
18
|
-
const defaultRegExp = /\.test\./i;
|
|
18
|
+
const defaultRegExp = /\.(test|spec)\./i;
|
|
19
19
|
const filter = (envFilter
|
|
20
20
|
? envFilter
|
|
21
21
|
: (configs === null || configs === void 0 ? void 0 : configs.filter) instanceof RegExp
|
|
@@ -28,6 +28,8 @@ const listFiles = (dirPath, files = [], configs) => {
|
|
|
28
28
|
: undefined;
|
|
29
29
|
for (const file of currentFiles) {
|
|
30
30
|
const fullPath = node_path_1.default.join(dirPath, file);
|
|
31
|
+
if (/node_modules/.test(fullPath))
|
|
32
|
+
continue;
|
|
31
33
|
if (exclude && exclude.some((regex) => regex.test(fullPath)))
|
|
32
34
|
continue;
|
|
33
35
|
if (node_fs_1.default.statSync(fullPath).isDirectory())
|
package/lib/modules/poku.js
CHANGED
|
@@ -10,17 +10,38 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.poku = void 0;
|
|
13
|
+
const node_os_1 = require("os");
|
|
13
14
|
const force_array_js_1 = require("../helpers/force-array.js");
|
|
14
15
|
const run_tests_js_1 = require("../services/run-tests.js");
|
|
15
16
|
const exit_js_1 = require("./exit.js");
|
|
17
|
+
const format_js_1 = require("../helpers/format.js");
|
|
18
|
+
const logs_js_1 = require("../helpers/logs.js");
|
|
19
|
+
const hr_js_1 = require("../helpers/hr.js");
|
|
20
|
+
const run_test_file_js_1 = require("../services/run-test-file.js");
|
|
21
|
+
const indentation_js_1 = require("../helpers/indentation.js");
|
|
16
22
|
function poku(targetDirs, configs) {
|
|
17
23
|
return __awaiter(this, void 0, void 0, function* () {
|
|
18
24
|
let code = 0;
|
|
19
|
-
const
|
|
25
|
+
const prepareDirs = (0, force_array_js_1.forceArray)(targetDirs);
|
|
26
|
+
const dirs = prepareDirs.length > 0 ? prepareDirs : ['./'];
|
|
27
|
+
const showLogs = !(0, logs_js_1.isQuiet)(configs);
|
|
20
28
|
if (configs === null || configs === void 0 ? void 0 : configs.parallel) {
|
|
21
|
-
|
|
22
|
-
|
|
29
|
+
if (showLogs) {
|
|
30
|
+
(0, hr_js_1.hr)();
|
|
31
|
+
console.log(`${format_js_1.format.bold('Running the Test Suite in Parallel')}${node_os_1.EOL}`);
|
|
32
|
+
}
|
|
33
|
+
const concurrency = yield Promise.all(dirs.map((dir) => (0, run_tests_js_1.runTestsParallel)(dir, configs)));
|
|
34
|
+
if (concurrency.some((result) => !result))
|
|
23
35
|
code = 1;
|
|
36
|
+
showLogs && (0, hr_js_1.hr)();
|
|
37
|
+
if (showLogs && run_test_file_js_1.fileResults.success.length > 0)
|
|
38
|
+
console.log(run_test_file_js_1.fileResults.success
|
|
39
|
+
.map((current) => `${indentation_js_1.indentation.test}${format_js_1.format.success('✔')} ${format_js_1.format.dim(current)}`)
|
|
40
|
+
.join(node_os_1.EOL));
|
|
41
|
+
if (showLogs && run_test_file_js_1.fileResults.fail.length > 0)
|
|
42
|
+
console.log(run_test_file_js_1.fileResults.fail
|
|
43
|
+
.map((current) => `${indentation_js_1.indentation.test}${format_js_1.format.fail('✘')} ${current}`)
|
|
44
|
+
.join(node_os_1.EOL));
|
|
24
45
|
if (configs === null || configs === void 0 ? void 0 : configs.noExit)
|
|
25
46
|
return code;
|
|
26
47
|
(0, exit_js_1.exit)(code, configs === null || configs === void 0 ? void 0 : configs.quiet);
|
|
@@ -1,2 +1,8 @@
|
|
|
1
1
|
import { Configs } from '../@types/poku.js';
|
|
2
|
+
type FileResults = {
|
|
3
|
+
success: string[];
|
|
4
|
+
fail: string[];
|
|
5
|
+
};
|
|
6
|
+
export declare const fileResults: FileResults;
|
|
2
7
|
export declare const runTestFile: (filePath: string, configs?: Configs) => Promise<boolean>;
|
|
8
|
+
export {};
|
|
@@ -3,44 +3,82 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.runTestFile = void 0;
|
|
6
|
+
exports.runTestFile = exports.fileResults = void 0;
|
|
7
7
|
const node_process_1 = __importDefault(require("process"));
|
|
8
|
-
const
|
|
8
|
+
const node_os_1 = require("os");
|
|
9
9
|
const node_path_1 = __importDefault(require("path"));
|
|
10
|
+
const node_child_process_1 = require("child_process");
|
|
10
11
|
const runner_js_1 = require("../helpers/runner.js");
|
|
11
12
|
const indentation_js_1 = require("../helpers/indentation.js");
|
|
12
13
|
const format_js_1 = require("../helpers/format.js");
|
|
13
14
|
const logs_js_1 = require("../helpers/logs.js");
|
|
15
|
+
const remove_repeats_js_1 = require("../helpers/remove-repeats.js");
|
|
16
|
+
exports.fileResults = {
|
|
17
|
+
success: [],
|
|
18
|
+
fail: [],
|
|
19
|
+
};
|
|
14
20
|
const runTestFile = (filePath, configs) => new Promise((resolve) => {
|
|
15
|
-
let output = '';
|
|
16
|
-
const showLogs = !(0, logs_js_1.isQuiet)(configs);
|
|
17
|
-
const showSuccess = (0, logs_js_1.showSuccesses)(configs);
|
|
18
|
-
const showFailure = (0, logs_js_1.showFailures)(configs);
|
|
19
|
-
const log = () => console.log(output === null || output === void 0 ? void 0 : output.trim());
|
|
20
|
-
const fileRelative = node_path_1.default.relative(node_process_1.default.cwd(), filePath);
|
|
21
|
-
showLogs &&
|
|
22
|
-
console.log(`${indentation_js_1.indentation.test}${format_js_1.format.info('→')} ${fileRelative}`);
|
|
23
21
|
const runtimeOptions = (0, runner_js_1.runner)(filePath, configs);
|
|
24
22
|
const runtime = runtimeOptions.shift();
|
|
25
23
|
const runtimeArguments = runtimeOptions.length > 1 ? [...runtimeOptions, filePath] : [filePath];
|
|
24
|
+
const fileRelative = node_path_1.default.relative(node_process_1.default.cwd(), filePath);
|
|
25
|
+
const showLogs = !(0, logs_js_1.isQuiet)(configs);
|
|
26
|
+
const showSuccess = (0, logs_js_1.isDebug)(configs);
|
|
27
|
+
const pad = (configs === null || configs === void 0 ? void 0 : configs.parallel) ? ' ' : ' ';
|
|
28
|
+
let output = '';
|
|
29
|
+
const log = () => {
|
|
30
|
+
const outputs = (0, remove_repeats_js_1.removeConsecutiveRepeats)(showSuccess
|
|
31
|
+
? output.split(/(\r\n|\r|\n)/)
|
|
32
|
+
: output.split(/(\r\n|\r|\n)/).filter((current) => {
|
|
33
|
+
if (current.includes('Exited with code'))
|
|
34
|
+
return false;
|
|
35
|
+
return (/u001b\[0m|(\r\n|\r|\n)/i.test(JSON.stringify(current)) ||
|
|
36
|
+
current === '');
|
|
37
|
+
}), /(\r\n|\r|\n)|^$/);
|
|
38
|
+
// Remove last EOL
|
|
39
|
+
outputs.length > 1 && outputs.pop();
|
|
40
|
+
if (!showSuccess &&
|
|
41
|
+
/error:/i.test(output) &&
|
|
42
|
+
!/error:/i.test(outputs.join()))
|
|
43
|
+
Object.assign(outputs, [
|
|
44
|
+
...outputs,
|
|
45
|
+
format_js_1.format.bold(format_js_1.format.fail(`✘ External Error ${format_js_1.format.dim(`› ${fileRelative}`)}`)),
|
|
46
|
+
format_js_1.format.dim(' For detailed diagnostics:'),
|
|
47
|
+
`${format_js_1.format.dim(` CLI ›`)} rerun with the ${format_js_1.format.bold('--debug')} flag enabled.`,
|
|
48
|
+
`${format_js_1.format.dim(` API ›`)} set the config option ${format_js_1.format.bold('debug')} to true.`,
|
|
49
|
+
`${format_js_1.format.dim(' RUN ›')} ${format_js_1.format.bold(`${runtime === 'tsx' ? 'npx tsx' : runtime}${runtimeArguments.slice(0, -1).join(' ')} ${fileRelative}`)}`,
|
|
50
|
+
]);
|
|
51
|
+
const mappedOutputs = outputs.map((current) => `${pad}${current}`);
|
|
52
|
+
if (outputs.length === 1 && outputs[0] === '')
|
|
53
|
+
return;
|
|
54
|
+
console.log(showSuccess ? mappedOutputs.join('') : mappedOutputs.join(node_os_1.EOL));
|
|
55
|
+
};
|
|
56
|
+
const stdOut = (data) => {
|
|
57
|
+
output += String(data);
|
|
58
|
+
};
|
|
59
|
+
if (!(configs === null || configs === void 0 ? void 0 : configs.parallel)) {
|
|
60
|
+
showLogs &&
|
|
61
|
+
console.log(`${indentation_js_1.indentation.test}${format_js_1.format.info(format_js_1.format.dim('●'))} ${format_js_1.format.dim(fileRelative)}`);
|
|
62
|
+
}
|
|
26
63
|
const child = (0, node_child_process_1.spawn)(runtime, runtimeArguments, {
|
|
27
64
|
stdio: ['inherit', 'pipe', 'pipe'],
|
|
28
|
-
env: node_process_1.default.env,
|
|
29
|
-
});
|
|
30
|
-
child.stdout.on('data', (data) => {
|
|
31
|
-
output += data.toString();
|
|
32
|
-
});
|
|
33
|
-
child.stderr.on('data', (data) => {
|
|
34
|
-
output += data.toString();
|
|
65
|
+
env: Object.assign(Object.assign({}, node_process_1.default.env), { FILE: (configs === null || configs === void 0 ? void 0 : configs.parallel) ? fileRelative : '' }),
|
|
35
66
|
});
|
|
67
|
+
child.stdout.on('data', stdOut);
|
|
68
|
+
child.stderr.on('data', stdOut);
|
|
36
69
|
child.on('close', (code) => {
|
|
37
|
-
if (showLogs
|
|
38
|
-
((code === 0 && showSuccess) || (code !== 0 && showFailure)))
|
|
70
|
+
if (showLogs)
|
|
39
71
|
log();
|
|
40
|
-
|
|
72
|
+
const result = code === 0;
|
|
73
|
+
if (result)
|
|
74
|
+
exports.fileResults.success.push(fileRelative);
|
|
75
|
+
else
|
|
76
|
+
exports.fileResults.fail.push(fileRelative);
|
|
77
|
+
resolve(result);
|
|
41
78
|
});
|
|
42
79
|
child.on('error', (err) => {
|
|
43
80
|
console.log(`Failed to start test: ${filePath}`, err);
|
|
81
|
+
exports.fileResults.fail.push(fileRelative);
|
|
44
82
|
resolve(false);
|
|
45
83
|
});
|
|
46
84
|
});
|
|
@@ -1,3 +1,7 @@
|
|
|
1
1
|
import { Configs } from '../@types/poku.js';
|
|
2
|
+
export declare const results: {
|
|
3
|
+
success: number;
|
|
4
|
+
fail: number;
|
|
5
|
+
};
|
|
2
6
|
export declare const runTests: (dir: string, configs?: Configs) => Promise<boolean>;
|
|
3
7
|
export declare const runTestsParallel: (dir: string, configs?: Configs) => Promise<boolean>;
|
|
@@ -12,7 +12,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
12
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.runTestsParallel = exports.runTests = void 0;
|
|
15
|
+
exports.runTestsParallel = exports.runTests = exports.results = void 0;
|
|
16
16
|
const node_process_1 = __importDefault(require("process"));
|
|
17
17
|
const node_os_1 = require("os");
|
|
18
18
|
const node_path_1 = __importDefault(require("path"));
|
|
@@ -23,6 +23,10 @@ const hr_js_1 = require("../helpers/hr.js");
|
|
|
23
23
|
const format_js_1 = require("../helpers/format.js");
|
|
24
24
|
const run_test_file_js_1 = require("./run-test-file.js");
|
|
25
25
|
const logs_js_1 = require("../helpers/logs.js");
|
|
26
|
+
exports.results = {
|
|
27
|
+
success: 0,
|
|
28
|
+
fail: 0,
|
|
29
|
+
};
|
|
26
30
|
const runTests = (dir, configs) => __awaiter(void 0, void 0, void 0, function* () {
|
|
27
31
|
const cwd = node_process_1.default.cwd();
|
|
28
32
|
const testDir = node_path_1.default.join(cwd, dir);
|
|
@@ -33,7 +37,7 @@ const runTests = (dir, configs) => __awaiter(void 0, void 0, void 0, function* (
|
|
|
33
37
|
let passed = true;
|
|
34
38
|
if (showLogs) {
|
|
35
39
|
(0, hr_js_1.hr)();
|
|
36
|
-
console.log(`${format_js_1.format.bold('Directory:')} ${format_js_1.format.underline(currentDir)}${node_os_1.EOL}`);
|
|
40
|
+
console.log(`${format_js_1.format.bold('Directory:')} ${format_js_1.format.underline(`./${currentDir}`)}${node_os_1.EOL}`);
|
|
37
41
|
}
|
|
38
42
|
for (let i = 0; i < files.length; i++) {
|
|
39
43
|
const filePath = files[i];
|
|
@@ -43,13 +47,16 @@ const runTests = (dir, configs) => __awaiter(void 0, void 0, void 0, function* (
|
|
|
43
47
|
const counter = format_js_1.format.counter(testNumber, totalTests);
|
|
44
48
|
const command = `${(0, runner_js_1.runner)(fileRelative, configs).join(' ')} ${fileRelative}`;
|
|
45
49
|
const nextLine = i + 1 !== files.length ? node_os_1.EOL : '';
|
|
46
|
-
const log = `${counter}/${totalTests} ${command}
|
|
50
|
+
const log = `${counter}/${totalTests} ${command}`;
|
|
47
51
|
if (testPassed) {
|
|
52
|
+
++exports.results.success;
|
|
48
53
|
showLogs &&
|
|
49
|
-
console.log(`${indentation_js_1.indentation.test}${format_js_1.format.success('✔')} ${log}
|
|
54
|
+
console.log(`${indentation_js_1.indentation.test}${format_js_1.format.success('✔')} ${log}`, nextLine);
|
|
50
55
|
}
|
|
51
56
|
else {
|
|
52
|
-
|
|
57
|
+
++exports.results.fail;
|
|
58
|
+
showLogs &&
|
|
59
|
+
console.log(`${indentation_js_1.indentation.test}${format_js_1.format.fail('✘')} ${log}`, nextLine);
|
|
53
60
|
passed = false;
|
|
54
61
|
}
|
|
55
62
|
}
|
|
@@ -60,23 +67,16 @@ const runTestsParallel = (dir, configs) => __awaiter(void 0, void 0, void 0, fun
|
|
|
60
67
|
const cwd = node_process_1.default.cwd();
|
|
61
68
|
const testDir = node_path_1.default.join(cwd, dir);
|
|
62
69
|
const files = (0, list_files_js_1.listFiles)(testDir, undefined, configs);
|
|
63
|
-
const showLogs = !(0, logs_js_1.isQuiet)(configs);
|
|
64
70
|
const promises = files.map((filePath) => __awaiter(void 0, void 0, void 0, function* () {
|
|
65
|
-
const fileRelative = node_path_1.default.relative(cwd, filePath);
|
|
66
71
|
const testPassed = yield (0, run_test_file_js_1.runTestFile)(filePath, configs);
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
showLogs &&
|
|
70
|
-
console.log(`${indentation_js_1.indentation.test}${format_js_1.format.success('✔')} ${command}`);
|
|
71
|
-
}
|
|
72
|
-
else {
|
|
73
|
-
showLogs &&
|
|
74
|
-
console.log(`${indentation_js_1.indentation.test}${format_js_1.format.fail('✖')} ${command}`);
|
|
72
|
+
if (!testPassed) {
|
|
73
|
+
++exports.results.fail;
|
|
75
74
|
return false;
|
|
76
75
|
}
|
|
76
|
+
++exports.results.success;
|
|
77
77
|
return true;
|
|
78
78
|
}));
|
|
79
|
-
const
|
|
80
|
-
return
|
|
79
|
+
const concurrency = yield Promise.all(promises);
|
|
80
|
+
return concurrency.every((result) => result);
|
|
81
81
|
});
|
|
82
82
|
exports.runTestsParallel = runTestsParallel;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "poku",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"description": "🐷 Poku is your test runner pet for Node.js, Bun and Deno, combining flexibility, parallel and sequential runs, human-friendly assertion errors and high isolation level",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -9,14 +9,16 @@
|
|
|
9
9
|
"test:node": "FILTER='node-' npm run test:ci",
|
|
10
10
|
"test:deno": "FILTER='deno-' npm run test:ci",
|
|
11
11
|
"test:bun": "FILTER='bun-' npm run test:ci",
|
|
12
|
-
"update": "npx npu;",
|
|
13
12
|
"prebuild": "rm -rf ./lib ./ci",
|
|
14
13
|
"build": "npx tsc; npx tsc -p tsconfig.test.json",
|
|
15
14
|
"postbuild": "npx tsx ./tools/compatibility/node.ts; chmod +x lib/bin/index.js; npm audit",
|
|
16
15
|
"eslint:checker": "npx eslint . --ext .js,.ts",
|
|
17
16
|
"eslint:fix": "npx eslint . --fix --config ./.eslintrc.json",
|
|
17
|
+
"lint:checker": "npm run eslint:checker; npm run prettier:checker",
|
|
18
|
+
"lint:fix": "npm run eslint:fix; npm run prettier:fix",
|
|
18
19
|
"prettier:checker": "npx prettier --check .",
|
|
19
|
-
"prettier:fix": "npx prettier --write .github/workflows/*.yml ."
|
|
20
|
+
"prettier:fix": "npx prettier --write .github/workflows/*.yml .",
|
|
21
|
+
"update": "npx npu; npm i; npm run lint:fix; npm audit"
|
|
20
22
|
},
|
|
21
23
|
"license": "MIT",
|
|
22
24
|
"repository": {
|
|
@@ -78,16 +80,17 @@
|
|
|
78
80
|
"engines": {
|
|
79
81
|
"node": ">=6.0.0",
|
|
80
82
|
"bun": ">=0.5.3",
|
|
81
|
-
"deno": ">=1.17.0"
|
|
83
|
+
"deno": ">=1.17.0",
|
|
84
|
+
"typescript": ">=5.0.2"
|
|
82
85
|
},
|
|
83
86
|
"files": [
|
|
84
87
|
"lib"
|
|
85
88
|
],
|
|
86
89
|
"type": "commonjs",
|
|
87
90
|
"devDependencies": {
|
|
88
|
-
"@types/node": "^20.11.
|
|
89
|
-
"@typescript-eslint/eslint-plugin": "^7.0.
|
|
90
|
-
"@typescript-eslint/parser": "^7.0.
|
|
91
|
+
"@types/node": "^20.11.20",
|
|
92
|
+
"@typescript-eslint/eslint-plugin": "^7.0.2",
|
|
93
|
+
"@typescript-eslint/parser": "^7.0.2",
|
|
91
94
|
"eslint": "^8.56.0",
|
|
92
95
|
"eslint-config-prettier": "^9.1.0",
|
|
93
96
|
"eslint-import-resolver-typescript": "^3.6.1",
|