poku 1.1.1 → 1.3.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 CHANGED
@@ -17,9 +17,7 @@
17
17
 
18
18
  <img align="right" width="128" height="128" alt="Logo" src=".github/assets/readme/poku.svg">
19
19
 
20
- 🖇️ A flexible and easy-to-use **Test Runner** for [**Node**][node-version-url], [**Bun**][bun-version-url] and [**Deno**][deno-version-url], which allows parallel or sequential runs and high isolation level.
21
-
22
- > **Poku** starts from the premise where tests come to help, not overcomplicate.
20
+ A flexible and easy-to-use **Test Runner** for [Node.js][node-version-url], [Bun][bun-version-url] and [Deno][deno-version-url] that allows you to run **parallel** and **sequential** tests, plus **high isolation level per test file**.
23
21
 
24
22
  [![Node.js Version][node-version-image]][node-version-url]
25
23
  [![Bun Version][bun-version-image]][bun-version-url]
@@ -33,25 +31,51 @@
33
31
 
34
32
  ## Why Poku?
35
33
 
36
- Runs test files in an individual process, shows progress and exits 🪄
34
+ > **Poku** starts from the premise where tests come to help, not overcomplicate: runs test files in an individual process per file, shows progress and exits 🧙🏻
37
35
 
38
- - **Poku** is designed to be highly intuitive
39
36
  - Supports **ESM** and **CJS**
37
+ - Designed to be highly intuitive
40
38
  - No need to compile **TypeScript**
41
39
  - Compatible with **Coverage** tools
42
40
  - Allows both **in-code** and **CLI** usage
41
+ - [**Node.js**][node-version-url], [**Bun**][bun-version-url] and [**Deno**][deno-version-url] compatibility
43
42
  - Zero configurations, except you want
44
43
  - No constraints or rules, code in your own signature style
45
44
 
46
45
  ---
47
46
 
48
- - Totally **dependency-free**
47
+ - <img src="https://img.shields.io/bundlephobia/min/poku?label=Final%20Size">
48
+ - **Zero** external dependencies
49
49
  - **Poku** dive to the deepest depths to find tests in the specified directories
50
50
  - **Compatibility:** **Poku** is tested across all **Node 6+**, **Bun 0.5.3+** and **Deno 1.30+** versions
51
51
  - **Poku** uses itself to test its own tests using `process.exit` at several depths on the same process node
52
52
 
53
53
  ---
54
54
 
55
+ | Sequential | Parallel |
56
+ | ------------------------------------------------------------ | ---------------------------------------------------------- |
57
+ | `npx poku test/unit,test/integration` | `npx poku --parallel test/unit,test/integration` |
58
+ | <img src=".github/assets/readme/sequential.png" width="360"> | <img src=".github/assets/readme/parallel.png" width="360"> |
59
+
60
+ - By default, **Poku** searches for all _`.test.`_ files, but you can customize it using the option [`filter`](https://github.com/wellwelwel/poku#filter-rexexp).
61
+ - The same idea for [**Bun**][bun-version-url] and [**Deno**][deno-version-url] (see bellow).
62
+
63
+ ---
64
+
65
+ **Poku** also includes the `assert` method, keeping everything as it is, but providing human readability:
66
+
67
+ ```ts
68
+ import { assert } from 'poku'; // Node and Bun
69
+ import { assert } from 'npm:poku'; // Deno
70
+
71
+ assert(true);
72
+ assert.deepStrictEqual(1, '1', 'My optional custom message');
73
+ ```
74
+
75
+ > <img src=".github/assets/readme/assert.png" width="468" />
76
+
77
+ ---
78
+
55
79
  ## Install
56
80
 
57
81
  ### **Node.js**
@@ -107,7 +131,7 @@ import { poku } from 'npm:poku';
107
131
  ```ts
108
132
  import { poku } from 'poku';
109
133
 
110
- await poku(['./a', './b']);
134
+ await poku(['targetDirA', 'targetDirB']);
111
135
  ```
112
136
 
113
137
  > <img src=".github/assets/readme/deno.svg" width="24" />
@@ -115,7 +139,7 @@ await poku(['./a', './b']);
115
139
  ```ts
116
140
  import { poku } from 'npm:poku';
117
141
 
118
- await poku(['./a', './b']);
142
+ await poku(['targetDirA', 'targetDirB']);
119
143
  ```
120
144
 
121
145
  ### CLI
@@ -123,54 +147,179 @@ await poku(['./a', './b']);
123
147
  > <img src=".github/assets/readme/node-js.svg" width="24" />
124
148
 
125
149
  ```bash
126
- npx poku --include='./a,./b'
150
+ npx poku targetDirA,targetDirB
127
151
  ```
128
152
 
129
153
  > <img src=".github/assets/readme/bun.svg" width="24" />
130
154
 
131
155
  ```bash
132
- bun poku --include='./a,./b'
156
+ bun poku targetDirA,targetDirB
133
157
  ```
134
158
 
135
159
  > <img src=".github/assets/readme/deno.svg" width="24" />
136
160
 
137
161
  ```bash
138
- deno run npm:poku --include='./a,./b'
162
+ deno run npm:poku targetDirA,targetDirB
139
163
  ```
140
164
 
141
165
  ---
142
166
 
143
167
  ## Documentation
144
168
 
145
- > Documentation in Progress 🧑🏻‍🔧
169
+ > Website in Progress 🧑🏻‍🔧
146
170
  >
147
171
  > Initially, the documentation is based on **Node.js** usage, but you can use all the options normally for both **Bun** and **Deno**.
148
172
 
149
- ### `poku(string | string[])`
173
+ ### `poku(targetDirs: string | string[])`
150
174
 
151
175
  #### Include directories
152
176
 
177
+ - **in-code**
178
+
153
179
  ```ts
154
- poku('./targetDir');
180
+ poku('targetDir');
155
181
  ```
156
182
 
157
183
  ```ts
158
- poku(['./targetDirA', './targetDirB']);
184
+ poku(['targetDirA', 'targetDirB']);
185
+ ```
186
+
187
+ - **CLI**
188
+
189
+ By setting the directories as the last argument:
190
+
191
+ > _Since **1.3.0**_
192
+
193
+ ```bash
194
+ npx poku targetDir
195
+ ```
196
+
197
+ ```bash
198
+ npx poku targetDirA,targetDirB
159
199
  ```
160
200
 
201
+ By using `--include` option:
202
+
203
+ > _Since **1.0.0**_
204
+
161
205
  ```bash
162
- npx poku --include='./targetDir'
206
+ npx poku --include='targetDir'
163
207
  ```
164
208
 
165
209
  ```bash
166
- npx poku --include='./targetDirA,./targetDirB'
210
+ npx poku --include='targetDirA,targetDirB'
167
211
  ```
168
212
 
169
213
  ---
170
214
 
171
- ### `poku(string | string[], configs: Configs)`
215
+ ### `poku(targetDirs: string | string[], configs?: Configs)`
216
+
217
+ #### `parallel: boolean`
218
+
219
+ Determines the mode of test execution across **sequential** or **parallel** modes.
172
220
 
173
- #### `filter`
221
+ - **in-code**
222
+
223
+ ```ts
224
+ /**
225
+ * @default
226
+ *
227
+ * Sequential mode
228
+ */
229
+
230
+ poku(['...'], {
231
+ parallel: false,
232
+ });
233
+ ```
234
+
235
+ ```ts
236
+ /**
237
+ * Parallel mode
238
+ */
239
+
240
+ poku(['...'], {
241
+ parallel: true,
242
+ });
243
+ ```
244
+
245
+ - **CLI**
246
+
247
+ > _Since **1.2.0**_
248
+
249
+ ```bash
250
+ # Parallel mode
251
+
252
+ npx poku --parallel ./test
253
+ ```
254
+
255
+ ---
256
+
257
+ #### `platform: "node" | "bun" | "deno"`
258
+
259
+ > _Since **1.2.0**_
260
+
261
+ By default, **Poku** tries to identify the platform automatically, but you can set it manually:
262
+
263
+ - **in-code**
264
+
265
+ ```ts
266
+ /**
267
+ * Force Node.js (or tsx for TypeScript)
268
+ *
269
+ * @default 'node'
270
+ */
271
+
272
+ poku('...', {
273
+ platform: 'node',
274
+ });
275
+ ```
276
+
277
+ ```ts
278
+ /**
279
+ * Force Bun
280
+ */
281
+
282
+ poku('...', {
283
+ platform: 'bun',
284
+ });
285
+ ```
286
+
287
+ ```ts
288
+ /**
289
+ * Force Deno
290
+ */
291
+
292
+ poku('...', {
293
+ platform: 'deno',
294
+ });
295
+ ```
296
+
297
+ - **CLI**
298
+
299
+ ```bash
300
+ # Normal
301
+
302
+ npx poku --platform=node ./test
303
+ bun poku --platform=bun ./test
304
+ deno run npm:poku --platform=deno ./test
305
+ ```
306
+
307
+ ```bash
308
+ # Custom
309
+ # When you're developing using a platform, but maintain compatibility with others
310
+
311
+ npx poku --platform=bun ./test
312
+ bun poku --platform=deno ./test
313
+ deno run npm:poku --platform=node ./test
314
+
315
+ # ...
316
+ ```
317
+
318
+ ---
319
+
320
+ #### `filter: RegExp`
321
+
322
+ By default, **Poku** searches for _`.test.`_ files, but you can customize it using the `filter` option.
174
323
 
175
324
  > Filter by path using **Regex** to match only the files that should be performed.
176
325
 
@@ -194,7 +343,7 @@ poku(['...'], {
194
343
  */
195
344
 
196
345
  poku(['...'], {
197
- filter: /\.(m)?(j|t)?s$/,
346
+ filter: /\.(m)?(j|t)s$/,
198
347
  // filter: /\.(js|ts|mjs|mts)$/,
199
348
  });
200
349
  ```
@@ -204,13 +353,19 @@ poku(['...'], {
204
353
  ```bash
205
354
  # Testing only a specific file
206
355
 
207
- npx poku --include='...' --filter='some-file'
356
+ npx poku --filter='some-file' ./test
357
+ ```
358
+
359
+ ```bash
360
+ # Testing only a specific file
361
+
362
+ npx poku --filter='some-file|other-file' ./test
208
363
  ```
209
364
 
210
365
  ```bash
211
366
  # Testing only paths that contains "unit"
212
367
 
213
- npx poku --include='...' --filter='unit'
368
+ npx poku --filter='unit' ./test
214
369
  ```
215
370
 
216
371
  - **Environment Variable**
@@ -220,45 +375,160 @@ npx poku --include='...' --filter='unit'
220
375
  ```bash
221
376
  # Testing only a specific file
222
377
 
223
- FILTER='some-file' npx poku --include='...'
378
+ FILTER='some-file' npx poku ./test
379
+ ```
380
+
381
+ ```bash
382
+ # Testing only a specific file
383
+
384
+ FILTER='some-file|other-file' npx poku ./test
224
385
  ```
225
386
 
226
387
  ```bash
227
388
  # Testing only paths that contains "unit"
228
389
 
229
- FILTER='unit' npx poku --include='...'
390
+ FILTER='unit' npx poku ./test
230
391
  ```
231
392
 
232
393
  ---
233
394
 
234
- #### `parallel`
395
+ #### `exclude: RegExp | RegExp[]`
235
396
 
236
- Determines the mode of test execution across **parallelism** or **sequential** modes.
397
+ > Exclude by path using Regex to match only the files that should be performed.
398
+ >
399
+ > _Since **1.2.0**_
400
+
401
+ - **in-code**:
237
402
 
238
403
  ```ts
239
404
  /**
240
- * @default
241
- *
242
- * Sequential mode
405
+ * Excluding directories from tests
243
406
  */
244
407
 
245
408
  poku(['...'], {
246
- parallel: false,
409
+ exclude: /\/(helpers|tools)\//,
247
410
  });
248
411
  ```
249
412
 
250
413
  ```ts
251
414
  /**
252
- * Parallel mode
415
+ * Excluding directories from tests
253
416
  */
254
417
 
255
418
  poku(['...'], {
256
- parallel: true,
419
+ exclude: [/\/helpers\//, /\/tools\//],
420
+ });
421
+ ```
422
+
423
+ ```ts
424
+ /**
425
+ * Excluding specific files from tests
426
+ */
427
+
428
+ poku(['...'], {
429
+ exclude: /(index|common).test.ts/,
430
+ });
431
+ ```
432
+
433
+ ```ts
434
+ /**
435
+ * Excluding specific files from tests
436
+ */
437
+
438
+ poku(['...'], {
439
+ exclude: [/index.test.ts/, /common.test.ts/],
440
+ });
441
+ ```
442
+
443
+ ```ts
444
+ /**
445
+ * Excluding directories and files from tests
446
+ */
447
+
448
+ poku(['...'], {
449
+ exclude: /\/(helpers|tools)\/|(index|common).test.ts/,
257
450
  });
258
451
  ```
259
452
 
453
+ ```ts
454
+ /**
455
+ * Excluding directories and files from tests
456
+ */
457
+
458
+ poku(['...'], {
459
+ exclude: [/\/helpers\//, /\/tools\//, /index.test.ts/, /common.test.ts/],
460
+ });
461
+ ```
462
+
463
+ - **CLI**
464
+
465
+ ```bash
466
+ # Excluding directories and files from tests
467
+
468
+ npx poku --exclude='some-file-or-dir' ./test
469
+ ```
470
+
471
+ ```bash
472
+ # Excluding directories and files from tests
473
+
474
+ npx poku --exclude='some-file-or-dir|other-file-or-dir' ./test
475
+ ```
476
+
477
+ ---
478
+
479
+ ### Assert
480
+
481
+ > _Since **1.3.0**_
482
+ >
483
+ > [**Node.js**][node-version-url], [**Bun**][bun-version-url] and [**Deno**][deno-version-url] compatible.
484
+
485
+ **Poku** includes the `assert` method, keeping everything as it is, but providing human readability.
486
+
487
+ **Available methods:**
488
+
489
+ - `assert(value[, message])`
490
+ - `assert.deepEqual(actual, expected[, message])`
491
+ - `assert.deepStrictEqual(actual, expected[, message])`
492
+ - `assert.doesNotMatch(string, regexp[, message])`
493
+ - `assert.doesNotReject(asyncFn[, error][, message])`
494
+ - `assert.doesNotThrow(fn[, error][, message])`
495
+ - `assert.equal(actual, expected[, message])`
496
+ - `assert.fail([message])`
497
+ - `assert.ifError(value)`
498
+ - `assert.match(string, regexp[, message])`
499
+ - `assert.notDeepEqual(actual, expected[, message])`
500
+ - `assert.notDeepStrictEqual(actual, expected[, message])`
501
+ - `assert.notEqual(actual, expected[, message])`
502
+ - `assert.notStrictEqual(actual, expected[, message])`
503
+ - `assert.ok(value[, message])`
504
+ - `assert.rejects(asyncFn[, error][, message])`
505
+ - `assert.strictEqual(actual, expected[, message])`
506
+ - `assert.throws(fn[, error][, message])`
507
+
508
+ You can follow the [**assert documentation**](https://nodejs.org/api/assert.html) from **Node.js**'s documentation.
509
+
510
+ ---
511
+
512
+ ### `listFiles(targetDir: string, configs?: ListFilesConfigs)`
513
+
514
+ > _Since **1.2.0**_
515
+
516
+ Returns all files in a directory, independent of their depth.
517
+
518
+ ```ts
519
+ listFiles('some-dir');
520
+ ```
521
+
522
+ - You can use the `filter` and `exclude` options, as well as they are for **`poku`** method.
523
+
524
+ ---
525
+
526
+ ## Community
527
+
528
+ 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).
529
+
260
530
  ---
261
531
 
262
- ## Documentation in Progress...
532
+ ## Acknowledgements
263
533
 
264
- > 🧑🏻‍🎓 Soon documenting all options and **Poku**'s usage variations.
534
+ - [**Contributors**](https://github.com/wellwelwel/poku/graphs/contributors)
@@ -0,0 +1,14 @@
1
+ export type Configs = {
2
+ /**
3
+ * Filter by path to match only the files that should be performed.
4
+ *
5
+ * @default /\.test\./i
6
+ */
7
+ filter?: RegExp;
8
+ /**
9
+ * Exclude by path to match only the files that should be performed.
10
+ *
11
+ * @default undefined
12
+ */
13
+ exclude?: RegExp | RegExp[];
14
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,3 +1,4 @@
1
+ import type { Configs as ListFilesConfigs } from './list-files.js';
1
2
  export type Configs = {
2
3
  /**
3
4
  * By setting `true`, **Poku** won't exit the process and will return the exit code (`0` or `1`).
@@ -26,16 +27,16 @@ export type Configs = {
26
27
  * @default false
27
28
  */
28
29
  quiet?: boolean;
29
- /**
30
- * Filter by path to match only the files that should be performed.
31
- *
32
- * @default /\.test\./i
33
- */
34
- filter?: RegExp;
35
30
  /**
36
31
  * Determines the mode of test execution.
37
32
  *
38
33
  * @default false
39
34
  */
40
35
  parallel?: boolean;
41
- };
36
+ /**
37
+ * Determines the platform for test execution.
38
+ *
39
+ * @default 'node'
40
+ */
41
+ platform?: 'node' | 'bun' | 'deno';
42
+ } & ListFilesConfigs;
package/lib/bin/index.js CHANGED
@@ -1,12 +1,21 @@
1
1
  #! /usr/bin/env node
2
2
  "use strict";
3
+ var _a, _b;
3
4
  Object.defineProperty(exports, "__esModule", { value: true });
4
- const get_files_js_1 = require("../helpers/get-files.js");
5
+ const list_files_js_1 = require("../modules/list-files.js");
5
6
  const get_arg_js_1 = require("../helpers/get-arg.js");
6
7
  const index_js_1 = require("../index.js");
7
- const rawDirs = (0, get_arg_js_1.getArg)('include');
8
- const rawFilter = (0, get_arg_js_1.getArg)('filter');
9
- const dirs = (rawDirs === null || rawDirs === void 0 ? void 0 : rawDirs.split(',')) || [];
8
+ const get_runtime_js_1 = require("../helpers/get-runtime.js");
9
+ const dirs = ((0, get_arg_js_1.hasArg)('include')
10
+ ? (_a = (0, get_arg_js_1.getArg)('include')) === null || _a === void 0 ? void 0 : _a.split(',')
11
+ : (_b = (0, get_arg_js_1.getLastParam)()) === null || _b === void 0 ? void 0 : _b.split(',')) || [];
12
+ const platform = (0, get_arg_js_1.getArg)('platform');
13
+ const filter = (0, get_arg_js_1.getArg)('filter');
14
+ const parallel = (0, get_arg_js_1.hasArg)('parallel');
15
+ const exclude = (0, get_arg_js_1.getArg)('exclude');
10
16
  (0, index_js_1.poku)(dirs, {
11
- filter: rawFilter ? new RegExp((0, get_files_js_1.escapeRegExp)(rawFilter)) : undefined,
17
+ platform: (0, get_runtime_js_1.platformIsValid)(platform) ? platform : undefined,
18
+ filter: filter ? new RegExp((0, list_files_js_1.escapeRegExp)(filter)) : undefined,
19
+ exclude: exclude ? new RegExp((0, list_files_js_1.escapeRegExp)(exclude)) : undefined,
20
+ parallel,
12
21
  });
@@ -1,5 +1,6 @@
1
1
  export declare const format: {
2
2
  counter: (current: number, total: number, pad?: string) => string;
3
+ dim: (value: string) => string;
3
4
  bold: (value: string) => string;
4
5
  underline: (value: string) => string;
5
6
  info: (value: string) => string;
@@ -7,6 +7,7 @@ exports.format = {
7
7
  const totalDigits = String(total).length;
8
8
  return (0, pad_js_1.padStart)(String(current), totalDigits, pad);
9
9
  },
10
+ dim: (value) => `\x1b[2m${value}\x1b[0m`,
10
11
  bold: (value) => `\x1b[1m${value}\x1b[0m`,
11
12
  underline: (value) => `\x1b[4m${value}\x1b[0m`,
12
13
  info: (value) => `\x1b[36m${value}\x1b[0m`,
@@ -1 +1,3 @@
1
1
  export declare const getArg: (arg: string) => string | undefined;
2
+ export declare const hasArg: (arg: string) => boolean;
3
+ export declare const getLastParam: () => string;
@@ -3,7 +3,7 @@ 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.getArg = void 0;
6
+ exports.getLastParam = exports.hasArg = exports.getArg = void 0;
7
7
  const node_process_1 = __importDefault(require("process"));
8
8
  const [, , ...args] = node_process_1.default.argv;
9
9
  const getArg = (arg) => {
@@ -14,3 +14,9 @@ const getArg = (arg) => {
14
14
  return undefined;
15
15
  };
16
16
  exports.getArg = getArg;
17
+ const hasArg = (arg) => args.some((a) => a.startsWith(`--${arg}`));
18
+ exports.hasArg = hasArg;
19
+ const getLastParam = () => {
20
+ return args[args.length - 1];
21
+ };
22
+ exports.getLastParam = getLastParam;
@@ -1 +1,4 @@
1
- export declare const getRuntime: () => "deno" | "bun" | "node";
1
+ import type { Configs } from '../@types/poku.ts';
2
+ export declare const supportedPlatforms: ReadonlyArray<Configs['platform']>;
3
+ export declare const platformIsValid: (platform: unknown) => platform is "node" | "bun" | "deno" | undefined;
4
+ export declare const getRuntime: (configs?: Configs) => (typeof supportedPlatforms)[number];
@@ -1,7 +1,21 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getRuntime = void 0;
4
- const getRuntime = () => {
3
+ exports.getRuntime = exports.platformIsValid = exports.supportedPlatforms = void 0;
4
+ exports.supportedPlatforms = [
5
+ 'node',
6
+ 'bun',
7
+ 'deno',
8
+ ];
9
+ const platformIsValid = (platform) => {
10
+ if (typeof platform === 'string' &&
11
+ exports.supportedPlatforms.some((supportedPlatform) => supportedPlatform === platform))
12
+ return true;
13
+ return false;
14
+ };
15
+ exports.platformIsValid = platformIsValid;
16
+ const getRuntime = (configs) => {
17
+ if ((configs === null || configs === void 0 ? void 0 : configs.platform) && (0, exports.platformIsValid)(configs.platform))
18
+ return configs.platform;
5
19
  if (typeof Deno !== 'undefined')
6
20
  return 'deno';
7
21
  if (typeof Bun !== 'undefined')
package/lib/helpers/hr.js CHANGED
@@ -8,7 +8,7 @@ const node_os_1 = require("os");
8
8
  const node_process_1 = __importDefault(require("process"));
9
9
  const hr = () => {
10
10
  const columns = node_process_1.default.stdout.columns;
11
- const line = '_'.repeat(columns - 10 || 0);
11
+ const line = '_'.repeat(columns - 10 || 30);
12
12
  console.log(`\x1b[2m${line}\x1b[0m${node_os_1.EOL}`);
13
13
  };
14
14
  exports.hr = hr;
@@ -0,0 +1,9 @@
1
+ export type ParseAssertionOptions = {
2
+ message?: string | Error;
3
+ defaultMessage?: string;
4
+ actual?: string;
5
+ expected?: string;
6
+ throw?: boolean;
7
+ hideDiff?: boolean;
8
+ };
9
+ export declare const parseAssertion: (cb: () => void, options: ParseAssertionOptions) => void;