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 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="170" height="170" alt="Logo" src="https://raw.githubusercontent.com/wellwelwel/poku/main/.github/assets/readme/poku.svg">
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** can show you _how simple testing can be_ 🌱
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
- > **Poku** takes on the testers' difficulties by itself and lets you focus on the tests.
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>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</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>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</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>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</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>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</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>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</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>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</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>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</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>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><img width="16" height="16" alt="check" src="https://raw.githubusercontent.com/wellwelwel/poku/main/.github/assets/readme/check.svg"> Easily handle **services**, **servers**, **processes** and **ports**<br />
50
+ <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</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>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</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>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</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 />
58
- <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</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<br />
59
- <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><img width="16" height="16" alt="check" src="https://raw.githubusercontent.com/wellwelwel/poku/main/.github/assets/readme/check.svg"> **Poku** doesn't use `eval` nor global state 🔐<br />
60
- <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><img width="16" height="16" alt="check" src="https://raw.githubusercontent.com/wellwelwel/poku/main/.github/assets/readme/check.svg"> _In other words, you can run your tests directly, without relying on **Poku**_<br />
54
+ <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</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>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</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
- [![Install Size](https://packagephobia.com/badge?p=poku)](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
- - **Test**
176
- - [**poku**](https://poku.io/docs/category/poku) (_test runner_)
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
- - [**describe**](https://poku.io/docs/documentation/helpers/describe) and [**it**](https://poku.io/docs/documentation/helpers/it)
186
- - [**beforeEach**](https://poku.io/docs/category/beforeeach-and-aftereach) and [**afterEach**](https://poku.io/docs/category/beforeeach-and-aftereach)
187
- - **Processes**
188
- - [**kill**](https://poku.io/docs/documentation/processes/kill) (_terminate Ports, Port Ranges and PIDs_)
189
- - [**getPIDs**](https://poku.io/docs/documentation/processes/get-pids) (_get all processes IDs using ports and port ranges_)
190
- - _and much more_
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
- > I'm continuously working to improve **Poku**. If you've got something interesting to share, feel free to submit a [**Pull Request**](https://github.com/wellwelwel/poku/compare). If you notice something wrong, I'd appreciate if you'd open an [**Issue**](https://github.com/wellwelwel/poku/issues/new).
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**](./SECURITY.md) and the section [**Is Poku Safe?**](https://poku.io/docs/security) from Documentation.
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 ([**CI**](https://github.com/wellwelwel/poku/blob/main/.github/workflows/ci_benchmark.yml)) to ensure the following expectations:
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
- - [x] **~4x** faster than [**Jest**](https://github.com/jestjs/jest) (v29.7.0)
229
- - [x] **~3x** faster than [**Vitest**](https://github.com/vitest-dev/vitest) (v1.6.0)
230
- - [x] **~1x** faster than [**Mocha**](https://github.com/mochajs/mocha) (v10.4.0) + [**Chai**](https://github.com/chaijs/chai) (v5.1.1)
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
- <a href="https://pkg-size.dev/poku"><img src="https://pkg-size.dev/badge/install/125875" title="Install size for poku"></a>
223
+ [![Install Size](https://packagephobia.com/badge?p=poku)](https://pkg-size.dev/poku)
239
224
 
240
- - [x] [~**175x** lighter than **Jest**](https://pkg-size.dev/jest)
241
- - [x] [~**302x** lighter than **Vitest**](https://pkg-size.dev/vitest)
242
- - [x] [~**44x** lighter than **Mocha** + **Chai**](https://pkg-size.dev/mocha%20chai)
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** community is gradually building up 🤝
249
- - Although it has no external dependencies, **Poku** is not _all-in-one_, so it doesn't have features such as _mocks_ and _spies_, where you can use your favorite packages or native solutions.
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**](./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 poku_js_1 = require("../modules/poku.js");
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 */
@@ -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: Omit<EachOptions, 'immediate'>) => Control;
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,2 @@
1
+ export declare const normalizePath: (filePath: string) => string;
2
+ export declare const mapTests: (srcDir: string, testPaths: string[]) => Promise<Map<string, string[]>>;
@@ -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.15.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.0",
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.2",
140
+ "tsx": "4.15.4",
140
141
  "typescript": "^5.4.5"
141
142
  }
142
143
  }