@augment-vir/test 30.3.0 → 30.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/augments/universal-testing-suite/it-cases.d.ts +98 -0
- package/dist/augments/universal-testing-suite/it-cases.js +39 -0
- package/dist/augments/universal-testing-suite/mocha-types.d.ts +76 -0
- package/dist/augments/universal-testing-suite/mocha-types.js +6 -0
- package/dist/augments/universal-testing-suite/snapshot-cases.d.ts +49 -0
- package/dist/augments/universal-testing-suite/snapshot-cases.js +75 -0
- package/dist/augments/universal-testing-suite/universal-it.js +25 -8
- package/dist/augments/universal-testing-suite/universal-snapshot.d.ts +25 -0
- package/dist/augments/universal-testing-suite/universal-snapshot.js +90 -0
- package/dist/augments/universal-testing-suite/universal-test-context.d.ts +10 -15
- package/dist/augments/universal-testing-suite/universal-test-context.js +4 -3
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/package.json +11 -10
- package/dist/mocha-types.d.ts +0 -73
- package/dist/mocha-types.js +0 -26
|
@@ -44,5 +44,103 @@ export type FunctionTestCaseMultipleInputs<FunctionToTest extends AnyFunction> =
|
|
|
44
44
|
* @package [`@augment-vir/test`](https://www.npmjs.com/package/@augment-vir/test)
|
|
45
45
|
*/
|
|
46
46
|
export type FunctionTestCase<FunctionToTest extends AnyFunction> = 1 extends Parameters<FunctionToTest>['length'] ? Parameters<FunctionToTest>['length'] extends 0 | 1 ? FunctionTestCaseSingleInput<FunctionToTest> : FunctionTestCaseMultipleInputs<FunctionToTest> : 0 extends Parameters<FunctionToTest>['length'] ? BaseTestCase<Awaited<ReturnType<FunctionToTest>>> : FunctionTestCaseMultipleInputs<FunctionToTest>;
|
|
47
|
+
/**
|
|
48
|
+
* Succinctly run many input / output tests for a pure function without repeating `it` boilerplate.
|
|
49
|
+
* Compatible with both [Node.js's test runner](https://nodejs.org/api/test.html) and
|
|
50
|
+
* [web-test-runner](https://modern-web.dev/docs/test-runner/overview/) or other Mocha-style test
|
|
51
|
+
* runners.
|
|
52
|
+
*
|
|
53
|
+
* @category Test
|
|
54
|
+
* @category Package : @augment-vir/test
|
|
55
|
+
* @example
|
|
56
|
+
*
|
|
57
|
+
* ```ts
|
|
58
|
+
* import {itCases, describe} from '@augment-vir/test';
|
|
59
|
+
*
|
|
60
|
+
* function myFunctionToTest(a: number, b: number) {
|
|
61
|
+
* return a + b;
|
|
62
|
+
* }
|
|
63
|
+
*
|
|
64
|
+
* describe(myFunctionToTest.name, () => {
|
|
65
|
+
* itCases(myFunctionToTest, [
|
|
66
|
+
* {
|
|
67
|
+
* it: 'handles negative numbers',
|
|
68
|
+
* inputs: [
|
|
69
|
+
* -1,
|
|
70
|
+
* -2,
|
|
71
|
+
* ],
|
|
72
|
+
* expect: -3,
|
|
73
|
+
* },
|
|
74
|
+
* {
|
|
75
|
+
* it: 'handles 0',
|
|
76
|
+
* inputs: [
|
|
77
|
+
* 0,
|
|
78
|
+
* 0,
|
|
79
|
+
* ],
|
|
80
|
+
* expect: 0,
|
|
81
|
+
* },
|
|
82
|
+
* {
|
|
83
|
+
* it: 'adds',
|
|
84
|
+
* inputs: [
|
|
85
|
+
* 3,
|
|
86
|
+
* 5,
|
|
87
|
+
* ],
|
|
88
|
+
* expect: 8,
|
|
89
|
+
* },
|
|
90
|
+
* ]);
|
|
91
|
+
* });
|
|
92
|
+
* ```
|
|
93
|
+
*
|
|
94
|
+
* @package [`@augment-vir/test`](https://www.npmjs.com/package/@augment-vir/test)
|
|
95
|
+
*/
|
|
47
96
|
export declare function itCases<const FunctionToTest extends AnyFunction>(functionToTest: FunctionToTest, customAsserter: CustomOutputAsserter<NoInfer<FunctionToTest>>, testCases: ReadonlyArray<FunctionTestCase<NoInfer<FunctionToTest>>>): unknown[];
|
|
97
|
+
/**
|
|
98
|
+
* Succinctly run many input / output tests for a pure function without repeating `it` boilerplate.
|
|
99
|
+
* Compatible with both [Node.js's test runner](https://nodejs.org/api/test.html) and
|
|
100
|
+
* [web-test-runner](https://modern-web.dev/docs/test-runner/overview/) or other Mocha-style test
|
|
101
|
+
* runners.
|
|
102
|
+
*
|
|
103
|
+
* @category Test
|
|
104
|
+
* @category Package : @augment-vir/test
|
|
105
|
+
* @example
|
|
106
|
+
*
|
|
107
|
+
* ```ts
|
|
108
|
+
* import {itCases, describe} from '@augment-vir/test';
|
|
109
|
+
*
|
|
110
|
+
* function myFunctionToTest(a: number, b: number) {
|
|
111
|
+
* return a + b;
|
|
112
|
+
* }
|
|
113
|
+
*
|
|
114
|
+
* describe(myFunctionToTest.name, () => {
|
|
115
|
+
* itCases(myFunctionToTest, [
|
|
116
|
+
* {
|
|
117
|
+
* it: 'handles negative numbers',
|
|
118
|
+
* inputs: [
|
|
119
|
+
* -1,
|
|
120
|
+
* -2,
|
|
121
|
+
* ],
|
|
122
|
+
* expect: -3,
|
|
123
|
+
* },
|
|
124
|
+
* {
|
|
125
|
+
* it: 'handles 0',
|
|
126
|
+
* inputs: [
|
|
127
|
+
* 0,
|
|
128
|
+
* 0,
|
|
129
|
+
* ],
|
|
130
|
+
* expect: 0,
|
|
131
|
+
* },
|
|
132
|
+
* {
|
|
133
|
+
* it: 'adds',
|
|
134
|
+
* inputs: [
|
|
135
|
+
* 3,
|
|
136
|
+
* 5,
|
|
137
|
+
* ],
|
|
138
|
+
* expect: 8,
|
|
139
|
+
* },
|
|
140
|
+
* ]);
|
|
141
|
+
* });
|
|
142
|
+
* ```
|
|
143
|
+
*
|
|
144
|
+
* @package [`@augment-vir/test`](https://www.npmjs.com/package/@augment-vir/test)
|
|
145
|
+
*/
|
|
48
146
|
export declare function itCases<const FunctionToTest extends AnyFunction>(functionToTest: FunctionToTest, testCases: ReadonlyArray<FunctionTestCase<NoInfer<FunctionToTest>>>): unknown[];
|
|
@@ -10,6 +10,45 @@ const unsetError = Symbol('unset-error');
|
|
|
10
10
|
*
|
|
11
11
|
* @category Test
|
|
12
12
|
* @category Package : @augment-vir/test
|
|
13
|
+
* @example
|
|
14
|
+
*
|
|
15
|
+
* ```ts
|
|
16
|
+
* import {itCases, describe} from '@augment-vir/test';
|
|
17
|
+
*
|
|
18
|
+
* function myFunctionToTest(a: number, b: number) {
|
|
19
|
+
* return a + b;
|
|
20
|
+
* }
|
|
21
|
+
*
|
|
22
|
+
* describe(myFunctionToTest.name, () => {
|
|
23
|
+
* itCases(myFunctionToTest, [
|
|
24
|
+
* {
|
|
25
|
+
* it: 'handles negative numbers',
|
|
26
|
+
* inputs: [
|
|
27
|
+
* -1,
|
|
28
|
+
* -2,
|
|
29
|
+
* ],
|
|
30
|
+
* expect: -3,
|
|
31
|
+
* },
|
|
32
|
+
* {
|
|
33
|
+
* it: 'handles 0',
|
|
34
|
+
* inputs: [
|
|
35
|
+
* 0,
|
|
36
|
+
* 0,
|
|
37
|
+
* ],
|
|
38
|
+
* expect: 0,
|
|
39
|
+
* },
|
|
40
|
+
* {
|
|
41
|
+
* it: 'adds',
|
|
42
|
+
* inputs: [
|
|
43
|
+
* 3,
|
|
44
|
+
* 5,
|
|
45
|
+
* ],
|
|
46
|
+
* expect: 8,
|
|
47
|
+
* },
|
|
48
|
+
* ]);
|
|
49
|
+
* });
|
|
50
|
+
* ```
|
|
51
|
+
*
|
|
13
52
|
* @package [`@augment-vir/test`](https://www.npmjs.com/package/@augment-vir/test)
|
|
14
53
|
*/
|
|
15
54
|
export function itCases(functionToTest, testCasesOrCustomAsserter, maybeTestCases) {
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* These types have all been deduced from local testing, as Mocha's types aren't accurate. Only
|
|
3
|
+
* properties that make sense are included. (Lots of actual properties on these types are
|
|
4
|
+
* misleadingly named. Those have been omitted.)
|
|
5
|
+
*/
|
|
6
|
+
import type { AnyFunction } from '@augment-vir/common';
|
|
7
|
+
/**
|
|
8
|
+
* Any Mocha context node inside {@link MochaTestContext}.
|
|
9
|
+
*
|
|
10
|
+
* @category Test : Util
|
|
11
|
+
* @category Package : @augment-vir/test
|
|
12
|
+
* @package [`@augment-vir/test`](https://www.npmjs.com/package/@augment-vir/test)
|
|
13
|
+
*/
|
|
14
|
+
export type MochaNode = MochaSuite | MochaTest | MochaRoot;
|
|
15
|
+
/**
|
|
16
|
+
* The root context inside {@link MochaTestContext}.
|
|
17
|
+
*
|
|
18
|
+
* @category Test : Util
|
|
19
|
+
* @category Package : @augment-vir/test
|
|
20
|
+
* @package [`@augment-vir/test`](https://www.npmjs.com/package/@augment-vir/test)
|
|
21
|
+
*/
|
|
22
|
+
export type MochaRoot = {
|
|
23
|
+
title: '';
|
|
24
|
+
root: true;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* An individual test suite inside {@link MochaTestContext}.
|
|
28
|
+
*
|
|
29
|
+
* @category Test : Util
|
|
30
|
+
* @category Package : @augment-vir/test
|
|
31
|
+
* @package [`@augment-vir/test`](https://www.npmjs.com/package/@augment-vir/test)
|
|
32
|
+
*/
|
|
33
|
+
export type MochaSuite = {
|
|
34
|
+
title: string;
|
|
35
|
+
root: false;
|
|
36
|
+
ctx: {
|
|
37
|
+
test: MochaTest;
|
|
38
|
+
};
|
|
39
|
+
suites: MochaSuite[];
|
|
40
|
+
tests: MochaSuite[];
|
|
41
|
+
parent: MochaNode;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* An individual test context inside {@link MochaTestContext}.
|
|
45
|
+
*
|
|
46
|
+
* @category Test : Util
|
|
47
|
+
* @category Package : @augment-vir/test
|
|
48
|
+
* @package [`@augment-vir/test`](https://www.npmjs.com/package/@augment-vir/test)
|
|
49
|
+
*/
|
|
50
|
+
export type MochaTest = {
|
|
51
|
+
type: 'test';
|
|
52
|
+
/** The current test name. */
|
|
53
|
+
title: string;
|
|
54
|
+
/** The current test callback. */
|
|
55
|
+
fn: AnyFunction;
|
|
56
|
+
id: string;
|
|
57
|
+
parent: MochaNode;
|
|
58
|
+
ctx: {
|
|
59
|
+
test: MochaTest;
|
|
60
|
+
};
|
|
61
|
+
root?: undefined;
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* The test context for [web-test-runner](https://modern-web.dev/docs/test-runner/overview/) or
|
|
65
|
+
* other Mocha-style test runners.
|
|
66
|
+
*
|
|
67
|
+
* @category Test : Util
|
|
68
|
+
* @category Package : @augment-vir/test
|
|
69
|
+
* @package [`@augment-vir/test`](https://www.npmjs.com/package/@augment-vir/test)
|
|
70
|
+
*/
|
|
71
|
+
export type MochaTestContext = Readonly<{
|
|
72
|
+
test: MochaTest;
|
|
73
|
+
}> & {
|
|
74
|
+
/** Added for use by `assertSnapshot`. */
|
|
75
|
+
snapshotCount?: number;
|
|
76
|
+
};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { AnyFunction } from '@augment-vir/core';
|
|
2
|
+
import { type FunctionTestCase } from './it-cases.js';
|
|
3
|
+
/**
|
|
4
|
+
* Similar to `itCases` but instead of defining expectation in each test case, each test case is a
|
|
5
|
+
* snapshot test.
|
|
6
|
+
*
|
|
7
|
+
* In order to generate or update the snapshot files, run tests in update mode.
|
|
8
|
+
*
|
|
9
|
+
* @category Test
|
|
10
|
+
* @category Package : @augment-vir/test
|
|
11
|
+
* @example
|
|
12
|
+
*
|
|
13
|
+
* ```ts
|
|
14
|
+
* import {snapshotCases, describe} from '@augment-vir/test';
|
|
15
|
+
*
|
|
16
|
+
* function myFunctionToTest(a: number, b: number) {
|
|
17
|
+
* return a + b;
|
|
18
|
+
* }
|
|
19
|
+
*
|
|
20
|
+
* describe(myFunctionToTest.name, () => {
|
|
21
|
+
* snapshotCases(myFunctionToTest, [
|
|
22
|
+
* {
|
|
23
|
+
* it: 'handles negative numbers',
|
|
24
|
+
* inputs: [
|
|
25
|
+
* -1,
|
|
26
|
+
* -2,
|
|
27
|
+
* ],
|
|
28
|
+
* },
|
|
29
|
+
* {
|
|
30
|
+
* it: 'handles 0',
|
|
31
|
+
* inputs: [
|
|
32
|
+
* 0,
|
|
33
|
+
* 0,
|
|
34
|
+
* ],
|
|
35
|
+
* },
|
|
36
|
+
* {
|
|
37
|
+
* it: 'adds',
|
|
38
|
+
* inputs: [
|
|
39
|
+
* 3,
|
|
40
|
+
* 5,
|
|
41
|
+
* ],
|
|
42
|
+
* },
|
|
43
|
+
* ]);
|
|
44
|
+
* });
|
|
45
|
+
* ```
|
|
46
|
+
*
|
|
47
|
+
* @package [`@augment-vir/test`](https://www.npmjs.com/package/@augment-vir/test)
|
|
48
|
+
*/
|
|
49
|
+
export declare function snapshotCases<const FunctionToTest extends AnyFunction>(functionToTest: FunctionToTest, testCases: ReadonlyArray<Omit<FunctionTestCase<NoInfer<FunctionToTest>>, 'expect' | 'throws'>>): void[];
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { wrapInTry } from '@augment-vir/common';
|
|
2
|
+
import { ensureError, extractErrorMessage } from '@augment-vir/core';
|
|
3
|
+
import { it } from './universal-it.js';
|
|
4
|
+
import { assertSnapshot } from './universal-snapshot.js';
|
|
5
|
+
/**
|
|
6
|
+
* Similar to `itCases` but instead of defining expectation in each test case, each test case is a
|
|
7
|
+
* snapshot test.
|
|
8
|
+
*
|
|
9
|
+
* In order to generate or update the snapshot files, run tests in update mode.
|
|
10
|
+
*
|
|
11
|
+
* @category Test
|
|
12
|
+
* @category Package : @augment-vir/test
|
|
13
|
+
* @example
|
|
14
|
+
*
|
|
15
|
+
* ```ts
|
|
16
|
+
* import {snapshotCases, describe} from '@augment-vir/test';
|
|
17
|
+
*
|
|
18
|
+
* function myFunctionToTest(a: number, b: number) {
|
|
19
|
+
* return a + b;
|
|
20
|
+
* }
|
|
21
|
+
*
|
|
22
|
+
* describe(myFunctionToTest.name, () => {
|
|
23
|
+
* snapshotCases(myFunctionToTest, [
|
|
24
|
+
* {
|
|
25
|
+
* it: 'handles negative numbers',
|
|
26
|
+
* inputs: [
|
|
27
|
+
* -1,
|
|
28
|
+
* -2,
|
|
29
|
+
* ],
|
|
30
|
+
* },
|
|
31
|
+
* {
|
|
32
|
+
* it: 'handles 0',
|
|
33
|
+
* inputs: [
|
|
34
|
+
* 0,
|
|
35
|
+
* 0,
|
|
36
|
+
* ],
|
|
37
|
+
* },
|
|
38
|
+
* {
|
|
39
|
+
* it: 'adds',
|
|
40
|
+
* inputs: [
|
|
41
|
+
* 3,
|
|
42
|
+
* 5,
|
|
43
|
+
* ],
|
|
44
|
+
* },
|
|
45
|
+
* ]);
|
|
46
|
+
* });
|
|
47
|
+
* ```
|
|
48
|
+
*
|
|
49
|
+
* @package [`@augment-vir/test`](https://www.npmjs.com/package/@augment-vir/test)
|
|
50
|
+
*/
|
|
51
|
+
export function snapshotCases(functionToTest, testCases) {
|
|
52
|
+
return testCases.map((testCase) => {
|
|
53
|
+
const itFunction = testCase.only ? it.only : testCase.skip ? it.skip : it;
|
|
54
|
+
return itFunction(testCase.it, async (testContext) => {
|
|
55
|
+
const functionInputs = 'input' in testCase
|
|
56
|
+
? [testCase.input]
|
|
57
|
+
: 'inputs' in testCase
|
|
58
|
+
? testCase.inputs
|
|
59
|
+
: // as cast here to cover the case where the input has NO inputs
|
|
60
|
+
[];
|
|
61
|
+
const snapshotData = await wrapInTry(async () => {
|
|
62
|
+
return await functionToTest(...functionInputs);
|
|
63
|
+
}, {
|
|
64
|
+
handleError(caught) {
|
|
65
|
+
const error = ensureError(caught);
|
|
66
|
+
const errorClassName = error.constructor.name;
|
|
67
|
+
return {
|
|
68
|
+
[errorClassName]: extractErrorMessage(error),
|
|
69
|
+
};
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
await assertSnapshot(testContext, snapshotData);
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
}
|
|
@@ -1,11 +1,26 @@
|
|
|
1
1
|
import { isRuntimeEnv, RuntimeEnv } from '@augment-vir/core';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
}
|
|
2
|
+
function createWebIt() {
|
|
3
|
+
const webIt = Object.assign((doesThis, callback) => {
|
|
4
|
+
return globalThis.it(doesThis, async function () {
|
|
5
|
+
const context = this;
|
|
6
|
+
await callback(context);
|
|
7
|
+
});
|
|
8
|
+
}, {
|
|
9
|
+
skip: (doesThis, callback) => {
|
|
10
|
+
return globalThis.it.skip(doesThis, async function () {
|
|
11
|
+
const context = this;
|
|
12
|
+
await callback(context);
|
|
13
|
+
});
|
|
14
|
+
},
|
|
15
|
+
only: (doesThis, callback) => {
|
|
16
|
+
return globalThis.it.only(doesThis, async function () {
|
|
17
|
+
const context = this;
|
|
18
|
+
await callback(context);
|
|
19
|
+
});
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
return webIt;
|
|
23
|
+
}
|
|
9
24
|
/**
|
|
10
25
|
* A single test declaration. This can be used in both web tests _and_ node tests, so you only have
|
|
11
26
|
* import from a single place and learn a single interface.
|
|
@@ -34,4 +49,6 @@ const its = isRuntimeEnv(RuntimeEnv.Node)
|
|
|
34
49
|
*
|
|
35
50
|
* @package [`@augment-vir/test`](https://www.npmjs.com/package/@augment-vir/test)
|
|
36
51
|
*/
|
|
37
|
-
export const it =
|
|
52
|
+
export const it = isRuntimeEnv(RuntimeEnv.Node)
|
|
53
|
+
? (await import('node:test')).it
|
|
54
|
+
: createWebIt();
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { UniversalTestContext } from './universal-test-context.js';
|
|
2
|
+
/**
|
|
3
|
+
* An error that is thrown from {@link assertSnapshot} when the snapshot comparison fails due to the
|
|
4
|
+
* snapshot expectation file simply not existing.
|
|
5
|
+
*
|
|
6
|
+
* @category Test : Util
|
|
7
|
+
* @category Package : @augment-vir/test
|
|
8
|
+
* @package [`@augment-vir/test`](https://www.npmjs.com/package/@augment-vir/test)
|
|
9
|
+
*/
|
|
10
|
+
export declare class SnapshotFileMissingError extends Error {
|
|
11
|
+
constructor(testName: string);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Assert that the given snapshot data matches already-saved snapshot file's expectations. Note that
|
|
15
|
+
* the given data will be serialized into a JSON string if it is not already a string. This works in
|
|
16
|
+
* both Node and web tests.
|
|
17
|
+
*
|
|
18
|
+
* Web tests require a web-test-runner config with the `snapshotPlugin` plugin from
|
|
19
|
+
* `@virmator/test/dist/web-snapshot-plugin/web-snapshot-plugin.js` in order to work.
|
|
20
|
+
*
|
|
21
|
+
* @category Test
|
|
22
|
+
* @category Package : @augment-vir/test
|
|
23
|
+
* @package [`@augment-vir/test`](https://www.npmjs.com/package/@augment-vir/test)
|
|
24
|
+
*/
|
|
25
|
+
export declare function assertSnapshot(testContext: UniversalTestContext, data: unknown): Promise<void>;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { check } from '@augment-vir/assert';
|
|
2
|
+
import { extractErrorMessage, log, RuntimeEnv } from '@augment-vir/common';
|
|
3
|
+
import { SnapshotCommand, } from '@virmator/test/dist/web-snapshot-plugin/snapshot-payload.js';
|
|
4
|
+
import { isTestContext } from './universal-test-context.js';
|
|
5
|
+
/**
|
|
6
|
+
* An error that is thrown from {@link assertSnapshot} when the snapshot comparison fails due to the
|
|
7
|
+
* snapshot expectation file simply not existing.
|
|
8
|
+
*
|
|
9
|
+
* @category Test : Util
|
|
10
|
+
* @category Package : @augment-vir/test
|
|
11
|
+
* @package [`@augment-vir/test`](https://www.npmjs.com/package/@augment-vir/test)
|
|
12
|
+
*/
|
|
13
|
+
export class SnapshotFileMissingError extends Error {
|
|
14
|
+
constructor(testName) {
|
|
15
|
+
super(`Missing snapshot file for test '${testName}'.\n\nRun tests in update mode to create the snapshot file.`);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Assert that the given snapshot data matches already-saved snapshot file's expectations. Note that
|
|
20
|
+
* the given data will be serialized into a JSON string if it is not already a string. This works in
|
|
21
|
+
* both Node and web tests.
|
|
22
|
+
*
|
|
23
|
+
* Web tests require a web-test-runner config with the `snapshotPlugin` plugin from
|
|
24
|
+
* `@virmator/test/dist/web-snapshot-plugin/web-snapshot-plugin.js` in order to work.
|
|
25
|
+
*
|
|
26
|
+
* @category Test
|
|
27
|
+
* @category Package : @augment-vir/test
|
|
28
|
+
* @package [`@augment-vir/test`](https://www.npmjs.com/package/@augment-vir/test)
|
|
29
|
+
*/
|
|
30
|
+
export async function assertSnapshot(testContext, data) {
|
|
31
|
+
const { snapshotName, testName } = getTestName(testContext);
|
|
32
|
+
const serializedData = check.isString(data) ? data : JSON.stringify(data);
|
|
33
|
+
if (isTestContext(testContext, RuntimeEnv.Node)) {
|
|
34
|
+
try {
|
|
35
|
+
testContext.snapshotCount = testContext.snapshotCount
|
|
36
|
+
? testContext.snapshotCount + 1
|
|
37
|
+
: 1;
|
|
38
|
+
testContext.assert.snapshot(serializedData);
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
if (extractErrorMessage(error).includes('Cannot read snapshot file')) {
|
|
42
|
+
throw new SnapshotFileMissingError(testName);
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
throw error;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
const { executeServerCommand } = await import('@web/test-runner-commands');
|
|
51
|
+
const result = await executeServerCommand(SnapshotCommand.CompareSnapshot, {
|
|
52
|
+
content: serializedData,
|
|
53
|
+
name: snapshotName,
|
|
54
|
+
});
|
|
55
|
+
if (result.updated) {
|
|
56
|
+
log.info(`Snapshot updated at '${result.snapshotPath}'`);
|
|
57
|
+
}
|
|
58
|
+
else if (!result.exists) {
|
|
59
|
+
throw new SnapshotFileMissingError(testName);
|
|
60
|
+
}
|
|
61
|
+
else if (!result.matches) {
|
|
62
|
+
throw new Error(`Snapshot mismatch at '${testName}':\n\nActual: ${serializedData}\n\nExpected: ${result.savedContent}\n`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
function flattenMochaParentTitles(node) {
|
|
67
|
+
if (node.root) {
|
|
68
|
+
return [];
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
return [
|
|
72
|
+
...flattenMochaParentTitles(node.parent),
|
|
73
|
+
node.title,
|
|
74
|
+
];
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
function getTestName(testContext) {
|
|
78
|
+
const testName = isTestContext(testContext, RuntimeEnv.Node)
|
|
79
|
+
? testContext.fullName
|
|
80
|
+
: flattenMochaParentTitles(testContext.test).join(' > ');
|
|
81
|
+
testContext.snapshotCount = testContext.snapshotCount ? testContext.snapshotCount + 1 : 1;
|
|
82
|
+
const snapshotName = [
|
|
83
|
+
testName,
|
|
84
|
+
testContext.snapshotCount,
|
|
85
|
+
].join(' ');
|
|
86
|
+
return {
|
|
87
|
+
snapshotName,
|
|
88
|
+
testName,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
@@ -1,15 +1,6 @@
|
|
|
1
1
|
import { RuntimeEnv } from '@augment-vir/core';
|
|
2
2
|
import { TestContext as NodeTestContextImport } from 'node:test';
|
|
3
|
-
import
|
|
4
|
-
/**
|
|
5
|
-
* The test context for [web-test-runner](https://modern-web.dev/docs/test-runner/overview/) or
|
|
6
|
-
* other Mocha-style test runners.
|
|
7
|
-
*
|
|
8
|
-
* @category Test : Util
|
|
9
|
-
* @category Package : @augment-vir/test
|
|
10
|
-
* @package [`@augment-vir/test`](https://www.npmjs.com/package/@augment-vir/test)
|
|
11
|
-
*/
|
|
12
|
-
export type MochaTestContext = MochaContext;
|
|
3
|
+
import { MochaTestContext } from './mocha-types.js';
|
|
13
4
|
/**
|
|
14
5
|
* The test context for [Node.js's test runner](https://nodejs.org/api/test.html).
|
|
15
6
|
*
|
|
@@ -17,7 +8,10 @@ export type MochaTestContext = MochaContext;
|
|
|
17
8
|
* @category Package : @augment-vir/test
|
|
18
9
|
* @package [`@augment-vir/test`](https://www.npmjs.com/package/@augment-vir/test)
|
|
19
10
|
*/
|
|
20
|
-
export type NodeTestContext = NodeTestContextImport
|
|
11
|
+
export type NodeTestContext = Readonly<NodeTestContextImport> & {
|
|
12
|
+
/** Added for use by `assertSnapshot`. */
|
|
13
|
+
snapshotCount?: number;
|
|
14
|
+
};
|
|
21
15
|
/**
|
|
22
16
|
* Test context provided by `it`'s callback.
|
|
23
17
|
*
|
|
@@ -41,16 +35,17 @@ export type UniversalTestContext = NodeTestContext | MochaTestContext;
|
|
|
41
35
|
*/
|
|
42
36
|
export type ContextByEnv = {
|
|
43
37
|
[RuntimeEnv.Node]: NodeTestContext;
|
|
44
|
-
[RuntimeEnv.Web]:
|
|
38
|
+
[RuntimeEnv.Web]: MochaTestContext;
|
|
45
39
|
};
|
|
46
40
|
/**
|
|
47
|
-
*
|
|
41
|
+
* Asserts that the given context is for the given env and returns that context.
|
|
48
42
|
*
|
|
49
43
|
* @category Test : Util
|
|
50
44
|
* @category Package : @augment-vir/test
|
|
45
|
+
* @throws `TypeError` if the context does not match the env.
|
|
51
46
|
* @package [`@augment-vir/test`](https://www.npmjs.com/package/@augment-vir/test)
|
|
52
47
|
*/
|
|
53
|
-
export declare function
|
|
48
|
+
export declare function assertWrapTestContext<const SpecificEnv extends RuntimeEnv>(context: UniversalTestContext, env: RuntimeEnv): ContextByEnv[SpecificEnv];
|
|
54
49
|
/**
|
|
55
50
|
* Asserts that the given context is for the given env, otherwise throws an Error.
|
|
56
51
|
*
|
|
@@ -66,7 +61,7 @@ export declare function assertTestContext<const SpecificEnv extends RuntimeEnv>(
|
|
|
66
61
|
* @category Package : @augment-vir/test
|
|
67
62
|
* @package [`@augment-vir/test`](https://www.npmjs.com/package/@augment-vir/test)
|
|
68
63
|
*/
|
|
69
|
-
export declare function isTestContext<const SpecificEnv extends RuntimeEnv>(context: UniversalTestContext, env:
|
|
64
|
+
export declare function isTestContext<const SpecificEnv extends RuntimeEnv>(context: UniversalTestContext, env: SpecificEnv): context is ContextByEnv[SpecificEnv];
|
|
70
65
|
/**
|
|
71
66
|
* Determine the env for the given test context.
|
|
72
67
|
*
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { RuntimeEnv } from '@augment-vir/core';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Asserts that the given context is for the given env and returns that context.
|
|
4
4
|
*
|
|
5
5
|
* @category Test : Util
|
|
6
6
|
* @category Package : @augment-vir/test
|
|
7
|
+
* @throws `TypeError` if the context does not match the env.
|
|
7
8
|
* @package [`@augment-vir/test`](https://www.npmjs.com/package/@augment-vir/test)
|
|
8
9
|
*/
|
|
9
|
-
export function
|
|
10
|
+
export function assertWrapTestContext(context, env) {
|
|
10
11
|
assertTestContext(context, env);
|
|
11
12
|
return context;
|
|
12
13
|
}
|
|
@@ -48,5 +49,5 @@ const nodeOnlyCheckKey = 'diagnostic';
|
|
|
48
49
|
* @package [`@augment-vir/test`](https://www.npmjs.com/package/@augment-vir/test)
|
|
49
50
|
*/
|
|
50
51
|
export function determineTestContextEnv(context) {
|
|
51
|
-
return
|
|
52
|
+
return nodeOnlyCheckKey in context ? RuntimeEnv.Node : RuntimeEnv.Web;
|
|
52
53
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
export * from './augments/test-web.js';
|
|
2
2
|
export * from './augments/universal-testing-suite/it-cases.js';
|
|
3
|
+
export * from './augments/universal-testing-suite/mocha-types.js';
|
|
4
|
+
export * from './augments/universal-testing-suite/snapshot-cases.js';
|
|
3
5
|
export * from './augments/universal-testing-suite/universal-describe.js';
|
|
4
6
|
export * from './augments/universal-testing-suite/universal-it.js';
|
|
7
|
+
export * from './augments/universal-testing-suite/universal-snapshot.js';
|
|
5
8
|
export * from './augments/universal-testing-suite/universal-test-context.js';
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
export * from './augments/test-web.js';
|
|
2
2
|
export * from './augments/universal-testing-suite/it-cases.js';
|
|
3
|
+
export * from './augments/universal-testing-suite/mocha-types.js';
|
|
4
|
+
export * from './augments/universal-testing-suite/snapshot-cases.js';
|
|
3
5
|
export * from './augments/universal-testing-suite/universal-describe.js';
|
|
4
6
|
export * from './augments/universal-testing-suite/universal-it.js';
|
|
7
|
+
export * from './augments/universal-testing-suite/universal-snapshot.js';
|
|
5
8
|
export * from './augments/universal-testing-suite/universal-test-context.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@augment-vir/test",
|
|
3
|
-
"version": "30.
|
|
3
|
+
"version": "30.5.0",
|
|
4
4
|
"description": "A universal testing suite that works with Mocha style test runners _and_ Node.js's built-in test runner.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"test",
|
|
@@ -39,24 +39,25 @@
|
|
|
39
39
|
"test:coverage": "npm run test",
|
|
40
40
|
"test:node": "virmator test --no-deps node 'src/augments/universal-testing-suite/**/*.test.ts'",
|
|
41
41
|
"test:update": "npm test",
|
|
42
|
-
"test:web": "virmator test --no-deps web 'src/test-web/**/*.test.ts'"
|
|
42
|
+
"test:web": "virmator test --no-deps web 'src/test-web/**/*.test.ts' 'src/augments/universal-testing-suite/**/*.test.ts'"
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@augment-vir/assert": "^30.
|
|
46
|
-
"@augment-vir/common": "^30.
|
|
45
|
+
"@augment-vir/assert": "^30.5.0",
|
|
46
|
+
"@augment-vir/common": "^30.5.0",
|
|
47
47
|
"@open-wc/testing-helpers": "^3.0.1",
|
|
48
|
+
"@virmator/test": "^13.7.0",
|
|
48
49
|
"type-fest": "^4.26.1"
|
|
49
50
|
},
|
|
50
51
|
"devDependencies": {
|
|
51
|
-
"@types/node": "^22.
|
|
52
|
-
"@web/dev-server-esbuild": "^1.0.
|
|
52
|
+
"@types/node": "^22.9.0",
|
|
53
|
+
"@web/dev-server-esbuild": "^1.0.3",
|
|
53
54
|
"@web/test-runner": "^0.19.0",
|
|
54
55
|
"@web/test-runner-commands": "^0.9.0",
|
|
55
56
|
"@web/test-runner-playwright": "^0.11.0",
|
|
56
|
-
"concurrently": "^9.0
|
|
57
|
-
"element-vir": "^
|
|
58
|
-
"istanbul-smart-text-reporter": "^1.1.
|
|
59
|
-
"typescript": "^5.6.
|
|
57
|
+
"concurrently": "^9.1.0",
|
|
58
|
+
"element-vir": "^23.0.0",
|
|
59
|
+
"istanbul-smart-text-reporter": "^1.1.5",
|
|
60
|
+
"typescript": "^5.6.3"
|
|
60
61
|
},
|
|
61
62
|
"engines": {
|
|
62
63
|
"node": ">=22"
|
package/dist/mocha-types.d.ts
DELETED
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Extracted from https://www.npmjs.com/package/@types/mocha/v/10.0.7 with modifications to prevent
|
|
3
|
-
* leakage of global types.
|
|
4
|
-
*
|
|
5
|
-
* The original code has the following license:
|
|
6
|
-
*
|
|
7
|
-
* MIT License
|
|
8
|
-
*
|
|
9
|
-
* Copyright (c) Microsoft Corporation.
|
|
10
|
-
*
|
|
11
|
-
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
|
12
|
-
* associated documentation files (the "Software"), to deal in the Software without restriction,
|
|
13
|
-
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
|
14
|
-
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
|
15
|
-
* furnished to do so, subject to the following conditions:
|
|
16
|
-
*
|
|
17
|
-
* The above copyright notice and this permission notice shall be included in all copies or
|
|
18
|
-
* substantial portions of the Software.
|
|
19
|
-
*
|
|
20
|
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
|
21
|
-
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
22
|
-
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
23
|
-
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
24
|
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
|
|
25
|
-
*/
|
|
26
|
-
interface Runnable extends NodeJS.EventEmitter {
|
|
27
|
-
on(event: 'error', listener: (error: any) => void): this;
|
|
28
|
-
once(event: 'error', listener: (error: any) => void): this;
|
|
29
|
-
addListener(event: 'error', listener: (error: any) => void): this;
|
|
30
|
-
removeListener(event: 'error', listener: (error: any) => void): this;
|
|
31
|
-
prependListener(event: 'error', listener: (error: any) => void): this;
|
|
32
|
-
prependOnceListener(event: 'error', listener: (error: any) => void): this;
|
|
33
|
-
emit(name: 'error', error: any): boolean;
|
|
34
|
-
}
|
|
35
|
-
interface Runnable extends NodeJS.EventEmitter {
|
|
36
|
-
on(event: string, listener: (...args: any[]) => void): this;
|
|
37
|
-
once(event: string, listener: (...args: any[]) => void): this;
|
|
38
|
-
addListener(event: string, listener: (...args: any[]) => void): this;
|
|
39
|
-
removeListener(event: string, listener: (...args: any[]) => void): this;
|
|
40
|
-
prependListener(event: string, listener: (...args: any[]) => void): this;
|
|
41
|
-
prependOnceListener(event: string, listener: (...args: any[]) => void): this;
|
|
42
|
-
emit(name: string, ...args: any[]): boolean;
|
|
43
|
-
}
|
|
44
|
-
interface Test extends Runnable {
|
|
45
|
-
type: 'test';
|
|
46
|
-
speed?: 'slow' | 'medium' | 'fast' | undefined;
|
|
47
|
-
err?: Error | undefined;
|
|
48
|
-
clone(): Test;
|
|
49
|
-
}
|
|
50
|
-
export interface MochaContext {
|
|
51
|
-
test?: Runnable | undefined;
|
|
52
|
-
currentTest?: Test | undefined;
|
|
53
|
-
/** Get the context `Runnable`. */
|
|
54
|
-
runnable(): Runnable;
|
|
55
|
-
/** Set the context `Runnable`. */
|
|
56
|
-
runnable(runnable: Runnable): MochaContext;
|
|
57
|
-
/** Get test timeout. */
|
|
58
|
-
timeout(): number;
|
|
59
|
-
/** Set test timeout. */
|
|
60
|
-
timeout(ms: string | number): MochaContext;
|
|
61
|
-
/** Get test slowness threshold. */
|
|
62
|
-
slow(): number;
|
|
63
|
-
/** Set test slowness threshold. */
|
|
64
|
-
slow(ms: string | number): MochaContext;
|
|
65
|
-
/** Mark a test as skipped. */
|
|
66
|
-
skip(): never;
|
|
67
|
-
/** Get the number of allowed retries on failed tests. */
|
|
68
|
-
retries(): number;
|
|
69
|
-
/** Set the number of allowed retries on failed tests. */
|
|
70
|
-
retries(n: number): MochaContext;
|
|
71
|
-
[key: string]: any;
|
|
72
|
-
}
|
|
73
|
-
export {};
|
package/dist/mocha-types.js
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Extracted from https://www.npmjs.com/package/@types/mocha/v/10.0.7 with modifications to prevent
|
|
3
|
-
* leakage of global types.
|
|
4
|
-
*
|
|
5
|
-
* The original code has the following license:
|
|
6
|
-
*
|
|
7
|
-
* MIT License
|
|
8
|
-
*
|
|
9
|
-
* Copyright (c) Microsoft Corporation.
|
|
10
|
-
*
|
|
11
|
-
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
|
12
|
-
* associated documentation files (the "Software"), to deal in the Software without restriction,
|
|
13
|
-
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
|
14
|
-
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
|
15
|
-
* furnished to do so, subject to the following conditions:
|
|
16
|
-
*
|
|
17
|
-
* The above copyright notice and this permission notice shall be included in all copies or
|
|
18
|
-
* substantial portions of the Software.
|
|
19
|
-
*
|
|
20
|
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
|
21
|
-
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
22
|
-
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
23
|
-
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
24
|
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
|
|
25
|
-
*/
|
|
26
|
-
export {};
|