vest 5.0.0-dev-9c596e → 5.0.0-dev-ae6b14

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 (47) hide show
  1. package/dist/cjs/classnames.development.js +1 -2
  2. package/dist/cjs/classnames.production.js +1 -1
  3. package/dist/cjs/enforce/compose.development.js +1 -5
  4. package/dist/cjs/enforce/compose.production.js +1 -1
  5. package/dist/cjs/enforce/compounds.development.js +3 -6
  6. package/dist/cjs/enforce/compounds.production.js +1 -1
  7. package/dist/cjs/enforce/schema.development.js +3 -6
  8. package/dist/cjs/enforce/schema.production.js +1 -1
  9. package/dist/cjs/parser.development.js +1 -4
  10. package/dist/cjs/parser.production.js +1 -1
  11. package/dist/cjs/promisify.development.js +1 -2
  12. package/dist/cjs/promisify.production.js +1 -1
  13. package/dist/cjs/vest.development.js +516 -682
  14. package/dist/cjs/vest.production.js +1 -1
  15. package/dist/es/classnames.development.js +1 -2
  16. package/dist/es/classnames.production.js +1 -1
  17. package/dist/es/parser.development.js +1 -2
  18. package/dist/es/parser.production.js +1 -1
  19. package/dist/es/promisify.development.js +1 -2
  20. package/dist/es/promisify.production.js +1 -1
  21. package/dist/es/vest.development.js +512 -676
  22. package/dist/es/vest.production.js +1 -1
  23. package/dist/umd/classnames.development.js +1 -2
  24. package/dist/umd/classnames.production.js +1 -1
  25. package/dist/umd/enforce/compose.development.js +1 -7
  26. package/dist/umd/enforce/compose.production.js +1 -1
  27. package/dist/umd/enforce/compounds.development.js +3 -6
  28. package/dist/umd/enforce/compounds.production.js +1 -1
  29. package/dist/umd/enforce/schema.development.js +3 -6
  30. package/dist/umd/enforce/schema.production.js +1 -1
  31. package/dist/umd/parser.development.js +1 -4
  32. package/dist/umd/parser.production.js +1 -1
  33. package/dist/umd/promisify.development.js +1 -2
  34. package/dist/umd/promisify.production.js +1 -1
  35. package/dist/umd/vest.development.js +520 -687
  36. package/dist/umd/vest.production.js +1 -1
  37. package/package.json +137 -136
  38. package/testUtils/TVestMock.ts +1 -1
  39. package/testUtils/asVestTest.ts +9 -0
  40. package/types/classnames.d.ts +82 -4
  41. package/types/classnames.d.ts.map +1 -1
  42. package/types/parser.d.ts +82 -4
  43. package/types/parser.d.ts.map +1 -1
  44. package/types/promisify.d.ts +82 -4
  45. package/types/promisify.d.ts.map +1 -1
  46. package/types/vest.d.ts +152 -140
  47. package/types/vest.d.ts.map +1 -1
@@ -1,33 +1,62 @@
1
1
  'use strict';
2
2
 
3
- Object.defineProperty(exports, '__esModule', { value: true });
4
-
5
3
  var n4s = require('n4s');
6
4
  var vestUtils = require('vest-utils');
5
+ var vestjsRuntime = require('vestjs-runtime');
7
6
  var context = require('context');
8
7
 
9
8
  var OptionalFieldTypes;
10
9
  (function (OptionalFieldTypes) {
11
- OptionalFieldTypes[OptionalFieldTypes["Immediate"] = 0] = "Immediate";
12
- OptionalFieldTypes[OptionalFieldTypes["Delayed"] = 1] = "Delayed";
10
+ OptionalFieldTypes[OptionalFieldTypes["CUSTOM_LOGIC"] = 0] = "CUSTOM_LOGIC";
11
+ OptionalFieldTypes[OptionalFieldTypes["AUTO"] = 1] = "AUTO";
13
12
  })(OptionalFieldTypes || (OptionalFieldTypes = {}));
14
13
 
15
- var ErrorStrings;
16
- (function (ErrorStrings) {
17
- ErrorStrings["HOOK_CALLED_OUTSIDE"] = "hook called outside of a running suite.";
18
- ErrorStrings["EXPECTED_VEST_TEST"] = "Expected value to be an instance of IsolateTest";
19
- ErrorStrings["FIELD_NAME_REQUIRED"] = "Field name must be passed";
20
- ErrorStrings["SUITE_MUST_BE_INITIALIZED_WITH_FUNCTION"] = "Suite must be initialized with a function";
21
- ErrorStrings["NO_ACTIVE_ISOLATE"] = "Not within an active isolate";
22
- ErrorStrings["PROMISIFY_REQUIRE_FUNCTION"] = "Vest.Promisify must be called with a function";
23
- ErrorStrings["PARSER_EXPECT_RESULT_OBJECT"] = "Vest parser: expected argument at position 0 to be Vest's result object.";
24
- ErrorStrings["WARN_MUST_BE_CALLED_FROM_TEST"] = "Warn must be called from within the body of a test function";
25
- ErrorStrings["EACH_CALLBACK_MUST_BE_A_FUNCTION"] = "Each must be called with a function";
26
- ErrorStrings["INVALID_PARAM_PASSED_TO_FUNCTION"] = "Incompatible params passed to {fn_name} function. \"{param}\" must be of type {expected}";
27
- ErrorStrings["ENCOUNTERED_THE_SAME_KEY_TWICE"] = "Encountered the same test key \"{key}\" twice. This may lead to tests overriding each other's results, or to tests being unexpectedly omitted.";
28
- ErrorStrings["TESTS_CALLED_IN_DIFFERENT_ORDER"] = "Vest Critical Error: Tests called in different order than previous run.\n expected: {fieldName}\n received: {prevName}\n This can happen on one of two reasons:\n 1. You're using if/else statements to conditionally select tests. Instead, use \"skipWhen\".\n 2. You are iterating over a list of tests, and their order changed. Use \"each\" and a custom key prop so that Vest retains their state.";
29
- ErrorStrings["UNEXPECTED_TEST_REGISTRATION_ERROR"] = "Unexpected error encountered during test registration.\n Please report this issue to Vest's Github repository.\n Test Object: {testObject}.\n Error: {error}.";
30
- })(ErrorStrings || (ErrorStrings = {}));
14
+ // @vx-allow use-use
15
+ function optional(optionals) {
16
+ const suiteRoot = vestjsRuntime.VestRuntime.useAvailableRoot();
17
+ // There are two types of optional field declarations:
18
+ // 1 AUTO: Vest will automatically determine whether the field should be omitted
19
+ // Based on the current run. Vest will ommit "auto" added fields without any
20
+ // configuration if their tests did not run at all in the suite.
21
+ //
22
+ // 2 Custom logic: Vest will determine whether they should fail based on the custom
23
+ // logic supplied by the user.
24
+ // AUTO case (field name)
25
+ if (vestUtils.isArray(optionals) || vestUtils.isStringValue(optionals)) {
26
+ vestUtils.asArray(optionals).forEach(optionalField => {
27
+ suiteRoot.setOptionalField(optionalField, () => ({
28
+ type: OptionalFieldTypes.AUTO,
29
+ applied: false,
30
+ rule: null,
31
+ }));
32
+ });
33
+ }
34
+ else {
35
+ // CUSTOM_LOGIC case (function or boolean)
36
+ for (const field in optionals) {
37
+ const value = optionals[field];
38
+ suiteRoot.setOptionalField(field, () => ({
39
+ type: OptionalFieldTypes.CUSTOM_LOGIC,
40
+ rule: value,
41
+ applied: value === true,
42
+ }));
43
+ }
44
+ }
45
+ }
46
+ function useIsOptionalFiedApplied(fieldName) {
47
+ var _a, _b, _c;
48
+ if (!fieldName) {
49
+ return false;
50
+ }
51
+ return ((_c = (_b = (_a = vestjsRuntime.VestRuntime.useAvailableRoot()) === null || _a === void 0 ? void 0 : _a.getOptionalField(fieldName)) === null || _b === void 0 ? void 0 : _b.applied) !== null && _c !== void 0 ? _c : false);
52
+ }
53
+
54
+ exports.Modes = void 0;
55
+ (function (Modes) {
56
+ Modes["EAGER"] = "EAGER";
57
+ Modes["ALL"] = "ALL";
58
+ Modes["ONE"] = "ONE";
59
+ })(exports.Modes || (exports.Modes = {}));
31
60
 
32
61
  var Events;
33
62
  (function (Events) {
@@ -38,230 +67,133 @@ var Events;
38
67
  Events["RESET_FIELD"] = "reset_field";
39
68
  Events["RESET_SUITE"] = "reset_suite";
40
69
  Events["SUITE_RUN_STARTED"] = "suite_run_started";
70
+ Events["SUITE_CALLBACK_RUN_FINISHED"] = "SUITE_CALLBACK_RUN_FINISHED";
71
+ Events["DONE_TEST_OMISSION_PASS"] = "DONE_TEST_OMISSION_PASS";
41
72
  })(Events || (Events = {}));
42
73
 
43
- // eslint-disable-next-line complexity, max-statements
44
- function walk(startNode, callback, visitOnly) {
45
- if (vestUtils.isNullish(startNode.children)) {
46
- return;
47
- }
48
- let broke = false;
49
- for (const isolate of startNode.children) {
50
- if (broke) {
51
- return;
52
- }
53
- if (vestUtils.isNullish(visitOnly) || vestUtils.optionalFunctionValue(visitOnly, isolate)) {
54
- callback(isolate, breakout);
55
- }
56
- if (broke) {
57
- return;
58
- }
59
- walk(isolate, (child, innerBreakout) => {
60
- callback(child, () => {
61
- innerBreakout();
62
- breakout();
63
- });
64
- }, visitOnly);
65
- }
66
- function breakout() {
67
- broke = true;
68
- }
69
- }
70
- function some(startNode, predicate, visitOnly) {
71
- let hasMatch = false;
72
- walk(startNode, (node, breakout) => {
73
- if (predicate(node)) {
74
- breakout();
75
- hasMatch = true;
76
- }
77
- }, visitOnly);
78
- return hasMatch;
79
- }
80
- function has(startNode, match) {
81
- return some(startNode, () => true, match);
82
- }
83
- function every(startNode, predicate, visitOnly) {
84
- let hasMatch = true;
85
- walk(startNode, (node, breakout) => {
86
- if (!predicate(node)) {
87
- breakout();
88
- hasMatch = false;
89
- }
90
- }, visitOnly);
91
- return hasMatch;
92
- }
93
- function pluck(startNode, predicate, visitOnly) {
94
- walk(startNode, node => {
95
- if (predicate(node) && node.parent) {
96
- node.parent.removeChild(node);
97
- }
98
- }, visitOnly);
99
- }
100
- function closest(startNode, predicate) {
101
- let current = startNode;
102
- while (current.parent) {
103
- if (predicate(current)) {
104
- return current;
105
- }
106
- current = current.parent;
74
+ class IsolateSuite extends vestjsRuntime.Isolate {
75
+ constructor() {
76
+ super(...arguments);
77
+ this.optional = {};
107
78
  }
108
- return null;
109
- }
110
- function closestExists(startNode, predicate) {
111
- return !!closest(startNode, predicate);
112
- }
113
-
114
- class Reconciler {
115
- static reconciler(currentNode, historicNode) {
116
- if (vestUtils.isNullish(historicNode)) {
117
- return currentNode;
118
- }
119
- return currentNode;
79
+ setOptionalField(fieldName, setter) {
80
+ const current = this.optional;
81
+ const currentField = current[fieldName];
82
+ Object.assign(current, {
83
+ [fieldName]: Object.assign({}, currentField, setter(currentField)),
84
+ });
120
85
  }
121
- static reconcile(node, callback) {
86
+ getOptionalField(fieldName) {
122
87
  var _a;
123
- const parent = useIsolate();
124
- const historyNode = useHistoryNode();
125
- let localHistoryNode = historyNode;
126
- if (parent) {
127
- // If we have a parent, we need to get the history node from the parent's children
128
- // We take the history node from the cursor of the active node's children
129
- localHistoryNode = (_a = historyNode === null || historyNode === void 0 ? void 0 : historyNode.at(useCurrentCursor())) !== null && _a !== void 0 ? _a : null;
130
- }
131
- const nextNode = this.reconciler(node, localHistoryNode);
132
- vestUtils.invariant(nextNode);
133
- if (Object.is(nextNode, node)) {
134
- return [node, useRunAsNew(localHistoryNode, node, callback)];
135
- }
136
- return [nextNode, nextNode.output];
137
- }
138
- static removeAllNextNodesInIsolate() {
139
- const testIsolate = useIsolate();
140
- const historyNode = useHistoryNode();
141
- if (!historyNode || !testIsolate) {
142
- return;
143
- }
144
- historyNode.slice(useCurrentCursor());
88
+ return (_a = this.optional[fieldName]) !== null && _a !== void 0 ? _a : {};
145
89
  }
146
- static handleCollision(newNode, prevNode) {
147
- // we should base our calculation on the key property
148
- if (newNode.usesKey()) {
149
- return this.handleIsolateNodeWithKey(newNode);
150
- }
151
- if (this.nodeReorderDetected(newNode, prevNode)) {
152
- this.onNodeReorder(newNode, prevNode);
153
- }
154
- return prevNode ? prevNode : newNode;
155
- }
156
- static nodeReorderDetected(newNode, prevNode) {
157
- // This is a dummy return just to satisfy the linter. Overrides will supply the real implementation.
158
- return !(newNode !== null && newNode !== void 0 ? newNode : prevNode);
159
- }
160
- static onNodeReorder(newNode, prevNode) {
161
- this.removeAllNextNodesInIsolate();
162
- // This is a dummy return just to satisfy the linter. Overrides will supply the real implementation.
163
- return newNode !== null && newNode !== void 0 ? newNode : prevNode;
164
- }
165
- static handleIsolateNodeWithKey(node) {
166
- vestUtils.invariant(node.usesKey());
167
- const prevNodeByKey = useHistoryKey(node.key);
168
- let nextNode = node;
169
- if (!vestUtils.isNullish(prevNodeByKey)) {
170
- nextNode = prevNodeByKey;
171
- }
172
- useSetIsolateKey(node.key, node);
173
- return nextNode;
90
+ getOptionalFields() {
91
+ return this.optional;
174
92
  }
175
93
  }
176
- function useRunAsNew(localHistoryNode, current, callback) {
177
- const runtimeRoot = useRuntimeRoot();
178
- // We're creating a new child isolate context where the local history node
179
- // is the current history node, thus advancing the history cursor.
180
- const output = PersistedContext.run(Object.assign({ historyNode: localHistoryNode, runtimeNode: current }, (!runtimeRoot && { runtimeRoot: current })), () => callback(current));
181
- current.output = output;
182
- return output;
94
+
95
+ const suiteResultCache = vestUtils.cache();
96
+ function useCreateVestState({ suiteName, } = {}) {
97
+ const stateRef = {
98
+ doneCallbacks: vestUtils.tinyState.createTinyState(() => []),
99
+ fieldCallbacks: vestUtils.tinyState.createTinyState(() => ({})),
100
+ suiteId: vestUtils.seq(),
101
+ suiteName,
102
+ suiteResultCache,
103
+ };
104
+ return vestjsRuntime.VestRuntime.createRef(stateRef);
105
+ }
106
+ function useX() {
107
+ return vestjsRuntime.VestRuntime.useXAppData();
108
+ }
109
+ function useDoneCallbacks() {
110
+ return useX().doneCallbacks();
111
+ }
112
+ function useFieldCallbacks() {
113
+ return useX().fieldCallbacks();
114
+ }
115
+ function useSuiteName() {
116
+ return useX().suiteName;
117
+ }
118
+ function useSuiteId() {
119
+ return useX().suiteId;
120
+ }
121
+ function useSuiteResultCache(action) {
122
+ const suiteResultCache = useX().suiteResultCache;
123
+ return suiteResultCache([useSuiteId()], action);
124
+ }
125
+ function useExpireSuiteResultCache() {
126
+ const suiteResultCache = useX().suiteResultCache;
127
+ suiteResultCache.invalidate([useSuiteId()]);
128
+ }
129
+ function useResetCallbacks() {
130
+ const [, , resetDoneCallbacks] = useDoneCallbacks();
131
+ const [, , resetFieldCallbacks] = useFieldCallbacks();
132
+ resetDoneCallbacks();
133
+ resetFieldCallbacks();
134
+ }
135
+ function useResetSuite() {
136
+ useResetCallbacks();
137
+ vestjsRuntime.VestRuntime.reset();
183
138
  }
184
139
 
185
- class Isolate {
186
- // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function
187
- constructor(_data) {
188
- this.children = [];
189
- this.keys = {};
190
- this.parent = null;
191
- this.key = null;
192
- this.allowReorder = false;
193
- }
194
- setParent(parent) {
195
- this.parent = parent;
196
- return this;
197
- }
198
- saveOutput(output) {
199
- this.output = output;
200
- return this;
201
- }
202
- setKey(key) {
203
- this.key = key;
204
- return this;
205
- }
206
- usesKey() {
207
- return vestUtils.isNotNullish(this.key);
208
- }
209
- addChild(child) {
210
- vestUtils.invariant(this.children);
211
- this.children.push(child);
212
- }
213
- removeChild(node) {
214
- var _a, _b;
215
- this.children = (_b = (_a = this.children) === null || _a === void 0 ? void 0 : _a.filter(child => child !== node)) !== null && _b !== void 0 ? _b : null;
216
- }
217
- slice(at) {
218
- if (vestUtils.isNullish(this.children)) {
219
- return;
220
- }
221
- this.children.length = at;
222
- }
223
- at(at) {
224
- var _a, _b;
225
- return (_b = (_a = this.children) === null || _a === void 0 ? void 0 : _a[at]) !== null && _b !== void 0 ? _b : null;
226
- }
227
- cursor() {
228
- var _a, _b;
229
- return (_b = (_a = this.children) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0;
230
- }
231
- shouldAllowReorder() {
232
- var _a;
233
- return (_a = closestExists(this, node => node.allowReorder)) !== null && _a !== void 0 ? _a : false;
234
- }
235
- get rootNode() {
236
- var _a;
237
- return (_a = closest(this, node => vestUtils.isNullish(node.parent))) !== null && _a !== void 0 ? _a : this;
238
- }
239
- static create(callback, data) {
240
- return this.createImplementation(callback, data);
241
- }
242
- static createImplementation(callback, data) {
243
- const parent = useIsolate();
244
- const newCreatedNode = new this(data).setParent(parent);
245
- const [nextIsolateChild, output] = this.reconciler.reconcile(newCreatedNode, callback);
246
- nextIsolateChild.saveOutput(output);
247
- this.setNode(nextIsolateChild);
248
- return nextIsolateChild;
249
- }
250
- static setNode(node) {
251
- const parent = useIsolate();
252
- if (parent) {
253
- useSetNextIsolateChild(node);
254
- }
255
- else {
256
- useSetHistory(node);
257
- }
258
- node.setParent(parent);
259
- }
260
- static is(node) {
261
- return node instanceof Isolate;
140
+ const SuiteContext = context.createCascade((ctxRef, parentContext) => {
141
+ if (parentContext) {
142
+ return null;
262
143
  }
144
+ return vestUtils.assign({
145
+ exclusion: {
146
+ tests: {},
147
+ groups: {},
148
+ },
149
+ inclusion: {},
150
+ mode: vestUtils.tinyState.createTinyState(exports.Modes.EAGER),
151
+ testMemoCache,
152
+ }, ctxRef);
153
+ });
154
+ function useCurrentTest(msg) {
155
+ return SuiteContext.useX(msg).currentTest;
156
+ }
157
+ function useGroupName() {
158
+ return SuiteContext.useX().groupName;
159
+ }
160
+ function useExclusion(hookError) {
161
+ return SuiteContext.useX(hookError).exclusion;
162
+ }
163
+ function useInclusion() {
164
+ return SuiteContext.useX().inclusion;
165
+ }
166
+ function useMode() {
167
+ return SuiteContext.useX().mode();
168
+ }
169
+ function useSkipped() {
170
+ var _a;
171
+ return (_a = SuiteContext.useX().skipped) !== null && _a !== void 0 ? _a : false;
172
+ }
173
+ function useOmitted() {
174
+ var _a;
175
+ return (_a = SuiteContext.useX().omitted) !== null && _a !== void 0 ? _a : false;
176
+ }
177
+ const testMemoCache = vestUtils.cache(10);
178
+ function useTestMemoCache() {
179
+ return SuiteContext.useX().testMemoCache;
263
180
  }
264
- Isolate.reconciler = Reconciler;
181
+
182
+ var ErrorStrings;
183
+ (function (ErrorStrings) {
184
+ ErrorStrings["HOOK_CALLED_OUTSIDE"] = "hook called outside of a running suite.";
185
+ ErrorStrings["EXPECTED_VEST_TEST"] = "Expected value to be an instance of IsolateTest";
186
+ ErrorStrings["FIELD_NAME_REQUIRED"] = "Field name must be passed";
187
+ ErrorStrings["SUITE_MUST_BE_INITIALIZED_WITH_FUNCTION"] = "Suite must be initialized with a function";
188
+ ErrorStrings["PROMISIFY_REQUIRE_FUNCTION"] = "Vest.Promisify must be called with a function";
189
+ ErrorStrings["PARSER_EXPECT_RESULT_OBJECT"] = "Vest parser: expected argument at position 0 to be Vest's result object.";
190
+ ErrorStrings["WARN_MUST_BE_CALLED_FROM_TEST"] = "Warn must be called from within the body of a test function";
191
+ ErrorStrings["EACH_CALLBACK_MUST_BE_A_FUNCTION"] = "Each must be called with a function";
192
+ ErrorStrings["INVALID_PARAM_PASSED_TO_FUNCTION"] = "Incompatible params passed to {fn_name} function. \"{param}\" must be of type {expected}";
193
+ ErrorStrings["TESTS_CALLED_IN_DIFFERENT_ORDER"] = "Vest Critical Error: Tests called in different order than previous run.\n expected: {fieldName}\n received: {prevName}\n This can happen on one of two reasons:\n 1. You're using if/else statements to conditionally select tests. Instead, use \"skipWhen\".\n 2. You are iterating over a list of tests, and their order changed. Use \"each\" and a custom key prop so that Vest retains their state.";
194
+ ErrorStrings["UNEXPECTED_TEST_REGISTRATION_ERROR"] = "Unexpected error encountered during test registration.\n Please report this issue to Vest's Github repository.\n Test Object: {testObject}.\n Error: {error}.";
195
+ ErrorStrings["UNEXPECTED_TEST_RUN_ERROR"] = "Unexpected error encountered during test run. Please report this issue to Vest's Github repository.\n Test Object: {testObject}.";
196
+ })(ErrorStrings || (ErrorStrings = {}));
265
197
 
266
198
  function nonMatchingFieldName(WithFieldName, fieldName) {
267
199
  return !!fieldName && !matchingFieldName(WithFieldName, fieldName);
@@ -299,6 +231,45 @@ function countKeyBySeverity(severity) {
299
231
  ? SeverityCount.ERROR_COUNT
300
232
  : SeverityCount.WARN_COUNT;
301
233
  }
234
+ var TestSeverity;
235
+ (function (TestSeverity) {
236
+ TestSeverity["Error"] = "error";
237
+ TestSeverity["Warning"] = "warning";
238
+ })(TestSeverity || (TestSeverity = {}));
239
+
240
+ var _a, _b;
241
+ class SummaryBase {
242
+ constructor() {
243
+ this.errorCount = 0;
244
+ this.warnCount = 0;
245
+ this.testCount = 0;
246
+ }
247
+ }
248
+ class SuiteSummary extends SummaryBase {
249
+ constructor() {
250
+ super(...arguments);
251
+ this[_a] = [];
252
+ this[_b] = [];
253
+ this.groups = {};
254
+ this.tests = {};
255
+ this.valid = false;
256
+ }
257
+ }
258
+ _a = Severity.ERRORS, _b = Severity.WARNINGS;
259
+
260
+ class SummaryFailure {
261
+ constructor(fieldName, message, groupName) {
262
+ this.fieldName = fieldName;
263
+ this.message = message;
264
+ this.groupName = groupName;
265
+ }
266
+ static fromTestObject(testObject) {
267
+ return new SummaryFailure(testObject.fieldName, testObject.message, testObject.groupName);
268
+ }
269
+ toString() {
270
+ return this.message || '';
271
+ }
272
+ }
302
273
 
303
274
  const nonMatchingGroupName = vestUtils.bindNot(matchingGroupName);
304
275
  function matchingGroupName(testObject, groupName) {
@@ -348,108 +319,6 @@ function hasFailuresByTestObject(testObject, severityKey, fieldName) {
348
319
  return true;
349
320
  }
350
321
 
351
- exports.Modes = void 0;
352
- (function (Modes) {
353
- Modes["ALL"] = "ALL";
354
- Modes["EAGER"] = "EAGER";
355
- })(exports.Modes || (exports.Modes = {}));
356
- /**
357
- * Sets the suite to "eager" (fail fast) mode.
358
- * Eager mode will skip running subsequent tests of a failing fields.
359
- *
360
- * @example
361
- * // in the following example, the second test of username will not run
362
- * // if the first test of username failed.
363
- * const suite = create((data) => {
364
- * eager();
365
- *
366
- * test('username', 'username is required', () => {
367
- * enforce(data.username).isNotBlank();
368
- * });
369
- *
370
- * test('username', 'username is too short', () => {
371
- * enforce(data.username).longerThan(2);
372
- * });
373
- * });
374
- */
375
- // @vx-allow use-use
376
- function mode(mode) {
377
- const [, setMode] = useMode();
378
- setMode(mode);
379
- }
380
- function useIsMode(mode) {
381
- const [currentMode] = useMode();
382
- return currentMode === mode;
383
- }
384
- function useIsEager() {
385
- return useIsMode(exports.Modes.EAGER);
386
- }
387
- function useShouldSkipBasedOnMode(testObject) {
388
- return useIsEager() && hasErrorsByTestObjects(testObject.fieldName);
389
- }
390
-
391
- const SuiteContext = context.createCascade((ctxRef, parentContext) => {
392
- if (parentContext) {
393
- return null;
394
- }
395
- return vestUtils.assign({
396
- exclusion: {
397
- tests: {},
398
- groups: {},
399
- },
400
- inclusion: {},
401
- mode: vestUtils.tinyState.createTinyState(exports.Modes.EAGER),
402
- testMemoCache,
403
- }, ctxRef);
404
- });
405
- function useCurrentTest(msg) {
406
- return SuiteContext.useX(msg).currentTest;
407
- }
408
- function useGroupName() {
409
- return SuiteContext.useX().groupName;
410
- }
411
- function useExclusion(hookError) {
412
- return SuiteContext.useX(hookError).exclusion;
413
- }
414
- function useInclusion() {
415
- return SuiteContext.useX().inclusion;
416
- }
417
- function useMode() {
418
- return SuiteContext.useX().mode();
419
- }
420
- function useSkipped() {
421
- var _a;
422
- return (_a = SuiteContext.useX().skipped) !== null && _a !== void 0 ? _a : false;
423
- }
424
- function useOmitted() {
425
- var _a;
426
- return (_a = SuiteContext.useX().omitted) !== null && _a !== void 0 ? _a : false;
427
- }
428
- const testMemoCache = vestUtils.cache(10);
429
- function useTestMemoCache() {
430
- return SuiteContext.useX().testMemoCache;
431
- }
432
-
433
- var _a, _b;
434
- class SummaryBase {
435
- constructor() {
436
- this.errorCount = 0;
437
- this.warnCount = 0;
438
- this.testCount = 0;
439
- }
440
- }
441
- class SuiteSummary extends SummaryBase {
442
- constructor() {
443
- super(...arguments);
444
- this[_a] = [];
445
- this[_b] = [];
446
- this.groups = {};
447
- this.tests = {};
448
- this.valid = false;
449
- }
450
- }
451
- _a = Severity.ERRORS, _b = Severity.WARNINGS;
452
-
453
322
  function useShouldAddValidProperty(fieldName) {
454
323
  // Is the field optional, and the optional condition is applied
455
324
  if (useIsOptionalFiedApplied(fieldName)) {
@@ -486,7 +355,10 @@ function useShouldAddValidPropertyInGroup(groupName, fieldName) {
486
355
  // Does the given field have any pending tests that are not optional?
487
356
  function useHasNonOptionalIncomplete(fieldName) {
488
357
  return TestWalker.someIncompleteTests(testObject => {
489
- return useIsTestObjectOptional(testObject, fieldName);
358
+ if (nonMatchingFieldName(testObject, fieldName)) {
359
+ return false;
360
+ }
361
+ return !useIsOptionalFiedApplied(fieldName);
490
362
  });
491
363
  }
492
364
  // Do the given group/field have any pending tests that are not optional?
@@ -495,15 +367,12 @@ function useHasNonOptionalIncompleteByGroup(groupName, fieldName) {
495
367
  if (nonMatchingGroupName(testObject, groupName)) {
496
368
  return false;
497
369
  }
498
- return useIsTestObjectOptional(testObject, fieldName);
370
+ if (nonMatchingFieldName(testObject, fieldName)) {
371
+ return false;
372
+ }
373
+ return !useIsOptionalFiedApplied(fieldName);
499
374
  });
500
375
  }
501
- function useIsTestObjectOptional(testObject, fieldName) {
502
- if (nonMatchingFieldName(testObject, fieldName)) {
503
- return false;
504
- }
505
- return useIsOptionalFiedApplied(fieldName);
506
- }
507
376
  // Did all of the tests for the provided field run/omit?
508
377
  // This makes sure that the fields are not skipped or pending.
509
378
  function useNoMissingTests(fieldName) {
@@ -533,16 +402,15 @@ function useNoMissingTestsLogic(testObject, fieldName) {
533
402
  * or if it is marked as optional, even if the optional check did not apply yet -
534
403
  * but the test did not reach its final state.
535
404
  */
536
- return (useOptionalTestAwaitsResolution(testObject) ||
405
+ return (testObject.isOmitted() ||
537
406
  testObject.isTested() ||
538
- testObject.isOmitted());
407
+ useOptionalTestAwaitsResolution(testObject));
539
408
  }
540
409
  function useOptionalTestAwaitsResolution(testObject) {
541
410
  // Does the test belong to an optional field,
542
411
  // and the test itself is still in an indeterminate state?
543
412
  var _a;
544
- return (((_a = useAvailableSuiteRoot()) === null || _a === void 0 ? void 0 : _a.getOptionalField(testObject.fieldName).type) ===
545
- OptionalFieldTypes.Delayed && testObject.awaitsResolution());
413
+ return (((_a = vestjsRuntime.VestRuntime.useAvailableRoot()) === null || _a === void 0 ? void 0 : _a.getOptionalField(testObject.fieldName).type) === OptionalFieldTypes.AUTO && testObject.awaitsResolution());
546
414
  }
547
415
 
548
416
  function useProduceSuiteSummary() {
@@ -557,13 +425,12 @@ function useProduceSuiteSummary() {
557
425
  return countFailures(summary);
558
426
  }
559
427
  function appendFailures(key, failures, testObject) {
428
+ if (testObject.isOmitted()) {
429
+ return failures;
430
+ }
560
431
  const shouldAppend = key === Severity.WARNINGS ? testObject.isWarning() : testObject.isFailing();
561
432
  if (shouldAppend) {
562
- return failures.concat({
563
- fieldName: testObject.fieldName,
564
- groupName: testObject.groupName,
565
- message: testObject.message,
566
- });
433
+ return failures.concat(SummaryFailure.fromTestObject(testObject));
567
434
  }
568
435
  return failures;
569
436
  }
@@ -663,6 +530,22 @@ function collectAll(testGroup, severityKey) {
663
530
  return output;
664
531
  }
665
532
 
533
+ function bindSuiteSelectors(get) {
534
+ return {
535
+ getError: (...args) => get().getError(...args),
536
+ getErrors: (...args) => get().getErrors(...args),
537
+ getErrorsByGroup: (...args) => get().getErrorsByGroup(...args),
538
+ getWarning: (...args) => get().getWarning(...args),
539
+ getWarnings: (...args) => get().getWarnings(...args),
540
+ getWarningsByGroup: (...args) => get().getWarningsByGroup(...args),
541
+ hasErrors: (...args) => get().hasErrors(...args),
542
+ hasErrorsByGroup: (...args) => get().hasErrorsByGroup(...args),
543
+ hasWarnings: (...args) => get().hasWarnings(...args),
544
+ hasWarningsByGroup: (...args) => get().hasWarningsByGroup(...args),
545
+ isValid: (...args) => get().isValid(...args),
546
+ isValidByGroup: (...args) => get().isValidByGroup(...args),
547
+ };
548
+ }
666
549
  // eslint-disable-next-line max-lines-per-function, max-statements
667
550
  function suiteSelectors(summary) {
668
551
  const selectors = {
@@ -781,11 +664,15 @@ function getFailure(severity, summary, fieldName) {
781
664
  }
782
665
 
783
666
  function useCreateSuiteResult() {
784
- const summary = useProduceSuiteSummary();
785
- const suiteName = useSuiteName();
786
- return useSuiteResultCache(() => vestUtils.assign(summary, suiteSelectors(summary), {
787
- suiteName,
788
- }));
667
+ return useSuiteResultCache(() => {
668
+ // eslint-disable-next-line vest-internal/use-use
669
+ const summary = useProduceSuiteSummary();
670
+ // eslint-disable-next-line vest-internal/use-use
671
+ const suiteName = useSuiteName();
672
+ return Object.freeze(vestUtils.assign(summary, suiteSelectors(summary), {
673
+ suiteName,
674
+ }));
675
+ });
789
676
  }
790
677
 
791
678
  /**
@@ -799,7 +686,7 @@ function useCreateSuiteResult() {
799
686
  */
800
687
  // @vx-allow use-use
801
688
  function skipWhen(condition, callback) {
802
- Isolate.create(() => {
689
+ vestjsRuntime.Isolate.create(() => {
803
690
  SuiteContext.run({
804
691
  skipped:
805
692
  // Checking for nested conditional. If we're in a nested skipWhen,
@@ -881,8 +768,6 @@ function useIsExcluded(testObject) {
881
768
  // If there is _ANY_ `only`ed test (and we already know this one isn't) return true
882
769
  if (hasIncludedTests(keyTests)) {
883
770
  // Check if inclusion rules for this field (`include` hook)
884
- // TODO: Check if this may need to be moved outside of the condition.
885
- // What if there are no included tests? This shouldn't run then?
886
771
  return !vestUtils.optionalFunctionValue(inclusion[fieldName]);
887
772
  }
888
773
  // We're done here. This field is not excluded
@@ -948,6 +833,51 @@ function useHasIncludedGroups() {
948
833
  return false;
949
834
  }
950
835
 
836
+ /**
837
+ * Sets the current execution mode for the current suite.
838
+ *
839
+ * Supported modes:
840
+ * - `EAGER` - (default) Runs all tests, but stops on first failure for each given field.
841
+ * - `ALL` - Runs all tests, regardless of failures.
842
+ * - `ONE` - Stops suite execution on first failure of any field.
843
+ *
844
+ * @example
845
+ * ```js
846
+ * import {Modes, create} from 'vest';
847
+ *
848
+ * const suite = create('suite_name', () => {
849
+ * vest.mode(Modes.ALL);
850
+ *
851
+ * // ...
852
+ * });
853
+ * ```
854
+ * @param 'ALL' | 'EAGER' | 'ONE' mode - The mode to set.
855
+ */
856
+ // @vx-allow use-use
857
+ function mode(mode) {
858
+ const [, setMode] = useMode();
859
+ setMode(mode);
860
+ }
861
+ function useIsMode(mode) {
862
+ const [currentMode] = useMode();
863
+ return currentMode === mode;
864
+ }
865
+ function useIsEager() {
866
+ return useIsMode(exports.Modes.EAGER);
867
+ }
868
+ function useIsOne() {
869
+ return useIsMode(exports.Modes.ONE);
870
+ }
871
+ function useShouldSkipBasedOnMode(testObject) {
872
+ if (useIsOne()) {
873
+ return hasErrorsByTestObjects();
874
+ }
875
+ if (useIsEager()) {
876
+ return hasErrorsByTestObjects(testObject.fieldName);
877
+ }
878
+ return false;
879
+ }
880
+
951
881
  /**
952
882
  * Conditionally omits tests from the suite.
953
883
  *
@@ -959,7 +889,7 @@ function useHasIncludedGroups() {
959
889
  */
960
890
  // @vx-allow use-use
961
891
  function omitWhen(conditional, callback) {
962
- Isolate.create(() => {
892
+ vestjsRuntime.Isolate.create(() => {
963
893
  SuiteContext.run({
964
894
  omitted: useWithinActiveOmitWhen() ||
965
895
  vestUtils.optionalFunctionValue(conditional, vestUtils.optionalFunctionValue(useCreateSuiteResult)),
@@ -1003,49 +933,64 @@ function useForceSkipIfInSkipWhen(testNode) {
1003
933
  return testNode;
1004
934
  }
1005
935
 
1006
- class IsolateTestReconciler extends Reconciler {
1007
- static reconciler(currentNode, historyNode) {
1008
- // Start by verifying params
1009
- if (!IsolateTest.is(currentNode)) {
1010
- return currentNode;
1011
- }
1012
- if (vestUtils.isNullish(historyNode)) {
1013
- return this.handleNoHistoryNode(currentNode);
1014
- }
1015
- if (!IsolateTest.is(historyNode)) {
1016
- return currentNode;
1017
- }
1018
- const reconcilerOutput = this.pickNode(historyNode, currentNode);
1019
- cancelOverriddenPendingTestOnTestReRun(reconcilerOutput, currentNode, historyNode);
1020
- return reconcilerOutput;
936
+ // @vx-allow use-use
937
+ function IsolateTestReconciler(currentNode, historyNode) {
938
+ // Start by verifying params
939
+ if (!IsolateTest.is(currentNode)) {
940
+ // This is unreachable, since this function should only be called with IsolateTest nodes
941
+ return currentNode;
1021
942
  }
1022
- static nodeReorderDetected(newNode, prevNode) {
1023
- return !!IsolateTest.is(prevNode) && !isSameProfileTest(prevNode, newNode);
943
+ if (vestUtils.isNullish(historyNode)) {
944
+ return handleNoHistoryNode(currentNode);
1024
945
  }
1025
- static handleCollision(newNode, prevNode) {
1026
- if (newNode.usesKey()) {
1027
- return IsolateTest.cast(this.handleIsolateNodeWithKey(newNode));
1028
- }
1029
- if (this.nodeReorderDetected(newNode, prevNode)) {
1030
- return this.onNodeReorder(newNode, prevNode);
1031
- }
1032
- return IsolateTest.cast(prevNode ? prevNode : newNode);
946
+ if (!IsolateTest.is(historyNode)) {
947
+ return currentNode;
948
+ }
949
+ const reconcilerOutput = usePickNode(historyNode, currentNode);
950
+ cancelOverriddenPendingTestOnTestReRun(reconcilerOutput, currentNode, historyNode);
951
+ return reconcilerOutput;
952
+ }
953
+ // eslint-disable-next-line max-statements
954
+ function nodeReorderDetected(newNode, prevNode) {
955
+ return !!IsolateTest.is(prevNode) && !isSameProfileTest(prevNode, newNode);
956
+ }
957
+ function handleCollision(newNode, prevNode) {
958
+ if (newNode.usesKey()) {
959
+ return IsolateTest.cast(vestjsRuntime.Reconciler.handleIsolateNodeWithKey(newNode));
960
+ }
961
+ if (nodeReorderDetected(newNode, prevNode)) {
962
+ return onNodeReorder(newNode, prevNode);
1033
963
  }
1034
- static onNodeReorder(newNode, prevNode) {
1035
- throwTestOrderError(newNode, prevNode);
1036
- this.removeAllNextNodesInIsolate();
964
+ if (!IsolateTest.is(prevNode)) {
965
+ // I believe we cannot actually reach this point.
966
+ // Because it should already be handled by nodeReorderDetected.
1037
967
  return newNode;
1038
968
  }
1039
- static pickNode(historyNode, currentNode) {
1040
- const collisionResult = this.handleCollision(currentNode, historyNode);
1041
- return useVerifyTestRun(currentNode, collisionResult);
969
+ // FIXME: May-13-2023
970
+ // This may not be the most ideal solution.
971
+ // In short: if the node was omitted in the previous run,
972
+ // we want to re-evaluate it. The reason is that we may incorrectly
973
+ // identify it is "optional" because it was omitted in the previous run.
974
+ // There may be a better way to handle this. Need to revisit this.
975
+ if (prevNode.isOmitted()) {
976
+ return newNode;
1042
977
  }
1043
- static handleNoHistoryNode(testNode) {
1044
- if (testNode.usesKey()) {
1045
- return IsolateTest.cast(this.handleIsolateNodeWithKey(testNode));
1046
- }
1047
- return testNode;
978
+ return prevNode;
979
+ }
980
+ function onNodeReorder(newNode, prevNode) {
981
+ throwTestOrderError(newNode, prevNode);
982
+ vestjsRuntime.Reconciler.removeAllNextNodesInIsolate();
983
+ return newNode;
984
+ }
985
+ function usePickNode(historyNode, currentNode) {
986
+ const collisionResult = handleCollision(currentNode, historyNode);
987
+ return useVerifyTestRun(currentNode, collisionResult);
988
+ }
989
+ function handleNoHistoryNode(testNode) {
990
+ if (testNode.usesKey()) {
991
+ return IsolateTest.cast(vestjsRuntime.Reconciler.handleIsolateNodeWithKey(testNode));
1048
992
  }
993
+ return testNode;
1049
994
  }
1050
995
  function cancelOverriddenPendingTestOnTestReRun(nextNode, currentNode, prevTestObject) {
1051
996
  if (nextNode === currentNode && IsolateTest.is(currentNode)) {
@@ -1062,30 +1007,6 @@ function throwTestOrderError(newNode, prevNode) {
1062
1007
  }));
1063
1008
  }
1064
1009
 
1065
- function StateMachine(machine) {
1066
- let state = machine.initial;
1067
- const api = { getState, transition };
1068
- return api;
1069
- function getState() {
1070
- return state;
1071
- }
1072
- function transition(action, payload) {
1073
- const transitionTo = machine.states[state][action];
1074
- let target = transitionTo;
1075
- if (Array.isArray(target)) {
1076
- const [, conditional] = target;
1077
- if (!conditional(payload)) {
1078
- return;
1079
- }
1080
- target = target[0];
1081
- }
1082
- if (!target || target === state) {
1083
- return;
1084
- }
1085
- state = target;
1086
- }
1087
- }
1088
-
1089
1010
  var TestStatus;
1090
1011
  (function (TestStatus) {
1091
1012
  TestStatus["UNTESTED"] = "UNTESTED";
@@ -1102,38 +1023,27 @@ var TestAction;
1102
1023
  TestAction["RESET"] = "RESET";
1103
1024
  })(TestAction || (TestAction = {}));
1104
1025
  function createTestStateMachine() {
1105
- return StateMachine(machine);
1026
+ return vestUtils.StateMachine(machine);
1106
1027
  }
1107
1028
  /* eslint-disable sort-keys */
1108
1029
  const machine = {
1109
1030
  initial: TestStatus.UNTESTED,
1110
1031
  states: {
1032
+ '*': {
1033
+ [TestStatus.OMITTED]: TestStatus.OMITTED,
1034
+ [TestAction.RESET]: TestStatus.UNTESTED,
1035
+ },
1111
1036
  [TestStatus.UNTESTED]: {
1112
1037
  [TestStatus.CANCELED]: TestStatus.CANCELED,
1113
1038
  [TestStatus.FAILED]: TestStatus.FAILED,
1114
- [TestStatus.OMITTED]: TestStatus.OMITTED,
1115
1039
  [TestStatus.PASSING]: TestStatus.PASSING,
1116
1040
  [TestStatus.PENDING]: TestStatus.PENDING,
1117
1041
  [TestStatus.SKIPPED]: TestStatus.SKIPPED,
1118
1042
  [TestStatus.WARNING]: TestStatus.WARNING,
1119
1043
  },
1120
- [TestStatus.SKIPPED]: {
1121
- [TestAction.RESET]: TestStatus.UNTESTED,
1122
- },
1123
- [TestStatus.FAILED]: {
1124
- [TestAction.RESET]: TestStatus.UNTESTED,
1125
- },
1126
- [TestStatus.WARNING]: {
1127
- [TestAction.RESET]: TestStatus.UNTESTED,
1128
- },
1129
- [TestStatus.PASSING]: {
1130
- [TestAction.RESET]: TestStatus.UNTESTED,
1131
- },
1132
1044
  [TestStatus.PENDING]: {
1133
- [TestAction.RESET]: TestStatus.UNTESTED,
1134
1045
  [TestStatus.CANCELED]: TestStatus.CANCELED,
1135
1046
  [TestStatus.FAILED]: TestStatus.FAILED,
1136
- [TestStatus.OMITTED]: TestStatus.OMITTED,
1137
1047
  [TestStatus.PASSING]: TestStatus.PASSING,
1138
1048
  [TestStatus.SKIPPED]: [
1139
1049
  TestStatus.SKIPPED,
@@ -1141,12 +1051,12 @@ const machine = {
1141
1051
  ],
1142
1052
  [TestStatus.WARNING]: TestStatus.WARNING,
1143
1053
  },
1144
- [TestStatus.CANCELED]: {
1145
- [TestAction.RESET]: TestStatus.UNTESTED,
1146
- },
1147
- [TestStatus.OMITTED]: {
1148
- [TestAction.RESET]: TestStatus.UNTESTED,
1149
- },
1054
+ [TestStatus.SKIPPED]: {},
1055
+ [TestStatus.FAILED]: {},
1056
+ [TestStatus.WARNING]: {},
1057
+ [TestStatus.PASSING]: {},
1058
+ [TestStatus.CANCELED]: {},
1059
+ [TestStatus.OMITTED]: {},
1150
1060
  },
1151
1061
  };
1152
1062
  /* eslint-enable sort-keys */
@@ -1156,7 +1066,7 @@ function shouldUseErrorAsMessage(message, error) {
1156
1066
  return vestUtils.isUndefined(message) && vestUtils.isStringValue(error);
1157
1067
  }
1158
1068
 
1159
- class IsolateTest extends Isolate {
1069
+ class IsolateTest extends vestjsRuntime.Isolate {
1160
1070
  constructor({ fieldName, testFn, message, groupName, key = null, }) {
1161
1071
  super();
1162
1072
  this.children = null;
@@ -1296,25 +1206,20 @@ class IsolateTest extends Isolate {
1296
1206
  }
1297
1207
  }
1298
1208
  IsolateTest.reconciler = IsolateTestReconciler;
1299
- var TestSeverity;
1300
- (function (TestSeverity) {
1301
- TestSeverity["Error"] = "error";
1302
- TestSeverity["Warning"] = "warning";
1303
- })(TestSeverity || (TestSeverity = {}));
1304
1209
 
1305
1210
  class TestWalker {
1306
1211
  static defaultRoot() {
1307
- return useAvailableSuiteRoot();
1212
+ return vestjsRuntime.VestRuntime.useAvailableRoot();
1308
1213
  }
1309
1214
  static hasNoTests(root = TestWalker.defaultRoot()) {
1310
1215
  if (!root)
1311
1216
  return true;
1312
- return !has(root, IsolateTest.is);
1217
+ return !vestjsRuntime.Walker.has(root, IsolateTest.is);
1313
1218
  }
1314
1219
  static someIncompleteTests(predicate, root = TestWalker.defaultRoot()) {
1315
1220
  if (!root)
1316
1221
  return false;
1317
- return some(root, isolate => {
1222
+ return vestjsRuntime.Walker.some(root, isolate => {
1318
1223
  IsolateTest.isX(isolate);
1319
1224
  return isolate.isPending() && predicate(isolate);
1320
1225
  }, IsolateTest.is);
@@ -1322,7 +1227,7 @@ class TestWalker {
1322
1227
  static someTests(predicate, root = TestWalker.defaultRoot()) {
1323
1228
  if (!root)
1324
1229
  return false;
1325
- return some(root, isolate => {
1230
+ return vestjsRuntime.Walker.some(root, isolate => {
1326
1231
  IsolateTest.isX(isolate);
1327
1232
  return predicate(isolate);
1328
1233
  }, IsolateTest.is);
@@ -1330,7 +1235,7 @@ class TestWalker {
1330
1235
  static everyTest(predicate, root = TestWalker.defaultRoot()) {
1331
1236
  if (!root)
1332
1237
  return false;
1333
- return every(root, isolate => {
1238
+ return vestjsRuntime.Walker.every(root, isolate => {
1334
1239
  IsolateTest.isX(isolate);
1335
1240
  return predicate(isolate);
1336
1241
  }, IsolateTest.is);
@@ -1338,7 +1243,7 @@ class TestWalker {
1338
1243
  static walkTests(callback, root = TestWalker.defaultRoot()) {
1339
1244
  if (!root)
1340
1245
  return;
1341
- walk(root, (isolate, breakout) => {
1246
+ vestjsRuntime.Walker.walk(root, (isolate, breakout) => {
1342
1247
  callback(IsolateTest.cast(isolate), breakout);
1343
1248
  }, IsolateTest.is);
1344
1249
  }
@@ -1353,7 +1258,7 @@ class TestWalker {
1353
1258
  static pluckTests(predicate, root = TestWalker.defaultRoot()) {
1354
1259
  if (!root)
1355
1260
  return;
1356
- pluck(root, isolate => {
1261
+ vestjsRuntime.Walker.pluck(root, isolate => {
1357
1262
  IsolateTest.isX(isolate);
1358
1263
  return predicate(isolate);
1359
1264
  }, IsolateTest.is);
@@ -1372,6 +1277,58 @@ class TestWalker {
1372
1277
  }
1373
1278
  }
1374
1279
 
1280
+ /**
1281
+ * This module gets triggered once the suite is done running its sync tests.
1282
+ *
1283
+ * It goes over all the tests in the state, and checks if they need to be omitted.
1284
+ */
1285
+ function useOmitOptionalFields() {
1286
+ const root = vestjsRuntime.VestRuntime.useAvailableRoot();
1287
+ const emit = vestjsRuntime.VestRuntime.useEmit();
1288
+ const optionalFields = root === null || root === void 0 ? void 0 : root.getOptionalFields();
1289
+ // If there are no optional fields, we don't need to do anything
1290
+ if (vestUtils.isEmpty(optionalFields)) {
1291
+ return;
1292
+ }
1293
+ // Create an object to store the fields that need to be omitted
1294
+ const shouldOmit = new Set();
1295
+ // iterate over each of the tests in the state
1296
+ TestWalker.walkTests(testObject => {
1297
+ if (testObject.isPending()) {
1298
+ return;
1299
+ }
1300
+ // If we already added the current field (not this test specifically)
1301
+ // no need for further checks, go and omit the test
1302
+ if (vestUtils.hasOwnProperty(shouldOmit, testObject.fieldName)) {
1303
+ verifyAndOmit(testObject);
1304
+ }
1305
+ else {
1306
+ // check if the field has an optional function
1307
+ // if so, run it and verify/omit the test
1308
+ runOptionalConfig(testObject);
1309
+ }
1310
+ });
1311
+ emit(Events.DONE_TEST_OMISSION_PASS);
1312
+ function verifyAndOmit(testObject) {
1313
+ if (shouldOmit.has(testObject.fieldName)) {
1314
+ testObject.omit();
1315
+ root === null || root === void 0 ? void 0 : root.setOptionalField(testObject.fieldName, current => (Object.assign(Object.assign({}, current), { applied: true })));
1316
+ }
1317
+ }
1318
+ function runOptionalConfig(testObject) {
1319
+ // Ge the optional configuration for the given field
1320
+ const optionalConfig = root === null || root === void 0 ? void 0 : root.getOptionalField(testObject.fieldName);
1321
+ if (vestUtils.isNullish(optionalConfig)) {
1322
+ return;
1323
+ }
1324
+ // If the optional was set to a function or a boolean, run it and verify/omit the test
1325
+ if (vestUtils.optionalFunctionValue(optionalConfig.rule) === true) {
1326
+ shouldOmit.add(testObject.fieldName);
1327
+ }
1328
+ verifyAndOmit(testObject);
1329
+ }
1330
+ }
1331
+
1375
1332
  /**
1376
1333
  * Runs done callback per field when async tests are finished running.
1377
1334
  */
@@ -1391,8 +1348,9 @@ function useRunDoneCallbacks() {
1391
1348
  vestUtils.callEach(doneCallbacks);
1392
1349
  }
1393
1350
 
1351
+ // eslint-disable-next-line max-statements
1394
1352
  function useInitVestBus() {
1395
- const VestBus = vestUtils.bus.createBus();
1353
+ const VestBus = vestjsRuntime.VestRuntime.useBus();
1396
1354
  // Report a the completion of a test. There may be other tests with the same
1397
1355
  // name that are still running, or not yet started.
1398
1356
  on(Events.TEST_COMPLETED, (testObject) => {
@@ -1408,8 +1366,18 @@ function useInitVestBus() {
1408
1366
  on(Events.TEST_RUN_STARTED, () => {
1409
1367
  /* Let's just invalidate the suite cache for now */
1410
1368
  });
1369
+ on(Events.DONE_TEST_OMISSION_PASS, () => {
1370
+ /* We NEED to refresh the cache here. Don't ask */
1371
+ });
1411
1372
  // Called when all the tests, including async, are done running
1412
1373
  on(Events.ALL_RUNNING_TESTS_FINISHED, () => {
1374
+ // Small optimization. We don't need to run this if there are no async tests
1375
+ // The reason is that we run this function immediately after the suite callback
1376
+ // is run, so if the suite is only comprised of sync tests, we don't need to
1377
+ // run this function twice since we know for a fact the state is up to date
1378
+ if (TestWalker.someTests(test => test.isAsyncTest())) {
1379
+ useOmitOptionalFields();
1380
+ }
1413
1381
  useRunDoneCallbacks();
1414
1382
  });
1415
1383
  on(Events.RESET_FIELD, (fieldName) => {
@@ -1418,6 +1386,9 @@ function useInitVestBus() {
1418
1386
  on(Events.SUITE_RUN_STARTED, () => {
1419
1387
  useResetCallbacks();
1420
1388
  });
1389
+ on(Events.SUITE_CALLBACK_RUN_FINISHED, () => {
1390
+ useOmitOptionalFields();
1391
+ });
1421
1392
  on(Events.REMOVE_FIELD, (fieldName) => {
1422
1393
  TestWalker.removeTestByFieldName(fieldName);
1423
1394
  });
@@ -1435,202 +1406,30 @@ function useInitVestBus() {
1435
1406
  }
1436
1407
  }
1437
1408
 
1438
- const suiteResultCache = vestUtils.cache();
1439
- const PersistedContext = context.createCascade((vestState, parentContext) => {
1440
- if (parentContext) {
1441
- return null;
1442
- }
1443
- vestUtils.invariant(vestState.historyRoot);
1444
- const [historyRootNode] = vestState.historyRoot();
1445
- const ctxRef = {};
1446
- vestUtils.assign(ctxRef, {
1447
- historyNode: historyRootNode,
1448
- runtimeNode: null,
1449
- runtimeRoot: null,
1450
- }, vestState);
1451
- return ctxRef;
1452
- });
1453
- function useCreateVestState({ suiteName, } = {}) {
1454
- const stateRef = {
1455
- VestBus: useInitVestBus(),
1456
- doneCallbacks: vestUtils.tinyState.createTinyState(() => []),
1457
- fieldCallbacks: vestUtils.tinyState.createTinyState(() => ({})),
1458
- historyRoot: vestUtils.tinyState.createTinyState(null),
1459
- suiteId: vestUtils.seq(),
1460
- suiteName,
1461
- suiteResultCache,
1462
- };
1463
- return stateRef;
1464
- }
1465
- function persist(cb) {
1466
- const prev = PersistedContext.useX();
1467
- return function persisted(...args) {
1468
- var _a;
1469
- const ctxToUse = (_a = PersistedContext.use()) !== null && _a !== void 0 ? _a : prev;
1470
- return PersistedContext.run(ctxToUse, () => cb(...args));
1471
- };
1472
- }
1473
- function useSuiteResultCache(action) {
1474
- const suiteResultCache = useX().suiteResultCache;
1475
- return suiteResultCache([useSuiteId()], action);
1476
- }
1477
- function useExpireSuiteResultCache() {
1478
- const suiteResultCache = useX().suiteResultCache;
1479
- suiteResultCache.invalidate([useSuiteId()]);
1480
- }
1481
- function useResetCallbacks() {
1482
- const [, , resetDoneCallbacks] = useDoneCallbacks();
1483
- const [, , resetFieldCallbacks] = useFieldCallbacks();
1484
- resetDoneCallbacks();
1485
- resetFieldCallbacks();
1486
- }
1487
- function useResetSuite() {
1488
- useResetCallbacks();
1489
- const [, , resetHistoryRoot] = useHistoryRoot();
1490
- resetHistoryRoot();
1491
- }
1492
- function useX() {
1493
- return PersistedContext.useX();
1494
- }
1495
- function useVestBus() {
1496
- return useX().VestBus;
1497
- }
1498
- /*
1499
- Returns an emitter, but it also has a shortcut for emitting an event immediately
1500
- by passing an event name.
1501
- */
1502
- function useEmit() {
1503
- return persist(useVestBus().emit);
1504
- }
1505
- function usePrepareEmitter(event) {
1506
- const emit = useEmit();
1507
- return (arg) => emit(event, arg);
1508
- }
1509
- function useDoneCallbacks() {
1510
- return useX().doneCallbacks();
1511
- }
1512
- function useFieldCallbacks() {
1513
- return useX().fieldCallbacks();
1514
- }
1515
- function useHistoryRoot() {
1516
- return useX().historyRoot();
1517
- }
1518
- function useHistoryNode() {
1519
- return useX().historyNode;
1520
- }
1521
- function useSuiteName() {
1522
- return useX().suiteName;
1523
- }
1524
- function useSuiteId() {
1525
- return useX().suiteId;
1526
- }
1527
- function useSetHistory(history) {
1528
- const context = PersistedContext.useX();
1529
- const [, setHistoryRoot] = context.historyRoot();
1530
- setHistoryRoot(history);
1531
- }
1532
- function useHistoryKey(key) {
1533
- var _a;
1534
- if (vestUtils.isNullish(key)) {
1535
- return null;
1536
- }
1537
- const historyNode = useX().historyNode;
1538
- return (_a = historyNode === null || historyNode === void 0 ? void 0 : historyNode.keys[key]) !== null && _a !== void 0 ? _a : null;
1539
- }
1540
- function useIsolate() {
1541
- var _a;
1542
- return (_a = useX().runtimeNode) !== null && _a !== void 0 ? _a : null;
1543
- }
1544
- function useCurrentCursor() {
1545
- var _a, _b;
1546
- return (_b = (_a = useIsolate()) === null || _a === void 0 ? void 0 : _a.cursor()) !== null && _b !== void 0 ? _b : 0;
1547
- }
1548
- function useRuntimeRoot() {
1549
- return useX().runtimeRoot;
1550
- }
1551
- function useSetNextIsolateChild(child) {
1552
- const currentIsolate = useIsolate();
1553
- vestUtils.invariant(currentIsolate, ErrorStrings.NO_ACTIVE_ISOLATE);
1554
- currentIsolate.addChild(child);
1555
- }
1556
- function useSetIsolateKey(key, value) {
1557
- if (!key) {
1558
- return;
1559
- }
1560
- const currentIsolate = useIsolate();
1561
- vestUtils.invariant(currentIsolate, ErrorStrings.NO_ACTIVE_ISOLATE);
1562
- if (vestUtils.isNullish(currentIsolate.keys[key])) {
1563
- currentIsolate.keys[key] = value;
1564
- return;
1565
- }
1566
- vestUtils.deferThrow(vestUtils.text(ErrorStrings.ENCOUNTERED_THE_SAME_KEY_TWICE, { key }));
1567
- }
1568
- function useAvailableSuiteRoot() {
1569
- const root = useRuntimeRoot();
1570
- if (root) {
1571
- return root;
1572
- }
1573
- const [historyRoot] = useHistoryRoot();
1574
- return historyRoot;
1575
- }
1576
-
1577
- // @vx-allow use-use
1578
- function optional(optionals) {
1579
- const suiteRoot = useRuntimeRoot();
1580
- // There are two types of optional field declarations:
1581
- // 1. Delayed: A string, which is the name of the field to be optional.
1582
- // We will only determine whether to omit the test after the suite is done running
1583
- //
1584
- // 2. Immediate: Either a boolean or a function, which is used to determine
1585
- // if the field should be optional.
1586
- // Delayed case (field name)
1587
- if (vestUtils.isArray(optionals) || vestUtils.isStringValue(optionals)) {
1588
- vestUtils.asArray(optionals).forEach(optionalField => {
1589
- suiteRoot.setOptionalField(optionalField, () => ({
1590
- type: OptionalFieldTypes.Delayed,
1591
- applied: false,
1592
- rule: null,
1593
- }));
1594
- });
1595
- }
1596
- else {
1597
- // Immediately case (function or boolean)
1598
- for (const field in optionals) {
1599
- const value = optionals[field];
1600
- suiteRoot.setOptionalField(field, () => ({
1601
- type: OptionalFieldTypes.Immediate,
1602
- rule: value,
1603
- applied: vestUtils.optionalFunctionValue(value),
1604
- }));
1605
- }
1606
- }
1607
- }
1608
- function useIsOptionalFiedApplied(fieldName) {
1609
- var _a, _b, _c;
1610
- if (!fieldName) {
1611
- return false;
1612
- }
1613
- return (_c = (_b = (_a = useAvailableSuiteRoot()) === null || _a === void 0 ? void 0 : _a.getOptionalField(fieldName)) === null || _b === void 0 ? void 0 : _b.applied) !== null && _c !== void 0 ? _c : false;
1614
- }
1615
-
1616
- class IsolateSuite extends Isolate {
1617
- constructor() {
1618
- super(...arguments);
1619
- this.optional = {};
1620
- }
1621
- setOptionalField(fieldName, setter) {
1622
- const current = this.optional;
1623
- const currentField = current[fieldName];
1624
- Object.assign(current, {
1625
- [fieldName]: Object.assign({}, currentField, setter(currentField)),
1626
- });
1627
- }
1628
- getOptionalField(fieldName) {
1629
- var _a;
1630
- return (_a = this.optional[fieldName]) !== null && _a !== void 0 ? _a : {};
1631
- }
1409
+ function group(groupName, callback) {
1410
+ return vestjsRuntime.Isolate.create(() => {
1411
+ SuiteContext.run({ groupName }, callback);
1412
+ });
1632
1413
  }
1633
1414
 
1415
+ /**
1416
+ * Conditionally includes a field for testing, based on specified criteria.
1417
+ *
1418
+ * @param {string} fieldName - The name of the field to include for testing.
1419
+ *
1420
+ * @example
1421
+ * include('confirm').when('password');
1422
+ * // Includes the "confirm" field for testing when the "password" field is included
1423
+ *
1424
+ * include('confirm').when(someValue);
1425
+ * // Includes the "confirm" field for testing when the value of `someValue` is true
1426
+ *
1427
+ * include('confirm').when(() => someValue);
1428
+ * // Includes the "confirm" field for testing when the callback function returns true
1429
+ *
1430
+ * include('username').when(result => result.hasErrors('username'));
1431
+ * // Includes the "username" field for testing when there are errors associated with it in the current suite result
1432
+ */
1634
1433
  // @vx-allow use-use
1635
1434
  function include(fieldName) {
1636
1435
  const inclusion = useInclusion();
@@ -1638,6 +1437,9 @@ function include(fieldName) {
1638
1437
  vestUtils.invariant(vestUtils.isStringValue(fieldName));
1639
1438
  inclusion[fieldName] = vestUtils.defaultTo(exclusion.tests[fieldName], true);
1640
1439
  return { when };
1440
+ /**
1441
+ * Specifies the inclusion criteria for the field in `include` function.
1442
+ */
1641
1443
  function when(condition) {
1642
1444
  const inclusion = useInclusion();
1643
1445
  const exclusion = useExclusion();
@@ -1657,18 +1459,16 @@ function include(fieldName) {
1657
1459
  }
1658
1460
  }
1659
1461
 
1660
- function useAttemptRunTestObjectByTier(testObject) {
1462
+ // eslint-disable-next-line max-statements
1463
+ function useAttemptRunTest(testObject) {
1661
1464
  useVerifyTestRun(testObject);
1662
- if (testObject.isNonActionable()) {
1663
- // TODO: Need to test that this works as expected
1664
- return;
1665
- }
1666
1465
  if (testObject.isUntested()) {
1667
- useRunTest(testObject);
1466
+ return useRunTest(testObject);
1668
1467
  }
1669
- else if (testObject.isAsyncTest()) {
1670
- testObject.setPending();
1671
- useRunAsyncTest(testObject);
1468
+ if (!testObject.isNonActionable()) {
1469
+ vestUtils.deferThrow(vestUtils.text(ErrorStrings.UNEXPECTED_TEST_REGISTRATION_ERROR, {
1470
+ testObject: JSON.stringify(testObject),
1471
+ }));
1672
1472
  }
1673
1473
  }
1674
1474
  function runSyncTest(testObject) {
@@ -1678,7 +1478,7 @@ function runSyncTest(testObject) {
1678
1478
  * runs test, if async - adds to pending array
1679
1479
  */
1680
1480
  function useRunTest(testObject) {
1681
- const VestBus = useVestBus();
1481
+ const VestBus = vestjsRuntime.VestRuntime.useBus();
1682
1482
  // Run test callback.
1683
1483
  // If a promise is returned, set as async and
1684
1484
  // Move to pending list.
@@ -1688,7 +1488,6 @@ function useRunTest(testObject) {
1688
1488
  // in case object is an enforce chain
1689
1489
  if (vestUtils.isPromise(result)) {
1690
1490
  testObject.asyncTest = result;
1691
- testObject.setPending();
1692
1491
  useRunAsyncTest(testObject);
1693
1492
  }
1694
1493
  else {
@@ -1709,11 +1508,12 @@ function useRunAsyncTest(testObject) {
1709
1508
  const { asyncTest, message } = testObject;
1710
1509
  if (!vestUtils.isPromise(asyncTest))
1711
1510
  return;
1712
- const VestBus = useVestBus();
1713
- const done = persist(() => {
1511
+ testObject.setPending();
1512
+ const VestBus = vestjsRuntime.VestRuntime.useBus();
1513
+ const done = vestjsRuntime.VestRuntime.persist(() => {
1714
1514
  onTestCompleted(VestBus, testObject);
1715
1515
  });
1716
- const fail = persist((rejectionMessage) => {
1516
+ const fail = vestjsRuntime.VestRuntime.persist((rejectionMessage) => {
1717
1517
  if (testObject.isCanceled()) {
1718
1518
  return;
1719
1519
  }
@@ -1737,7 +1537,11 @@ function wrapTestMemo(test) {
1737
1537
  function memo(fieldName, ...args) {
1738
1538
  const [deps, testFn, msg] = args.reverse();
1739
1539
  // Implicit dependency for better specificity
1740
- const dependencies = [useSuiteId(), fieldName, useCurrentCursor()].concat(deps);
1540
+ const dependencies = [
1541
+ useSuiteId(),
1542
+ fieldName,
1543
+ vestjsRuntime.VestRuntime.useCurrentCursor(),
1544
+ ].concat(deps);
1741
1545
  return useGetTestFromCache(dependencies, cacheAction);
1742
1546
  function cacheAction() {
1743
1547
  return test(fieldName, msg, testFn);
@@ -1767,11 +1571,11 @@ function vestTest(fieldName, ...args) {
1767
1571
  const [message, testFn, key] = (vestUtils.isFunction(args[1]) ? args : [undefined, ...args]);
1768
1572
  validateTestParams(fieldName, testFn);
1769
1573
  const groupName = useGroupName();
1770
- const emit = useEmit();
1574
+ const emit = vestjsRuntime.VestRuntime.useEmit();
1771
1575
  const testObjectInput = { fieldName, groupName, key, message, testFn };
1772
1576
  // This invalidates the suite cache.
1773
1577
  emit(Events.TEST_RUN_STARTED);
1774
- return IsolateTest.create(useAttemptRunTestObjectByTier, testObjectInput);
1578
+ return IsolateTest.create(useAttemptRunTest, testObjectInput);
1775
1579
  }
1776
1580
  const test = vestUtils.assign(vestTest, {
1777
1581
  memo: wrapTestMemo(vestTest),
@@ -1790,6 +1594,7 @@ function validateTestParams(fieldName, testFn) {
1790
1594
  }));
1791
1595
  }
1792
1596
 
1597
+ // import { optional, skipWhen, omitWhen, IsolateTest, group } from 'vest';
1793
1598
  function getTypedMethods() {
1794
1599
  return {
1795
1600
  group,
@@ -1826,9 +1631,9 @@ function shouldSkipDoneRegistration(callback, fieldName, output) {
1826
1631
  }
1827
1632
 
1828
1633
  function useSuiteRunResult() {
1829
- return vestUtils.assign({}, useCreateSuiteResult(), {
1830
- done: persist(done),
1831
- });
1634
+ return Object.freeze(vestUtils.assign({
1635
+ done: vestjsRuntime.VestRuntime.persist(done),
1636
+ }, useCreateSuiteResult()));
1832
1637
  }
1833
1638
  /**
1834
1639
  * Registers done callbacks.
@@ -1864,29 +1669,32 @@ function createSuite(...args) {
1864
1669
  function suite(...args) {
1865
1670
  return SuiteContext.run({}, () => {
1866
1671
  // eslint-disable-next-line vest-internal/use-use
1867
- const emit = useEmit();
1672
+ const emit = vestjsRuntime.VestRuntime.useEmit();
1868
1673
  emit(Events.SUITE_RUN_STARTED);
1869
1674
  return IsolateSuite.create(useRunSuiteCallback(suiteCallback, ...args));
1870
1675
  }).output;
1871
1676
  }
1872
1677
  // Assign methods to the suite
1873
- // We do this within the PersistedContext so that the suite methods
1678
+ // We do this within the VestRuntime so that the suite methods
1874
1679
  // will be bound to the suite's stateRef and be able to access it.
1875
- return PersistedContext.run(stateRef, () => {
1680
+ return vestjsRuntime.VestRuntime.Run(stateRef, () => {
1681
+ useInitVestBus();
1876
1682
  return vestUtils.assign(
1877
1683
  // We're also binding the suite to the stateRef, so that the suite
1878
1684
  // can access the stateRef when it's called.
1879
- PersistedContext.bind(stateRef, suite), Object.assign({ get: persist(useCreateSuiteResult), remove: usePrepareEmitter(Events.REMOVE_FIELD), reset: usePrepareEmitter(Events.RESET_SUITE), resetField: usePrepareEmitter(Events.RESET_FIELD) }, getTypedMethods()));
1685
+ vestjsRuntime.VestRuntime.persist(suite), Object.assign(Object.assign({ get: vestjsRuntime.VestRuntime.persist(useCreateSuiteResult), remove: vestjsRuntime.VestRuntime.usePrepareEmitter(Events.REMOVE_FIELD), reset: vestjsRuntime.VestRuntime.usePrepareEmitter(Events.RESET_SUITE), resetField: vestjsRuntime.VestRuntime.usePrepareEmitter(Events.RESET_FIELD) }, bindSuiteSelectors(vestjsRuntime.VestRuntime.persist(useCreateSuiteResult))), getTypedMethods()));
1880
1686
  });
1881
1687
  }
1882
1688
  function useRunSuiteCallback(suiteCallback, ...args) {
1689
+ const emit = vestjsRuntime.VestRuntime.useEmit();
1883
1690
  return () => {
1884
1691
  suiteCallback(...args);
1692
+ emit(Events.SUITE_CALLBACK_RUN_FINISHED);
1885
1693
  return useSuiteRunResult();
1886
1694
  };
1887
1695
  }
1888
1696
 
1889
- class IsolateEach extends Isolate {
1697
+ class IsolateEach extends vestjsRuntime.Isolate {
1890
1698
  constructor() {
1891
1699
  super(...arguments);
1892
1700
  this.allowReorder = true;
@@ -1915,19 +1723,45 @@ function each(list, callback) {
1915
1723
  });
1916
1724
  }
1917
1725
 
1918
- function group(groupName, callback) {
1919
- return Isolate.create(() => {
1920
- SuiteContext.run({ groupName }, callback);
1921
- });
1922
- }
1923
-
1726
+ /**
1727
+ * Creates a static suite for server-side validation.
1728
+ *
1729
+ * @param {Function} validationFn - The validation function that defines the suite's tests.
1730
+ * @returns {Function} - A function that runs the validations defined in the suite.
1731
+ *
1732
+ * @example
1733
+ * import { staticSuite, test, enforce } from 'vest';
1734
+ *
1735
+ * const suite = staticSuite(data => {
1736
+ * test('username', 'username is required', () => {
1737
+ * enforce(data.username).isNotEmpty();
1738
+ * });
1739
+ * });
1740
+ *
1741
+ * suite(data);
1742
+ */
1924
1743
  function staticSuite(suiteCallback) {
1925
1744
  return vestUtils.assign((...args) => createSuite(suiteCallback)(...args), Object.assign({}, getTypedMethods()));
1926
1745
  }
1927
1746
 
1928
1747
  const ERROR_OUTSIDE_OF_TEST = ErrorStrings.WARN_MUST_BE_CALLED_FROM_TEST;
1929
1748
  /**
1930
- * Sets a running test to warn only mode.
1749
+ * Sets the severity level of a test to `warn`, allowing it to fail without marking the suite as invalid.
1750
+ * Use this function within the body of a test to create warn-only tests.
1751
+ *
1752
+ * @returns {void}
1753
+ *
1754
+ * @example
1755
+ * test('password', 'Your password strength is: WEAK', () => {
1756
+ * warn();
1757
+ *
1758
+ * enforce(data.password).matches(/0-9/);
1759
+ * });
1760
+ *
1761
+ * @limitations
1762
+ * - The `warn` function should only be used within the body of a `test` function.
1763
+ * - When using `warn()` in an async test, it should be called in the synchronous portion of the test, not after an `await` call or in the Promise body.
1764
+ * - It is recommended to call `warn()` at the top of the test function.
1931
1765
  */
1932
1766
  // @vx-allow use-use
1933
1767
  function warn() {