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.
Files changed (182) hide show
  1. package/LICENSE +2 -2
  2. package/README.md +2 -57
  3. package/dist/cjs/classnames.development.js +18 -16
  4. package/dist/cjs/classnames.production.js +1 -1
  5. package/dist/cjs/enforce/compose.development.js +5 -54
  6. package/dist/cjs/enforce/compose.production.js +1 -1
  7. package/dist/cjs/enforce/compounds.development.js +20 -83
  8. package/dist/cjs/enforce/compounds.production.js +1 -1
  9. package/dist/cjs/enforce/schema.development.js +19 -82
  10. package/dist/cjs/enforce/schema.production.js +1 -1
  11. package/dist/cjs/parser.development.js +12 -9
  12. package/dist/cjs/parser.production.js +1 -1
  13. package/dist/cjs/promisify.development.js +4 -8
  14. package/dist/cjs/promisify.production.js +1 -1
  15. package/dist/cjs/vest.development.js +1287 -1153
  16. package/dist/cjs/vest.production.js +1 -1
  17. package/dist/es/classnames.development.js +20 -18
  18. package/dist/es/classnames.production.js +1 -1
  19. package/dist/es/enforce/compose.development.js +1 -58
  20. package/dist/es/enforce/compose.production.js +1 -1
  21. package/dist/es/enforce/compounds.development.js +2 -90
  22. package/dist/es/enforce/compounds.production.js +1 -1
  23. package/dist/es/enforce/schema.development.js +2 -88
  24. package/dist/es/enforce/schema.production.js +1 -1
  25. package/dist/es/parser.development.js +12 -9
  26. package/dist/es/parser.production.js +1 -1
  27. package/dist/es/promisify.development.js +5 -9
  28. package/dist/es/promisify.production.js +1 -1
  29. package/dist/es/vest.development.js +1286 -1148
  30. package/dist/es/vest.production.js +1 -1
  31. package/dist/umd/classnames.development.js +21 -19
  32. package/dist/umd/classnames.production.js +1 -1
  33. package/dist/umd/enforce/compose.development.js +9 -57
  34. package/dist/umd/enforce/compose.production.js +1 -1
  35. package/dist/umd/enforce/compounds.development.js +32 -94
  36. package/dist/umd/enforce/compounds.production.js +1 -1
  37. package/dist/umd/enforce/schema.development.js +32 -94
  38. package/dist/umd/enforce/schema.production.js +1 -1
  39. package/dist/umd/parser.development.js +16 -13
  40. package/dist/umd/parser.production.js +1 -1
  41. package/dist/umd/promisify.development.js +7 -11
  42. package/dist/umd/promisify.production.js +1 -1
  43. package/dist/umd/vest.development.js +1289 -1155
  44. package/dist/umd/vest.production.js +1 -1
  45. package/package.json +12 -16
  46. package/src/__tests__/__snapshots__/integration.async-tests.test.ts.snap +71 -0
  47. package/src/__tests__/__snapshots__/integration.base.test.ts.snap +71 -0
  48. package/src/__tests__/__snapshots__/integration.stateful-async.test.ts.snap +243 -0
  49. package/src/__tests__/__snapshots__/integration.stateful-tests.test.ts.snap +376 -0
  50. package/src/__tests__/integration.async-tests.test.ts +90 -0
  51. package/src/__tests__/integration.base.test.ts +45 -0
  52. package/src/__tests__/integration.exclusive.test.ts +88 -0
  53. package/src/__tests__/integration.stateful-async.test.ts +137 -0
  54. package/src/__tests__/integration.stateful-tests.test.ts +155 -0
  55. package/src/__tests__/isolate.test.ts +288 -0
  56. package/src/__tests__/state_refill.test.ts +41 -0
  57. package/src/core/SuiteWalker/SuiteWalker.ts +64 -0
  58. package/src/core/SuiteWalker/__tests__/hasRemainingTests.test.ts +130 -0
  59. package/src/core/VestBus/VestBus.ts +78 -0
  60. package/src/core/context/PersistedContext.ts +243 -0
  61. package/src/core/context/SuiteContext.ts +74 -0
  62. package/src/core/isolate/IsolateTest/IsolateTest.ts +213 -0
  63. package/src/core/isolate/IsolateTest/IsolateTestReconciler.ts +156 -0
  64. package/src/core/isolate/IsolateTest/IsolateTestStateMachine.ts +69 -0
  65. package/src/core/isolate/IsolateTest/SimpleStateMachine.ts +43 -0
  66. package/src/core/isolate/IsolateTest/TestWalker.ts +77 -0
  67. package/src/core/isolate/IsolateTypes.ts +10 -0
  68. package/src/core/isolate/isIsolate.ts +6 -0
  69. package/src/core/isolate/isolate.ts +110 -0
  70. package/src/core/isolate/reconciler/Reconciler/Reconciler.ts +123 -0
  71. package/src/core/isolate/reconciler/cancelOverriddenPendingTest.ts +15 -0
  72. package/src/core/isolate/reconciler/isSameProfileTest.ts +12 -0
  73. package/src/core/isolate/walker.ts +127 -0
  74. package/src/core/test/TestTypes.ts +3 -0
  75. package/src/core/test/__tests__/IsolateTest.test.ts +152 -0
  76. package/src/core/test/__tests__/__snapshots__/IsolateTest.test.ts.snap +39 -0
  77. package/src/core/test/__tests__/__snapshots__/memo.test.ts.snap +101 -0
  78. package/src/core/test/__tests__/__snapshots__/test.test.ts.snap +231 -0
  79. package/src/core/test/__tests__/key.test.ts +195 -0
  80. package/src/core/test/__tests__/memo.test.ts +218 -0
  81. package/src/core/test/__tests__/merging_of_previous_test_runs.test.ts +341 -0
  82. package/src/core/test/__tests__/runAsyncTest.test.ts +175 -0
  83. package/src/core/test/__tests__/test.test.ts +226 -0
  84. package/src/core/test/helpers/__tests__/nonMatchingSeverityProfile.test.ts +52 -0
  85. package/src/core/test/helpers/asVestTest.ts +9 -0
  86. package/src/core/test/helpers/matchingFieldName.ts +16 -0
  87. package/src/core/test/helpers/matchingGroupName.ts +12 -0
  88. package/src/core/test/helpers/nonMatchingSeverityProfile.ts +14 -0
  89. package/src/core/test/helpers/shouldUseErrorMessage.ts +9 -0
  90. package/src/core/test/test.memo.ts +81 -0
  91. package/src/core/test/test.ts +64 -0
  92. package/src/core/test/testLevelFlowControl/runTest.ts +86 -0
  93. package/src/core/test/testLevelFlowControl/verifyTestRun.ts +32 -0
  94. package/src/core/test/testObjectIsolate.ts +11 -0
  95. package/src/errors/ErrorStrings.ts +4 -0
  96. package/src/exports/__tests__/classnames.test.ts +92 -0
  97. package/src/exports/__tests__/parser.test.ts +441 -0
  98. package/src/exports/__tests__/promisify.test.ts +77 -0
  99. package/src/exports/classnames.ts +35 -0
  100. package/src/exports/enforce@compose.ts +1 -0
  101. package/src/exports/enforce@compounds.ts +1 -0
  102. package/src/exports/enforce@schema.ts +1 -0
  103. package/src/exports/parser.ts +63 -0
  104. package/src/exports/promisify.ts +18 -0
  105. package/src/hooks/__tests__/__snapshots__/include.test.ts.snap +794 -0
  106. package/src/hooks/__tests__/eager.test.ts +130 -0
  107. package/src/hooks/__tests__/exclusive.test.ts +578 -0
  108. package/src/hooks/__tests__/include.test.ts +431 -0
  109. package/src/hooks/__tests__/optional.test.ts +83 -0
  110. package/src/hooks/__tests__/warn.test.ts +42 -0
  111. package/src/hooks/exclusive.ts +179 -0
  112. package/src/hooks/include.ts +54 -0
  113. package/src/hooks/mode.ts +47 -0
  114. package/src/hooks/optional/OptionalTypes.ts +31 -0
  115. package/src/hooks/optional/optional.ts +69 -0
  116. package/src/hooks/warn.ts +19 -0
  117. package/src/isolates/__tests__/__snapshots__/each.test.ts.snap +3 -0
  118. package/src/isolates/__tests__/__snapshots__/group.test.ts.snap +114 -0
  119. package/src/isolates/__tests__/__snapshots__/omitWhen.test.ts.snap +443 -0
  120. package/src/isolates/__tests__/__snapshots__/skipWhen.test.ts.snap +99 -0
  121. package/src/isolates/__tests__/each.test.ts +35 -0
  122. package/src/isolates/__tests__/group.test.ts +362 -0
  123. package/src/isolates/__tests__/omitWhen.test.ts +246 -0
  124. package/src/isolates/__tests__/skipWhen.test.ts +163 -0
  125. package/src/isolates/each.ts +30 -0
  126. package/src/isolates/group.ts +9 -0
  127. package/src/isolates/omitWhen.ts +41 -0
  128. package/src/isolates/skipWhen.ts +42 -0
  129. package/src/suite/__tests__/__snapshots__/create.test.ts.snap +67 -0
  130. package/src/suite/__tests__/create.test.ts +109 -0
  131. package/src/suite/__tests__/remove.test.ts +50 -0
  132. package/src/suite/__tests__/resetField.test.ts +74 -0
  133. package/src/suite/createSuite.ts +94 -0
  134. package/src/suite/runCallbacks.ts +28 -0
  135. package/src/suiteResult/Severity.ts +15 -0
  136. package/src/suiteResult/SuiteResultTypes.ts +42 -0
  137. package/src/suiteResult/__tests__/done.test.ts +334 -0
  138. package/src/suiteResult/__tests__/produce.test.ts +163 -0
  139. package/src/suiteResult/done/deferDoneCallback.ts +28 -0
  140. package/src/suiteResult/done/shouldSkipDoneRegistration.ts +20 -0
  141. package/src/suiteResult/selectors/__tests__/__snapshots__/collectFailureMessages.test.ts.snap +89 -0
  142. package/src/suiteResult/selectors/__tests__/collectFailureMessages.test.ts +124 -0
  143. package/src/suiteResult/selectors/__tests__/getFailures.test.ts +158 -0
  144. package/src/suiteResult/selectors/__tests__/getFailuresByGroup.test.ts +199 -0
  145. package/src/suiteResult/selectors/__tests__/hasFailures.test.ts +141 -0
  146. package/src/suiteResult/selectors/__tests__/hasFailuresByGroup.test.ts +185 -0
  147. package/src/suiteResult/selectors/__tests__/hasFailuresByTestObject.test.ts +88 -0
  148. package/src/suiteResult/selectors/__tests__/isValid.test.ts +359 -0
  149. package/src/suiteResult/selectors/__tests__/isValidByGroup.test.ts +480 -0
  150. package/src/suiteResult/selectors/collectFailures.ts +43 -0
  151. package/src/suiteResult/selectors/hasFailuresByTestObjects.ts +62 -0
  152. package/src/suiteResult/selectors/produceSuiteSummary.ts +135 -0
  153. package/src/suiteResult/selectors/shouldAddValidProperty.ts +148 -0
  154. package/src/suiteResult/selectors/suiteSelectors.ts +199 -0
  155. package/src/suiteResult/suiteResult.ts +15 -0
  156. package/src/suiteResult/suiteRunResult.ts +43 -0
  157. package/src/vest.ts +36 -0
  158. package/testUtils/TVestMock.ts +5 -0
  159. package/testUtils/__tests__/partition.test.ts +4 -4
  160. package/testUtils/mockThrowError.ts +4 -2
  161. package/testUtils/suiteDummy.ts +2 -1
  162. package/testUtils/testDummy.ts +12 -10
  163. package/testUtils/testPromise.ts +3 -0
  164. package/tsconfig.json +84 -2
  165. package/types/classnames.d.ts +39 -4
  166. package/types/classnames.d.ts.map +1 -0
  167. package/types/enforce/compose.d.ts +2 -126
  168. package/types/enforce/compose.d.ts.map +1 -0
  169. package/types/enforce/compounds.d.ts +2 -136
  170. package/types/enforce/compounds.d.ts.map +1 -0
  171. package/types/enforce/schema.d.ts +2 -144
  172. package/types/enforce/schema.d.ts.map +1 -0
  173. package/types/parser.d.ts +45 -10
  174. package/types/parser.d.ts.map +1 -0
  175. package/types/promisify.d.ts +36 -34
  176. package/types/promisify.d.ts.map +1 -0
  177. package/types/vest.d.ts +169 -224
  178. package/types/vest.d.ts.map +1 -0
  179. package/CHANGELOG.md +0 -87
  180. package/testUtils/expandStateRef.ts +0 -8
  181. package/testUtils/runCreateRef.ts +0 -10
  182. 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
+ }