vest 5.0.0-dev-781e21 → 5.0.2-dev-d315d9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +2 -2
- package/README.md +2 -57
- package/dist/cjs/classnames.development.js +18 -16
- package/dist/cjs/classnames.production.js +1 -1
- package/dist/cjs/enforce/compose.development.js +5 -54
- package/dist/cjs/enforce/compose.production.js +1 -1
- package/dist/cjs/enforce/compounds.development.js +20 -83
- package/dist/cjs/enforce/compounds.production.js +1 -1
- package/dist/cjs/enforce/schema.development.js +19 -82
- package/dist/cjs/enforce/schema.production.js +1 -1
- package/dist/cjs/parser.development.js +12 -9
- package/dist/cjs/parser.production.js +1 -1
- package/dist/cjs/promisify.development.js +4 -8
- package/dist/cjs/promisify.production.js +1 -1
- package/dist/cjs/vest.development.js +1287 -1153
- package/dist/cjs/vest.production.js +1 -1
- package/dist/es/classnames.development.js +20 -18
- package/dist/es/classnames.production.js +1 -1
- package/dist/es/enforce/compose.development.js +1 -58
- package/dist/es/enforce/compose.production.js +1 -1
- package/dist/es/enforce/compounds.development.js +2 -90
- package/dist/es/enforce/compounds.production.js +1 -1
- package/dist/es/enforce/schema.development.js +2 -88
- package/dist/es/enforce/schema.production.js +1 -1
- package/dist/es/parser.development.js +12 -9
- package/dist/es/parser.production.js +1 -1
- package/dist/es/promisify.development.js +5 -9
- package/dist/es/promisify.production.js +1 -1
- package/dist/es/vest.development.js +1286 -1148
- package/dist/es/vest.production.js +1 -1
- package/dist/umd/classnames.development.js +21 -19
- package/dist/umd/classnames.production.js +1 -1
- package/dist/umd/enforce/compose.development.js +9 -57
- package/dist/umd/enforce/compose.production.js +1 -1
- package/dist/umd/enforce/compounds.development.js +32 -94
- package/dist/umd/enforce/compounds.production.js +1 -1
- package/dist/umd/enforce/schema.development.js +32 -94
- package/dist/umd/enforce/schema.production.js +1 -1
- package/dist/umd/parser.development.js +16 -13
- package/dist/umd/parser.production.js +1 -1
- package/dist/umd/promisify.development.js +7 -11
- package/dist/umd/promisify.production.js +1 -1
- package/dist/umd/vest.development.js +1289 -1155
- package/dist/umd/vest.production.js +1 -1
- package/package.json +12 -16
- package/src/__tests__/__snapshots__/integration.async-tests.test.ts.snap +71 -0
- package/src/__tests__/__snapshots__/integration.base.test.ts.snap +71 -0
- package/src/__tests__/__snapshots__/integration.stateful-async.test.ts.snap +243 -0
- package/src/__tests__/__snapshots__/integration.stateful-tests.test.ts.snap +376 -0
- package/src/__tests__/integration.async-tests.test.ts +90 -0
- package/src/__tests__/integration.base.test.ts +45 -0
- package/src/__tests__/integration.exclusive.test.ts +88 -0
- package/src/__tests__/integration.stateful-async.test.ts +137 -0
- package/src/__tests__/integration.stateful-tests.test.ts +155 -0
- package/src/__tests__/isolate.test.ts +288 -0
- package/src/__tests__/state_refill.test.ts +41 -0
- package/src/core/SuiteWalker/SuiteWalker.ts +64 -0
- package/src/core/SuiteWalker/__tests__/hasRemainingTests.test.ts +130 -0
- package/src/core/VestBus/VestBus.ts +78 -0
- package/src/core/context/PersistedContext.ts +243 -0
- package/src/core/context/SuiteContext.ts +74 -0
- package/src/core/isolate/IsolateTest/IsolateTest.ts +213 -0
- package/src/core/isolate/IsolateTest/IsolateTestReconciler.ts +156 -0
- package/src/core/isolate/IsolateTest/IsolateTestStateMachine.ts +69 -0
- package/src/core/isolate/IsolateTest/SimpleStateMachine.ts +43 -0
- package/src/core/isolate/IsolateTest/TestWalker.ts +77 -0
- package/src/core/isolate/IsolateTypes.ts +10 -0
- package/src/core/isolate/isIsolate.ts +6 -0
- package/src/core/isolate/isolate.ts +110 -0
- package/src/core/isolate/reconciler/Reconciler/Reconciler.ts +123 -0
- package/src/core/isolate/reconciler/cancelOverriddenPendingTest.ts +15 -0
- package/src/core/isolate/reconciler/isSameProfileTest.ts +12 -0
- package/src/core/isolate/walker.ts +127 -0
- package/src/core/test/TestTypes.ts +3 -0
- package/src/core/test/__tests__/IsolateTest.test.ts +152 -0
- package/src/core/test/__tests__/__snapshots__/IsolateTest.test.ts.snap +39 -0
- package/src/core/test/__tests__/__snapshots__/memo.test.ts.snap +101 -0
- package/src/core/test/__tests__/__snapshots__/test.test.ts.snap +231 -0
- package/src/core/test/__tests__/key.test.ts +195 -0
- package/src/core/test/__tests__/memo.test.ts +218 -0
- package/src/core/test/__tests__/merging_of_previous_test_runs.test.ts +341 -0
- package/src/core/test/__tests__/runAsyncTest.test.ts +175 -0
- package/src/core/test/__tests__/test.test.ts +226 -0
- package/src/core/test/helpers/__tests__/nonMatchingSeverityProfile.test.ts +52 -0
- package/src/core/test/helpers/asVestTest.ts +9 -0
- package/src/core/test/helpers/matchingFieldName.ts +16 -0
- package/src/core/test/helpers/matchingGroupName.ts +12 -0
- package/src/core/test/helpers/nonMatchingSeverityProfile.ts +14 -0
- package/src/core/test/helpers/shouldUseErrorMessage.ts +9 -0
- package/src/core/test/test.memo.ts +81 -0
- package/src/core/test/test.ts +64 -0
- package/src/core/test/testLevelFlowControl/runTest.ts +86 -0
- package/src/core/test/testLevelFlowControl/verifyTestRun.ts +32 -0
- package/src/core/test/testObjectIsolate.ts +11 -0
- package/src/errors/ErrorStrings.ts +4 -0
- package/src/exports/__tests__/classnames.test.ts +92 -0
- package/src/exports/__tests__/parser.test.ts +441 -0
- package/src/exports/__tests__/promisify.test.ts +77 -0
- package/src/exports/classnames.ts +35 -0
- package/src/exports/enforce@compose.ts +1 -0
- package/src/exports/enforce@compounds.ts +1 -0
- package/src/exports/enforce@schema.ts +1 -0
- package/src/exports/parser.ts +63 -0
- package/src/exports/promisify.ts +18 -0
- package/src/hooks/__tests__/__snapshots__/include.test.ts.snap +794 -0
- package/src/hooks/__tests__/eager.test.ts +130 -0
- package/src/hooks/__tests__/exclusive.test.ts +578 -0
- package/src/hooks/__tests__/include.test.ts +431 -0
- package/src/hooks/__tests__/optional.test.ts +83 -0
- package/src/hooks/__tests__/warn.test.ts +42 -0
- package/src/hooks/exclusive.ts +179 -0
- package/src/hooks/include.ts +54 -0
- package/src/hooks/mode.ts +47 -0
- package/src/hooks/optional/OptionalTypes.ts +31 -0
- package/src/hooks/optional/optional.ts +69 -0
- package/src/hooks/warn.ts +19 -0
- package/src/isolates/__tests__/__snapshots__/each.test.ts.snap +3 -0
- package/src/isolates/__tests__/__snapshots__/group.test.ts.snap +114 -0
- package/src/isolates/__tests__/__snapshots__/omitWhen.test.ts.snap +443 -0
- package/src/isolates/__tests__/__snapshots__/skipWhen.test.ts.snap +99 -0
- package/src/isolates/__tests__/each.test.ts +35 -0
- package/src/isolates/__tests__/group.test.ts +362 -0
- package/src/isolates/__tests__/omitWhen.test.ts +246 -0
- package/src/isolates/__tests__/skipWhen.test.ts +163 -0
- package/src/isolates/each.ts +30 -0
- package/src/isolates/group.ts +9 -0
- package/src/isolates/omitWhen.ts +41 -0
- package/src/isolates/skipWhen.ts +42 -0
- package/src/suite/__tests__/__snapshots__/create.test.ts.snap +67 -0
- package/src/suite/__tests__/create.test.ts +109 -0
- package/src/suite/__tests__/remove.test.ts +50 -0
- package/src/suite/__tests__/resetField.test.ts +74 -0
- package/src/suite/createSuite.ts +94 -0
- package/src/suite/runCallbacks.ts +28 -0
- package/src/suiteResult/Severity.ts +15 -0
- package/src/suiteResult/SuiteResultTypes.ts +42 -0
- package/src/suiteResult/__tests__/done.test.ts +334 -0
- package/src/suiteResult/__tests__/produce.test.ts +163 -0
- package/src/suiteResult/done/deferDoneCallback.ts +28 -0
- package/src/suiteResult/done/shouldSkipDoneRegistration.ts +20 -0
- package/src/suiteResult/selectors/__tests__/__snapshots__/collectFailureMessages.test.ts.snap +89 -0
- package/src/suiteResult/selectors/__tests__/collectFailureMessages.test.ts +124 -0
- package/src/suiteResult/selectors/__tests__/getFailures.test.ts +158 -0
- package/src/suiteResult/selectors/__tests__/getFailuresByGroup.test.ts +199 -0
- package/src/suiteResult/selectors/__tests__/hasFailures.test.ts +141 -0
- package/src/suiteResult/selectors/__tests__/hasFailuresByGroup.test.ts +185 -0
- package/src/suiteResult/selectors/__tests__/hasFailuresByTestObject.test.ts +88 -0
- package/src/suiteResult/selectors/__tests__/isValid.test.ts +359 -0
- package/src/suiteResult/selectors/__tests__/isValidByGroup.test.ts +480 -0
- package/src/suiteResult/selectors/collectFailures.ts +43 -0
- package/src/suiteResult/selectors/hasFailuresByTestObjects.ts +62 -0
- package/src/suiteResult/selectors/produceSuiteSummary.ts +135 -0
- package/src/suiteResult/selectors/shouldAddValidProperty.ts +148 -0
- package/src/suiteResult/selectors/suiteSelectors.ts +199 -0
- package/src/suiteResult/suiteResult.ts +15 -0
- package/src/suiteResult/suiteRunResult.ts +43 -0
- package/src/vest.ts +36 -0
- package/testUtils/TVestMock.ts +5 -0
- package/testUtils/__tests__/partition.test.ts +4 -4
- package/testUtils/mockThrowError.ts +4 -2
- package/testUtils/suiteDummy.ts +2 -1
- package/testUtils/testDummy.ts +12 -10
- package/testUtils/testPromise.ts +3 -0
- package/tsconfig.json +84 -2
- package/types/classnames.d.ts +39 -4
- package/types/classnames.d.ts.map +1 -0
- package/types/enforce/compose.d.ts +2 -126
- package/types/enforce/compose.d.ts.map +1 -0
- package/types/enforce/compounds.d.ts +2 -136
- package/types/enforce/compounds.d.ts.map +1 -0
- package/types/enforce/schema.d.ts +2 -144
- package/types/enforce/schema.d.ts.map +1 -0
- package/types/parser.d.ts +45 -10
- package/types/parser.d.ts.map +1 -0
- package/types/promisify.d.ts +36 -34
- package/types/promisify.d.ts.map +1 -0
- package/types/vest.d.ts +169 -224
- package/types/vest.d.ts.map +1 -0
- package/CHANGELOG.md +0 -87
- package/testUtils/expandStateRef.ts +0 -8
- package/testUtils/runCreateRef.ts +0 -10
- package/testUtils/testObjects.ts +0 -6
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import wait from 'wait';
|
|
2
|
+
|
|
3
|
+
import { TestWalker } from 'TestWalker';
|
|
4
|
+
import * as vest from 'vest';
|
|
5
|
+
|
|
6
|
+
describe('TestWalker.hasRemainingTests', () => {
|
|
7
|
+
let hasRemaining: boolean | null = null;
|
|
8
|
+
let count = 0;
|
|
9
|
+
|
|
10
|
+
beforeEach(() => {
|
|
11
|
+
hasRemaining = null;
|
|
12
|
+
count = 0;
|
|
13
|
+
});
|
|
14
|
+
describe('When no field specified', () => {
|
|
15
|
+
describe('When no remaining tests', () => {
|
|
16
|
+
it('should return false', () => {
|
|
17
|
+
vest.create(() => {
|
|
18
|
+
hasRemaining = TestWalker.hasRemainingTests();
|
|
19
|
+
})();
|
|
20
|
+
expect(hasRemaining).toBe(false);
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
describe('When there are remaining tests', () => {
|
|
25
|
+
it('pending tests return true', () => {
|
|
26
|
+
vest.create(() => {
|
|
27
|
+
vest.test('f1', async () => {
|
|
28
|
+
await wait(100);
|
|
29
|
+
});
|
|
30
|
+
hasRemaining = TestWalker.hasRemainingTests();
|
|
31
|
+
})();
|
|
32
|
+
|
|
33
|
+
expect(hasRemaining).toBe(true);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('lagging tests return true', () => {
|
|
37
|
+
const suite = vest.create(() => {
|
|
38
|
+
if (count) vest.skip('f1');
|
|
39
|
+
vest.test('f1', async () => {
|
|
40
|
+
await wait(100);
|
|
41
|
+
});
|
|
42
|
+
count++;
|
|
43
|
+
hasRemaining = TestWalker.hasRemainingTests();
|
|
44
|
+
});
|
|
45
|
+
suite();
|
|
46
|
+
suite();
|
|
47
|
+
|
|
48
|
+
expect(hasRemaining).toBe(true);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('lagging and pending tests return true', () => {
|
|
52
|
+
const suite = vest.create(() => {
|
|
53
|
+
if (count) vest.skip('f1');
|
|
54
|
+
vest.test('f1', async () => {
|
|
55
|
+
await wait(100);
|
|
56
|
+
});
|
|
57
|
+
vest.test('f2', async () => {
|
|
58
|
+
await wait(100);
|
|
59
|
+
});
|
|
60
|
+
count++;
|
|
61
|
+
hasRemaining = TestWalker.hasRemainingTests();
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
suite();
|
|
65
|
+
suite();
|
|
66
|
+
|
|
67
|
+
expect(hasRemaining).toBe(true);
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
describe('When field specified', () => {
|
|
73
|
+
describe('When no remaining tests', () => {
|
|
74
|
+
it('Should return false', () => {
|
|
75
|
+
vest.create(() => {
|
|
76
|
+
hasRemaining = TestWalker.hasRemainingTests('f1');
|
|
77
|
+
})();
|
|
78
|
+
expect(hasRemaining).toBe(false);
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
describe('When remaining tests', () => {
|
|
83
|
+
it('pending tests return true', () => {
|
|
84
|
+
vest.create(() => {
|
|
85
|
+
vest.test('f1', async () => {
|
|
86
|
+
await wait(100);
|
|
87
|
+
});
|
|
88
|
+
hasRemaining = TestWalker.hasRemainingTests('f1');
|
|
89
|
+
})();
|
|
90
|
+
expect(hasRemaining).toBe(true);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it('lagging tests return true', () => {
|
|
94
|
+
const suite = vest.create(() => {
|
|
95
|
+
if (count) vest.skip('f1');
|
|
96
|
+
vest.test('f1', async () => {
|
|
97
|
+
await wait(100);
|
|
98
|
+
});
|
|
99
|
+
count++;
|
|
100
|
+
hasRemaining = TestWalker.hasRemainingTests('f1');
|
|
101
|
+
});
|
|
102
|
+
suite();
|
|
103
|
+
suite();
|
|
104
|
+
|
|
105
|
+
expect(hasRemaining).toBe(true);
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it('lagging and pending tests return true', () => {
|
|
109
|
+
const suite = vest.create(() => {
|
|
110
|
+
if (count) vest.skip('f1');
|
|
111
|
+
vest.test('f1', async () => {
|
|
112
|
+
await wait(100);
|
|
113
|
+
});
|
|
114
|
+
vest.test('f2', async () => {
|
|
115
|
+
await wait(100);
|
|
116
|
+
});
|
|
117
|
+
count++;
|
|
118
|
+
hasRemaining =
|
|
119
|
+
TestWalker.hasRemainingTests('f1') &&
|
|
120
|
+
TestWalker.hasRemainingTests('f2');
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
suite();
|
|
124
|
+
suite();
|
|
125
|
+
|
|
126
|
+
expect(hasRemaining).toBe(true);
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
});
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { bus } from 'vest-utils';
|
|
2
|
+
|
|
3
|
+
import { IsolateTest } from 'IsolateTest';
|
|
4
|
+
import {
|
|
5
|
+
useExpireSuiteResultCache,
|
|
6
|
+
useResetCallbacks,
|
|
7
|
+
useResetSuite,
|
|
8
|
+
} from 'PersistedContext';
|
|
9
|
+
import { TFieldName } from 'SuiteResultTypes';
|
|
10
|
+
import { TestWalker } from 'TestWalker';
|
|
11
|
+
import { runDoneCallbacks, runFieldCallbacks } from 'runCallbacks';
|
|
12
|
+
|
|
13
|
+
export function initVestBus() {
|
|
14
|
+
const VestBus = bus.createBus();
|
|
15
|
+
|
|
16
|
+
// Report a the completion of a test. There may be other tests with the same
|
|
17
|
+
// name that are still running, or not yet started.
|
|
18
|
+
on(Events.TEST_COMPLETED, (testObject: IsolateTest) => {
|
|
19
|
+
if (testObject.isCanceled()) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
testObject.pass();
|
|
24
|
+
runFieldCallbacks(testObject.fieldName);
|
|
25
|
+
|
|
26
|
+
if (!TestWalker.hasRemainingTests()) {
|
|
27
|
+
// When no more tests are running, emit the done event
|
|
28
|
+
VestBus.emit(Events.ALL_RUNNING_TESTS_FINISHED);
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
on(Events.TEST_RUN_STARTED, () => {
|
|
33
|
+
/* Let's just invalidate the suite cache for now */
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
// Called when all the tests, including async, are done running
|
|
37
|
+
on(Events.ALL_RUNNING_TESTS_FINISHED, () => {
|
|
38
|
+
runDoneCallbacks();
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
on(Events.RESET_FIELD, (fieldName: TFieldName) => {
|
|
42
|
+
TestWalker.resetField(fieldName);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
on(Events.SUITE_RUN_STARTED, () => {
|
|
46
|
+
useResetCallbacks();
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
on(Events.REMOVE_FIELD, (fieldName: TFieldName) => {
|
|
50
|
+
TestWalker.removeTestByFieldName(fieldName);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
on(Events.RESET_SUITE, () => {
|
|
54
|
+
useResetSuite();
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
return VestBus;
|
|
58
|
+
|
|
59
|
+
function on(event: Events, cb: (...args: any[]) => void) {
|
|
60
|
+
VestBus.on(event, (...args: any[]) => {
|
|
61
|
+
// This is more concise, but it might be an overkill
|
|
62
|
+
// if we're adding events that don't need to invalidate the cache
|
|
63
|
+
useExpireSuiteResultCache();
|
|
64
|
+
cb(...args);
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export enum Events {
|
|
70
|
+
TEST_RUN_STARTED = 'test_run_started',
|
|
71
|
+
TEST_COMPLETED = 'test_completed',
|
|
72
|
+
ALL_RUNNING_TESTS_FINISHED = 'all_running_tests_finished',
|
|
73
|
+
REMOVE_FIELD = 'remove_field',
|
|
74
|
+
RESET_FIELD = 'reset_field',
|
|
75
|
+
RESET_SUITE = 'reset_suite',
|
|
76
|
+
SUITE_CALLBACK_DONE_RUNNING = 'suite_callback_done_running', // TODO: IMPLEMENT
|
|
77
|
+
SUITE_RUN_STARTED = 'suite_run_started',
|
|
78
|
+
}
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
import { createCascade } from 'context';
|
|
2
|
+
import {
|
|
3
|
+
invariant,
|
|
4
|
+
deferThrow,
|
|
5
|
+
isNullish,
|
|
6
|
+
CB,
|
|
7
|
+
seq,
|
|
8
|
+
cache,
|
|
9
|
+
assign,
|
|
10
|
+
BusType,
|
|
11
|
+
TinyState,
|
|
12
|
+
tinyState,
|
|
13
|
+
CacheApi,
|
|
14
|
+
} from 'vest-utils';
|
|
15
|
+
|
|
16
|
+
import { OptionalFields } from 'OptionalTypes';
|
|
17
|
+
import { SuiteName, SuiteResult, TFieldName } from 'SuiteResultTypes';
|
|
18
|
+
import { Events, initVestBus } from 'VestBus';
|
|
19
|
+
import { Isolate } from 'isolate';
|
|
20
|
+
|
|
21
|
+
const suiteResultCache = cache<SuiteResult<TFieldName>>();
|
|
22
|
+
|
|
23
|
+
export const PersistedContext = createCascade<CTXType>(
|
|
24
|
+
(vestState, parentContext) => {
|
|
25
|
+
if (parentContext) {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
invariant(vestState.historyRoot);
|
|
30
|
+
|
|
31
|
+
const [historyRootNode] = vestState.historyRoot();
|
|
32
|
+
|
|
33
|
+
const ctxRef = {} as CTXType;
|
|
34
|
+
|
|
35
|
+
assign(
|
|
36
|
+
ctxRef,
|
|
37
|
+
{
|
|
38
|
+
historyNode: historyRootNode,
|
|
39
|
+
optional: {},
|
|
40
|
+
runtimeNode: null,
|
|
41
|
+
runtimeRoot: null,
|
|
42
|
+
},
|
|
43
|
+
vestState
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
return ctxRef;
|
|
47
|
+
}
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
export function createVestState({
|
|
51
|
+
suiteName,
|
|
52
|
+
}: {
|
|
53
|
+
suiteName?: SuiteName;
|
|
54
|
+
}): StateType {
|
|
55
|
+
const stateRef: StateType = {
|
|
56
|
+
VestBus: initVestBus(),
|
|
57
|
+
doneCallbacks: tinyState.createTinyState<DoneCallbacks>(() => []),
|
|
58
|
+
fieldCallbacks: tinyState.createTinyState<FieldCallbacks>(() => ({})),
|
|
59
|
+
historyRoot: tinyState.createTinyState<Isolate | null>(null),
|
|
60
|
+
optional: {},
|
|
61
|
+
suiteId: seq(),
|
|
62
|
+
suiteName,
|
|
63
|
+
suiteResultCache,
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
return stateRef;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export function persist<T extends CB>(cb: T): T {
|
|
70
|
+
const prev = PersistedContext.useX();
|
|
71
|
+
|
|
72
|
+
return function persisted(...args: Parameters<T>): ReturnType<T> {
|
|
73
|
+
const ctxToUse = PersistedContext.use() ?? prev;
|
|
74
|
+
return PersistedContext.run(ctxToUse, () => cb(...args));
|
|
75
|
+
} as T;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export function useSuiteResultCache(action: () => SuiteResult<TFieldName>) {
|
|
79
|
+
const suiteResultCache = PersistedContext.useX().suiteResultCache;
|
|
80
|
+
|
|
81
|
+
return suiteResultCache([useSuiteId()], action);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export function useExpireSuiteResultCache() {
|
|
85
|
+
const suiteResultCache = PersistedContext.useX().suiteResultCache;
|
|
86
|
+
suiteResultCache.invalidate([useSuiteId()]);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export function useResetCallbacks() {
|
|
90
|
+
const [, , resetDoneCallbacks] = useDoneCallbacks();
|
|
91
|
+
const [, , resetFieldCallbacks] = useFieldCallbacks();
|
|
92
|
+
|
|
93
|
+
resetDoneCallbacks();
|
|
94
|
+
resetFieldCallbacks();
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export function useResetSuite() {
|
|
98
|
+
useResetCallbacks();
|
|
99
|
+
const [, , resetHistoryRoot] = useHistoryRoot();
|
|
100
|
+
|
|
101
|
+
resetHistoryRoot();
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
type CTXType = StateType & {
|
|
105
|
+
historyNode: Isolate | null;
|
|
106
|
+
runtimeNode: Isolate | null;
|
|
107
|
+
runtimeRoot: Isolate | null;
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
type StateType = {
|
|
111
|
+
historyRoot: TinyState<Isolate | null>;
|
|
112
|
+
doneCallbacks: TinyState<DoneCallbacks>;
|
|
113
|
+
fieldCallbacks: TinyState<FieldCallbacks>;
|
|
114
|
+
suiteName: string | undefined;
|
|
115
|
+
suiteId: string;
|
|
116
|
+
optional: OptionalFields;
|
|
117
|
+
VestBus: BusType;
|
|
118
|
+
suiteResultCache: CacheApi<SuiteResult<TFieldName>>;
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
type FieldCallbacks = Record<string, DoneCallbacks>;
|
|
122
|
+
type DoneCallbacks = Array<DoneCallback>;
|
|
123
|
+
|
|
124
|
+
export function useVestBus() {
|
|
125
|
+
return PersistedContext.useX().VestBus;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/*
|
|
129
|
+
Returns an emitter, but it also has a shortcut for emitting an event immediately
|
|
130
|
+
by passing an event name.
|
|
131
|
+
*/
|
|
132
|
+
export function useEmit() {
|
|
133
|
+
return persist(useVestBus().emit);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export function prepareEmitter<T = void>(event: Events): (arg: T) => void {
|
|
137
|
+
const emit = useEmit();
|
|
138
|
+
|
|
139
|
+
return (arg: T) => emit(event, arg);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export type DoneCallback = (res: SuiteResult<TFieldName>) => void;
|
|
143
|
+
|
|
144
|
+
export function useOptionalFields(): OptionalFields {
|
|
145
|
+
return PersistedContext.useX().optional;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export function useOptionalField(fieldName: TFieldName) {
|
|
149
|
+
return useOptionalFields()[fieldName] ?? {};
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export function useDoneCallbacks() {
|
|
153
|
+
return PersistedContext.useX().doneCallbacks();
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export function useFieldCallbacks() {
|
|
157
|
+
return PersistedContext.useX().fieldCallbacks();
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export function useHistoryRoot() {
|
|
161
|
+
return PersistedContext.useX().historyRoot();
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
export function useHistoryNode() {
|
|
165
|
+
return PersistedContext.useX().historyNode;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
export function useSuiteName() {
|
|
169
|
+
return PersistedContext.useX().suiteName;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
export function useSuiteId() {
|
|
173
|
+
return PersistedContext.useX().suiteId;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export function useSetHistory(history: Isolate) {
|
|
177
|
+
const context = PersistedContext.useX();
|
|
178
|
+
|
|
179
|
+
const [, setHistoryRoot] = context.historyRoot();
|
|
180
|
+
setHistoryRoot(history);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
export function useHistoryKey(key?: string | null): Isolate | null {
|
|
184
|
+
if (isNullish(key)) {
|
|
185
|
+
return null;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
const historyNode = PersistedContext.useX().historyNode;
|
|
189
|
+
|
|
190
|
+
return historyNode?.keys[key] ?? null;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
export function useIsolate() {
|
|
194
|
+
return PersistedContext.useX().runtimeNode ?? null;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
export function useCurrentCursor() {
|
|
198
|
+
return useIsolate()?.cursor() ?? 0;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
export function useRuntimeRoot() {
|
|
202
|
+
return PersistedContext.useX().runtimeRoot;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
export function useSetNextIsolateChild(child: Isolate): void {
|
|
206
|
+
const currentIsolate = useIsolate();
|
|
207
|
+
|
|
208
|
+
invariant(currentIsolate, 'Not within an active isolate');
|
|
209
|
+
|
|
210
|
+
currentIsolate.addChild(child);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
export function useSetIsolateKey(key: string | null, value: Isolate): void {
|
|
214
|
+
if (!key) {
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
const currentIsolate = useIsolate();
|
|
219
|
+
|
|
220
|
+
invariant(currentIsolate, 'Not within an active isolate');
|
|
221
|
+
|
|
222
|
+
if (isNullish(currentIsolate.keys[key])) {
|
|
223
|
+
currentIsolate.keys[key] = value;
|
|
224
|
+
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
deferThrow(
|
|
229
|
+
`Encountered the same test key "${key}" twice. This may lead to tests overriding each other's results, or to tests being unexpectedly omitted.`
|
|
230
|
+
);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
export function useAvailableSuiteRoot(): Isolate | null {
|
|
234
|
+
const root = useRuntimeRoot();
|
|
235
|
+
|
|
236
|
+
if (root) {
|
|
237
|
+
return root;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
const [historyRoot] = useHistoryRoot();
|
|
241
|
+
|
|
242
|
+
return historyRoot;
|
|
243
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { createCascade } from 'context';
|
|
2
|
+
import { assign, TinyState, tinyState, cache, CacheApi } from 'vest-utils';
|
|
3
|
+
|
|
4
|
+
import { IsolateTest } from 'IsolateTest';
|
|
5
|
+
import { Modes } from 'mode';
|
|
6
|
+
|
|
7
|
+
export const SuiteContext = createCascade<CTXType>((ctxRef, parentContext) => {
|
|
8
|
+
if (parentContext) {
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
return assign(
|
|
13
|
+
{
|
|
14
|
+
exclusion: {
|
|
15
|
+
tests: {},
|
|
16
|
+
groups: {},
|
|
17
|
+
},
|
|
18
|
+
inclusion: {},
|
|
19
|
+
mode: tinyState.createTinyState<Modes>(Modes.ALL),
|
|
20
|
+
testMemoCache,
|
|
21
|
+
},
|
|
22
|
+
ctxRef
|
|
23
|
+
);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
type CTXType = {
|
|
27
|
+
exclusion: TExclusion;
|
|
28
|
+
inclusion: Record<string, boolean | (() => boolean)>;
|
|
29
|
+
currentTest?: IsolateTest;
|
|
30
|
+
groupName?: string;
|
|
31
|
+
skipped?: boolean;
|
|
32
|
+
omitted?: boolean;
|
|
33
|
+
mode: TinyState<Modes>;
|
|
34
|
+
testMemoCache: CacheApi<IsolateTest>;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export type TExclusion = {
|
|
38
|
+
tests: Record<string, boolean>;
|
|
39
|
+
groups: Record<string, boolean>;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export function useCurrentTest(msg?: string) {
|
|
43
|
+
return SuiteContext.useX(msg).currentTest;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function useGroupName() {
|
|
47
|
+
return SuiteContext.useX().groupName;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function useExclusion(hookError?: string) {
|
|
51
|
+
return SuiteContext.useX(hookError).exclusion;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function useInclusion() {
|
|
55
|
+
return SuiteContext.useX().inclusion;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function useMode() {
|
|
59
|
+
return SuiteContext.useX().mode();
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function useSkipped() {
|
|
63
|
+
return SuiteContext.useX().skipped ?? false;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function useOmitted() {
|
|
67
|
+
return SuiteContext.useX().omitted ?? false;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const testMemoCache = cache<IsolateTest>(10);
|
|
71
|
+
|
|
72
|
+
export function useTestMemoCache() {
|
|
73
|
+
return SuiteContext.useX().testMemoCache;
|
|
74
|
+
}
|