poku 1.15.1 → 1.17.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/LICENSE +1 -1
- package/README.md +33 -48
- package/lib/bin/index.js +55 -3
- package/lib/modules/each.d.ts +1 -1
- package/lib/polyfills/fs.d.ts +8 -0
- package/lib/polyfills/fs.js +35 -0
- package/lib/services/map-tests.d.ts +2 -0
- package/lib/services/map-tests.js +55 -0
- package/lib/services/watch.d.ts +18 -0
- package/lib/services/watch.js +122 -0
- package/package.json +4 -3
package/LICENSE
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2024-current Weslley Araújo (@wellwelwel)
|
|
3
|
+
Copyright (c) 2024-current Weslley Araújo ([@wellwelwel](https://github.com/wellwelwel)).
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
package/README.md
CHANGED
|
@@ -18,11 +18,11 @@
|
|
|
18
18
|
[license-image]: https://img.shields.io/npm/l/poku.svg?maxAge=2592000&color=9c88ff&style=flat-square&label=License
|
|
19
19
|
|
|
20
20
|
<div align="center">
|
|
21
|
-
<img width="
|
|
21
|
+
<img width="125" height="125" alt="Logo" src="https://raw.githubusercontent.com/wellwelwel/poku/main/.github/assets/readme/poku.svg">
|
|
22
22
|
|
|
23
23
|
# Poku
|
|
24
24
|
|
|
25
|
-
**Poku
|
|
25
|
+
Enjoying **Poku**? Give him a star to show your support 🌟
|
|
26
26
|
|
|
27
27
|
[![NPM Downloads][downloads-image]][downloads-url]
|
|
28
28
|
[![Coverage][coverage-image]][coverage-url]
|
|
@@ -31,33 +31,30 @@
|
|
|
31
31
|
[![GitHub Workflow Status (with event)][ci-osx-image]][ci-osx-url]
|
|
32
32
|
[![GitHub Workflow Status (with event)][ci-windows-image]][ci-windows-url]
|
|
33
33
|
|
|
34
|
-
Enjoying **Poku**? Give him a star to show your support ⭐️
|
|
35
|
-
|
|
36
34
|
</div>
|
|
37
35
|
|
|
38
36
|
---
|
|
39
37
|
|
|
40
38
|
## Why does Poku exist?
|
|
41
39
|
|
|
42
|
-
|
|
40
|
+
**Poku** makes testing easy and takes on the testers' difficulties to _let you focus on your tests_:
|
|
43
41
|
|
|
44
42
|
<img width="16" height="16" alt="check" src="https://raw.githubusercontent.com/wellwelwel/poku/main/.github/assets/readme/check.svg"> No configurations<br />
|
|
45
43
|
<span> </span><img width="16" height="16" alt="check" src="https://raw.githubusercontent.com/wellwelwel/poku/main/.github/assets/readme/check.svg"> Auto detect **ESM** and **CJS**<br />
|
|
46
44
|
<span> </span><img width="16" height="16" alt="check" src="https://raw.githubusercontent.com/wellwelwel/poku/main/.github/assets/readme/check.svg"> Auto detect **Typescript** files<br />
|
|
47
|
-
<span> </span><img width="16" height="16" alt="check" src="https://raw.githubusercontent.com/wellwelwel/poku/main/.github/assets/readme/check.svg"> Run the same test suite for [**Node.js**][node-version-url], [**Bun**][bun-version-url] and [**Deno**][deno-version-url]<br />
|
|
45
|
+
<span> </span><img width="16" height="16" alt="check" src="https://raw.githubusercontent.com/wellwelwel/poku/main/.github/assets/readme/check.svg"> Run the same test suite for [**Node.js**][node-version-url] _(6+)_, [**Bun**][bun-version-url] and [**Deno**][deno-version-url]<br />
|
|
48
46
|
|
|
49
47
|
<img width="16" height="16" alt="check" src="https://raw.githubusercontent.com/wellwelwel/poku/main/.github/assets/readme/check.svg"> Easier and Less Verbose<br />
|
|
50
48
|
<span> </span><img width="16" height="16" alt="check" src="https://raw.githubusercontent.com/wellwelwel/poku/main/.github/assets/readme/check.svg"> [**Node.js**][node-version-url] familiar **API**<br />
|
|
51
|
-
<span> </span><img width="16" height="16" alt="check" src="https://raw.githubusercontent.com/wellwelwel/poku/main/.github/assets/readme/check.svg"> Easily test your server just by running it 🚀<br />
|
|
52
49
|
<span> </span><img width="16" height="16" alt="check" src="https://raw.githubusercontent.com/wellwelwel/poku/main/.github/assets/readme/check.svg"> Run **CJS** (**CommonJS**) files directly with [**Deno**][deno-version-url]<br />
|
|
53
|
-
<span> </span><img width="16" height="16" alt="check" src="https://raw.githubusercontent.com/wellwelwel/poku/main/.github/assets/readme/check.svg"> Easily handle **
|
|
50
|
+
<span> </span><img width="16" height="16" alt="check" src="https://raw.githubusercontent.com/wellwelwel/poku/main/.github/assets/readme/check.svg"> Easily handle, **servers**, **services**, **processes**, and **ports**<br />
|
|
54
51
|
|
|
55
52
|
<img width="16" height="16" alt="check" src="https://raw.githubusercontent.com/wellwelwel/poku/main/.github/assets/readme/check.svg"> Safety and Reliability<br />
|
|
56
53
|
<span> </span><img width="16" height="16" alt="check" src="https://raw.githubusercontent.com/wellwelwel/poku/main/.github/assets/readme/check.svg"> High **isolation** level per file<br />
|
|
57
|
-
<span> </span><img width="16" height="16" alt="check" src="https://raw.githubusercontent.com/wellwelwel/poku/main/.github/assets/readme/check.svg"> Performant and lightweight
|
|
58
|
-
<span> </span><img width="16" height="16" alt="check" src="https://raw.githubusercontent.com/wellwelwel/poku/main/.github/assets/readme/check.svg"> Compatible with **
|
|
59
|
-
|
|
60
|
-
|
|
54
|
+
<span> </span><img width="16" height="16" alt="check" src="https://raw.githubusercontent.com/wellwelwel/poku/main/.github/assets/readme/check.svg"> **Performant** and **lightweight**<br />
|
|
55
|
+
<span> </span><img width="16" height="16" alt="check" src="https://raw.githubusercontent.com/wellwelwel/poku/main/.github/assets/readme/check.svg"> Compatible with **coverage** tools
|
|
56
|
+
|
|
57
|
+
> 💡 **Poku** brings the [essence of **JavaScript** back to testing](https://poku.io/docs/philosophy), allowing to use your knowledge to create tests intuitively.
|
|
61
58
|
|
|
62
59
|
---
|
|
63
60
|
|
|
@@ -65,8 +62,6 @@ Enjoying **Poku**? Give him a star to show your support ⭐️
|
|
|
65
62
|
|
|
66
63
|
### Install
|
|
67
64
|
|
|
68
|
-
[](https://packagephobia.com/result?p=poku)
|
|
69
|
-
|
|
70
65
|
<table>
|
|
71
66
|
<tr>
|
|
72
67
|
<td><blockquote><b>Node.js</b</blockquote></td>
|
|
@@ -160,7 +155,7 @@ deno run npm:poku
|
|
|
160
155
|
</tr>
|
|
161
156
|
</table>
|
|
162
157
|
|
|
163
|
-
That's it 🎉
|
|
158
|
+
- That's it 🎉
|
|
164
159
|
|
|
165
160
|
---
|
|
166
161
|
|
|
@@ -172,22 +167,20 @@ That's it 🎉
|
|
|
172
167
|
|
|
173
168
|
### Essentials
|
|
174
169
|
|
|
175
|
-
- **
|
|
176
|
-
|
|
177
|
-
- [**assert**](https://poku.io/docs/documentation/assert) (_test assertion_)
|
|
178
|
-
- **Background Services**
|
|
179
|
-
- [**startScript**](https://poku.io/docs/documentation/startScript) (_run `package.json` scripts in a background process_)
|
|
180
|
-
- [**startService**](https://poku.io/docs/documentation/startService) (_run files in a background process_)
|
|
170
|
+
- [**poku**](https://poku.io/docs/category/poku) _(test runner)_
|
|
171
|
+
- [**assert**](https://poku.io/docs/documentation/assert) _(test assertion)_
|
|
181
172
|
|
|
182
173
|
### Helpers
|
|
183
174
|
|
|
184
175
|
- [**test**](https://poku.io/docs/documentation/helpers/test)
|
|
185
|
-
|
|
186
|
-
- [**beforeEach**](https://poku.io/docs/category/beforeeach-and-aftereach) and [**afterEach**](https://poku.io/docs/category/beforeeach-and-aftereach)
|
|
187
|
-
- **
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
-
|
|
176
|
+
, [**describe**](https://poku.io/docs/documentation/helpers/describe) and [**it**](https://poku.io/docs/documentation/helpers/it) _(organize, group, and isolate tests)_
|
|
177
|
+
- [**beforeEach**](https://poku.io/docs/category/beforeeach-and-aftereach) and [**afterEach**](https://poku.io/docs/category/beforeeach-and-aftereach) _(hooks for test setup and teardown)_
|
|
178
|
+
- [**watch**](https://poku.io/docs/documentation/poku/options/watch) _(watch test files for changes)_
|
|
179
|
+
- [**startScript**](https://poku.io/docs/documentation/startScript) _(run **package.json** scripts in background)_
|
|
180
|
+
- [**startService**](https://poku.io/docs/documentation/startService) _(run files in background)_
|
|
181
|
+
- [**kill**](https://poku.io/docs/documentation/processes/kill) _(terminate ports, port ranges, and PIDs)_
|
|
182
|
+
- [**getPIDs**](https://poku.io/docs/documentation/processes/get-pids) _(debug processes IDs using ports and port ranges)_
|
|
183
|
+
- _and much more_ 👇🏻
|
|
191
184
|
|
|
192
185
|
---
|
|
193
186
|
|
|
@@ -199,15 +192,7 @@ To see the detailed documentation, please visit the [**Documentation**](https://
|
|
|
199
192
|
|
|
200
193
|
## Contributing
|
|
201
194
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
Please check the [**CONTRIBUTING.md**](./CONTRIBUTING.md) for instructions 🚀
|
|
205
|
-
|
|
206
|
-
---
|
|
207
|
-
|
|
208
|
-
## Philosophy
|
|
209
|
-
|
|
210
|
-
Please check the [**Philosophy**](https://poku.io/docs/philosophy) section from Documentation.
|
|
195
|
+
See the [**Contributing Guide**](https://github.com/wellwelwel/poku/blob/main/CONTRIBUTING.md) and please follow our [**Code of Conduct**](https://github.com/wellwelwel/poku/blob/main/CODE_OF_CONDUCT.md) 🚀
|
|
211
196
|
|
|
212
197
|
---
|
|
213
198
|
|
|
@@ -215,7 +200,7 @@ Please check the [**Philosophy**](https://poku.io/docs/philosophy) section from
|
|
|
215
200
|
|
|
216
201
|
[![GitHub Workflow Status (with event)][ql-image]][ql-url]
|
|
217
202
|
|
|
218
|
-
Please check the [**SECURITY.md**](
|
|
203
|
+
Please check the [**SECURITY.md**](https://github.com/wellwelwel/poku/blob/main/SECURITY.md).
|
|
219
204
|
|
|
220
205
|
---
|
|
221
206
|
|
|
@@ -223,11 +208,11 @@ Please check the [**SECURITY.md**](./SECURITY.md) and the section [**Is Poku Saf
|
|
|
223
208
|
|
|
224
209
|
### Performance
|
|
225
210
|
|
|
226
|
-
**Poku** is continuously tested
|
|
211
|
+
**Poku** is [continuously tested](https://github.com/wellwelwel/poku/blob/main/.github/workflows/ci_benchmark.yml) to ensure the following expectations:
|
|
227
212
|
|
|
228
|
-
-
|
|
229
|
-
-
|
|
230
|
-
-
|
|
213
|
+
- **~4x** faster than [**Jest**](https://github.com/jestjs/jest) (v29.7.0)
|
|
214
|
+
- **~3x** faster than [**Vitest**](https://github.com/vitest-dev/vitest) (v1.6.0)
|
|
215
|
+
- **~1x** faster than [**Mocha**](https://github.com/mochajs/mocha) (v10.4.0) + [**Chai**](https://github.com/chaijs/chai) (v5.1.1)
|
|
231
216
|
|
|
232
217
|
> You can see how the tests are run and compared in the [benchmark](https://github.com/wellwelwel/poku/tree/main/benchmark) directory.
|
|
233
218
|
|
|
@@ -235,18 +220,18 @@ Please check the [**SECURITY.md**](./SECURITY.md) and the section [**Is Poku Saf
|
|
|
235
220
|
|
|
236
221
|
### Installation Size
|
|
237
222
|
|
|
238
|
-
|
|
223
|
+
[](https://pkg-size.dev/poku)
|
|
239
224
|
|
|
240
|
-
- [
|
|
241
|
-
- [
|
|
242
|
-
- [
|
|
225
|
+
- [~**300x** lighter than **Vitest**](https://pkg-size.dev/vitest)
|
|
226
|
+
- [~**170x** lighter than **Jest**](https://pkg-size.dev/jest)
|
|
227
|
+
- [~**40x** lighter than **Mocha** + **Chai**](https://pkg-size.dev/mocha%20chai)
|
|
243
228
|
|
|
244
229
|
---
|
|
245
230
|
|
|
246
231
|
### Limitations
|
|
247
232
|
|
|
248
|
-
- **Poku**
|
|
249
|
-
-
|
|
233
|
+
- Although it has no external dependencies, **Poku** is not _all-in-one_, so it doesn't have features such as _mocks_, _spies_, _coverage reports_, etc., where you can use your favorite packages or native solutions.
|
|
234
|
+
- **Poku** community is gradually building up.
|
|
250
235
|
|
|
251
236
|
---
|
|
252
237
|
|
|
@@ -260,4 +245,4 @@ Please check the [**SECURITY.md**](./SECURITY.md) and the section [**Is Poku Saf
|
|
|
260
245
|
|
|
261
246
|
## License
|
|
262
247
|
|
|
263
|
-
Poku is under the [**MIT License**](
|
|
248
|
+
**Poku** is under the [**MIT License**](https://github.com/wellwelwel/poku/blob/main/LICENSE).
|
package/lib/bin/index.js
CHANGED
|
@@ -13,12 +13,15 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
13
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
14
|
const list_files_js_1 = require("../modules/list-files.js");
|
|
15
15
|
const get_arg_js_1 = require("../helpers/get-arg.js");
|
|
16
|
-
const
|
|
17
|
-
const processes_js_1 = require("../modules/processes.js");
|
|
16
|
+
const files_js_1 = require("../configs/files.js");
|
|
18
17
|
const get_runtime_js_1 = require("../helpers/get-runtime.js");
|
|
19
18
|
const format_js_1 = require("../helpers/format.js");
|
|
20
19
|
const logs_js_1 = require("../helpers/logs.js");
|
|
21
20
|
const hr_js_1 = require("../helpers/hr.js");
|
|
21
|
+
const map_tests_js_1 = require("../services/map-tests.js");
|
|
22
|
+
const watch_js_1 = require("../services/watch.js");
|
|
23
|
+
const poku_js_1 = require("../modules/poku.js");
|
|
24
|
+
const processes_js_1 = require("../modules/processes.js");
|
|
22
25
|
(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
23
26
|
var _a;
|
|
24
27
|
const dirs = (() => {
|
|
@@ -43,6 +46,7 @@ const hr_js_1 = require("../helpers/hr.js");
|
|
|
43
46
|
const quiet = (0, get_arg_js_1.hasArg)('quiet');
|
|
44
47
|
const debug = (0, get_arg_js_1.hasArg)('debug');
|
|
45
48
|
const failFast = (0, get_arg_js_1.hasArg)('fail-fast');
|
|
49
|
+
const watchMode = (0, get_arg_js_1.hasArg)('watch');
|
|
46
50
|
const concurrency = parallel
|
|
47
51
|
? Number((0, get_arg_js_1.getArg)('concurrency')) || undefined
|
|
48
52
|
: undefined;
|
|
@@ -72,6 +76,7 @@ const hr_js_1 = require("../helpers/hr.js");
|
|
|
72
76
|
debug,
|
|
73
77
|
failFast,
|
|
74
78
|
concurrency,
|
|
79
|
+
noExit: watchMode,
|
|
75
80
|
deno: {
|
|
76
81
|
allow: denoAllow,
|
|
77
82
|
deny: denoDeny,
|
|
@@ -87,6 +92,53 @@ const hr_js_1 = require("../helpers/hr.js");
|
|
|
87
92
|
(0, logs_js_1.write)(`${format_js_1.format.italic(format_js_1.format.info('…'))} ${format_js_1.format.bold('Options')}`);
|
|
88
93
|
console.dir(options, { depth: null, colors: true });
|
|
89
94
|
}
|
|
90
|
-
(0, poku_js_1.poku)(dirs, options);
|
|
95
|
+
yield (0, poku_js_1.poku)(dirs, options);
|
|
96
|
+
if (watchMode) {
|
|
97
|
+
const executing = new Set();
|
|
98
|
+
const interval = Number((0, get_arg_js_1.getArg)('watch-interval')) || 1500;
|
|
99
|
+
const resultsClear = () => {
|
|
100
|
+
files_js_1.fileResults.success.clear();
|
|
101
|
+
files_js_1.fileResults.fail.clear();
|
|
102
|
+
};
|
|
103
|
+
resultsClear();
|
|
104
|
+
(0, map_tests_js_1.mapTests)('.', dirs).then((mappedTests) => [
|
|
105
|
+
Array.from(mappedTests.keys()).forEach((mappedTest) => {
|
|
106
|
+
(0, watch_js_1.watch)(mappedTest, (file, event) => {
|
|
107
|
+
if (event === 'change') {
|
|
108
|
+
const filePath = (0, map_tests_js_1.normalizePath)(file);
|
|
109
|
+
if (executing.has(filePath))
|
|
110
|
+
return;
|
|
111
|
+
executing.add(filePath);
|
|
112
|
+
resultsClear();
|
|
113
|
+
const tests = mappedTests.get(filePath);
|
|
114
|
+
if (!tests)
|
|
115
|
+
return;
|
|
116
|
+
(0, poku_js_1.poku)(tests, options).then(() => {
|
|
117
|
+
setTimeout(() => {
|
|
118
|
+
executing.delete(filePath);
|
|
119
|
+
}, interval);
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
}),
|
|
124
|
+
]);
|
|
125
|
+
dirs.forEach((dir) => {
|
|
126
|
+
(0, watch_js_1.watch)(dir, (file, event) => {
|
|
127
|
+
if (event === 'change') {
|
|
128
|
+
if (executing.has(file))
|
|
129
|
+
return;
|
|
130
|
+
executing.add(file);
|
|
131
|
+
resultsClear();
|
|
132
|
+
(0, poku_js_1.poku)(file, options).then(() => {
|
|
133
|
+
setTimeout(() => {
|
|
134
|
+
executing.delete(file);
|
|
135
|
+
}, interval);
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
(0, hr_js_1.hr)();
|
|
141
|
+
(0, logs_js_1.write)(`Watching: ${dirs.join(', ')}`);
|
|
142
|
+
}
|
|
91
143
|
}))();
|
|
92
144
|
/* c8 ignore stop */
|
package/lib/modules/each.d.ts
CHANGED
|
@@ -47,5 +47,5 @@ export declare const beforeEach: (callback: () => unknown, options?: EachOptions
|
|
|
47
47
|
* after.reset();
|
|
48
48
|
* ```
|
|
49
49
|
*/
|
|
50
|
-
export declare const afterEach: (callback: () => unknown, options
|
|
50
|
+
export declare const afterEach: (callback: () => unknown, options?: Omit<EachOptions, 'immediate'>) => Control;
|
|
51
51
|
export {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
/// <reference types="node" />
|
|
3
|
+
import { type Dirent, type Stats } from 'node:fs';
|
|
4
|
+
export declare const readdir: (path: string, options: {
|
|
5
|
+
withFileTypes: true;
|
|
6
|
+
}) => Promise<Dirent[]>;
|
|
7
|
+
export declare const stat: (path: string) => Promise<Stats>;
|
|
8
|
+
export declare const readFile: (path: string, encoding?: BufferEncoding) => Promise<string>;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* c8 ignore start */
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.readFile = exports.stat = exports.readdir = void 0;
|
|
5
|
+
const node_fs_1 = require("fs");
|
|
6
|
+
const readdir = (path, options) => new Promise((resolve, reject) => {
|
|
7
|
+
(0, node_fs_1.readdir)(path, options, (err, entries) => {
|
|
8
|
+
if (err)
|
|
9
|
+
reject(err);
|
|
10
|
+
else
|
|
11
|
+
resolve(entries);
|
|
12
|
+
});
|
|
13
|
+
});
|
|
14
|
+
exports.readdir = readdir;
|
|
15
|
+
const stat = (path) => {
|
|
16
|
+
return new Promise((resolve, reject) => {
|
|
17
|
+
(0, node_fs_1.stat)(path, (err, stats) => {
|
|
18
|
+
if (err)
|
|
19
|
+
reject(err);
|
|
20
|
+
else
|
|
21
|
+
resolve(stats);
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
};
|
|
25
|
+
exports.stat = stat;
|
|
26
|
+
const readFile = (path, encoding = 'utf-8') => new Promise((resolve, reject) => {
|
|
27
|
+
(0, node_fs_1.readFile)(path, encoding, (err, data) => {
|
|
28
|
+
if (err)
|
|
29
|
+
reject(err);
|
|
30
|
+
else
|
|
31
|
+
resolve(data);
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
exports.readFile = readFile;
|
|
35
|
+
/* c8 ignore stop */
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.mapTests = exports.normalizePath = void 0;
|
|
13
|
+
/* c8 ignore next */
|
|
14
|
+
const node_path_1 = require("path");
|
|
15
|
+
const fs_js_1 = require("../polyfills/fs.js");
|
|
16
|
+
const list_files_js_1 = require("../modules/list-files.js");
|
|
17
|
+
const filter = /\.(js|cjs|mjs|ts|cts|mts)$/;
|
|
18
|
+
const normalizePath = (filePath) => filePath
|
|
19
|
+
.replace(/(\.\/)/g, '')
|
|
20
|
+
.replace(/^\.+/, '')
|
|
21
|
+
.replace(/[/\\]+/g, node_path_1.sep)
|
|
22
|
+
.replace(/\\/g, '/');
|
|
23
|
+
exports.normalizePath = normalizePath;
|
|
24
|
+
/* c8 ignore next */
|
|
25
|
+
const mapTests = (srcDir, testPaths) => __awaiter(void 0, void 0, void 0, function* () {
|
|
26
|
+
const allTestFiles = [];
|
|
27
|
+
const allSrcFiles = yield (0, list_files_js_1.listFiles)(srcDir, { filter });
|
|
28
|
+
const importMap = new Map();
|
|
29
|
+
for (const testPath of testPaths) {
|
|
30
|
+
const stats = yield (0, fs_js_1.stat)(testPath);
|
|
31
|
+
if (stats.isDirectory()) {
|
|
32
|
+
const testFiles = yield (0, list_files_js_1.listFiles)(testPath, { filter });
|
|
33
|
+
allTestFiles.push(...testFiles);
|
|
34
|
+
}
|
|
35
|
+
else if (stats.isFile() && filter.test(testPath))
|
|
36
|
+
allTestFiles.push(testPath);
|
|
37
|
+
}
|
|
38
|
+
for (const testFile of allTestFiles) {
|
|
39
|
+
const content = yield (0, fs_js_1.readFile)(testFile, 'utf-8');
|
|
40
|
+
for (const srcFile of allSrcFiles) {
|
|
41
|
+
const relativePath = (0, exports.normalizePath)((0, node_path_1.relative)((0, node_path_1.dirname)(testFile), srcFile));
|
|
42
|
+
const normalizedSrcFile = (0, exports.normalizePath)(srcFile);
|
|
43
|
+
/* c8 ignore start */
|
|
44
|
+
if (content.includes(relativePath.replace(filter, '')) ||
|
|
45
|
+
content.includes(normalizedSrcFile)) {
|
|
46
|
+
if (!importMap.has(normalizedSrcFile))
|
|
47
|
+
importMap.set(normalizedSrcFile, []);
|
|
48
|
+
importMap.get(normalizedSrcFile).push((0, exports.normalizePath)(testFile));
|
|
49
|
+
}
|
|
50
|
+
/* c8 ignore stop */
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return importMap;
|
|
54
|
+
});
|
|
55
|
+
exports.mapTests = mapTests;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export type WatchCallback = (file: string, event: string) => void;
|
|
2
|
+
declare class Watcher {
|
|
3
|
+
private rootDir;
|
|
4
|
+
private files;
|
|
5
|
+
private fileWatchers;
|
|
6
|
+
private dirWatchers;
|
|
7
|
+
private callback;
|
|
8
|
+
constructor(rootDir: string, callback: WatchCallback);
|
|
9
|
+
private watchFile;
|
|
10
|
+
private unwatchFiles;
|
|
11
|
+
private watchFiles;
|
|
12
|
+
private watchDirectory;
|
|
13
|
+
start(): Promise<void>;
|
|
14
|
+
stop(): void;
|
|
15
|
+
private unwatchDirectories;
|
|
16
|
+
}
|
|
17
|
+
export declare const watch: (path: string, callback: WatchCallback) => Promise<Watcher>;
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.watch = void 0;
|
|
13
|
+
/* c8 ignore next */
|
|
14
|
+
const node_fs_1 = require("fs");
|
|
15
|
+
const node_path_1 = require("path");
|
|
16
|
+
const fs_js_1 = require("../polyfills/fs.js");
|
|
17
|
+
const list_files_js_1 = require("../modules/list-files.js");
|
|
18
|
+
class Watcher {
|
|
19
|
+
constructor(rootDir, callback) {
|
|
20
|
+
this.files = [];
|
|
21
|
+
this.fileWatchers = new Map();
|
|
22
|
+
this.dirWatchers = new Map();
|
|
23
|
+
this.rootDir = rootDir;
|
|
24
|
+
this.callback = callback;
|
|
25
|
+
}
|
|
26
|
+
watchFile(filePath) {
|
|
27
|
+
/* c8 ignore next */
|
|
28
|
+
if (this.fileWatchers.has(filePath))
|
|
29
|
+
return;
|
|
30
|
+
const watcher = (0, node_fs_1.watch)(filePath, (eventType) => {
|
|
31
|
+
this.callback(filePath, eventType);
|
|
32
|
+
});
|
|
33
|
+
/* c8 ignore start */
|
|
34
|
+
watcher.on('error', () => {
|
|
35
|
+
return;
|
|
36
|
+
});
|
|
37
|
+
/* c8 ignore stop */
|
|
38
|
+
this.fileWatchers.set(filePath, watcher);
|
|
39
|
+
}
|
|
40
|
+
unwatchFiles() {
|
|
41
|
+
for (const [filePath, watcher] of this.fileWatchers) {
|
|
42
|
+
watcher.close();
|
|
43
|
+
this.fileWatchers.delete(filePath);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
watchFiles(filePaths) {
|
|
47
|
+
this.unwatchFiles();
|
|
48
|
+
for (const filePath of filePaths) {
|
|
49
|
+
this.watchFile(filePath);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
watchDirectory(dir) {
|
|
53
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
54
|
+
if (this.dirWatchers.has(dir))
|
|
55
|
+
return;
|
|
56
|
+
const watcher = (0, node_fs_1.watch)(dir, (_, filename) => __awaiter(this, void 0, void 0, function* () {
|
|
57
|
+
if (filename) {
|
|
58
|
+
const fullPath = (0, node_path_1.join)(dir, filename);
|
|
59
|
+
this.files = yield (0, list_files_js_1.listFiles)(this.rootDir);
|
|
60
|
+
this.watchFiles(this.files);
|
|
61
|
+
try {
|
|
62
|
+
const stats = yield (0, fs_js_1.stat)(fullPath);
|
|
63
|
+
if (stats.isDirectory())
|
|
64
|
+
yield this.watchDirectory(fullPath);
|
|
65
|
+
/* c8 ignore start */
|
|
66
|
+
}
|
|
67
|
+
catch (_a) { }
|
|
68
|
+
/* c8 ignore stop */
|
|
69
|
+
}
|
|
70
|
+
}));
|
|
71
|
+
/* c8 ignore start */
|
|
72
|
+
watcher.on('error', () => {
|
|
73
|
+
return;
|
|
74
|
+
});
|
|
75
|
+
/* c8 ignore stop */
|
|
76
|
+
this.dirWatchers.set(dir, watcher);
|
|
77
|
+
const entries = yield (0, fs_js_1.readdir)(dir, { withFileTypes: true });
|
|
78
|
+
for (const entry of entries) {
|
|
79
|
+
if (entry.isDirectory()) {
|
|
80
|
+
const fullPath = (0, node_path_1.join)(dir, entry.name);
|
|
81
|
+
yield this.watchDirectory(fullPath);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
start() {
|
|
87
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
88
|
+
try {
|
|
89
|
+
const stats = yield (0, fs_js_1.stat)(this.rootDir);
|
|
90
|
+
if (stats.isDirectory()) {
|
|
91
|
+
this.files = yield (0, list_files_js_1.listFiles)(this.rootDir);
|
|
92
|
+
this.watchFiles(this.files);
|
|
93
|
+
yield this.watchDirectory(this.rootDir);
|
|
94
|
+
}
|
|
95
|
+
else
|
|
96
|
+
this.watchFile(this.rootDir);
|
|
97
|
+
/* c8 ignore start */
|
|
98
|
+
}
|
|
99
|
+
catch (err) {
|
|
100
|
+
throw new Error(`Path does not exist or is not accessible: ${this.rootDir}`);
|
|
101
|
+
}
|
|
102
|
+
/* c8 ignore stop */
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
stop() {
|
|
106
|
+
this.unwatchFiles();
|
|
107
|
+
this.unwatchDirectories();
|
|
108
|
+
}
|
|
109
|
+
unwatchDirectories() {
|
|
110
|
+
for (const [dirPath, watcher] of this.dirWatchers) {
|
|
111
|
+
watcher.close();
|
|
112
|
+
this.dirWatchers.delete(dirPath);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
/* c8 ignore next */
|
|
117
|
+
const watch = (path, callback) => __awaiter(void 0, void 0, void 0, function* () {
|
|
118
|
+
const watcher = new Watcher(path, callback);
|
|
119
|
+
yield watcher.start();
|
|
120
|
+
return watcher;
|
|
121
|
+
});
|
|
122
|
+
exports.watch = watch;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "poku",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.17.0",
|
|
4
4
|
"description": "🐷 Poku makes testing easy for Node.js, Bun, Deno and you at the same time.",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -70,6 +70,7 @@
|
|
|
70
70
|
"run",
|
|
71
71
|
"queue",
|
|
72
72
|
"queuing",
|
|
73
|
+
"watch",
|
|
73
74
|
"nodejs",
|
|
74
75
|
"node",
|
|
75
76
|
"cli-app",
|
|
@@ -126,7 +127,7 @@
|
|
|
126
127
|
"@types/node": "^20.14.2",
|
|
127
128
|
"@typescript-eslint/eslint-plugin": "^7.13.0",
|
|
128
129
|
"@typescript-eslint/parser": "^7.13.0",
|
|
129
|
-
"c8": "^10.1.
|
|
130
|
+
"c8": "^10.1.2",
|
|
130
131
|
"esbuild": "^0.21.5",
|
|
131
132
|
"eslint": "^8.57.0",
|
|
132
133
|
"eslint-config-prettier": "^9.1.0",
|
|
@@ -136,7 +137,7 @@
|
|
|
136
137
|
"packages-update": "^2.0.0",
|
|
137
138
|
"prettier": "^3.3.2",
|
|
138
139
|
"shx": "^0.3.4",
|
|
139
|
-
"tsx": "4.15.
|
|
140
|
+
"tsx": "4.15.4",
|
|
140
141
|
"typescript": "^5.4.5"
|
|
141
142
|
}
|
|
142
143
|
}
|