kizu 0.0.0-autorel

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.
Files changed (48) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +124 -0
  3. package/bin/cli.js +3 -0
  4. package/dist/assertions/AssertionError.d.ts +3 -0
  5. package/dist/assertions/AssertionError.js +11 -0
  6. package/dist/assertions/equal.d.ts +2 -0
  7. package/dist/assertions/equal.js +55 -0
  8. package/dist/assertions/errorsEquivalent.d.ts +3 -0
  9. package/dist/assertions/errorsEquivalent.js +49 -0
  10. package/dist/assertions/fail.d.ts +2 -0
  11. package/dist/assertions/fail.js +7 -0
  12. package/dist/assertions/index.d.ts +10 -0
  13. package/dist/assertions/index.js +22 -0
  14. package/dist/assertions/isFalse.d.ts +2 -0
  15. package/dist/assertions/isFalse.js +49 -0
  16. package/dist/assertions/isTrue.d.ts +2 -0
  17. package/dist/assertions/isTrue.js +49 -0
  18. package/dist/assertions/pass.d.ts +2 -0
  19. package/dist/assertions/pass.js +7 -0
  20. package/dist/assertions/throws.d.ts +2 -0
  21. package/dist/assertions/throws.js +16 -0
  22. package/dist/calculateFinalResults.d.ts +9 -0
  23. package/dist/calculateFinalResults.js +21 -0
  24. package/dist/getSpecFiles.d.ts +1 -0
  25. package/dist/getSpecFiles.js +22 -0
  26. package/dist/index.d.ts +1 -0
  27. package/dist/index.js +18 -0
  28. package/dist/isTestPassing.d.ts +6 -0
  29. package/dist/isTestPassing.js +15 -0
  30. package/dist/lib/deepStrictEqual.d.ts +1 -0
  31. package/dist/lib/deepStrictEqual.js +60 -0
  32. package/dist/lib/diff.d.ts +2 -0
  33. package/dist/lib/diff.js +32 -0
  34. package/dist/lib/toResult.d.ts +4 -0
  35. package/dist/lib/toResult.js +34 -0
  36. package/dist/output.d.ts +5 -0
  37. package/dist/output.js +84 -0
  38. package/dist/run.d.ts +12 -0
  39. package/dist/run.js +52 -0
  40. package/dist/shouldExitWithError.d.ts +2 -0
  41. package/dist/shouldExitWithError.js +7 -0
  42. package/dist/sortTestResults.d.ts +3 -0
  43. package/dist/sortTestResults.js +32 -0
  44. package/dist/test.d.ts +16 -0
  45. package/dist/test.js +44 -0
  46. package/dist/workerPool.d.ts +2 -0
  47. package/dist/workerPool.js +36 -0
  48. package/package.json +61 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2021 Marc H. Weiner
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,124 @@
1
+ <picture>
2
+ <source srcset="docs/kitest-logo-light.svg" media="(prefers-color-scheme: light)">
3
+ <source srcset="docs/kitest-logo-dark.svg" media="(prefers-color-scheme: dark)">
4
+ <img src="docs/kitest-logo-light.svg" alt="Logo" style="margin: 0 0 10px" size="250">
5
+ </picture>
6
+
7
+ [![build status](https://github.com/mhweiner/kitest/actions/workflows/release.yml/badge.svg)](https://github.com/mhweiner/kitest/actions)
8
+ [![SemVer](https://img.shields.io/badge/SemVer-2.0.0-blue)]()
9
+ [![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)
10
+ [![AutoRel](https://img.shields.io/badge/v2-AutoRel?label=AutoRel&labelColor=0ab5fc&color=grey&link=https%3A%2F%2Fgithub.com%2Fmhweiner%2Fautorel)](https://github.com/mhweiner/autorel)
11
+
12
+ **kitest** is a fast, minimalist test runner for TypeScript and JavaScript, with a small, easy-to-learn API that lets you focus on your tests — not your tooling.
13
+
14
+ Fast, minimal, precise, safe, atomic, and easy to use.
15
+
16
+ ## Features
17
+
18
+ **🚀 Fast & Reliable**
19
+ - Multi-process parallel test runner. Each test file is run in its own process/runtime for performance and isolation benefits. _Use on a multicore machine for best results._
20
+ - Optimized for speed and simplicity.
21
+ - Minimal dependencies.
22
+
23
+ **😀 Easy to Use**
24
+ - Very simple functional [assertion API](docs/api.md). No need to learn a DSL or framework.
25
+ - Built-in [powerful diff visualization tool](#visual-diff-tool) and clean, organized output.
26
+ - Failed tests are easy to find, grouped at the end of the output.
27
+ - Errors or unhandled promise rejections are buffered and grouped under the test file in the output. This helps you know where they came from.
28
+ - Clean stack traces with no extra noise.
29
+
30
+ **🛡 Defensive**
31
+ - Uncaught errors and unhandled promise rejections will cause the test to fail.
32
+ - Any spec files without tests, or tests without assertions, result in a failed test.
33
+ - Strict and deep equality comparison by default.
34
+
35
+ **🔒 Out-of-the-box Typescript support**
36
+ - No special configuration needed, and no plugins to install.
37
+ - Works great with [c8](https://github.com/bcoe/c8) for code coverage.
38
+ - Handles compilation errors gracefully.
39
+
40
+ # Quick Examples
41
+
42
+ ```typescript
43
+ import {test} from '@kitest/kitest';
44
+
45
+ // Basic test
46
+
47
+ function greet(name: string): string {
48
+ return `hello, ${name}`;
49
+ }
50
+
51
+ test('greet()', (assert) => {
52
+ assert.equal(hello('world'), 'hello, world');
53
+ });
54
+
55
+ // Error handling
56
+
57
+ function throwError(): never {
58
+ throw new Error('oops');
59
+ }
60
+
61
+ test('throwError()', (assert) => {
62
+ assert.throws(() => throwError(), /oops/);
63
+ });
64
+
65
+ // Async test
66
+
67
+ async function fetchData(): Promise<string> {
68
+ return Promise.resolve('data');
69
+ }
70
+
71
+ test('fetchData()', async (assert) => {
72
+ const data = await fetchData();
73
+ assert.equal(data, 'data');
74
+ });
75
+ ```
76
+
77
+ # Table of Contents
78
+
79
+ - [Getting Started](docs/gettingStarted.md)
80
+ - [Examples](#examples)
81
+ - [API](docs/api.md)
82
+ - [Visual Diff Tool](docs/visualDiff.md)
83
+ - [Best Practices](docs/bestPractices.md)
84
+ - [Inspiration, Philosophy & Attribution](docs/inspiration.md)
85
+ - [FAQ](docs/faq.md)
86
+ - [Support, Feedback, and Contributions](#support-feedback-and-contributions)
87
+ - [Sponsorship](#sponsorship)
88
+ - [License](LICENSE)
89
+
90
+ # Getting Started
91
+
92
+ To install and get started with `kitest`, see our [Getting Started](docs/gettingStarted.md) guide.
93
+
94
+ # Examples
95
+
96
+ See the [examples](examples) and [src](src) folders for more examples.
97
+
98
+ # Support, feedback, and contributions
99
+
100
+ - Star this repo if you like it!
101
+ - Submit an [issue](https://github.com/mhweiner/kitest/issues) with your problem, feature request or bug report
102
+ - Issue a PR against `main` and request review. Make sure all tests pass and coverage is good.
103
+ - Write about this project in your blog, tweet about it, or share it with your friends!
104
+
105
+ # Sponsorship
106
+ <br>
107
+ <picture>
108
+ <source srcset="docs/aeroview-white.svg" media="(prefers-color-scheme: dark)">
109
+ <source srcset="docs/aeroview-black.svg" media="(prefers-color-scheme: light)">
110
+ <img src="docs/aeroview-black.svg" alt="Logo" height="20">
111
+ </picture>
112
+ <br>
113
+
114
+ Aeroview is a lightning-fast, developer-friendly, AI-powered logging IDE. Get started for free at [https://aeroview.io](https://aeroview.io).
115
+
116
+ Want to sponsor this project? [Reach out](mailto:mhweiner234@gmail.com?subject=I%20want%20to%20sponsor%20kitest).
117
+
118
+ # Other useful libraries
119
+
120
+ - [autorel](https://github.com/mhweiner/autorel): Automate semantic releases based on conventional commits. Similar to semantic-release but much simpler.
121
+ - [brek](https://github.com/mhweiner/brek): A powerful yet simple configuration library for Node.js. It’s structured, typed, and designed for dynamic configuration loading, making it perfect for securely managing secrets (e.g., AWS Secrets Manager).
122
+ - [jsout](https://github.com/mhweiner/jsout): A Syslog-compatible, small, and simple logger for Typescript/Javascript projects.
123
+ - [cjs-mock](https://github.com/mhweiner/cjs-mock): NodeJS module mocking for CJS (CommonJS) modules for unit testing purposes.
124
+ - [typura](https://github.com/aeroview/typura): Simple and extensible runtime input validation for TS/JS, written in TS.
package/bin/cli.js ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ts-node
2
+
3
+ require('../dist/run');
@@ -0,0 +1,3 @@
1
+ export declare class AssertionError extends Error {
2
+ constructor(message: string);
3
+ }
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AssertionError = void 0;
4
+ class AssertionError extends Error {
5
+ constructor(message) {
6
+ super(message);
7
+ this.name = this.constructor.name;
8
+ }
9
+ }
10
+ exports.AssertionError = AssertionError;
11
+ //# sourceMappingURL=AssertionError.js.map
@@ -0,0 +1,2 @@
1
+ import { Assertion } from '../test';
2
+ export declare function equal(assertions: Assertion[], actual: any, expected: any, description?: string): void;
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.equal = equal;
30
+ const deepStrictEqual_1 = require("../lib/deepStrictEqual");
31
+ const util = __importStar(require("util"));
32
+ const kleur_1 = __importDefault(require("kleur"));
33
+ const AssertionError_1 = require("./AssertionError");
34
+ const diff_1 = require("../lib/diff");
35
+ function equal(assertions, actual, expected, description) {
36
+ const descWithDefault = description || 'equal()';
37
+ if ((0, deepStrictEqual_1.deepStrictEqual)(actual, expected)) {
38
+ assertions.push({ pass: true, description: descWithDefault });
39
+ }
40
+ else {
41
+ const diagnostic = createDiagnostic(actual, expected);
42
+ const stack = new AssertionError_1.AssertionError('not deeply and strictly equivalent').stack;
43
+ assertions.push({ pass: false, description: descWithDefault, diagnostic, stack });
44
+ }
45
+ }
46
+ function createDiagnostic(actual, expected) {
47
+ const diff = (0, diff_1.getDiff)(actual, expected);
48
+ const actualStr = util.inspect(actual, { colors: true, depth: null });
49
+ const expectedStr = util.inspect(expected, { colors: true, depth: null });
50
+ const sectionActual = `${kleur_1.default.grey().bold('Actual:')}\n\n${actualStr}`;
51
+ const sectionExpected = `\n\n${kleur_1.default.grey().bold('Expected:')}\n\n${expectedStr}`;
52
+ const sectionDiff = diff && `\n\n${kleur_1.default.grey().bold('Diff:')}\n\n${diff}`;
53
+ return `${sectionActual}${sectionExpected}${sectionDiff}\n`;
54
+ }
55
+ //# sourceMappingURL=equal.js.map
@@ -0,0 +1,3 @@
1
+ import { Assertion } from '../test';
2
+ export declare function errorsEquivalent(assertions: Assertion[], actualErr: Error, expectedErr: Error | RegExp, description?: string): void;
3
+ export declare function createDiagnosticRegexMismatch(actualErrMsg: string, expectedRegEx: RegExp): string;
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.errorsEquivalent = errorsEquivalent;
7
+ exports.createDiagnosticRegexMismatch = createDiagnosticRegexMismatch;
8
+ const serialize_error_1 = require("serialize-error");
9
+ const equal_1 = require("./equal");
10
+ const pass_1 = require("./pass");
11
+ const AssertionError_1 = require("./AssertionError");
12
+ const kleur_1 = __importDefault(require("kleur"));
13
+ function errorsEquivalent(assertions, actualErr, expectedErr, description) {
14
+ if (!(actualErr instanceof Error))
15
+ throw new Error('actualErr is not an instance of Error');
16
+ if (!(expectedErr instanceof Error) && !(expectedErr instanceof RegExp))
17
+ throw new Error('expectedErr is not an instance of Error or a RegExp');
18
+ if (expectedErr instanceof RegExp) {
19
+ if (!expectedErr.test(actualErr.message)) {
20
+ const diagnostic = createDiagnosticRegexMismatch(actualErr.message, expectedErr);
21
+ const stack = new AssertionError_1.AssertionError('Expected error message does not match').stack;
22
+ assertions.push({ pass: false, description: description !== null && description !== void 0 ? description : 'errorsEquivalent()', diagnostic, stack });
23
+ }
24
+ else {
25
+ (0, pass_1.pass)(assertions, description !== null && description !== void 0 ? description : 'errorsEquivalent()');
26
+ }
27
+ }
28
+ else {
29
+ compareErrorObjects(assertions, actualErr, expectedErr, description);
30
+ }
31
+ }
32
+ function compareErrorObjects(assertions, actualErr, expectedErr, description) {
33
+ if (!(actualErr instanceof Error))
34
+ throw new Error('actualErr is not an instance of Error');
35
+ if (!(expectedErr instanceof Error) && !(expectedErr instanceof RegExp))
36
+ throw new Error('expectedErr is not an instance of Error or a RegExp');
37
+ const actualErrSerialized = (0, serialize_error_1.serializeError)(actualErr);
38
+ const expectedErrSerialized = (0, serialize_error_1.serializeError)(expectedErr);
39
+ // ignore stack traces
40
+ actualErrSerialized === null || actualErrSerialized === void 0 ? true : delete actualErrSerialized.stack;
41
+ expectedErrSerialized === null || expectedErrSerialized === void 0 ? true : delete expectedErrSerialized.stack;
42
+ (0, equal_1.equal)(assertions, actualErrSerialized, expectedErrSerialized, description || 'errorsEquivalent()');
43
+ }
44
+ function createDiagnosticRegexMismatch(actualErrMsg, expectedRegEx) {
45
+ const actual = `${kleur_1.default.grey().bold('Actual Error Message:')}\n\n${actualErrMsg}`;
46
+ const expected = `\n\n${kleur_1.default.grey().bold('Expected RegEx:')}\n\n${expectedRegEx}`;
47
+ return `${actual}${expected}\n\n`;
48
+ }
49
+ //# sourceMappingURL=errorsEquivalent.js.map
@@ -0,0 +1,2 @@
1
+ import { Assertion } from '../test';
2
+ export declare function fail(assertions: Assertion[], description?: string): void;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.fail = fail;
4
+ function fail(assertions, description) {
5
+ assertions.push({ pass: false, description: description !== null && description !== void 0 ? description : 'fail()' });
6
+ }
7
+ //# sourceMappingURL=fail.js.map
@@ -0,0 +1,10 @@
1
+ import { Assertion } from '../test';
2
+ export declare function createAssertionPredicates(assertions: Assertion[]): {
3
+ pass: (description?: string) => void;
4
+ fail: (description?: string) => void;
5
+ isTrue: (condition: boolean, description?: string) => void;
6
+ isFalse: (condition: boolean, description?: string) => void;
7
+ equal: (actual: any, expected: any, description?: string) => void;
8
+ errorsEquivalent: (actual: any, expected: any, description?: string) => void;
9
+ throws: (experiment: () => any, expectedErr: Error | RegExp, description?: string) => void;
10
+ };
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createAssertionPredicates = createAssertionPredicates;
4
+ const errorsEquivalent_1 = require("./errorsEquivalent");
5
+ const equal_1 = require("./equal");
6
+ const throws_1 = require("./throws");
7
+ const isTrue_1 = require("./isTrue");
8
+ const isFalse_1 = require("./isFalse");
9
+ const fail_1 = require("./fail");
10
+ const pass_1 = require("./pass");
11
+ function createAssertionPredicates(assertions) {
12
+ return {
13
+ pass: (description) => ((0, pass_1.pass)(assertions, description)),
14
+ fail: (description) => ((0, fail_1.fail)(assertions, description)),
15
+ isTrue: (condition, description) => ((0, isTrue_1.isTrue)(assertions, condition, description)),
16
+ isFalse: (condition, description) => ((0, isFalse_1.isFalse)(assertions, condition, description)),
17
+ equal: (actual, expected, description) => ((0, equal_1.equal)(assertions, actual, expected, description)),
18
+ errorsEquivalent: (actual, expected, description) => ((0, errorsEquivalent_1.errorsEquivalent)(assertions, actual, expected, description)),
19
+ throws: (experiment, expectedErr, description) => ((0, throws_1.throws)(assertions, experiment, expectedErr, description)),
20
+ };
21
+ }
22
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,2 @@
1
+ import { Assertion } from '../test';
2
+ export declare function isFalse(assertions: Assertion[], condition: boolean, description?: string): void;
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.isFalse = isFalse;
30
+ const util = __importStar(require("util"));
31
+ const kleur_1 = __importDefault(require("kleur"));
32
+ const AssertionError_1 = require("./AssertionError");
33
+ function isFalse(assertions, condition, description) {
34
+ const descWithDefault = description || 'isFalse()';
35
+ if (!condition) {
36
+ assertions.push({ pass: true, description: descWithDefault });
37
+ }
38
+ else {
39
+ const diagnostic = createDiagnostic(condition);
40
+ const stack = new AssertionError_1.AssertionError('is not false').stack;
41
+ assertions.push({ pass: false, description: descWithDefault, diagnostic, stack });
42
+ }
43
+ }
44
+ function createDiagnostic(actual) {
45
+ const actualStr = util.inspect(actual, { colors: true, depth: null });
46
+ const sectionActual = `${kleur_1.default.grey().bold('Actual:')}\n\n${actualStr}`;
47
+ return `${sectionActual}\n`;
48
+ }
49
+ //# sourceMappingURL=isFalse.js.map
@@ -0,0 +1,2 @@
1
+ import { Assertion } from '../test';
2
+ export declare function isTrue(assertions: Assertion[], condition: boolean, description?: string): void;
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.isTrue = isTrue;
30
+ const util = __importStar(require("util"));
31
+ const kleur_1 = __importDefault(require("kleur"));
32
+ const AssertionError_1 = require("./AssertionError");
33
+ function isTrue(assertions, condition, description) {
34
+ const descWithDefault = description || 'isTrue()';
35
+ if (condition) {
36
+ assertions.push({ pass: true, description: descWithDefault });
37
+ }
38
+ else {
39
+ const diagnostic = createDiagnostic(condition);
40
+ const stack = new AssertionError_1.AssertionError('is not true').stack;
41
+ assertions.push({ pass: false, description: descWithDefault, diagnostic, stack });
42
+ }
43
+ }
44
+ function createDiagnostic(actual) {
45
+ const actualStr = util.inspect(actual, { colors: true, depth: null });
46
+ const sectionActual = `${kleur_1.default.grey().bold('Actual:')}\n\n${actualStr}`;
47
+ return `${sectionActual}\n`;
48
+ }
49
+ //# sourceMappingURL=isTrue.js.map
@@ -0,0 +1,2 @@
1
+ import { Assertion } from '../test';
2
+ export declare function pass(assertions: Assertion[], description?: string): void;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.pass = pass;
4
+ function pass(assertions, description) {
5
+ assertions.push({ pass: true, description: description !== null && description !== void 0 ? description : 'pass()' });
6
+ }
7
+ //# sourceMappingURL=pass.js.map
@@ -0,0 +1,2 @@
1
+ import { Assertion } from '../test';
2
+ export declare function throws(assertions: Assertion[], experiment: () => any, expectedErr: Error | RegExp, description?: string): void;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.throws = throws;
4
+ const toResult_1 = require("../lib/toResult");
5
+ const errorsEquivalent_1 = require("./errorsEquivalent");
6
+ function throws(assertions, experiment, expectedErr, description) {
7
+ if (typeof experiment !== 'function')
8
+ throw new Error('experiment must be a function');
9
+ if (!(expectedErr instanceof Error) && !(expectedErr instanceof RegExp))
10
+ throw new Error('expectedErr is not an instance of Error or a RegExp');
11
+ const [actualErr] = (0, toResult_1.toResult)(experiment);
12
+ if (!actualErr)
13
+ throw new Error('experiment did not throw an error');
14
+ (0, errorsEquivalent_1.errorsEquivalent)(assertions, actualErr, expectedErr, description || 'throws()');
15
+ }
16
+ //# sourceMappingURL=throws.js.map
@@ -0,0 +1,9 @@
1
+ import { TestResultsByFile } from './run';
2
+ export declare function calculateFinalResults(specFiles: string[], testResults: TestResultsByFile): {
3
+ numFiles: number;
4
+ numTests: number;
5
+ numSuccessfulTests: number;
6
+ filesWithNoTests: string[];
7
+ numAssertions: number;
8
+ numSuccessfulAssertions: number;
9
+ };
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.calculateFinalResults = calculateFinalResults;
4
+ const isTestPassing_1 = require("./isTestPassing");
5
+ function calculateFinalResults(specFiles, testResults) {
6
+ const numFiles = Object.keys(testResults).length;
7
+ const filesWithNoTests = specFiles.reduce((files, filename) => (testResults[filename] ? files : files.concat([filename])), []);
8
+ const numTests = Object.values(testResults).reduce((acc, results) => acc + results.length, 0);
9
+ const numSuccessfulTests = Object.values(testResults).reduce((acc, results) => (acc + results.reduce((acc, test) => (acc + ((0, isTestPassing_1.isTestPassing)(test) ? 1 : 0)), 0)), 0);
10
+ const numAssertions = Object.values(testResults).reduce((acc, results) => (acc + results.reduce((acc, test) => acc + test.assertions.length, 0)), 0);
11
+ const numSuccessfulAssertions = Object.values(testResults).reduce((acc, results) => (acc + results.reduce((acc, test) => (acc + test.assertions.reduce((acc, assertion) => acc + (assertion.pass ? 1 : 0), 0)), 0)), 0);
12
+ return {
13
+ numFiles,
14
+ numTests,
15
+ numSuccessfulTests,
16
+ filesWithNoTests,
17
+ numAssertions,
18
+ numSuccessfulAssertions,
19
+ };
20
+ }
21
+ //# sourceMappingURL=calculateFinalResults.js.map
@@ -0,0 +1 @@
1
+ export declare function getSpecFiles(): Promise<string[]>;
@@ -0,0 +1,22 @@
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
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.getSpecFiles = getSpecFiles;
16
+ const tiny_glob_1 = __importDefault(require("tiny-glob"));
17
+ function getSpecFiles() {
18
+ return __awaiter(this, void 0, void 0, function* () {
19
+ return (0, tiny_glob_1.default)(process.argv[2]);
20
+ });
21
+ }
22
+ //# sourceMappingURL=getSpecFiles.js.map
@@ -0,0 +1 @@
1
+ export * from './test';
package/dist/index.js ADDED
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./test"), exports);
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,6 @@
1
+ import { TestResults } from './test';
2
+ /**
3
+ * All assertions must pass, with no errors, and at least one assertion.
4
+ * @param test
5
+ */
6
+ export declare function isTestPassing(test: TestResults): boolean;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isTestPassing = isTestPassing;
4
+ /**
5
+ * All assertions must pass, with no errors, and at least one assertion.
6
+ * @param test
7
+ */
8
+ function isTestPassing(test) {
9
+ if (!test.assertions.length)
10
+ return false;
11
+ if (test.error)
12
+ return false;
13
+ return test.assertions.reduce((pass, assertion) => pass && assertion.pass, true);
14
+ }
15
+ //# sourceMappingURL=isTestPassing.js.map
@@ -0,0 +1 @@
1
+ export declare function deepStrictEqual(obj1: any, obj2: any): boolean;
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.deepStrictEqual = deepStrictEqual;
4
+ /* eslint-disable max-lines-per-function */
5
+ function deepStrictEqual(obj1, obj2) {
6
+ if (obj1 === obj2)
7
+ return true;
8
+ if (isPrimitive(obj1) && isPrimitive(obj2))
9
+ return obj1 === obj2;
10
+ if (Array.isArray(obj1) !== Array.isArray(obj2))
11
+ return false;
12
+ if (typeof obj1 !== typeof obj2)
13
+ return false;
14
+ if (obj1 === null || obj2 === null)
15
+ return false;
16
+ // Handle Map objects
17
+ if (obj1 instanceof Map && obj2 instanceof Map) {
18
+ if (obj1.size !== obj2.size)
19
+ return false;
20
+ for (const [key, value] of obj1) {
21
+ if (!obj2.has(key) || !deepStrictEqual(value, obj2.get(key)))
22
+ return false;
23
+ }
24
+ return true;
25
+ }
26
+ // Handle Set objects
27
+ if (obj1 instanceof Set && obj2 instanceof Set) {
28
+ if (obj1.size !== obj2.size)
29
+ return false;
30
+ for (const item of obj1) {
31
+ let matchFound = false;
32
+ for (const item2 of obj2) {
33
+ if (deepStrictEqual(item, item2)) {
34
+ matchFound = true;
35
+ break;
36
+ }
37
+ }
38
+ if (!matchFound)
39
+ return false;
40
+ }
41
+ return true;
42
+ }
43
+ // Handle object comparison
44
+ const keys1 = Object.keys(obj1);
45
+ const keys2 = Object.keys(obj2);
46
+ if (keys1.length !== keys2.length)
47
+ return false;
48
+ for (const key of keys1) {
49
+ if (!Object.prototype.hasOwnProperty.call(obj2, key))
50
+ return false;
51
+ if (!deepStrictEqual(obj1[key], obj2[key]))
52
+ return false;
53
+ }
54
+ return true;
55
+ }
56
+ // Helper function to check if a value is a primitive
57
+ function isPrimitive(value) {
58
+ return value !== Object(value);
59
+ }
60
+ //# sourceMappingURL=deepStrictEqual.js.map
@@ -0,0 +1,2 @@
1
+ export declare function getDiff(actual: any, expected: any): string;
2
+ export declare function stringVisualDiff(actual: string, expected: string): string;
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getDiff = getDiff;
7
+ exports.stringVisualDiff = stringVisualDiff;
8
+ const deep_object_diff_1 = require("deep-object-diff");
9
+ const diff_1 = require("diff");
10
+ const kleur_1 = __importDefault(require("kleur"));
11
+ const node_util_1 = require("node:util");
12
+ function getDiff(actual, expected) {
13
+ if (actual === expected)
14
+ return '';
15
+ if (typeof actual === 'string' && typeof expected === 'string') {
16
+ return stringVisualDiff(actual, expected);
17
+ }
18
+ else if (typeof actual === 'object' && typeof expected === 'object') {
19
+ return (0, node_util_1.inspect)((0, deep_object_diff_1.diff)(actual, expected), {
20
+ colors: true,
21
+ depth: null,
22
+ });
23
+ }
24
+ else {
25
+ return '';
26
+ }
27
+ }
28
+ function stringVisualDiff(actual, expected) {
29
+ return (0, diff_1.diffChars)(actual, expected).reduce((str, part) => str + (part.added ? kleur_1.default.bgGreen().black(part.value) : part.removed
30
+ ? kleur_1.default.bgRed().white(part.value) : kleur_1.default.white(part.value)), '');
31
+ }
32
+ //# sourceMappingURL=diff.js.map
@@ -0,0 +1,4 @@
1
+ export type Result<E, T> = [E] | [undefined, T];
2
+ export type PromiseResult<E, T> = Promise<Result<E, T>>;
3
+ export declare function toResult<E extends Error, T>(executable: () => T): Result<E, T>;
4
+ export declare function toResultAsync<E extends Error, T>(p: Promise<T>): PromiseResult<E, T>;
@@ -0,0 +1,34 @@
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.toResult = toResult;
13
+ exports.toResultAsync = toResultAsync;
14
+ function toResult(executable) {
15
+ try {
16
+ const result = executable();
17
+ return [undefined, result];
18
+ }
19
+ catch (e) {
20
+ return [e];
21
+ }
22
+ }
23
+ function toResultAsync(p) {
24
+ return __awaiter(this, void 0, void 0, function* () {
25
+ try {
26
+ const result = yield p;
27
+ return [undefined, result];
28
+ }
29
+ catch (e) {
30
+ return [e];
31
+ }
32
+ });
33
+ }
34
+ //# sourceMappingURL=toResult.js.map
@@ -0,0 +1,5 @@
1
+ import { TestResultsByFile, FinalResults } from './run';
2
+ import { TestResults } from './test';
3
+ export declare function printResultsByFile(resultsByFile: TestResultsByFile): void;
4
+ export declare function printFileResults(filename: string, tests: TestResults[]): void;
5
+ export declare function printSummary(finalResults: FinalResults): void;
package/dist/output.js ADDED
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.printResultsByFile = printResultsByFile;
7
+ exports.printFileResults = printFileResults;
8
+ exports.printSummary = printSummary;
9
+ const kleur_1 = __importDefault(require("kleur"));
10
+ const isTestPassing_1 = require("./isTestPassing");
11
+ const serialize_error_1 = require("serialize-error");
12
+ const sortTestResults_1 = require("./sortTestResults");
13
+ const log = console.log;
14
+ const successSymbol = kleur_1.default.green('✔');
15
+ const failureSymbol = kleur_1.default.red('✖');
16
+ const hr = kleur_1.default.gray('\n────────────────────────────────\n');
17
+ const noTestErrorTpl = (files) => kleur_1.default.red().bold(`
18
+ Error: ${files.length} spec file(s) have no tests. This could indicate a compilation error
19
+ (ie. Typescript), or an early runtime error. All spec files must have at least one test.
20
+ The following spec files do not have any attempted or completed tests:
21
+
22
+ ${files.join(', ')}
23
+ `);
24
+ function printResultsByFile(resultsByFile) {
25
+ const sortedResults = (0, sortTestResults_1.sortTestResults)(resultsByFile);
26
+ for (const [filename, tests] of sortedResults) {
27
+ printFileResults(filename, tests);
28
+ }
29
+ }
30
+ function printFileResults(filename, tests) {
31
+ const doesFileHaveFailures = tests.some((test) => !(0, isTestPassing_1.isTestPassing)(test));
32
+ const header = `${kleur_1.default.underline().blue(filename)} ${doesFileHaveFailures ? failureSymbol : successSymbol}\n`;
33
+ log(header);
34
+ tests.forEach(((test) => {
35
+ log(`${test.description} ${(0, isTestPassing_1.isTestPassing)(test) ? successSymbol : failureSymbol}`);
36
+ test.assertions.forEach((assertion) => {
37
+ log(kleur_1.default.gray(` ${assertion.description} ${assertion.pass ? successSymbol : failureSymbol}`));
38
+ !assertion.pass && printFailedAssertionDiag(assertion);
39
+ });
40
+ test.error && printError(test.error);
41
+ log('');
42
+ }));
43
+ }
44
+ function printError(serializedError) {
45
+ log(hr);
46
+ log((0, serialize_error_1.deserializeError)(serializedError));
47
+ log(hr);
48
+ }
49
+ function printFailedAssertionDiag(assertion) {
50
+ if (!assertion.diagnostic && !assertion.stack)
51
+ return;
52
+ log(hr);
53
+ assertion.diagnostic && log(assertion.diagnostic);
54
+ assertion.stack && log(kleur_1.default.grey(filterStackTrace(assertion.stack)));
55
+ log(hr);
56
+ }
57
+ function printSummary(finalResults) {
58
+ const successRate = finalResults.numSuccessfulTests / finalResults.numTests;
59
+ const assertionSuccessRate = finalResults.numSuccessfulAssertions / finalResults.numAssertions;
60
+ const numFilesWithNoTests = finalResults.filesWithNoTests.length;
61
+ if (assertionSuccessRate === 1) {
62
+ log(kleur_1.default.bold().green(`${successSymbol} ${finalResults.numSuccessfulAssertions}/${finalResults.numAssertions} assertions passed`));
63
+ }
64
+ else {
65
+ log(kleur_1.default.bold().red(`${failureSymbol} ${finalResults.numSuccessfulAssertions}/${finalResults.numAssertions} assertions passed`));
66
+ }
67
+ if (successRate === 1) {
68
+ log(kleur_1.default.bold().green(`${successSymbol} ${finalResults.numSuccessfulTests}/${finalResults.numTests} tests passed`));
69
+ }
70
+ else {
71
+ log(kleur_1.default.bold().red(`${failureSymbol} ${finalResults.numSuccessfulTests}/${finalResults.numTests} tests passed`));
72
+ }
73
+ numFilesWithNoTests && log(noTestErrorTpl(finalResults.filesWithNoTests));
74
+ }
75
+ function filterStackTrace(stack) {
76
+ const ignoreRegex = [
77
+ /at Generator.next \(<anonymous>\)/,
78
+ /at new Promise \(<anonymous>\)/,
79
+ /assertions\/index.[ts|js]{2}/,
80
+ /\/kitest\/[src|dist]{3,4}\/test.[ts|js]{2}/,
81
+ ].reduce((combined, exp) => (new RegExp(`${combined.source}|${exp.source}`)), new RegExp('a^'));
82
+ return stack.split('\n').reduce((acc, line) => (!ignoreRegex.test(line) ? acc.concat([line]) : acc), []).join('\n');
83
+ }
84
+ //# sourceMappingURL=output.js.map
package/dist/run.d.ts ADDED
@@ -0,0 +1,12 @@
1
+ import { TestResults } from './test';
2
+ export type TestResultsByFile = {
3
+ [file: string]: TestResults[];
4
+ };
5
+ export type FinalResults = {
6
+ numFiles: number;
7
+ numTests: number;
8
+ numSuccessfulTests: number;
9
+ filesWithNoTests: string[];
10
+ numAssertions: number;
11
+ numSuccessfulAssertions: number;
12
+ };
package/dist/run.js ADDED
@@ -0,0 +1,52 @@
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
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ const ora_1 = __importDefault(require("ora"));
16
+ const output_1 = require("./output");
17
+ const calculateFinalResults_1 = require("./calculateFinalResults");
18
+ const workerPool_1 = require("./workerPool");
19
+ const shouldExitWithError_1 = require("./shouldExitWithError");
20
+ const getSpecFiles_1 = require("./getSpecFiles");
21
+ const testResultsByFile = {};
22
+ let numCompletedTests = 0;
23
+ const status = (0, ora_1.default)();
24
+ function start() {
25
+ return __awaiter(this, void 0, void 0, function* () {
26
+ const specFiles = yield (0, getSpecFiles_1.getSpecFiles)();
27
+ console.log(`Found ${specFiles.length} spec files.\n`);
28
+ status.start('Running tests...');
29
+ yield (0, workerPool_1.workerPool)(specFiles, addTestResults);
30
+ finish(specFiles);
31
+ });
32
+ }
33
+ /**
34
+ * Add TestResults and update status.
35
+ * @param file
36
+ * @param results
37
+ */
38
+ function addTestResults(file, results) {
39
+ numCompletedTests = numCompletedTests + 1;
40
+ testResultsByFile[file] = (testResultsByFile[file] || []).concat([results]);
41
+ status.text = `${numCompletedTests} tests completed.`;
42
+ }
43
+ function finish(specFiles) {
44
+ status.stop();
45
+ const finalResults = (0, calculateFinalResults_1.calculateFinalResults)(specFiles, testResultsByFile);
46
+ (0, output_1.printResultsByFile)(testResultsByFile);
47
+ (0, output_1.printSummary)(finalResults);
48
+ if ((0, shouldExitWithError_1.shouldExitWithError)(finalResults))
49
+ process.exit(1);
50
+ }
51
+ start().catch(console.log.bind(console));
52
+ //# sourceMappingURL=run.js.map
@@ -0,0 +1,2 @@
1
+ import { FinalResults } from './run';
2
+ export declare function shouldExitWithError(finalResults: FinalResults): boolean;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.shouldExitWithError = shouldExitWithError;
4
+ function shouldExitWithError(finalResults) {
5
+ return !!finalResults.filesWithNoTests.length || finalResults.numSuccessfulTests / finalResults.numTests !== 1;
6
+ }
7
+ //# sourceMappingURL=shouldExitWithError.js.map
@@ -0,0 +1,3 @@
1
+ import { TestResultsByFile } from './run';
2
+ import { TestResults } from './test';
3
+ export declare function sortTestResults(resultsByFile: TestResultsByFile): Map<string, TestResults[]>;
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sortTestResults = sortTestResults;
4
+ const isTestPassing_1 = require("./isTestPassing");
5
+ function sortTestResults(resultsByFile) {
6
+ const sortedResults = new Map();
7
+ const passingFiles = [];
8
+ const failingFiles = [];
9
+ // Separate passing and failing files
10
+ for (const [file, tests] of Object.entries(resultsByFile)) {
11
+ const hasFailingTests = tests.some((test) => !(0, isTestPassing_1.isTestPassing)(test));
12
+ if (hasFailingTests) {
13
+ failingFiles.push([file, tests]);
14
+ }
15
+ else {
16
+ passingFiles.push([file, tests]);
17
+ }
18
+ }
19
+ // Sort passing files first, failing files last
20
+ const sortedFiles = [...passingFiles, ...failingFiles];
21
+ for (const [file, tests] of sortedFiles) {
22
+ // Sort tests: passing tests first, failing tests last
23
+ const sortedTests = [...tests].sort((a, b) => Number((0, isTestPassing_1.isTestPassing)(b)) - Number((0, isTestPassing_1.isTestPassing)(a)));
24
+ // Sort assertions inside each test: passing assertions first
25
+ for (const test of sortedTests) {
26
+ test.assertions.sort((a, b) => Number(b.pass) - Number(a.pass));
27
+ }
28
+ sortedResults.set(file, sortedTests);
29
+ }
30
+ return sortedResults;
31
+ }
32
+ //# sourceMappingURL=sortTestResults.js.map
package/dist/test.d.ts ADDED
@@ -0,0 +1,16 @@
1
+ import { createAssertionPredicates } from './assertions';
2
+ import { ErrorObject } from 'serialize-error';
3
+ export type TestResults = {
4
+ description: string;
5
+ assertions: Assertion[];
6
+ error?: ErrorObject;
7
+ };
8
+ export type Assertion = {
9
+ pass: boolean;
10
+ description: string;
11
+ diagnostic?: string;
12
+ stack?: string;
13
+ };
14
+ type AssertionAPI = ReturnType<typeof createAssertionPredicates>;
15
+ export declare function test(description: string, experiment: (assert: AssertionAPI) => void): Promise<void>;
16
+ export {};
package/dist/test.js ADDED
@@ -0,0 +1,44 @@
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.test = test;
13
+ const assertions_1 = require("./assertions");
14
+ const serialize_error_1 = require("serialize-error");
15
+ const toResult_1 = require("./lib/toResult");
16
+ process.on('unhandledRejection', (err) => {
17
+ sendTestResults({
18
+ description: 'Unhandled Promise Rejection',
19
+ assertions: [],
20
+ error: (0, serialize_error_1.serializeError)(err),
21
+ });
22
+ });
23
+ function test(description, experiment) {
24
+ return __awaiter(this, void 0, void 0, function* () {
25
+ const assertions = [];
26
+ const expAsync = () => __awaiter(this, void 0, void 0, function* () { return experiment((0, assertions_1.createAssertionPredicates)(assertions)); });
27
+ const [err] = yield (0, toResult_1.toResultAsync)(expAsync());
28
+ if (err) {
29
+ sendTestResults({
30
+ description,
31
+ assertions: [],
32
+ error: (0, serialize_error_1.serializeError)(err),
33
+ });
34
+ }
35
+ else {
36
+ sendTestResults({ description, assertions });
37
+ }
38
+ });
39
+ }
40
+ function sendTestResults(results) {
41
+ // @ts-ignore
42
+ process.send(results);
43
+ }
44
+ //# sourceMappingURL=test.js.map
@@ -0,0 +1,2 @@
1
+ import { TestResults } from './test';
2
+ export declare function workerPool(specFiles: string[], addTestResults: (file: string, testResults: TestResults) => void): Promise<void>;
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.workerPool = workerPool;
4
+ const os_1 = require("os");
5
+ const child_process_1 = require("child_process");
6
+ const toResult_1 = require("./lib/toResult");
7
+ const numCores = (0, os_1.cpus)().length; // will be the size of our worker pool
8
+ let numWorkers = 0;
9
+ let currentSpecFileIndex = 0;
10
+ function workerPool(specFiles, addTestResults) {
11
+ return new Promise((resolve, reject) => {
12
+ function next() {
13
+ if (currentSpecFileIndex >= specFiles.length && numWorkers === 0)
14
+ resolve();
15
+ if (currentSpecFileIndex >= specFiles.length)
16
+ return;
17
+ if (numWorkers >= numCores)
18
+ return;
19
+ const file = specFiles[currentSpecFileIndex];
20
+ const [err, worker] = (0, toResult_1.toResult)(() => (0, child_process_1.fork)(file));
21
+ if (err) {
22
+ return reject(new Error(`failed to create worker for ${file}`));
23
+ }
24
+ numWorkers++;
25
+ currentSpecFileIndex++;
26
+ worker.on('close', () => {
27
+ numWorkers--;
28
+ next();
29
+ });
30
+ worker.on('message', (msg) => addTestResults(file, msg));
31
+ next();
32
+ }
33
+ next();
34
+ });
35
+ }
36
+ //# sourceMappingURL=workerPool.js.map
package/package.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "kizu",
3
+ "version": "0.0.0-autorel",
4
+ "description": "An easy-to-use, fast, and defensive Typescript/Javascript test runner designed to help you to write simple, readable, and maintainable tests.",
5
+ "license": "MIT",
6
+ "main": "./dist/index.js",
7
+ "bin": {
8
+ "kitest": "bin/cli.js"
9
+ },
10
+ "types": "dist/index.d.ts",
11
+ "files": [
12
+ "bin",
13
+ "dist",
14
+ "!dist/**/*.map",
15
+ "!dist/**/*.spec.*",
16
+ "package.json",
17
+ "package-lock.json"
18
+ ],
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "git+https://github.com/mhweiner/hoare.git"
22
+ },
23
+ "scripts": {
24
+ "prepare": "npm run build",
25
+ "test": "npm run build && c8 ./bin/cli.js '@(examples|src)/**/*.spec.@(ts|js)' && c8 report -r text -r html",
26
+ "lint": "eslint ./ --ext .js,.ts",
27
+ "build": "rm -rf ./dist && tsc"
28
+ },
29
+ "homepage": "https://github.com/mhweiner/hoare",
30
+ "keywords": [
31
+ "unit test",
32
+ "ts unit test",
33
+ "typescript unit test",
34
+ "unit-test",
35
+ "mocha",
36
+ "jasmine",
37
+ "jest",
38
+ "tape",
39
+ "ava",
40
+ "node-tap"
41
+ ],
42
+ "dependencies": {
43
+ "deep-object-diff": "^1.1.0",
44
+ "diff": "^5.0.0",
45
+ "kleur": "^4.1.4",
46
+ "ora": "^5.4.1",
47
+ "serialize-error": "^8.1.0",
48
+ "tiny-glob": "^0.2.9"
49
+ },
50
+ "devDependencies": {
51
+ "@types/diff": "^5.0.1",
52
+ "@types/node": "^16.11.6",
53
+ "@typescript-eslint/eslint-plugin": "^5.2.0",
54
+ "@typescript-eslint/parser": "^5.2.0",
55
+ "c8": "^7.10.0",
56
+ "cjs-mock": "^0.1.0",
57
+ "eslint": "^8.1.0",
58
+ "ts-node": "^10.9.2",
59
+ "typescript": "^5.5.2"
60
+ }
61
+ }