track-cli 4.0.3 → 4.1.0-rc2
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/esm/_dnt.shims.d.ts +1 -1
- package/esm/_dnt.test_shims.d.ts +20 -0
- package/esm/_dnt.test_shims.js +77 -0
- package/esm/deps/deno.land/std@0.195.0/_util/diff.d.ts +26 -0
- package/esm/deps/deno.land/std@0.195.0/_util/diff.js +311 -0
- package/esm/deps/deno.land/std@0.195.0/assert/_constants.d.ts +1 -0
- package/esm/deps/deno.land/std@0.195.0/assert/_constants.js +2 -0
- package/esm/deps/deno.land/std@0.195.0/assert/_format.d.ts +1 -0
- package/esm/deps/deno.land/std@0.195.0/assert/_format.js +23 -0
- package/esm/deps/deno.land/std@0.195.0/assert/assert_almost_equals.d.ts +18 -0
- package/esm/deps/deno.land/std@0.195.0/assert/assert_almost_equals.js +32 -0
- package/esm/deps/deno.land/std@0.195.0/assert/assert_array_includes.d.ts +14 -0
- package/esm/deps/deno.land/std@0.195.0/assert/assert_array_includes.js +38 -0
- package/esm/deps/deno.land/std@0.195.0/assert/assert_equals.d.ts +17 -0
- package/esm/deps/deno.land/std@0.195.0/assert/assert_equals.js +45 -0
- package/esm/deps/deno.land/std@0.195.0/assert/assert_exists.d.ts +5 -0
- package/esm/deps/deno.land/std@0.195.0/assert/assert_exists.js +14 -0
- package/esm/deps/deno.land/std@0.195.0/assert/assert_false.d.ts +4 -0
- package/esm/deps/deno.land/std@0.195.0/assert/assert_false.js +7 -0
- package/esm/deps/deno.land/std@0.195.0/assert/assert_instance_of.d.ts +8 -0
- package/esm/deps/deno.land/std@0.195.0/assert/assert_instance_of.js +38 -0
- package/esm/deps/deno.land/std@0.195.0/assert/assert_is_error.d.ts +7 -0
- package/esm/deps/deno.land/std@0.195.0/assert/assert_is_error.js +26 -0
- package/esm/deps/deno.land/std@0.195.0/assert/assert_match.d.ts +5 -0
- package/esm/deps/deno.land/std@0.195.0/assert/assert_match.js +13 -0
- package/esm/deps/deno.land/std@0.195.0/assert/assert_not_equals.d.ts +14 -0
- package/esm/deps/deno.land/std@0.195.0/assert/assert_not_equals.js +37 -0
- package/esm/deps/deno.land/std@0.195.0/assert/assert_not_instance_of.d.ts +5 -0
- package/esm/deps/deno.land/std@0.195.0/assert/assert_not_instance_of.js +14 -0
- package/esm/deps/deno.land/std@0.195.0/assert/assert_not_match.d.ts +5 -0
- package/esm/deps/deno.land/std@0.195.0/assert/assert_not_match.js +14 -0
- package/esm/deps/deno.land/std@0.195.0/assert/assert_not_strict_equals.d.ts +11 -0
- package/esm/deps/deno.land/std@0.195.0/assert/assert_not_strict_equals.js +20 -0
- package/esm/deps/deno.land/std@0.195.0/assert/assert_object_match.d.ts +5 -0
- package/esm/deps/deno.land/std@0.195.0/assert/assert_object_match.js +78 -0
- package/esm/deps/deno.land/std@0.195.0/assert/assert_rejects.d.ts +64 -0
- package/esm/deps/deno.land/std@0.195.0/assert/assert_rejects.js +50 -0
- package/esm/deps/deno.land/std@0.195.0/assert/assert_strict_equals.d.ts +23 -0
- package/esm/deps/deno.land/std@0.195.0/assert/assert_strict_equals.js +60 -0
- package/esm/deps/deno.land/std@0.195.0/assert/assert_string_includes.d.ts +5 -0
- package/esm/deps/deno.land/std@0.195.0/assert/assert_string_includes.js +13 -0
- package/esm/deps/deno.land/std@0.195.0/assert/assert_throws.d.ts +54 -0
- package/esm/deps/deno.land/std@0.195.0/assert/assert_throws.js +44 -0
- package/esm/deps/deno.land/std@0.195.0/assert/equal.d.ts +6 -0
- package/esm/deps/deno.land/std@0.195.0/assert/equal.js +102 -0
- package/esm/deps/deno.land/std@0.195.0/assert/fail.d.ts +4 -0
- package/esm/deps/deno.land/std@0.195.0/assert/fail.js +9 -0
- package/esm/deps/deno.land/std@0.195.0/assert/mod.d.ts +32 -0
- package/esm/deps/deno.land/std@0.195.0/assert/mod.js +33 -0
- package/esm/deps/deno.land/std@0.195.0/assert/unimplemented.d.ts +2 -0
- package/esm/deps/deno.land/std@0.195.0/assert/unimplemented.js +7 -0
- package/esm/deps/deno.land/std@0.195.0/assert/unreachable.d.ts +2 -0
- package/esm/deps/deno.land/std@0.195.0/assert/unreachable.js +6 -0
- package/esm/deps/deno.land/std@0.195.0/testing/_test_suite.d.ts +70 -0
- package/esm/deps/deno.land/std@0.195.0/testing/_test_suite.js +321 -0
- package/esm/deps/deno.land/std@0.195.0/testing/asserts.d.ts +329 -0
- package/esm/deps/deno.land/std@0.195.0/testing/asserts.js +330 -0
- package/esm/deps/deno.land/std@0.195.0/testing/bdd.d.ts +440 -0
- package/esm/deps/deno.land/std@0.195.0/testing/bdd.js +215 -0
- package/esm/deps/deno.land/std@0.195.0/testing/mock.d.ts +110 -0
- package/esm/deps/deno.land/std@0.195.0/testing/mock.js +746 -0
- package/esm/src/action/clone.js +4 -3
- package/esm/src/action/frontend-template-switch.d.ts +1 -0
- package/esm/src/action/frontend-template-switch.js +53 -0
- package/esm/src/action/frontend-template.d.ts +2 -0
- package/esm/src/action/frontend-template.js +12 -0
- package/esm/src/action/lang.js +11 -2
- package/esm/src/action/run.js +6 -7
- package/esm/src/main.js +9 -2
- package/esm/src/meta.d.ts +1 -1
- package/esm/src/meta.js +108 -25
- package/esm/src/orca/client.js +1 -1
- package/esm/src/shared/config.d.ts +1 -0
- package/esm/src/shared/errors.d.ts +7 -1
- package/esm/src/shared/errors.js +16 -3
- package/esm/src/shared/file.js +1 -1
- package/esm/src/shared/mod.d.ts +1 -1
- package/esm/src/shared/mod.js +10 -2
- package/esm/src/shared/types.d.ts +16 -0
- package/esm/src/shared/types.js +2 -0
- package/esm/src/track/client.d.ts +4 -1
- package/esm/src/track/test.d.ts +6 -2
- package/esm/src/track/test.js +28 -5
- package/esm/src/track/training.d.ts +4 -1
- package/esm/src/track/training.js +9 -0
- package/esm/test/shared/config_test.d.ts +1 -0
- package/esm/test/shared/config_test.js +57 -0
- package/esm/test/shared/file_test.d.ts +1 -0
- package/esm/test/shared/file_test.js +265 -0
- package/esm/test/shared/mod_test.d.ts +1 -0
- package/esm/test/shared/mod_test.js +353 -0
- package/package.json +1 -1
- package/test_runner.js +186 -0
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
|
2
|
+
function isKeyedCollection(x) {
|
|
3
|
+
return [Symbol.iterator, "size"].every((k) => k in x);
|
|
4
|
+
}
|
|
5
|
+
function constructorsEqual(a, b) {
|
|
6
|
+
return a.constructor === b.constructor ||
|
|
7
|
+
a.constructor === Object && !b.constructor ||
|
|
8
|
+
!a.constructor && b.constructor === Object;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Deep equality comparison used in assertions
|
|
12
|
+
* @param c actual value
|
|
13
|
+
* @param d expected value
|
|
14
|
+
*/
|
|
15
|
+
export function equal(c, d) {
|
|
16
|
+
const seen = new Map();
|
|
17
|
+
return (function compare(a, b) {
|
|
18
|
+
// Have to render RegExp & Date for string comparison
|
|
19
|
+
// unless it's mistreated as object
|
|
20
|
+
if (a &&
|
|
21
|
+
b &&
|
|
22
|
+
((a instanceof RegExp && b instanceof RegExp) ||
|
|
23
|
+
(a instanceof URL && b instanceof URL))) {
|
|
24
|
+
return String(a) === String(b);
|
|
25
|
+
}
|
|
26
|
+
if (a instanceof Date && b instanceof Date) {
|
|
27
|
+
const aTime = a.getTime();
|
|
28
|
+
const bTime = b.getTime();
|
|
29
|
+
// Check for NaN equality manually since NaN is not
|
|
30
|
+
// equal to itself.
|
|
31
|
+
if (Number.isNaN(aTime) && Number.isNaN(bTime)) {
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
return aTime === bTime;
|
|
35
|
+
}
|
|
36
|
+
if (typeof a === "number" && typeof b === "number") {
|
|
37
|
+
return Number.isNaN(a) && Number.isNaN(b) || a === b;
|
|
38
|
+
}
|
|
39
|
+
if (Object.is(a, b)) {
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
if (a && typeof a === "object" && b && typeof b === "object") {
|
|
43
|
+
if (a && b && !constructorsEqual(a, b)) {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
if (a instanceof WeakMap || b instanceof WeakMap) {
|
|
47
|
+
if (!(a instanceof WeakMap && b instanceof WeakMap))
|
|
48
|
+
return false;
|
|
49
|
+
throw new TypeError("cannot compare WeakMap instances");
|
|
50
|
+
}
|
|
51
|
+
if (a instanceof WeakSet || b instanceof WeakSet) {
|
|
52
|
+
if (!(a instanceof WeakSet && b instanceof WeakSet))
|
|
53
|
+
return false;
|
|
54
|
+
throw new TypeError("cannot compare WeakSet instances");
|
|
55
|
+
}
|
|
56
|
+
if (seen.get(a) === b) {
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
if (Object.keys(a || {}).length !== Object.keys(b || {}).length) {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
seen.set(a, b);
|
|
63
|
+
if (isKeyedCollection(a) && isKeyedCollection(b)) {
|
|
64
|
+
if (a.size !== b.size) {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
let unmatchedEntries = a.size;
|
|
68
|
+
for (const [aKey, aValue] of a.entries()) {
|
|
69
|
+
for (const [bKey, bValue] of b.entries()) {
|
|
70
|
+
/* Given that Map keys can be references, we need
|
|
71
|
+
* to ensure that they are also deeply equal */
|
|
72
|
+
if ((aKey === aValue && bKey === bValue && compare(aKey, bKey)) ||
|
|
73
|
+
(compare(aKey, bKey) && compare(aValue, bValue))) {
|
|
74
|
+
unmatchedEntries--;
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return unmatchedEntries === 0;
|
|
80
|
+
}
|
|
81
|
+
const merged = { ...a, ...b };
|
|
82
|
+
for (const key of [
|
|
83
|
+
...Object.getOwnPropertyNames(merged),
|
|
84
|
+
...Object.getOwnPropertySymbols(merged),
|
|
85
|
+
]) {
|
|
86
|
+
if (!compare(a && a[key], b && b[key])) {
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
if (((key in a) && (!(key in b))) || ((key in b) && (!(key in a)))) {
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
if (a instanceof WeakRef || b instanceof WeakRef) {
|
|
94
|
+
if (!(a instanceof WeakRef && b instanceof WeakRef))
|
|
95
|
+
return false;
|
|
96
|
+
return compare(a.deref(), b.deref());
|
|
97
|
+
}
|
|
98
|
+
return true;
|
|
99
|
+
}
|
|
100
|
+
return false;
|
|
101
|
+
})(c, d);
|
|
102
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
|
2
|
+
import { assert } from "./assert.js";
|
|
3
|
+
/**
|
|
4
|
+
* Forcefully throws a failed assertion
|
|
5
|
+
*/
|
|
6
|
+
export function fail(msg) {
|
|
7
|
+
const msgSuffix = msg ? `: ${msg}` : ".";
|
|
8
|
+
assert(false, `Failed assertion${msgSuffix}`);
|
|
9
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/** A library of assertion functions.
|
|
2
|
+
* If the assertion is false an `AssertionError` will be thrown which will
|
|
3
|
+
* result in pretty-printed diff of failing assertion.
|
|
4
|
+
*
|
|
5
|
+
* This module is browser compatible, but do not rely on good formatting of
|
|
6
|
+
* values for AssertionError messages in browsers.
|
|
7
|
+
*
|
|
8
|
+
* @module
|
|
9
|
+
*/
|
|
10
|
+
export * from "./assert_almost_equals.js";
|
|
11
|
+
export * from "./assert_array_includes.js";
|
|
12
|
+
export * from "./assert_equals.js";
|
|
13
|
+
export * from "./assert_exists.js";
|
|
14
|
+
export * from "./assert_false.js";
|
|
15
|
+
export * from "./assert_instance_of.js";
|
|
16
|
+
export * from "./assert_is_error.js";
|
|
17
|
+
export * from "./assert_match.js";
|
|
18
|
+
export * from "./assert_not_equals.js";
|
|
19
|
+
export * from "./assert_not_instance_of.js";
|
|
20
|
+
export * from "./assert_not_match.js";
|
|
21
|
+
export * from "./assert_not_strict_equals.js";
|
|
22
|
+
export * from "./assert_object_match.js";
|
|
23
|
+
export * from "./assert_rejects.js";
|
|
24
|
+
export * from "./assert_strict_equals.js";
|
|
25
|
+
export * from "./assert_string_includes.js";
|
|
26
|
+
export * from "./assert_throws.js";
|
|
27
|
+
export * from "./assert.js";
|
|
28
|
+
export * from "./assertion_error.js";
|
|
29
|
+
export * from "./equal.js";
|
|
30
|
+
export * from "./fail.js";
|
|
31
|
+
export * from "./unimplemented.js";
|
|
32
|
+
export * from "./unreachable.js";
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
|
2
|
+
/** A library of assertion functions.
|
|
3
|
+
* If the assertion is false an `AssertionError` will be thrown which will
|
|
4
|
+
* result in pretty-printed diff of failing assertion.
|
|
5
|
+
*
|
|
6
|
+
* This module is browser compatible, but do not rely on good formatting of
|
|
7
|
+
* values for AssertionError messages in browsers.
|
|
8
|
+
*
|
|
9
|
+
* @module
|
|
10
|
+
*/
|
|
11
|
+
export * from "./assert_almost_equals.js";
|
|
12
|
+
export * from "./assert_array_includes.js";
|
|
13
|
+
export * from "./assert_equals.js";
|
|
14
|
+
export * from "./assert_exists.js";
|
|
15
|
+
export * from "./assert_false.js";
|
|
16
|
+
export * from "./assert_instance_of.js";
|
|
17
|
+
export * from "./assert_is_error.js";
|
|
18
|
+
export * from "./assert_match.js";
|
|
19
|
+
export * from "./assert_not_equals.js";
|
|
20
|
+
export * from "./assert_not_instance_of.js";
|
|
21
|
+
export * from "./assert_not_match.js";
|
|
22
|
+
export * from "./assert_not_strict_equals.js";
|
|
23
|
+
export * from "./assert_object_match.js";
|
|
24
|
+
export * from "./assert_rejects.js";
|
|
25
|
+
export * from "./assert_strict_equals.js";
|
|
26
|
+
export * from "./assert_string_includes.js";
|
|
27
|
+
export * from "./assert_throws.js";
|
|
28
|
+
export * from "./assert.js";
|
|
29
|
+
export * from "./assertion_error.js";
|
|
30
|
+
export * from "./equal.js";
|
|
31
|
+
export * from "./fail.js";
|
|
32
|
+
export * from "./unimplemented.js";
|
|
33
|
+
export * from "./unreachable.js";
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
|
2
|
+
import { AssertionError } from "./assertion_error.js";
|
|
3
|
+
/** Use this to stub out methods that will throw when invoked. */
|
|
4
|
+
export function unimplemented(msg) {
|
|
5
|
+
const msgSuffix = msg ? `: ${msg}` : ".";
|
|
6
|
+
throw new AssertionError(`Unimplemented${msgSuffix}`);
|
|
7
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/** The options for creating a test suite with the describe function. */
|
|
2
|
+
import * as dntShim from "../../../../_dnt.test_shims.js";
|
|
3
|
+
export interface DescribeDefinition<T> extends Omit<dntShim.Deno.TestDefinition, "fn"> {
|
|
4
|
+
fn?: () => void;
|
|
5
|
+
/**
|
|
6
|
+
* The `describe` function returns a `TestSuite` representing the group of tests.
|
|
7
|
+
* If `describe` is called within another `describe` calls `fn`, the suite will default to that parent `describe` calls returned `TestSuite`.
|
|
8
|
+
* If `describe` is not called within another `describe` calls `fn`, the suite will default to the `TestSuite` representing the global group of tests.
|
|
9
|
+
*/
|
|
10
|
+
suite?: TestSuite<T>;
|
|
11
|
+
/** Run some shared setup before all of the tests in the suite. */
|
|
12
|
+
beforeAll?: ((this: T) => void | Promise<void>) | ((this: T) => void | Promise<void>)[];
|
|
13
|
+
/** Run some shared teardown after all of the tests in the suite. */
|
|
14
|
+
afterAll?: ((this: T) => void | Promise<void>) | ((this: T) => void | Promise<void>)[];
|
|
15
|
+
/** Run some shared setup before each test in the suite. */
|
|
16
|
+
beforeEach?: ((this: T) => void | Promise<void>) | ((this: T) => void | Promise<void>)[];
|
|
17
|
+
/** Run some shared teardown after each test in the suite. */
|
|
18
|
+
afterEach?: ((this: T) => void | Promise<void>) | ((this: T) => void | Promise<void>)[];
|
|
19
|
+
}
|
|
20
|
+
/** The options for creating an individual test case with the it function. */
|
|
21
|
+
export interface ItDefinition<T> extends Omit<dntShim.Deno.TestDefinition, "fn"> {
|
|
22
|
+
fn: (this: T, t: dntShim.Deno.TestContext) => void | Promise<void>;
|
|
23
|
+
/**
|
|
24
|
+
* The `describe` function returns a `TestSuite` representing the group of tests.
|
|
25
|
+
* If `it` is called within a `describe` calls `fn`, the suite will default to that parent `describe` calls returned `TestSuite`.
|
|
26
|
+
* If `it` is not called within a `describe` calls `fn`, the suite will default to the `TestSuite` representing the global group of tests.
|
|
27
|
+
*/
|
|
28
|
+
suite?: TestSuite<T>;
|
|
29
|
+
}
|
|
30
|
+
/** The names of all the different types of hooks. */
|
|
31
|
+
export type HookNames = "beforeAll" | "afterAll" | "beforeEach" | "afterEach";
|
|
32
|
+
/**
|
|
33
|
+
* A group of tests.
|
|
34
|
+
*/
|
|
35
|
+
export interface TestSuite<T> {
|
|
36
|
+
symbol: symbol;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* An internal representation of a group of tests.
|
|
40
|
+
*/
|
|
41
|
+
export declare class TestSuiteInternal<T> implements TestSuite<T> {
|
|
42
|
+
symbol: symbol;
|
|
43
|
+
protected describe: DescribeDefinition<T>;
|
|
44
|
+
protected steps: (TestSuiteInternal<T> | ItDefinition<T>)[];
|
|
45
|
+
protected hasOnlyStep: boolean;
|
|
46
|
+
constructor(describe: DescribeDefinition<T>);
|
|
47
|
+
/** Stores how many test suites are executing. */
|
|
48
|
+
static runningCount: number;
|
|
49
|
+
/** If a test has been registered yet. Block adding global hooks if a test has been registered. */
|
|
50
|
+
static started: boolean;
|
|
51
|
+
/** A map of all test suites by symbol. */
|
|
52
|
+
static suites: Map<symbol, TestSuiteInternal<any>>;
|
|
53
|
+
/** The current test suite being registered. */
|
|
54
|
+
static current: TestSuiteInternal<any> | null;
|
|
55
|
+
/** The stack of tests that are actively running. */
|
|
56
|
+
static active: symbol[];
|
|
57
|
+
/** This is used internally for testing this module. */
|
|
58
|
+
static reset(): void;
|
|
59
|
+
/** This is used internally to register tests. */
|
|
60
|
+
static registerTest(options: dntShim.Deno.TestDefinition): void;
|
|
61
|
+
/** Updates all steps within top level suite to have ignore set to true if only is not set to true on step. */
|
|
62
|
+
static addingOnlyStep<T>(suite: TestSuiteInternal<T>): void;
|
|
63
|
+
/** This is used internally to add steps to a test suite. */
|
|
64
|
+
static addStep<T>(suite: TestSuiteInternal<T>, step: TestSuiteInternal<T> | ItDefinition<T>): void;
|
|
65
|
+
/** This is used internally to add hooks to a test suite. */
|
|
66
|
+
static setHook<T>(suite: TestSuiteInternal<T>, name: HookNames, fn: (this: T) => void | Promise<void>): void;
|
|
67
|
+
/** This is used internally to run all steps for a test suite. */
|
|
68
|
+
static run<T>(suite: TestSuiteInternal<T>, context: T, t: dntShim.Deno.TestContext): Promise<void>;
|
|
69
|
+
static runTest<T>(t: dntShim.Deno.TestContext, fn: (this: T, t: dntShim.Deno.TestContext) => void | Promise<void>, context: T, activeIndex?: number): Promise<void>;
|
|
70
|
+
}
|
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
|
2
|
+
/** The options for creating a test suite with the describe function. */
|
|
3
|
+
import * as dntShim from "../../../../_dnt.test_shims.js";
|
|
4
|
+
/** Optional test definition keys. */
|
|
5
|
+
const optionalTestDefinitionKeys = [
|
|
6
|
+
"only",
|
|
7
|
+
"permissions",
|
|
8
|
+
"ignore",
|
|
9
|
+
"sanitizeExit",
|
|
10
|
+
"sanitizeOps",
|
|
11
|
+
"sanitizeResources",
|
|
12
|
+
];
|
|
13
|
+
/** Optional test step definition keys. */
|
|
14
|
+
const optionalTestStepDefinitionKeys = [
|
|
15
|
+
"ignore",
|
|
16
|
+
"sanitizeExit",
|
|
17
|
+
"sanitizeOps",
|
|
18
|
+
"sanitizeResources",
|
|
19
|
+
];
|
|
20
|
+
/**
|
|
21
|
+
* An internal representation of a group of tests.
|
|
22
|
+
*/
|
|
23
|
+
export class TestSuiteInternal {
|
|
24
|
+
constructor(describe) {
|
|
25
|
+
Object.defineProperty(this, "symbol", {
|
|
26
|
+
enumerable: true,
|
|
27
|
+
configurable: true,
|
|
28
|
+
writable: true,
|
|
29
|
+
value: void 0
|
|
30
|
+
});
|
|
31
|
+
Object.defineProperty(this, "describe", {
|
|
32
|
+
enumerable: true,
|
|
33
|
+
configurable: true,
|
|
34
|
+
writable: true,
|
|
35
|
+
value: void 0
|
|
36
|
+
});
|
|
37
|
+
Object.defineProperty(this, "steps", {
|
|
38
|
+
enumerable: true,
|
|
39
|
+
configurable: true,
|
|
40
|
+
writable: true,
|
|
41
|
+
value: void 0
|
|
42
|
+
});
|
|
43
|
+
Object.defineProperty(this, "hasOnlyStep", {
|
|
44
|
+
enumerable: true,
|
|
45
|
+
configurable: true,
|
|
46
|
+
writable: true,
|
|
47
|
+
value: void 0
|
|
48
|
+
});
|
|
49
|
+
this.describe = describe;
|
|
50
|
+
this.steps = [];
|
|
51
|
+
this.hasOnlyStep = false;
|
|
52
|
+
const { suite } = describe;
|
|
53
|
+
if (suite && !TestSuiteInternal.suites.has(suite.symbol)) {
|
|
54
|
+
throw new Error("suite does not represent a registered test suite");
|
|
55
|
+
}
|
|
56
|
+
const testSuite = suite
|
|
57
|
+
? TestSuiteInternal.suites.get(suite.symbol)
|
|
58
|
+
: TestSuiteInternal.current;
|
|
59
|
+
this.symbol = Symbol();
|
|
60
|
+
TestSuiteInternal.suites.set(this.symbol, this);
|
|
61
|
+
const { fn } = describe;
|
|
62
|
+
if (fn) {
|
|
63
|
+
const temp = TestSuiteInternal.current;
|
|
64
|
+
TestSuiteInternal.current = this;
|
|
65
|
+
try {
|
|
66
|
+
fn();
|
|
67
|
+
}
|
|
68
|
+
finally {
|
|
69
|
+
TestSuiteInternal.current = temp;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (testSuite) {
|
|
73
|
+
TestSuiteInternal.addStep(testSuite, this);
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
const { name, ignore, permissions, sanitizeExit, sanitizeOps, sanitizeResources, } = describe;
|
|
77
|
+
let { only } = describe;
|
|
78
|
+
if (!ignore && this.hasOnlyStep) {
|
|
79
|
+
only = true;
|
|
80
|
+
}
|
|
81
|
+
TestSuiteInternal.registerTest({
|
|
82
|
+
name,
|
|
83
|
+
ignore,
|
|
84
|
+
only,
|
|
85
|
+
permissions,
|
|
86
|
+
sanitizeExit,
|
|
87
|
+
sanitizeOps,
|
|
88
|
+
sanitizeResources,
|
|
89
|
+
fn: async (t) => {
|
|
90
|
+
TestSuiteInternal.runningCount++;
|
|
91
|
+
try {
|
|
92
|
+
const context = {};
|
|
93
|
+
const { beforeAll } = this.describe;
|
|
94
|
+
if (typeof beforeAll === "function") {
|
|
95
|
+
await beforeAll.call(context);
|
|
96
|
+
}
|
|
97
|
+
else if (beforeAll) {
|
|
98
|
+
for (const hook of beforeAll) {
|
|
99
|
+
await hook.call(context);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
try {
|
|
103
|
+
TestSuiteInternal.active.push(this.symbol);
|
|
104
|
+
await TestSuiteInternal.run(this, context, t);
|
|
105
|
+
}
|
|
106
|
+
finally {
|
|
107
|
+
TestSuiteInternal.active.pop();
|
|
108
|
+
const { afterAll } = this.describe;
|
|
109
|
+
if (typeof afterAll === "function") {
|
|
110
|
+
await afterAll.call(context);
|
|
111
|
+
}
|
|
112
|
+
else if (afterAll) {
|
|
113
|
+
for (const hook of afterAll) {
|
|
114
|
+
await hook.call(context);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
finally {
|
|
120
|
+
TestSuiteInternal.runningCount--;
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/** This is used internally for testing this module. */
|
|
127
|
+
static reset() {
|
|
128
|
+
TestSuiteInternal.runningCount = 0;
|
|
129
|
+
TestSuiteInternal.started = false;
|
|
130
|
+
TestSuiteInternal.current = null;
|
|
131
|
+
TestSuiteInternal.active = [];
|
|
132
|
+
}
|
|
133
|
+
/** This is used internally to register tests. */
|
|
134
|
+
static registerTest(options) {
|
|
135
|
+
options = { ...options };
|
|
136
|
+
optionalTestDefinitionKeys.forEach((key) => {
|
|
137
|
+
if (typeof options[key] === "undefined")
|
|
138
|
+
delete options[key];
|
|
139
|
+
});
|
|
140
|
+
dntShim.Deno.test(options);
|
|
141
|
+
}
|
|
142
|
+
/** Updates all steps within top level suite to have ignore set to true if only is not set to true on step. */
|
|
143
|
+
static addingOnlyStep(suite) {
|
|
144
|
+
if (!suite.hasOnlyStep) {
|
|
145
|
+
for (let i = 0; i < suite.steps.length; i++) {
|
|
146
|
+
const step = suite.steps[i];
|
|
147
|
+
if (!(step instanceof TestSuiteInternal) && !step.only) {
|
|
148
|
+
suite.steps.splice(i--, 1);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
suite.hasOnlyStep = true;
|
|
152
|
+
}
|
|
153
|
+
const parentSuite = suite.describe.suite;
|
|
154
|
+
const parentTestSuite = parentSuite &&
|
|
155
|
+
TestSuiteInternal.suites.get(parentSuite.symbol);
|
|
156
|
+
if (parentTestSuite) {
|
|
157
|
+
TestSuiteInternal.addingOnlyStep(parentTestSuite);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
/** This is used internally to add steps to a test suite. */
|
|
161
|
+
static addStep(suite, step) {
|
|
162
|
+
if (!suite.hasOnlyStep) {
|
|
163
|
+
if (step instanceof TestSuiteInternal) {
|
|
164
|
+
if (step.hasOnlyStep || step.describe.only) {
|
|
165
|
+
TestSuiteInternal.addingOnlyStep(suite);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
if (step.only)
|
|
170
|
+
TestSuiteInternal.addingOnlyStep(suite);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
if (!(suite.hasOnlyStep && !(step instanceof TestSuiteInternal) && !step.only)) {
|
|
174
|
+
suite.steps.push(step);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
/** This is used internally to add hooks to a test suite. */
|
|
178
|
+
static setHook(suite, name, fn) {
|
|
179
|
+
if (suite.describe[name]) {
|
|
180
|
+
if (typeof suite.describe[name] === "function") {
|
|
181
|
+
suite.describe[name] = [
|
|
182
|
+
suite.describe[name],
|
|
183
|
+
];
|
|
184
|
+
}
|
|
185
|
+
suite.describe[name].push(fn);
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
suite.describe[name] = fn;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
/** This is used internally to run all steps for a test suite. */
|
|
192
|
+
static async run(suite, context, t) {
|
|
193
|
+
const hasOnly = suite.hasOnlyStep || suite.describe.only || false;
|
|
194
|
+
for (const step of suite.steps) {
|
|
195
|
+
if (hasOnly && step instanceof TestSuiteInternal &&
|
|
196
|
+
!(step.hasOnlyStep || step.describe.only || false)) {
|
|
197
|
+
continue;
|
|
198
|
+
}
|
|
199
|
+
const { name, fn, ignore, permissions, sanitizeExit, sanitizeOps, sanitizeResources, } = step instanceof TestSuiteInternal ? step.describe : step;
|
|
200
|
+
const options = {
|
|
201
|
+
name,
|
|
202
|
+
ignore,
|
|
203
|
+
sanitizeExit,
|
|
204
|
+
sanitizeOps,
|
|
205
|
+
sanitizeResources,
|
|
206
|
+
fn: async (t) => {
|
|
207
|
+
if (permissions) {
|
|
208
|
+
throw new Error("permissions option not available for nested tests");
|
|
209
|
+
}
|
|
210
|
+
context = { ...context };
|
|
211
|
+
if (step instanceof TestSuiteInternal) {
|
|
212
|
+
const { beforeAll } = step.describe;
|
|
213
|
+
if (typeof beforeAll === "function") {
|
|
214
|
+
await beforeAll.call(context);
|
|
215
|
+
}
|
|
216
|
+
else if (beforeAll) {
|
|
217
|
+
for (const hook of beforeAll) {
|
|
218
|
+
await hook.call(context);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
try {
|
|
222
|
+
TestSuiteInternal.active.push(step.symbol);
|
|
223
|
+
await TestSuiteInternal.run(step, context, t);
|
|
224
|
+
}
|
|
225
|
+
finally {
|
|
226
|
+
TestSuiteInternal.active.pop();
|
|
227
|
+
const { afterAll } = step.describe;
|
|
228
|
+
if (typeof afterAll === "function") {
|
|
229
|
+
await afterAll.call(context);
|
|
230
|
+
}
|
|
231
|
+
else if (afterAll) {
|
|
232
|
+
for (const hook of afterAll) {
|
|
233
|
+
await hook.call(context);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
else {
|
|
239
|
+
await TestSuiteInternal.runTest(t, fn, context);
|
|
240
|
+
}
|
|
241
|
+
},
|
|
242
|
+
};
|
|
243
|
+
optionalTestStepDefinitionKeys.forEach((key) => {
|
|
244
|
+
if (typeof options[key] === "undefined")
|
|
245
|
+
delete options[key];
|
|
246
|
+
});
|
|
247
|
+
await t.step(options);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
static async runTest(t, fn, context, activeIndex = 0) {
|
|
251
|
+
const suite = TestSuiteInternal.active[activeIndex];
|
|
252
|
+
const testSuite = suite && TestSuiteInternal.suites.get(suite);
|
|
253
|
+
if (testSuite) {
|
|
254
|
+
if (activeIndex === 0)
|
|
255
|
+
context = { ...context };
|
|
256
|
+
const { beforeEach } = testSuite.describe;
|
|
257
|
+
if (typeof beforeEach === "function") {
|
|
258
|
+
await beforeEach.call(context);
|
|
259
|
+
}
|
|
260
|
+
else if (beforeEach) {
|
|
261
|
+
for (const hook of beforeEach) {
|
|
262
|
+
await hook.call(context);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
try {
|
|
266
|
+
await TestSuiteInternal.runTest(t, fn, context, activeIndex + 1);
|
|
267
|
+
}
|
|
268
|
+
finally {
|
|
269
|
+
const { afterEach } = testSuite.describe;
|
|
270
|
+
if (typeof afterEach === "function") {
|
|
271
|
+
await afterEach.call(context);
|
|
272
|
+
}
|
|
273
|
+
else if (afterEach) {
|
|
274
|
+
for (const hook of afterEach) {
|
|
275
|
+
await hook.call(context);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
else {
|
|
281
|
+
await fn.call(context, t);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
/** Stores how many test suites are executing. */
|
|
286
|
+
Object.defineProperty(TestSuiteInternal, "runningCount", {
|
|
287
|
+
enumerable: true,
|
|
288
|
+
configurable: true,
|
|
289
|
+
writable: true,
|
|
290
|
+
value: 0
|
|
291
|
+
});
|
|
292
|
+
/** If a test has been registered yet. Block adding global hooks if a test has been registered. */
|
|
293
|
+
Object.defineProperty(TestSuiteInternal, "started", {
|
|
294
|
+
enumerable: true,
|
|
295
|
+
configurable: true,
|
|
296
|
+
writable: true,
|
|
297
|
+
value: false
|
|
298
|
+
});
|
|
299
|
+
/** A map of all test suites by symbol. */
|
|
300
|
+
// deno-lint-ignore no-explicit-any
|
|
301
|
+
Object.defineProperty(TestSuiteInternal, "suites", {
|
|
302
|
+
enumerable: true,
|
|
303
|
+
configurable: true,
|
|
304
|
+
writable: true,
|
|
305
|
+
value: new Map()
|
|
306
|
+
});
|
|
307
|
+
/** The current test suite being registered. */
|
|
308
|
+
// deno-lint-ignore no-explicit-any
|
|
309
|
+
Object.defineProperty(TestSuiteInternal, "current", {
|
|
310
|
+
enumerable: true,
|
|
311
|
+
configurable: true,
|
|
312
|
+
writable: true,
|
|
313
|
+
value: null
|
|
314
|
+
});
|
|
315
|
+
/** The stack of tests that are actively running. */
|
|
316
|
+
Object.defineProperty(TestSuiteInternal, "active", {
|
|
317
|
+
enumerable: true,
|
|
318
|
+
configurable: true,
|
|
319
|
+
writable: true,
|
|
320
|
+
value: []
|
|
321
|
+
});
|