vest 5.2.9 → 5.2.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/SuiteSerializer.development.js.map +1 -1
- package/dist/cjs/SuiteSerializer.production.js.map +1 -1
- package/dist/cjs/vest.development.js +1041 -1055
- package/dist/cjs/vest.development.js.map +1 -1
- package/dist/cjs/vest.production.js +1 -1
- package/dist/cjs/vest.production.js.map +1 -1
- package/dist/es/SuiteSerializer.development.js.map +1 -1
- package/dist/es/SuiteSerializer.production.js.map +1 -1
- package/dist/es/vest.development.js +1042 -1056
- package/dist/es/vest.development.js.map +1 -1
- package/dist/es/vest.production.js +1 -1
- package/dist/es/vest.production.js.map +1 -1
- package/dist/umd/SuiteSerializer.development.js.map +1 -1
- package/dist/umd/SuiteSerializer.production.js.map +1 -1
- package/dist/umd/vest.development.js +1041 -1055
- package/dist/umd/vest.development.js.map +1 -1
- package/dist/umd/vest.production.js +1 -1
- package/dist/umd/vest.production.js.map +1 -1
- package/package.json +6 -6
- package/types/SuiteSerializer.d.ts +12 -5
- package/types/SuiteSerializer.d.ts.map +1 -1
- package/types/vest.d.ts +28 -25
- package/types/vest.d.ts.map +1 -1
|
@@ -140,18 +140,85 @@ function useIsOptionalFieldApplied(fieldName) {
|
|
|
140
140
|
return ((_b = (_a = SuiteOptionalFields.getOptionalField(root, fieldName)) === null || _a === void 0 ? void 0 : _a.applied) !== null && _b !== void 0 ? _b : false);
|
|
141
141
|
}
|
|
142
142
|
|
|
143
|
-
var
|
|
144
|
-
(function (
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
})
|
|
143
|
+
var FocusModes;
|
|
144
|
+
(function (FocusModes) {
|
|
145
|
+
FocusModes[FocusModes["ONLY"] = 0] = "ONLY";
|
|
146
|
+
FocusModes[FocusModes["SKIP"] = 1] = "SKIP";
|
|
147
|
+
})(FocusModes || (FocusModes = {}));
|
|
148
|
+
|
|
149
|
+
function IsolateFocused(focusMode, match) {
|
|
150
|
+
return vestjsRuntime.Isolate.create(VestIsolateType.Focused, vestUtils.noop, {
|
|
151
|
+
focusMode,
|
|
152
|
+
match: vestUtils.asArray(match).filter(vestUtils.isStringValue),
|
|
153
|
+
matchAll: match === true,
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
class FocusSelectors {
|
|
157
|
+
static isSkipFocused(focus, fieldName) {
|
|
158
|
+
return ((focus === null || focus === void 0 ? void 0 : focus.data.focusMode) === FocusModes.SKIP &&
|
|
159
|
+
(hasFocus(focus, fieldName) || focus.data.matchAll === true));
|
|
160
|
+
}
|
|
161
|
+
static isOnlyFocused(focus, fieldName) {
|
|
162
|
+
return ((focus === null || focus === void 0 ? void 0 : focus.data.focusMode) === FocusModes.ONLY && hasFocus(focus, fieldName));
|
|
163
|
+
}
|
|
164
|
+
static isIsolateFocused(isolate) {
|
|
165
|
+
return vestjsRuntime.IsolateSelectors.isIsolateType(isolate, VestIsolateType.Focused);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Adds a field or a list of fields into the inclusion list
|
|
170
|
+
*
|
|
171
|
+
* @example
|
|
172
|
+
*
|
|
173
|
+
* only('username');
|
|
174
|
+
*/
|
|
175
|
+
// @vx-allow use-use
|
|
176
|
+
function only(match) {
|
|
177
|
+
return IsolateFocused(FocusModes.ONLY, defaultMatch(match));
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Adds a field or a list of fields into the exclusion list
|
|
181
|
+
*
|
|
182
|
+
* @example
|
|
183
|
+
*
|
|
184
|
+
* skip('username');
|
|
185
|
+
*/
|
|
186
|
+
// @vx-allow use-use
|
|
187
|
+
function skip(match) {
|
|
188
|
+
return IsolateFocused(FocusModes.SKIP, defaultMatch(match));
|
|
189
|
+
}
|
|
190
|
+
function defaultMatch(match) {
|
|
191
|
+
return match === false ? [] : match;
|
|
192
|
+
}
|
|
193
|
+
function hasFocus(focus, fieldName) {
|
|
194
|
+
var _a, _b;
|
|
195
|
+
return (vestUtils.isNotEmpty(focus === null || focus === void 0 ? void 0 : focus.data.match) &&
|
|
196
|
+
(fieldName ? (_b = (_a = focus === null || focus === void 0 ? void 0 : focus.data.match) === null || _a === void 0 ? void 0 : _a.includes(fieldName)) !== null && _b !== void 0 ? _b : true : true));
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function group(...args) {
|
|
200
|
+
const [callback, groupName] = args.reverse();
|
|
201
|
+
return vestjsRuntime.Isolate.create(VestIsolateType.Group, () => {
|
|
202
|
+
return SuiteContext.run(Object.assign({}, (groupName && { groupName })), callback);
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
var ErrorStrings;
|
|
207
|
+
(function (ErrorStrings) {
|
|
208
|
+
ErrorStrings["HOOK_CALLED_OUTSIDE"] = "hook called outside of a running suite.";
|
|
209
|
+
ErrorStrings["EXPECTED_VEST_TEST"] = "Expected value to be an instance of IsolateTest";
|
|
210
|
+
ErrorStrings["FIELD_NAME_REQUIRED"] = "Field name must be passed";
|
|
211
|
+
ErrorStrings["SUITE_MUST_BE_INITIALIZED_WITH_FUNCTION"] = "Suite must be initialized with a function";
|
|
212
|
+
ErrorStrings["PROMISIFY_REQUIRE_FUNCTION"] = "Vest.Promisify must be called with a function";
|
|
213
|
+
ErrorStrings["PARSER_EXPECT_RESULT_OBJECT"] = "Vest parser: expected argument at position 0 to be Vest's result object.";
|
|
214
|
+
ErrorStrings["WARN_MUST_BE_CALLED_FROM_TEST"] = "Warn must be called from within the body of a test function";
|
|
215
|
+
ErrorStrings["EACH_CALLBACK_MUST_BE_A_FUNCTION"] = "Each must be called with a function";
|
|
216
|
+
ErrorStrings["INVALID_PARAM_PASSED_TO_FUNCTION"] = "Incompatible params passed to {fn_name} function. \"{param}\" must be of type {expected}";
|
|
217
|
+
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.";
|
|
218
|
+
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}.";
|
|
219
|
+
ErrorStrings["UNEXPECTED_TEST_RUN_ERROR"] = "Unexpected error encountered during test run. Please report this issue to Vest's Github repository.\n Test Object: {testObject}.";
|
|
220
|
+
ErrorStrings["INCLUDE_SELF"] = "Trying to call include.when on the same field.";
|
|
221
|
+
})(ErrorStrings || (ErrorStrings = {}));
|
|
155
222
|
|
|
156
223
|
const suiteResultCache = vestUtils.cache();
|
|
157
224
|
function useCreateVestState({ suiteName, VestReconciler, }) {
|
|
@@ -202,124 +269,6 @@ function useLoadSuite(rootNode) {
|
|
|
202
269
|
useExpireSuiteResultCache();
|
|
203
270
|
}
|
|
204
271
|
|
|
205
|
-
const CommonStates = {
|
|
206
|
-
PENDING: 'PENDING',
|
|
207
|
-
INITIAL: 'INITIAL',
|
|
208
|
-
};
|
|
209
|
-
const State = {
|
|
210
|
-
[CommonStates.PENDING]: CommonStates.PENDING,
|
|
211
|
-
[CommonStates.INITIAL]: CommonStates.INITIAL,
|
|
212
|
-
DONE: 'DONE',
|
|
213
|
-
};
|
|
214
|
-
const machine$1 = {
|
|
215
|
-
initial: State.INITIAL,
|
|
216
|
-
states: {
|
|
217
|
-
[State.DONE]: {},
|
|
218
|
-
[State.INITIAL]: {
|
|
219
|
-
[State.PENDING]: State.PENDING,
|
|
220
|
-
[State.DONE]: State.DONE,
|
|
221
|
-
},
|
|
222
|
-
[State.PENDING]: {
|
|
223
|
-
[State.DONE]: State.DONE,
|
|
224
|
-
},
|
|
225
|
-
},
|
|
226
|
-
};
|
|
227
|
-
function transition(from, to) {
|
|
228
|
-
return CommonStateMachine.staticTransition(from !== null && from !== void 0 ? from : State.INITIAL, to);
|
|
229
|
-
}
|
|
230
|
-
function setDone(isolate) {
|
|
231
|
-
isolate.status = transition(isolate.status, State.DONE);
|
|
232
|
-
}
|
|
233
|
-
function setPending(isolate) {
|
|
234
|
-
isolate.status = transition(isolate.status, State.PENDING);
|
|
235
|
-
}
|
|
236
|
-
const CommonStateMachine = vestUtils.StateMachine(machine$1);
|
|
237
|
-
|
|
238
|
-
class VestIsolate {
|
|
239
|
-
static getStatus(isolate) {
|
|
240
|
-
var _a;
|
|
241
|
-
return (_a = isolate.status) !== null && _a !== void 0 ? _a : CommonStates.INITIAL;
|
|
242
|
-
}
|
|
243
|
-
static setStatus(isolate, status, payload) {
|
|
244
|
-
isolate.status = this.stateMachine.staticTransition(VestIsolate.getStatus(isolate), status, payload);
|
|
245
|
-
}
|
|
246
|
-
static statusEquals(isolate, status) {
|
|
247
|
-
return VestIsolate.getStatus(isolate) === status;
|
|
248
|
-
}
|
|
249
|
-
static setPending(isolate) {
|
|
250
|
-
this.setStatus(isolate, CommonStates.PENDING);
|
|
251
|
-
}
|
|
252
|
-
static isPending(isolate) {
|
|
253
|
-
return VestIsolate.statusEquals(isolate, CommonStates.PENDING);
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
VestIsolate.stateMachine = CommonStateMachine;
|
|
257
|
-
|
|
258
|
-
var ErrorStrings;
|
|
259
|
-
(function (ErrorStrings) {
|
|
260
|
-
ErrorStrings["HOOK_CALLED_OUTSIDE"] = "hook called outside of a running suite.";
|
|
261
|
-
ErrorStrings["EXPECTED_VEST_TEST"] = "Expected value to be an instance of IsolateTest";
|
|
262
|
-
ErrorStrings["FIELD_NAME_REQUIRED"] = "Field name must be passed";
|
|
263
|
-
ErrorStrings["SUITE_MUST_BE_INITIALIZED_WITH_FUNCTION"] = "Suite must be initialized with a function";
|
|
264
|
-
ErrorStrings["PROMISIFY_REQUIRE_FUNCTION"] = "Vest.Promisify must be called with a function";
|
|
265
|
-
ErrorStrings["PARSER_EXPECT_RESULT_OBJECT"] = "Vest parser: expected argument at position 0 to be Vest's result object.";
|
|
266
|
-
ErrorStrings["WARN_MUST_BE_CALLED_FROM_TEST"] = "Warn must be called from within the body of a test function";
|
|
267
|
-
ErrorStrings["EACH_CALLBACK_MUST_BE_A_FUNCTION"] = "Each must be called with a function";
|
|
268
|
-
ErrorStrings["INVALID_PARAM_PASSED_TO_FUNCTION"] = "Incompatible params passed to {fn_name} function. \"{param}\" must be of type {expected}";
|
|
269
|
-
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.";
|
|
270
|
-
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}.";
|
|
271
|
-
ErrorStrings["UNEXPECTED_TEST_RUN_ERROR"] = "Unexpected error encountered during test run. Please report this issue to Vest's Github repository.\n Test Object: {testObject}.";
|
|
272
|
-
ErrorStrings["INCLUDE_SELF"] = "Trying to call include.when on the same field.";
|
|
273
|
-
})(ErrorStrings || (ErrorStrings = {}));
|
|
274
|
-
|
|
275
|
-
const TestStatus = {
|
|
276
|
-
[CommonStates.PENDING]: CommonStates.PENDING,
|
|
277
|
-
CANCELED: 'CANCELED',
|
|
278
|
-
FAILED: 'FAILED',
|
|
279
|
-
OMITTED: 'OMITTED',
|
|
280
|
-
PASSING: 'PASSING',
|
|
281
|
-
SKIPPED: 'SKIPPED',
|
|
282
|
-
UNTESTED: 'UNTESTED',
|
|
283
|
-
WARNING: 'WARNING',
|
|
284
|
-
};
|
|
285
|
-
const TestAction = {
|
|
286
|
-
RESET: 'RESET',
|
|
287
|
-
};
|
|
288
|
-
const machine = {
|
|
289
|
-
initial: TestStatus.UNTESTED,
|
|
290
|
-
states: {
|
|
291
|
-
'*': {
|
|
292
|
-
[TestStatus.OMITTED]: TestStatus.OMITTED,
|
|
293
|
-
[TestAction.RESET]: TestStatus.UNTESTED,
|
|
294
|
-
},
|
|
295
|
-
[TestStatus.UNTESTED]: {
|
|
296
|
-
[TestStatus.CANCELED]: TestStatus.CANCELED,
|
|
297
|
-
[TestStatus.FAILED]: TestStatus.FAILED,
|
|
298
|
-
[TestStatus.PASSING]: TestStatus.PASSING,
|
|
299
|
-
[TestStatus.PENDING]: TestStatus.PENDING,
|
|
300
|
-
[TestStatus.SKIPPED]: TestStatus.SKIPPED,
|
|
301
|
-
[TestStatus.WARNING]: TestStatus.WARNING,
|
|
302
|
-
},
|
|
303
|
-
[TestStatus.PENDING]: {
|
|
304
|
-
[TestStatus.CANCELED]: TestStatus.CANCELED,
|
|
305
|
-
[TestStatus.FAILED]: TestStatus.FAILED,
|
|
306
|
-
[TestStatus.PASSING]: TestStatus.PASSING,
|
|
307
|
-
[TestStatus.SKIPPED]: [
|
|
308
|
-
TestStatus.SKIPPED,
|
|
309
|
-
(force) => force === true,
|
|
310
|
-
],
|
|
311
|
-
[TestStatus.WARNING]: TestStatus.WARNING,
|
|
312
|
-
},
|
|
313
|
-
[TestStatus.SKIPPED]: {},
|
|
314
|
-
[TestStatus.FAILED]: {},
|
|
315
|
-
[TestStatus.WARNING]: {},
|
|
316
|
-
[TestStatus.PASSING]: {},
|
|
317
|
-
[TestStatus.CANCELED]: {},
|
|
318
|
-
[TestStatus.OMITTED]: {},
|
|
319
|
-
},
|
|
320
|
-
};
|
|
321
|
-
const IsolateTestStateMachine = vestUtils.StateMachine(machine);
|
|
322
|
-
|
|
323
272
|
var Severity;
|
|
324
273
|
(function (Severity) {
|
|
325
274
|
Severity["WARNINGS"] = "warnings";
|
|
@@ -341,161 +290,449 @@ var TestSeverity;
|
|
|
341
290
|
TestSeverity["Warning"] = "warning";
|
|
342
291
|
})(TestSeverity || (TestSeverity = {}));
|
|
343
292
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
293
|
+
// calls collectAll or getByFieldName depending on whether fieldName is provided
|
|
294
|
+
function gatherFailures(testGroup, severityKey, fieldName) {
|
|
295
|
+
return fieldName
|
|
296
|
+
? getByFieldName(testGroup, severityKey, fieldName)
|
|
297
|
+
: collectAll(testGroup, severityKey);
|
|
298
|
+
}
|
|
299
|
+
function getByFieldName(testGroup, severityKey, fieldName) {
|
|
300
|
+
var _a;
|
|
301
|
+
return ((_a = testGroup === null || testGroup === void 0 ? void 0 : testGroup[fieldName]) === null || _a === void 0 ? void 0 : _a[severityKey]) || [];
|
|
302
|
+
}
|
|
303
|
+
function collectAll(testGroup, severityKey) {
|
|
304
|
+
const output = {};
|
|
305
|
+
const countKey = countKeyBySeverity(severityKey);
|
|
306
|
+
for (const field in testGroup) {
|
|
307
|
+
if (vestUtils.isPositive(testGroup[field][countKey])) {
|
|
308
|
+
// We will probably never get to the fallback array
|
|
309
|
+
// leaving it just in case the implementation changes
|
|
310
|
+
output[field] = testGroup[field][severityKey] || [];
|
|
311
|
+
}
|
|
355
312
|
}
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
313
|
+
return output;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
function nonMatchingFieldName(WithFieldName, fieldName) {
|
|
317
|
+
return !!fieldName && !matchingFieldName(WithFieldName, fieldName);
|
|
318
|
+
}
|
|
319
|
+
function matchingFieldName(WithFieldName, fieldName) {
|
|
320
|
+
return !!(fieldName && WithFieldName.fieldName === fieldName);
|
|
321
|
+
}
|
|
322
|
+
function matchesOrHasNoFieldName(WithFieldName, fieldName) {
|
|
323
|
+
if (fieldName) {
|
|
324
|
+
return matchingFieldName(WithFieldName, fieldName);
|
|
359
325
|
}
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
326
|
+
return true;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
function bindSuiteSelectors(get) {
|
|
330
|
+
return {
|
|
331
|
+
getError: (...args) => get().getError(...args),
|
|
332
|
+
getErrors: (...args) => get().getErrors(...args),
|
|
333
|
+
getErrorsByGroup: (...args) => get().getErrorsByGroup(...args),
|
|
334
|
+
getWarning: (...args) => get().getWarning(...args),
|
|
335
|
+
getWarnings: (...args) => get().getWarnings(...args),
|
|
336
|
+
getWarningsByGroup: (...args) => get().getWarningsByGroup(...args),
|
|
337
|
+
hasErrors: (...args) => get().hasErrors(...args),
|
|
338
|
+
hasErrorsByGroup: (...args) => get().hasErrorsByGroup(...args),
|
|
339
|
+
hasWarnings: (...args) => get().hasWarnings(...args),
|
|
340
|
+
hasWarningsByGroup: (...args) => get().hasWarningsByGroup(...args),
|
|
341
|
+
isPending: (...args) => {
|
|
342
|
+
return get().isPending(...args);
|
|
343
|
+
},
|
|
344
|
+
isTested: (...args) => get().isTested(...args),
|
|
345
|
+
isValid: (...args) => get().isValid(...args),
|
|
346
|
+
isValidByGroup: (...args) => get().isValidByGroup(...args),
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
// eslint-disable-next-line max-lines-per-function, max-statements
|
|
350
|
+
function suiteSelectors(summary) {
|
|
351
|
+
const selectors = {
|
|
352
|
+
getError,
|
|
353
|
+
getErrors,
|
|
354
|
+
getErrorsByGroup,
|
|
355
|
+
getWarning,
|
|
356
|
+
getWarnings,
|
|
357
|
+
getWarningsByGroup,
|
|
358
|
+
hasErrors,
|
|
359
|
+
hasErrorsByGroup,
|
|
360
|
+
hasWarnings,
|
|
361
|
+
hasWarningsByGroup,
|
|
362
|
+
isPending,
|
|
363
|
+
isTested,
|
|
364
|
+
isValid,
|
|
365
|
+
isValidByGroup,
|
|
366
|
+
};
|
|
367
|
+
return selectors;
|
|
368
|
+
// Booleans
|
|
369
|
+
function isValid(fieldName) {
|
|
370
|
+
var _a;
|
|
371
|
+
return fieldName ? Boolean((_a = summary.tests[fieldName]) === null || _a === void 0 ? void 0 : _a.valid) : summary.valid;
|
|
383
372
|
}
|
|
384
|
-
|
|
385
|
-
|
|
373
|
+
function isValidByGroup(groupName, fieldName) {
|
|
374
|
+
const group = summary.groups[groupName];
|
|
375
|
+
if (!group) {
|
|
376
|
+
return false;
|
|
377
|
+
}
|
|
378
|
+
if (fieldName) {
|
|
379
|
+
return isFieldValid(group, fieldName);
|
|
380
|
+
}
|
|
381
|
+
for (const fieldName in group) {
|
|
382
|
+
if (!isFieldValid(group, fieldName)) {
|
|
383
|
+
return false;
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
return true;
|
|
386
387
|
}
|
|
387
|
-
|
|
388
|
-
return (
|
|
389
|
-
VestTest.isOmitted(test) ||
|
|
390
|
-
VestTest.isCanceled(test));
|
|
388
|
+
function hasWarnings(fieldName) {
|
|
389
|
+
return hasFailures(summary, SeverityCount.WARN_COUNT, fieldName);
|
|
391
390
|
}
|
|
392
|
-
|
|
393
|
-
return
|
|
391
|
+
function hasErrors(fieldName) {
|
|
392
|
+
return hasFailures(summary, SeverityCount.ERROR_COUNT, fieldName);
|
|
394
393
|
}
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
return (VestTest.isSkipped(test) ||
|
|
399
|
-
VestTest.isUntested(test) ||
|
|
400
|
-
VestTest.isPending(test));
|
|
394
|
+
function isTested(fieldName) {
|
|
395
|
+
var _a;
|
|
396
|
+
return vestUtils.isPositive((_a = summary.tests[fieldName]) === null || _a === void 0 ? void 0 : _a.testCount);
|
|
401
397
|
}
|
|
402
|
-
|
|
403
|
-
return
|
|
398
|
+
function hasWarningsByGroup(groupName, fieldName) {
|
|
399
|
+
return hasFailuresByGroup(summary, SeverityCount.WARN_COUNT, groupName, fieldName);
|
|
404
400
|
}
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
// this.setStatus(test, TestStatus.PENDING);
|
|
408
|
-
// }
|
|
409
|
-
static fail(test) {
|
|
410
|
-
VestTest.setStatus(test, VestTest.warns(test) ? TestStatus.WARNING : TestStatus.FAILED);
|
|
401
|
+
function hasErrorsByGroup(groupName, fieldName) {
|
|
402
|
+
return hasFailuresByGroup(summary, SeverityCount.ERROR_COUNT, groupName, fieldName);
|
|
411
403
|
}
|
|
412
|
-
|
|
413
|
-
|
|
404
|
+
function getWarnings(fieldName) {
|
|
405
|
+
return getFailures(summary, Severity.WARNINGS, fieldName);
|
|
414
406
|
}
|
|
415
|
-
|
|
416
|
-
|
|
407
|
+
function getWarning(fieldName) {
|
|
408
|
+
return getFailure(Severity.WARNINGS, summary, fieldName);
|
|
417
409
|
}
|
|
418
|
-
|
|
419
|
-
|
|
410
|
+
function getErrors(fieldName) {
|
|
411
|
+
return getFailures(summary, Severity.ERRORS, fieldName);
|
|
420
412
|
}
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
// This means that it will not be counted in "allIncomplete" and its done callbacks
|
|
424
|
-
// will not be called, or will be called prematurely.
|
|
425
|
-
// What this mostly say is that when we have a pending test for one field, and we then
|
|
426
|
-
// start typing in a different field - the pending test will be canceled, which
|
|
427
|
-
// is usually an unwanted behavior.
|
|
428
|
-
// The only scenario in which we DO want to cancel the async test regardless
|
|
429
|
-
// is when we specifically skip a test with `skipWhen`, which is handled by the
|
|
430
|
-
// "force" boolean flag.
|
|
431
|
-
// I am not a fan of this flag, but it gets the job done.
|
|
432
|
-
VestTest.setStatus(test, TestStatus.SKIPPED, force);
|
|
413
|
+
function getError(fieldName) {
|
|
414
|
+
return getFailure(Severity.ERRORS, summary, fieldName);
|
|
433
415
|
}
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
vestjsRuntime.IsolateMutator.abort(test, TestStatus.CANCELED);
|
|
416
|
+
function getErrorsByGroup(groupName, fieldName) {
|
|
417
|
+
return getFailuresByGroup(summary, Severity.ERRORS, groupName, fieldName);
|
|
437
418
|
}
|
|
438
|
-
|
|
439
|
-
|
|
419
|
+
function getWarningsByGroup(groupName, fieldName) {
|
|
420
|
+
return getFailuresByGroup(summary, Severity.WARNINGS, groupName, fieldName);
|
|
440
421
|
}
|
|
441
|
-
|
|
442
|
-
|
|
422
|
+
function isPending(fieldName) {
|
|
423
|
+
var _a;
|
|
424
|
+
return fieldName
|
|
425
|
+
? vestUtils.greaterThan((_a = summary.tests[fieldName]) === null || _a === void 0 ? void 0 : _a.pendingCount, 0)
|
|
426
|
+
: vestUtils.greaterThan(summary.pendingCount, 0);
|
|
443
427
|
}
|
|
444
428
|
}
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
function nonMatchingFieldName(WithFieldName, fieldName) {
|
|
448
|
-
return !!fieldName && !matchingFieldName(WithFieldName, fieldName);
|
|
429
|
+
function getFailures(summary, severityKey, fieldName) {
|
|
430
|
+
return gatherFailures(summary.tests, severityKey, fieldName);
|
|
449
431
|
}
|
|
450
|
-
|
|
451
|
-
|
|
432
|
+
// Gathers all failures of a given severity within a group
|
|
433
|
+
// With a fieldName, it will only gather failures for that field
|
|
434
|
+
function getFailuresByGroup(summary, severityKey, groupName, fieldName) {
|
|
435
|
+
return gatherFailures(summary.groups[groupName], severityKey, fieldName);
|
|
452
436
|
}
|
|
453
|
-
|
|
437
|
+
// Checks if a field is valid within a container object - can be within a group or top level
|
|
438
|
+
function isFieldValid(testContainer, fieldName) {
|
|
439
|
+
var _a;
|
|
440
|
+
return !!((_a = testContainer[fieldName]) === null || _a === void 0 ? void 0 : _a.valid);
|
|
441
|
+
}
|
|
442
|
+
// Checks if a there are any failures of a given severity within a group
|
|
443
|
+
// If a fieldName is provided, it will only check for failures within that field
|
|
444
|
+
function hasFailuresByGroup(summary, severityCount, groupName, fieldName) {
|
|
445
|
+
var _a, _b;
|
|
446
|
+
const group = summary.groups[groupName];
|
|
447
|
+
if (!group) {
|
|
448
|
+
return false;
|
|
449
|
+
}
|
|
454
450
|
if (fieldName) {
|
|
455
|
-
return
|
|
451
|
+
return vestUtils.isPositive((_a = group[fieldName]) === null || _a === void 0 ? void 0 : _a[severityCount]);
|
|
456
452
|
}
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
class SuiteWalker {
|
|
461
|
-
static hasPending(predicate) {
|
|
462
|
-
const root = SuiteWalker.defaultRoot();
|
|
463
|
-
if (!root) {
|
|
464
|
-
return false;
|
|
453
|
+
for (const field in group) {
|
|
454
|
+
if (vestUtils.isPositive((_b = group[field]) === null || _b === void 0 ? void 0 : _b[severityCount])) {
|
|
455
|
+
return true;
|
|
465
456
|
}
|
|
466
|
-
return vestjsRuntime.Walker.some(root, vestUtils.Predicates.all(VestIsolate.isPending, predicate !== null && predicate !== void 0 ? predicate : true));
|
|
467
457
|
}
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
458
|
+
return false;
|
|
459
|
+
}
|
|
460
|
+
// Checks if there are any failures of a given severity
|
|
461
|
+
// If a fieldName is provided, it will only check for failures within that field
|
|
462
|
+
function hasFailures(summary, countKey, fieldName) {
|
|
463
|
+
var _a;
|
|
464
|
+
const failureCount = fieldName
|
|
465
|
+
? (_a = summary.tests[fieldName]) === null || _a === void 0 ? void 0 : _a[countKey]
|
|
466
|
+
: summary[countKey] || 0;
|
|
467
|
+
return vestUtils.isPositive(failureCount);
|
|
468
|
+
}
|
|
469
|
+
function getFailure(severity, summary, fieldName) {
|
|
470
|
+
var _a;
|
|
471
|
+
const summaryKey = summary[severity];
|
|
472
|
+
if (!fieldName) {
|
|
473
|
+
return summaryKey[0];
|
|
474
474
|
}
|
|
475
|
+
return (_a = summaryKey.find((summaryFailure) => matchingFieldName(summaryFailure, fieldName))) === null || _a === void 0 ? void 0 : _a.message;
|
|
475
476
|
}
|
|
476
|
-
SuiteWalker.defaultRoot = vestjsRuntime.VestRuntime.useAvailableRoot;
|
|
477
477
|
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
if (!root)
|
|
486
|
-
return false;
|
|
487
|
-
return vestjsRuntime.Walker.some(root, isolate => {
|
|
488
|
-
VestTest.isX(isolate);
|
|
489
|
-
return predicate(isolate);
|
|
490
|
-
}, VestTest.is);
|
|
478
|
+
var _a, _b;
|
|
479
|
+
class SummaryBase {
|
|
480
|
+
constructor() {
|
|
481
|
+
this.errorCount = 0;
|
|
482
|
+
this.warnCount = 0;
|
|
483
|
+
this.testCount = 0;
|
|
484
|
+
this.pendingCount = 0;
|
|
491
485
|
}
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
}
|
|
486
|
+
}
|
|
487
|
+
class SuiteSummary extends SummaryBase {
|
|
488
|
+
constructor() {
|
|
489
|
+
super(...arguments);
|
|
490
|
+
this[_a] = [];
|
|
491
|
+
this[_b] = [];
|
|
492
|
+
this.groups = {};
|
|
493
|
+
this.tests = {};
|
|
494
|
+
this.valid = false;
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
_a = Severity.ERRORS, _b = Severity.WARNINGS;
|
|
498
|
+
|
|
499
|
+
const CommonStates = {
|
|
500
|
+
PENDING: 'PENDING',
|
|
501
|
+
INITIAL: 'INITIAL',
|
|
502
|
+
};
|
|
503
|
+
const State = {
|
|
504
|
+
[CommonStates.PENDING]: CommonStates.PENDING,
|
|
505
|
+
[CommonStates.INITIAL]: CommonStates.INITIAL,
|
|
506
|
+
DONE: 'DONE',
|
|
507
|
+
};
|
|
508
|
+
const machine$1 = {
|
|
509
|
+
initial: State.INITIAL,
|
|
510
|
+
states: {
|
|
511
|
+
[State.DONE]: {},
|
|
512
|
+
[State.INITIAL]: {
|
|
513
|
+
[State.PENDING]: State.PENDING,
|
|
514
|
+
[State.DONE]: State.DONE,
|
|
515
|
+
},
|
|
516
|
+
[State.PENDING]: {
|
|
517
|
+
[State.DONE]: State.DONE,
|
|
518
|
+
},
|
|
519
|
+
},
|
|
520
|
+
};
|
|
521
|
+
function transition(from, to) {
|
|
522
|
+
return CommonStateMachine.staticTransition(from !== null && from !== void 0 ? from : State.INITIAL, to);
|
|
523
|
+
}
|
|
524
|
+
function setDone(isolate) {
|
|
525
|
+
isolate.status = transition(isolate.status, State.DONE);
|
|
526
|
+
}
|
|
527
|
+
function setPending(isolate) {
|
|
528
|
+
isolate.status = transition(isolate.status, State.PENDING);
|
|
529
|
+
}
|
|
530
|
+
const CommonStateMachine = vestUtils.StateMachine(machine$1);
|
|
531
|
+
|
|
532
|
+
const TestStatus = {
|
|
533
|
+
[CommonStates.PENDING]: CommonStates.PENDING,
|
|
534
|
+
CANCELED: 'CANCELED',
|
|
535
|
+
FAILED: 'FAILED',
|
|
536
|
+
OMITTED: 'OMITTED',
|
|
537
|
+
PASSING: 'PASSING',
|
|
538
|
+
SKIPPED: 'SKIPPED',
|
|
539
|
+
UNTESTED: 'UNTESTED',
|
|
540
|
+
WARNING: 'WARNING',
|
|
541
|
+
};
|
|
542
|
+
const TestAction = {
|
|
543
|
+
RESET: 'RESET',
|
|
544
|
+
};
|
|
545
|
+
const machine = {
|
|
546
|
+
initial: TestStatus.UNTESTED,
|
|
547
|
+
states: {
|
|
548
|
+
'*': {
|
|
549
|
+
[TestStatus.OMITTED]: TestStatus.OMITTED,
|
|
550
|
+
[TestAction.RESET]: TestStatus.UNTESTED,
|
|
551
|
+
},
|
|
552
|
+
[TestStatus.UNTESTED]: {
|
|
553
|
+
[TestStatus.CANCELED]: TestStatus.CANCELED,
|
|
554
|
+
[TestStatus.FAILED]: TestStatus.FAILED,
|
|
555
|
+
[TestStatus.PASSING]: TestStatus.PASSING,
|
|
556
|
+
[TestStatus.PENDING]: TestStatus.PENDING,
|
|
557
|
+
[TestStatus.SKIPPED]: TestStatus.SKIPPED,
|
|
558
|
+
[TestStatus.WARNING]: TestStatus.WARNING,
|
|
559
|
+
},
|
|
560
|
+
[TestStatus.PENDING]: {
|
|
561
|
+
[TestStatus.CANCELED]: TestStatus.CANCELED,
|
|
562
|
+
[TestStatus.FAILED]: TestStatus.FAILED,
|
|
563
|
+
[TestStatus.PASSING]: TestStatus.PASSING,
|
|
564
|
+
[TestStatus.SKIPPED]: [
|
|
565
|
+
TestStatus.SKIPPED,
|
|
566
|
+
(force) => force === true,
|
|
567
|
+
],
|
|
568
|
+
[TestStatus.WARNING]: TestStatus.WARNING,
|
|
569
|
+
},
|
|
570
|
+
[TestStatus.SKIPPED]: {},
|
|
571
|
+
[TestStatus.FAILED]: {},
|
|
572
|
+
[TestStatus.WARNING]: {},
|
|
573
|
+
[TestStatus.PASSING]: {},
|
|
574
|
+
[TestStatus.CANCELED]: {},
|
|
575
|
+
[TestStatus.OMITTED]: {},
|
|
576
|
+
},
|
|
577
|
+
};
|
|
578
|
+
const IsolateTestStateMachine = vestUtils.StateMachine(machine);
|
|
579
|
+
|
|
580
|
+
class VestIsolate {
|
|
581
|
+
static getStatus(isolate) {
|
|
582
|
+
var _a;
|
|
583
|
+
return (_a = isolate.status) !== null && _a !== void 0 ? _a : CommonStates.INITIAL;
|
|
584
|
+
}
|
|
585
|
+
static setStatus(isolate, status, payload) {
|
|
586
|
+
isolate.status = this.stateMachine.staticTransition(VestIsolate.getStatus(isolate), status, payload);
|
|
587
|
+
}
|
|
588
|
+
static statusEquals(isolate, status) {
|
|
589
|
+
return VestIsolate.getStatus(isolate) === status;
|
|
590
|
+
}
|
|
591
|
+
static setPending(isolate) {
|
|
592
|
+
this.setStatus(isolate, CommonStates.PENDING);
|
|
593
|
+
}
|
|
594
|
+
static isPending(isolate) {
|
|
595
|
+
return VestIsolate.statusEquals(isolate, CommonStates.PENDING);
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
VestIsolate.stateMachine = CommonStateMachine;
|
|
599
|
+
|
|
600
|
+
class VestTest extends VestIsolate {
|
|
601
|
+
// Read
|
|
602
|
+
static getData(test) {
|
|
603
|
+
vestUtils.invariant(test.data);
|
|
604
|
+
return test.data;
|
|
605
|
+
}
|
|
606
|
+
static is(isolate) {
|
|
607
|
+
return vestjsRuntime.IsolateSelectors.isIsolateType(isolate, VestIsolateType.Test);
|
|
608
|
+
}
|
|
609
|
+
static isX(isolate) {
|
|
610
|
+
vestUtils.invariant(VestTest.is(isolate), ErrorStrings.EXPECTED_VEST_TEST);
|
|
611
|
+
}
|
|
612
|
+
static cast(isolate) {
|
|
613
|
+
VestTest.isX(isolate);
|
|
614
|
+
return isolate;
|
|
615
|
+
}
|
|
616
|
+
static warns(test) {
|
|
617
|
+
return VestTest.getData(test).severity === TestSeverity.Warning;
|
|
618
|
+
}
|
|
619
|
+
static isOmitted(test) {
|
|
620
|
+
return VestTest.statusEquals(test, TestStatus.OMITTED);
|
|
621
|
+
}
|
|
622
|
+
static isUntested(test) {
|
|
623
|
+
return VestTest.statusEquals(test, TestStatus.UNTESTED);
|
|
624
|
+
}
|
|
625
|
+
static isFailing(test) {
|
|
626
|
+
return VestTest.statusEquals(test, TestStatus.FAILED);
|
|
627
|
+
}
|
|
628
|
+
static isCanceled(test) {
|
|
629
|
+
return VestTest.statusEquals(test, TestStatus.CANCELED);
|
|
630
|
+
}
|
|
631
|
+
static isSkipped(test) {
|
|
632
|
+
return VestTest.statusEquals(test, TestStatus.SKIPPED);
|
|
633
|
+
}
|
|
634
|
+
static isPassing(test) {
|
|
635
|
+
return VestTest.statusEquals(test, TestStatus.PASSING);
|
|
636
|
+
}
|
|
637
|
+
static isWarning(test) {
|
|
638
|
+
return VestTest.statusEquals(test, TestStatus.WARNING);
|
|
639
|
+
}
|
|
640
|
+
static hasFailures(test) {
|
|
641
|
+
return VestTest.isFailing(test) || VestTest.isWarning(test);
|
|
642
|
+
}
|
|
643
|
+
static isNonActionable(test) {
|
|
644
|
+
return (VestTest.isSkipped(test) ||
|
|
645
|
+
VestTest.isOmitted(test) ||
|
|
646
|
+
VestTest.isCanceled(test));
|
|
647
|
+
}
|
|
648
|
+
static isTested(test) {
|
|
649
|
+
return VestTest.hasFailures(test) || VestTest.isPassing(test);
|
|
650
|
+
}
|
|
651
|
+
static awaitsResolution(test) {
|
|
652
|
+
// Is the test in a state where it can still be run, or complete running
|
|
653
|
+
// and its final status is indeterminate?
|
|
654
|
+
return (VestTest.isSkipped(test) ||
|
|
655
|
+
VestTest.isUntested(test) ||
|
|
656
|
+
VestTest.isPending(test));
|
|
657
|
+
}
|
|
658
|
+
static isAsyncTest(test) {
|
|
659
|
+
return vestUtils.isPromise(VestTest.getData(test).asyncTest);
|
|
660
|
+
}
|
|
661
|
+
// Mutate
|
|
662
|
+
// static setPending(test: TIsolateTest) {
|
|
663
|
+
// this.setStatus(test, TestStatus.PENDING);
|
|
664
|
+
// }
|
|
665
|
+
static fail(test) {
|
|
666
|
+
VestTest.setStatus(test, VestTest.warns(test) ? TestStatus.WARNING : TestStatus.FAILED);
|
|
667
|
+
}
|
|
668
|
+
static pass(test) {
|
|
669
|
+
VestTest.setStatus(test, TestStatus.PASSING);
|
|
670
|
+
}
|
|
671
|
+
static warn(test) {
|
|
672
|
+
VestTest.setData(test, current => (Object.assign(Object.assign({}, current), { severity: TestSeverity.Warning })));
|
|
673
|
+
}
|
|
674
|
+
static setData(test, setter) {
|
|
675
|
+
test.data = vestUtils.optionalFunctionValue(setter, VestTest.getData(test));
|
|
676
|
+
}
|
|
677
|
+
static skip(test, force) {
|
|
678
|
+
// Without this force flag, the test will be marked as skipped even if it is pending.
|
|
679
|
+
// This means that it will not be counted in "allIncomplete" and its done callbacks
|
|
680
|
+
// will not be called, or will be called prematurely.
|
|
681
|
+
// What this mostly say is that when we have a pending test for one field, and we then
|
|
682
|
+
// start typing in a different field - the pending test will be canceled, which
|
|
683
|
+
// is usually an unwanted behavior.
|
|
684
|
+
// The only scenario in which we DO want to cancel the async test regardless
|
|
685
|
+
// is when we specifically skip a test with `skipWhen`, which is handled by the
|
|
686
|
+
// "force" boolean flag.
|
|
687
|
+
// I am not a fan of this flag, but it gets the job done.
|
|
688
|
+
VestTest.setStatus(test, TestStatus.SKIPPED, force);
|
|
689
|
+
}
|
|
690
|
+
static cancel(test) {
|
|
691
|
+
VestTest.setStatus(test, TestStatus.CANCELED);
|
|
692
|
+
vestjsRuntime.IsolateMutator.abort(test, TestStatus.CANCELED);
|
|
693
|
+
}
|
|
694
|
+
static omit(test) {
|
|
695
|
+
VestTest.setStatus(test, TestStatus.OMITTED);
|
|
696
|
+
}
|
|
697
|
+
static reset(test) {
|
|
698
|
+
VestTest.setStatus(test, TestAction.RESET);
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
VestTest.stateMachine = IsolateTestStateMachine;
|
|
702
|
+
|
|
703
|
+
class SummaryFailure {
|
|
704
|
+
constructor(fieldName, message, groupName) {
|
|
705
|
+
this.fieldName = fieldName;
|
|
706
|
+
this.message = message;
|
|
707
|
+
this.groupName = groupName;
|
|
708
|
+
}
|
|
709
|
+
static fromTestObject(testObject) {
|
|
710
|
+
const { fieldName, message, groupName } = VestTest.getData(testObject);
|
|
711
|
+
return new SummaryFailure(fieldName, message, groupName);
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
class TestWalker {
|
|
716
|
+
static hasNoTests(root = TestWalker.defaultRoot()) {
|
|
717
|
+
if (!root)
|
|
718
|
+
return true;
|
|
719
|
+
return !vestjsRuntime.Walker.has(root, VestTest.is);
|
|
720
|
+
}
|
|
721
|
+
static someTests(predicate, root = TestWalker.defaultRoot()) {
|
|
722
|
+
if (!root)
|
|
723
|
+
return false;
|
|
724
|
+
return vestjsRuntime.Walker.some(root, isolate => {
|
|
725
|
+
VestTest.isX(isolate);
|
|
726
|
+
return predicate(isolate);
|
|
727
|
+
}, VestTest.is);
|
|
728
|
+
}
|
|
729
|
+
static everyTest(predicate, root = TestWalker.defaultRoot()) {
|
|
730
|
+
if (!root)
|
|
731
|
+
return false;
|
|
732
|
+
return vestjsRuntime.Walker.every(root, isolate => {
|
|
733
|
+
VestTest.isX(isolate);
|
|
734
|
+
return predicate(isolate);
|
|
735
|
+
}, VestTest.is);
|
|
499
736
|
}
|
|
500
737
|
static walkTests(callback, root = TestWalker.defaultRoot()) {
|
|
501
738
|
if (!root)
|
|
@@ -527,180 +764,23 @@ class TestWalker {
|
|
|
527
764
|
}
|
|
528
765
|
TestWalker.defaultRoot = vestjsRuntime.VestRuntime.useAvailableRoot;
|
|
529
766
|
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
function useOmitOptionalFields() {
|
|
536
|
-
const root = vestjsRuntime.VestRuntime.useAvailableRoot();
|
|
537
|
-
const optionalFields = SuiteOptionalFields.getOptionalFields(root);
|
|
538
|
-
// If there are no optional fields, we don't need to do anything
|
|
539
|
-
if (vestUtils.isEmpty(optionalFields)) {
|
|
540
|
-
return;
|
|
541
|
-
}
|
|
542
|
-
// Create an object to store the fields that need to be omitted
|
|
543
|
-
const shouldOmit = new Set();
|
|
544
|
-
// iterate over each of the tests in the state
|
|
545
|
-
TestWalker.walkTests(testObject => {
|
|
546
|
-
if (VestTest.isPending(testObject)) {
|
|
547
|
-
return;
|
|
548
|
-
}
|
|
549
|
-
const { fieldName } = VestTest.getData(testObject);
|
|
550
|
-
// If we already added the current field (not this test specifically)
|
|
551
|
-
// no need for further checks, go and omit the test
|
|
552
|
-
if (shouldOmit.has(fieldName)) {
|
|
553
|
-
verifyAndOmit(testObject);
|
|
554
|
-
}
|
|
555
|
-
else {
|
|
556
|
-
// check if the field has an optional function
|
|
557
|
-
// if so, run it and verify/omit the test
|
|
558
|
-
runOptionalConfig(testObject);
|
|
559
|
-
}
|
|
560
|
-
});
|
|
561
|
-
vestjsRuntime.Bus.useEmit(Events.DONE_TEST_OMISSION_PASS);
|
|
562
|
-
function verifyAndOmit(testObject) {
|
|
563
|
-
const { fieldName } = VestTest.getData(testObject);
|
|
564
|
-
if (shouldOmit.has(fieldName)) {
|
|
565
|
-
VestTest.omit(testObject);
|
|
566
|
-
SuiteOptionalFields.setOptionalField(root, fieldName, current => (Object.assign(Object.assign({}, current), { applied: true })));
|
|
567
|
-
}
|
|
568
|
-
}
|
|
569
|
-
function runOptionalConfig(testObject) {
|
|
570
|
-
const { fieldName } = VestTest.getData(testObject);
|
|
571
|
-
// Ge the optional configuration for the given field
|
|
572
|
-
const optionalConfig = SuiteOptionalFields.getOptionalField(root, fieldName);
|
|
573
|
-
// If the optional was set to a function or a boolean, run it and verify/omit the test
|
|
574
|
-
if (vestUtils.optionalFunctionValue(optionalConfig.rule) === true) {
|
|
575
|
-
shouldOmit.add(fieldName);
|
|
576
|
-
}
|
|
577
|
-
verifyAndOmit(testObject);
|
|
578
|
-
}
|
|
579
|
-
}
|
|
580
|
-
|
|
581
|
-
/**
|
|
582
|
-
* Runs done callback per field when async tests are finished running.
|
|
583
|
-
*/
|
|
584
|
-
function useRunFieldCallbacks(fieldName) {
|
|
585
|
-
const [fieldCallbacks] = useFieldCallbacks();
|
|
586
|
-
if (fieldName &&
|
|
587
|
-
!SuiteWalker.hasRemainingWithTestNameMatching(fieldName) &&
|
|
588
|
-
vestUtils.isArray(fieldCallbacks[fieldName])) {
|
|
589
|
-
vestUtils.callEach(fieldCallbacks[fieldName]);
|
|
590
|
-
}
|
|
591
|
-
}
|
|
592
|
-
/**
|
|
593
|
-
* Runs unlabelled done callback when async tests are finished running.
|
|
594
|
-
*/
|
|
595
|
-
function useRunDoneCallbacks() {
|
|
596
|
-
const [doneCallbacks] = useDoneCallbacks();
|
|
597
|
-
vestUtils.callEach(doneCallbacks);
|
|
598
|
-
}
|
|
599
|
-
|
|
600
|
-
// eslint-disable-next-line max-statements, max-lines-per-function
|
|
601
|
-
function useInitVestBus() {
|
|
602
|
-
const VestBus = vestjsRuntime.Bus.useBus();
|
|
603
|
-
// Report a the completion of a test. There may be other tests with the same
|
|
604
|
-
// name that are still running, or not yet started.
|
|
605
|
-
on(Events.TEST_COMPLETED, (testObject) => {
|
|
606
|
-
if (VestTest.isCanceled(testObject)) {
|
|
607
|
-
return;
|
|
608
|
-
}
|
|
609
|
-
const { fieldName } = VestTest.getData(testObject);
|
|
610
|
-
useRunFieldCallbacks(fieldName);
|
|
611
|
-
});
|
|
612
|
-
on(Events.TEST_RUN_STARTED, () => {
|
|
613
|
-
/* Let's just invalidate the suite cache for now */
|
|
614
|
-
});
|
|
615
|
-
on(vestjsRuntime.RuntimeEvents.ISOLATE_PENDING, (isolate) => {
|
|
616
|
-
if (VestTest.is(isolate)) {
|
|
617
|
-
VestTest.setPending(isolate);
|
|
618
|
-
}
|
|
619
|
-
setPending(isolate);
|
|
620
|
-
});
|
|
621
|
-
on(vestjsRuntime.RuntimeEvents.ISOLATE_DONE, (isolate) => {
|
|
622
|
-
if (VestTest.is(isolate)) {
|
|
623
|
-
VestBus.emit(Events.TEST_COMPLETED, isolate);
|
|
624
|
-
}
|
|
625
|
-
setDone(isolate);
|
|
626
|
-
if (!SuiteWalker.hasPending()) {
|
|
627
|
-
// When no more tests are running, emit the done event
|
|
628
|
-
VestBus.emit(Events.ALL_RUNNING_TESTS_FINISHED);
|
|
629
|
-
}
|
|
630
|
-
});
|
|
631
|
-
on(Events.DONE_TEST_OMISSION_PASS, () => {
|
|
632
|
-
/* We NEED to refresh the cache here. Don't ask */
|
|
633
|
-
});
|
|
634
|
-
// Called when all the tests, including async, are done running
|
|
635
|
-
on(Events.ALL_RUNNING_TESTS_FINISHED, () => {
|
|
636
|
-
// Small optimization. We don't need to run this if there are no async tests
|
|
637
|
-
// The reason is that we run this function immediately after the suite callback
|
|
638
|
-
// is run, so if the suite is only comprised of sync tests, we don't need to
|
|
639
|
-
// run this function twice since we know for a fact the state is up to date
|
|
640
|
-
if (TestWalker.someTests(VestTest.isAsyncTest)) {
|
|
641
|
-
useOmitOptionalFields();
|
|
767
|
+
class SuiteWalker {
|
|
768
|
+
static hasPending(predicate) {
|
|
769
|
+
const root = SuiteWalker.defaultRoot();
|
|
770
|
+
if (!root) {
|
|
771
|
+
return false;
|
|
642
772
|
}
|
|
643
|
-
|
|
644
|
-
});
|
|
645
|
-
on(Events.RESET_FIELD, (fieldName) => {
|
|
646
|
-
TestWalker.resetField(fieldName);
|
|
647
|
-
});
|
|
648
|
-
on(Events.SUITE_RUN_STARTED, () => {
|
|
649
|
-
useResetCallbacks();
|
|
650
|
-
});
|
|
651
|
-
on(Events.SUITE_CALLBACK_RUN_FINISHED, () => {
|
|
652
|
-
useOmitOptionalFields();
|
|
653
|
-
});
|
|
654
|
-
on(Events.REMOVE_FIELD, (fieldName) => {
|
|
655
|
-
TestWalker.removeTestByFieldName(fieldName);
|
|
656
|
-
});
|
|
657
|
-
on(Events.RESET_SUITE, () => {
|
|
658
|
-
useResetSuite();
|
|
659
|
-
});
|
|
660
|
-
return {
|
|
661
|
-
subscribe,
|
|
662
|
-
};
|
|
663
|
-
function subscribe(cb) {
|
|
664
|
-
return VestBus.on('*', () => {
|
|
665
|
-
cb();
|
|
666
|
-
}).off;
|
|
667
|
-
}
|
|
668
|
-
function on(event, cb) {
|
|
669
|
-
VestBus.on(event, (...args) => {
|
|
670
|
-
// This is more concise, but it might be an overkill
|
|
671
|
-
// if we're adding events that don't need to invalidate the cache
|
|
672
|
-
useExpireSuiteResultCache();
|
|
673
|
-
cb(...args);
|
|
674
|
-
});
|
|
675
|
-
}
|
|
676
|
-
}
|
|
677
|
-
|
|
678
|
-
class IsolateReconciler {
|
|
679
|
-
static match(_currentNode, _historyNode) {
|
|
680
|
-
return false;
|
|
681
|
-
}
|
|
682
|
-
static reconcile(currentNode, historyNode) {
|
|
683
|
-
return (currentNode !== null && currentNode !== void 0 ? currentNode : historyNode);
|
|
773
|
+
return vestjsRuntime.Walker.some(root, vestUtils.Predicates.all(VestIsolate.isPending, predicate !== null && predicate !== void 0 ? predicate : true));
|
|
684
774
|
}
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
gn1 === gn2 &&
|
|
692
|
-
// Specifically using == here. The reason is that when serializing
|
|
693
|
-
// suite result, empty key gets removed, but it can also be null.
|
|
694
|
-
testObject1.key == testObject2.key);
|
|
695
|
-
}
|
|
696
|
-
|
|
697
|
-
function cancelOverriddenPendingTest(prevRunTestObject, currentRunTestObject) {
|
|
698
|
-
if (currentRunTestObject !== prevRunTestObject &&
|
|
699
|
-
isSameProfileTest(prevRunTestObject, currentRunTestObject) &&
|
|
700
|
-
VestTest.isPending(prevRunTestObject)) {
|
|
701
|
-
VestTest.cancel(prevRunTestObject);
|
|
775
|
+
// Checks whether there are pending isolates in the tree.
|
|
776
|
+
// If a fieldname is provided, will only check tests with a matching fieldname.
|
|
777
|
+
static hasRemainingWithTestNameMatching(fieldName) {
|
|
778
|
+
return SuiteWalker.hasPending(vestUtils.Predicates.any(vestUtils.isNullish(fieldName), vestUtils.Predicates.all(VestTest.is, (testObject) => {
|
|
779
|
+
return matchesOrHasNoFieldName(VestTest.getData(testObject), fieldName);
|
|
780
|
+
})));
|
|
702
781
|
}
|
|
703
782
|
}
|
|
783
|
+
SuiteWalker.defaultRoot = vestjsRuntime.VestRuntime.useAvailableRoot;
|
|
704
784
|
|
|
705
785
|
const nonMatchingGroupName = vestUtils.bindNot(matchingGroupName);
|
|
706
786
|
function matchingGroupName(testObject, groupName) {
|
|
@@ -750,296 +830,46 @@ function hasFailuresByTestObject(testObject, severityKey, fieldName) {
|
|
|
750
830
|
return true;
|
|
751
831
|
}
|
|
752
832
|
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
*/
|
|
773
|
-
// @vx-allow use-use
|
|
774
|
-
function mode(mode) {
|
|
775
|
-
const [, setMode] = useMode();
|
|
776
|
-
setMode(mode);
|
|
777
|
-
}
|
|
778
|
-
function useIsMode(mode) {
|
|
779
|
-
const [currentMode] = useMode();
|
|
780
|
-
return currentMode === mode;
|
|
781
|
-
}
|
|
782
|
-
function useIsEager() {
|
|
783
|
-
return useIsMode(exports.Modes.EAGER);
|
|
784
|
-
}
|
|
785
|
-
function useIsOne() {
|
|
786
|
-
return useIsMode(exports.Modes.ONE);
|
|
833
|
+
function useShouldAddValidProperty(fieldName) {
|
|
834
|
+
// Is the field optional, and the optional condition is applied
|
|
835
|
+
if (useIsOptionalFieldApplied(fieldName)) {
|
|
836
|
+
return true;
|
|
837
|
+
}
|
|
838
|
+
// Are there no tests?
|
|
839
|
+
if (TestWalker.hasNoTests()) {
|
|
840
|
+
return false;
|
|
841
|
+
}
|
|
842
|
+
// // Does the field have any tests with errors?
|
|
843
|
+
if (hasErrorsByTestObjects(fieldName)) {
|
|
844
|
+
return false;
|
|
845
|
+
}
|
|
846
|
+
// Does the given field have any pending tests that are not optional?
|
|
847
|
+
if (useHasNonOptionalIncomplete(fieldName)) {
|
|
848
|
+
return false;
|
|
849
|
+
}
|
|
850
|
+
// Does the field have no missing tests?
|
|
851
|
+
return useNoMissingTests(fieldName);
|
|
787
852
|
}
|
|
788
|
-
function
|
|
789
|
-
if (
|
|
790
|
-
return
|
|
853
|
+
function useShouldAddValidPropertyInGroup(groupName, fieldName) {
|
|
854
|
+
if (useIsOptionalFieldApplied(fieldName)) {
|
|
855
|
+
return true;
|
|
791
856
|
}
|
|
792
|
-
if (
|
|
793
|
-
return
|
|
857
|
+
if (hasGroupFailuresByTestObjects(Severity.ERRORS, groupName, fieldName)) {
|
|
858
|
+
return false;
|
|
794
859
|
}
|
|
795
|
-
|
|
860
|
+
// Do the given group/field have any pending tests that are not optional?
|
|
861
|
+
if (useHasNonOptionalIncompleteByGroup(groupName, fieldName)) {
|
|
862
|
+
return false;
|
|
863
|
+
}
|
|
864
|
+
return useNoMissingTestsByGroup(groupName, fieldName);
|
|
796
865
|
}
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
return fieldName
|
|
801
|
-
? getByFieldName(testGroup, severityKey, fieldName)
|
|
802
|
-
: collectAll(testGroup, severityKey);
|
|
866
|
+
// Does the given field have any pending tests that are not optional?
|
|
867
|
+
function useHasNonOptionalIncomplete(fieldName) {
|
|
868
|
+
return SuiteWalker.hasPending(vestUtils.Predicates.all(VestTest.is, (testObject) => !nonMatchingFieldName(VestTest.getData(testObject), fieldName), () => !useIsOptionalFieldApplied(fieldName)));
|
|
803
869
|
}
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
return ((
|
|
807
|
-
}
|
|
808
|
-
function collectAll(testGroup, severityKey) {
|
|
809
|
-
const output = {};
|
|
810
|
-
const countKey = countKeyBySeverity(severityKey);
|
|
811
|
-
for (const field in testGroup) {
|
|
812
|
-
if (vestUtils.isPositive(testGroup[field][countKey])) {
|
|
813
|
-
// We will probably never get to the fallback array
|
|
814
|
-
// leaving it just in case the implementation changes
|
|
815
|
-
output[field] = testGroup[field][severityKey] || [];
|
|
816
|
-
}
|
|
817
|
-
}
|
|
818
|
-
return output;
|
|
819
|
-
}
|
|
820
|
-
|
|
821
|
-
function bindSuiteSelectors(get) {
|
|
822
|
-
return {
|
|
823
|
-
getError: (...args) => get().getError(...args),
|
|
824
|
-
getErrors: (...args) => get().getErrors(...args),
|
|
825
|
-
getErrorsByGroup: (...args) => get().getErrorsByGroup(...args),
|
|
826
|
-
getWarning: (...args) => get().getWarning(...args),
|
|
827
|
-
getWarnings: (...args) => get().getWarnings(...args),
|
|
828
|
-
getWarningsByGroup: (...args) => get().getWarningsByGroup(...args),
|
|
829
|
-
hasErrors: (...args) => get().hasErrors(...args),
|
|
830
|
-
hasErrorsByGroup: (...args) => get().hasErrorsByGroup(...args),
|
|
831
|
-
hasWarnings: (...args) => get().hasWarnings(...args),
|
|
832
|
-
hasWarningsByGroup: (...args) => get().hasWarningsByGroup(...args),
|
|
833
|
-
isPending: (...args) => {
|
|
834
|
-
return get().isPending(...args);
|
|
835
|
-
},
|
|
836
|
-
isTested: (...args) => get().isTested(...args),
|
|
837
|
-
isValid: (...args) => get().isValid(...args),
|
|
838
|
-
isValidByGroup: (...args) => get().isValidByGroup(...args),
|
|
839
|
-
};
|
|
840
|
-
}
|
|
841
|
-
// eslint-disable-next-line max-lines-per-function, max-statements
|
|
842
|
-
function suiteSelectors(summary) {
|
|
843
|
-
const selectors = {
|
|
844
|
-
getError,
|
|
845
|
-
getErrors,
|
|
846
|
-
getErrorsByGroup,
|
|
847
|
-
getWarning,
|
|
848
|
-
getWarnings,
|
|
849
|
-
getWarningsByGroup,
|
|
850
|
-
hasErrors,
|
|
851
|
-
hasErrorsByGroup,
|
|
852
|
-
hasWarnings,
|
|
853
|
-
hasWarningsByGroup,
|
|
854
|
-
isPending,
|
|
855
|
-
isTested,
|
|
856
|
-
isValid,
|
|
857
|
-
isValidByGroup,
|
|
858
|
-
};
|
|
859
|
-
return selectors;
|
|
860
|
-
// Booleans
|
|
861
|
-
function isValid(fieldName) {
|
|
862
|
-
var _a;
|
|
863
|
-
return fieldName ? Boolean((_a = summary.tests[fieldName]) === null || _a === void 0 ? void 0 : _a.valid) : summary.valid;
|
|
864
|
-
}
|
|
865
|
-
function isValidByGroup(groupName, fieldName) {
|
|
866
|
-
const group = summary.groups[groupName];
|
|
867
|
-
if (!group) {
|
|
868
|
-
return false;
|
|
869
|
-
}
|
|
870
|
-
if (fieldName) {
|
|
871
|
-
return isFieldValid(group, fieldName);
|
|
872
|
-
}
|
|
873
|
-
for (const fieldName in group) {
|
|
874
|
-
if (!isFieldValid(group, fieldName)) {
|
|
875
|
-
return false;
|
|
876
|
-
}
|
|
877
|
-
}
|
|
878
|
-
return true;
|
|
879
|
-
}
|
|
880
|
-
function hasWarnings(fieldName) {
|
|
881
|
-
return hasFailures(summary, SeverityCount.WARN_COUNT, fieldName);
|
|
882
|
-
}
|
|
883
|
-
function hasErrors(fieldName) {
|
|
884
|
-
return hasFailures(summary, SeverityCount.ERROR_COUNT, fieldName);
|
|
885
|
-
}
|
|
886
|
-
function isTested(fieldName) {
|
|
887
|
-
var _a;
|
|
888
|
-
return vestUtils.isPositive((_a = summary.tests[fieldName]) === null || _a === void 0 ? void 0 : _a.testCount);
|
|
889
|
-
}
|
|
890
|
-
function hasWarningsByGroup(groupName, fieldName) {
|
|
891
|
-
return hasFailuresByGroup(summary, SeverityCount.WARN_COUNT, groupName, fieldName);
|
|
892
|
-
}
|
|
893
|
-
function hasErrorsByGroup(groupName, fieldName) {
|
|
894
|
-
return hasFailuresByGroup(summary, SeverityCount.ERROR_COUNT, groupName, fieldName);
|
|
895
|
-
}
|
|
896
|
-
function getWarnings(fieldName) {
|
|
897
|
-
return getFailures(summary, Severity.WARNINGS, fieldName);
|
|
898
|
-
}
|
|
899
|
-
function getWarning(fieldName) {
|
|
900
|
-
return getFailure(Severity.WARNINGS, summary, fieldName);
|
|
901
|
-
}
|
|
902
|
-
function getErrors(fieldName) {
|
|
903
|
-
return getFailures(summary, Severity.ERRORS, fieldName);
|
|
904
|
-
}
|
|
905
|
-
function getError(fieldName) {
|
|
906
|
-
return getFailure(Severity.ERRORS, summary, fieldName);
|
|
907
|
-
}
|
|
908
|
-
function getErrorsByGroup(groupName, fieldName) {
|
|
909
|
-
return getFailuresByGroup(summary, Severity.ERRORS, groupName, fieldName);
|
|
910
|
-
}
|
|
911
|
-
function getWarningsByGroup(groupName, fieldName) {
|
|
912
|
-
return getFailuresByGroup(summary, Severity.WARNINGS, groupName, fieldName);
|
|
913
|
-
}
|
|
914
|
-
function isPending(fieldName) {
|
|
915
|
-
var _a;
|
|
916
|
-
return fieldName
|
|
917
|
-
? vestUtils.greaterThan((_a = summary.tests[fieldName]) === null || _a === void 0 ? void 0 : _a.pendingCount, 0)
|
|
918
|
-
: vestUtils.greaterThan(summary.pendingCount, 0);
|
|
919
|
-
}
|
|
920
|
-
}
|
|
921
|
-
function getFailures(summary, severityKey, fieldName) {
|
|
922
|
-
return gatherFailures(summary.tests, severityKey, fieldName);
|
|
923
|
-
}
|
|
924
|
-
// Gathers all failures of a given severity within a group
|
|
925
|
-
// With a fieldName, it will only gather failures for that field
|
|
926
|
-
function getFailuresByGroup(summary, severityKey, groupName, fieldName) {
|
|
927
|
-
return gatherFailures(summary.groups[groupName], severityKey, fieldName);
|
|
928
|
-
}
|
|
929
|
-
// Checks if a field is valid within a container object - can be within a group or top level
|
|
930
|
-
function isFieldValid(testContainer, fieldName) {
|
|
931
|
-
var _a;
|
|
932
|
-
return !!((_a = testContainer[fieldName]) === null || _a === void 0 ? void 0 : _a.valid);
|
|
933
|
-
}
|
|
934
|
-
// Checks if a there are any failures of a given severity within a group
|
|
935
|
-
// If a fieldName is provided, it will only check for failures within that field
|
|
936
|
-
function hasFailuresByGroup(summary, severityCount, groupName, fieldName) {
|
|
937
|
-
var _a, _b;
|
|
938
|
-
const group = summary.groups[groupName];
|
|
939
|
-
if (!group) {
|
|
940
|
-
return false;
|
|
941
|
-
}
|
|
942
|
-
if (fieldName) {
|
|
943
|
-
return vestUtils.isPositive((_a = group[fieldName]) === null || _a === void 0 ? void 0 : _a[severityCount]);
|
|
944
|
-
}
|
|
945
|
-
for (const field in group) {
|
|
946
|
-
if (vestUtils.isPositive((_b = group[field]) === null || _b === void 0 ? void 0 : _b[severityCount])) {
|
|
947
|
-
return true;
|
|
948
|
-
}
|
|
949
|
-
}
|
|
950
|
-
return false;
|
|
951
|
-
}
|
|
952
|
-
// Checks if there are any failures of a given severity
|
|
953
|
-
// If a fieldName is provided, it will only check for failures within that field
|
|
954
|
-
function hasFailures(summary, countKey, fieldName) {
|
|
955
|
-
var _a;
|
|
956
|
-
const failureCount = fieldName
|
|
957
|
-
? (_a = summary.tests[fieldName]) === null || _a === void 0 ? void 0 : _a[countKey]
|
|
958
|
-
: summary[countKey] || 0;
|
|
959
|
-
return vestUtils.isPositive(failureCount);
|
|
960
|
-
}
|
|
961
|
-
function getFailure(severity, summary, fieldName) {
|
|
962
|
-
var _a;
|
|
963
|
-
const summaryKey = summary[severity];
|
|
964
|
-
if (!fieldName) {
|
|
965
|
-
return summaryKey[0];
|
|
966
|
-
}
|
|
967
|
-
return (_a = summaryKey.find((summaryFailure) => matchingFieldName(summaryFailure, fieldName))) === null || _a === void 0 ? void 0 : _a.message;
|
|
968
|
-
}
|
|
969
|
-
|
|
970
|
-
var _a, _b;
|
|
971
|
-
class SummaryBase {
|
|
972
|
-
constructor() {
|
|
973
|
-
this.errorCount = 0;
|
|
974
|
-
this.warnCount = 0;
|
|
975
|
-
this.testCount = 0;
|
|
976
|
-
this.pendingCount = 0;
|
|
977
|
-
}
|
|
978
|
-
}
|
|
979
|
-
class SuiteSummary extends SummaryBase {
|
|
980
|
-
constructor() {
|
|
981
|
-
super(...arguments);
|
|
982
|
-
this[_a] = [];
|
|
983
|
-
this[_b] = [];
|
|
984
|
-
this.groups = {};
|
|
985
|
-
this.tests = {};
|
|
986
|
-
this.valid = false;
|
|
987
|
-
}
|
|
988
|
-
}
|
|
989
|
-
_a = Severity.ERRORS, _b = Severity.WARNINGS;
|
|
990
|
-
|
|
991
|
-
class SummaryFailure {
|
|
992
|
-
constructor(fieldName, message, groupName) {
|
|
993
|
-
this.fieldName = fieldName;
|
|
994
|
-
this.message = message;
|
|
995
|
-
this.groupName = groupName;
|
|
996
|
-
}
|
|
997
|
-
static fromTestObject(testObject) {
|
|
998
|
-
const { fieldName, message, groupName } = VestTest.getData(testObject);
|
|
999
|
-
return new SummaryFailure(fieldName, message, groupName);
|
|
1000
|
-
}
|
|
1001
|
-
}
|
|
1002
|
-
|
|
1003
|
-
function useShouldAddValidProperty(fieldName) {
|
|
1004
|
-
// Is the field optional, and the optional condition is applied
|
|
1005
|
-
if (useIsOptionalFieldApplied(fieldName)) {
|
|
1006
|
-
return true;
|
|
1007
|
-
}
|
|
1008
|
-
// Are there no tests?
|
|
1009
|
-
if (TestWalker.hasNoTests()) {
|
|
1010
|
-
return false;
|
|
1011
|
-
}
|
|
1012
|
-
// // Does the field have any tests with errors?
|
|
1013
|
-
if (hasErrorsByTestObjects(fieldName)) {
|
|
1014
|
-
return false;
|
|
1015
|
-
}
|
|
1016
|
-
// Does the given field have any pending tests that are not optional?
|
|
1017
|
-
if (useHasNonOptionalIncomplete(fieldName)) {
|
|
1018
|
-
return false;
|
|
1019
|
-
}
|
|
1020
|
-
// Does the field have no missing tests?
|
|
1021
|
-
return useNoMissingTests(fieldName);
|
|
1022
|
-
}
|
|
1023
|
-
function useShouldAddValidPropertyInGroup(groupName, fieldName) {
|
|
1024
|
-
if (useIsOptionalFieldApplied(fieldName)) {
|
|
1025
|
-
return true;
|
|
1026
|
-
}
|
|
1027
|
-
if (hasGroupFailuresByTestObjects(Severity.ERRORS, groupName, fieldName)) {
|
|
1028
|
-
return false;
|
|
1029
|
-
}
|
|
1030
|
-
// Do the given group/field have any pending tests that are not optional?
|
|
1031
|
-
if (useHasNonOptionalIncompleteByGroup(groupName, fieldName)) {
|
|
1032
|
-
return false;
|
|
1033
|
-
}
|
|
1034
|
-
return useNoMissingTestsByGroup(groupName, fieldName);
|
|
1035
|
-
}
|
|
1036
|
-
// Does the given field have any pending tests that are not optional?
|
|
1037
|
-
function useHasNonOptionalIncomplete(fieldName) {
|
|
1038
|
-
return SuiteWalker.hasPending(vestUtils.Predicates.all(VestTest.is, (testObject) => !nonMatchingFieldName(VestTest.getData(testObject), fieldName), () => !useIsOptionalFieldApplied(fieldName)));
|
|
1039
|
-
}
|
|
1040
|
-
// Do the given group/field have any pending tests that are not optional?
|
|
1041
|
-
function useHasNonOptionalIncompleteByGroup(groupName, fieldName) {
|
|
1042
|
-
return SuiteWalker.hasPending(vestUtils.Predicates.all(VestTest.is, (testObject) => !nonMatchingGroupName(testObject, groupName), (testObject) => !nonMatchingFieldName(VestTest.getData(testObject), fieldName), () => !useIsOptionalFieldApplied(fieldName)));
|
|
870
|
+
// Do the given group/field have any pending tests that are not optional?
|
|
871
|
+
function useHasNonOptionalIncompleteByGroup(groupName, fieldName) {
|
|
872
|
+
return SuiteWalker.hasPending(vestUtils.Predicates.all(VestTest.is, (testObject) => !nonMatchingGroupName(testObject, groupName), (testObject) => !nonMatchingFieldName(VestTest.getData(testObject), fieldName), () => !useIsOptionalFieldApplied(fieldName)));
|
|
1043
873
|
}
|
|
1044
874
|
// Did all of the tests for the provided field run/omit?
|
|
1045
875
|
// This makes sure that the fields are not skipped or pending.
|
|
@@ -1202,17 +1032,68 @@ function useCreateSuiteResult() {
|
|
|
1202
1032
|
}
|
|
1203
1033
|
|
|
1204
1034
|
/**
|
|
1205
|
-
*
|
|
1035
|
+
* Checks if context has included tests
|
|
1036
|
+
*/
|
|
1037
|
+
function useHasOnliedTests(testObject, fieldName) {
|
|
1038
|
+
return vestUtils.isNotNullish(vestjsRuntime.Walker.findClosest(testObject, (child) => {
|
|
1039
|
+
if (!FocusSelectors.isIsolateFocused(child))
|
|
1040
|
+
return false;
|
|
1041
|
+
return FocusSelectors.isOnlyFocused(child, fieldName);
|
|
1042
|
+
}));
|
|
1043
|
+
}
|
|
1044
|
+
|
|
1045
|
+
/**
|
|
1046
|
+
* Conditionally includes a field for testing, based on specified criteria.
|
|
1047
|
+
*
|
|
1048
|
+
* @param {string} fieldName - The name of the field to include for testing.
|
|
1206
1049
|
*
|
|
1207
1050
|
* @example
|
|
1051
|
+
* include('confirm').when('password');
|
|
1052
|
+
* // Includes the "confirm" field for testing when the "password" field is included
|
|
1208
1053
|
*
|
|
1209
|
-
*
|
|
1210
|
-
*
|
|
1211
|
-
*
|
|
1212
|
-
|
|
1213
|
-
//
|
|
1214
|
-
|
|
1215
|
-
|
|
1054
|
+
* include('confirm').when(someValue);
|
|
1055
|
+
* // Includes the "confirm" field for testing when the value of `someValue` is true
|
|
1056
|
+
*
|
|
1057
|
+
* include('confirm').when(() => someValue);
|
|
1058
|
+
* // Includes the "confirm" field for testing when the callback function returns true
|
|
1059
|
+
*
|
|
1060
|
+
* include('username').when(result => result.hasErrors('username'));
|
|
1061
|
+
* // Includes the "username" field for testing when there are errors associated with it in the current suite result
|
|
1062
|
+
*/
|
|
1063
|
+
// @vx-allow use-use
|
|
1064
|
+
function include(fieldName) {
|
|
1065
|
+
vestUtils.invariant(vestUtils.isStringValue(fieldName));
|
|
1066
|
+
const inclusion = useInclusion();
|
|
1067
|
+
inclusion[fieldName] = true;
|
|
1068
|
+
return { when };
|
|
1069
|
+
/**
|
|
1070
|
+
* Specifies the inclusion criteria for the field in `include` function.
|
|
1071
|
+
*/
|
|
1072
|
+
function when(condition) {
|
|
1073
|
+
vestUtils.invariant(condition !== fieldName, ErrorStrings.INCLUDE_SELF);
|
|
1074
|
+
const inclusion = useInclusion();
|
|
1075
|
+
// This callback will run as part of the "isExcluded" series of checks
|
|
1076
|
+
inclusion[fieldName] = function isIncluded(currentNode) {
|
|
1077
|
+
if (vestUtils.isStringValue(condition)) {
|
|
1078
|
+
return useHasOnliedTests(currentNode, condition);
|
|
1079
|
+
}
|
|
1080
|
+
return vestUtils.optionalFunctionValue(condition, vestUtils.optionalFunctionValue(useCreateSuiteResult));
|
|
1081
|
+
};
|
|
1082
|
+
}
|
|
1083
|
+
}
|
|
1084
|
+
|
|
1085
|
+
/**
|
|
1086
|
+
* Conditionally omits tests from the suite.
|
|
1087
|
+
*
|
|
1088
|
+
* @example
|
|
1089
|
+
*
|
|
1090
|
+
* omitWhen(res => res.hasErrors('username'), () => {
|
|
1091
|
+
* test('username', 'User already taken', async () => await doesUserExist(username)
|
|
1092
|
+
* });
|
|
1093
|
+
*/
|
|
1094
|
+
// @vx-allow use-use
|
|
1095
|
+
function omitWhen(conditional, callback) {
|
|
1096
|
+
vestjsRuntime.Isolate.create(VestIsolateType.OmitWhen, () => {
|
|
1216
1097
|
SuiteContext.run({
|
|
1217
1098
|
omitted: useWithinActiveOmitWhen() ||
|
|
1218
1099
|
vestUtils.optionalFunctionValue(conditional, vestUtils.optionalFunctionValue(useCreateSuiteResult)),
|
|
@@ -1250,71 +1131,85 @@ function useIsExcludedIndividually() {
|
|
|
1250
1131
|
return useSkipped();
|
|
1251
1132
|
}
|
|
1252
1133
|
|
|
1253
|
-
var
|
|
1254
|
-
(function (
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1134
|
+
var Events;
|
|
1135
|
+
(function (Events) {
|
|
1136
|
+
Events["TEST_RUN_STARTED"] = "test_run_started";
|
|
1137
|
+
Events["TEST_COMPLETED"] = "test_completed";
|
|
1138
|
+
Events["ALL_RUNNING_TESTS_FINISHED"] = "all_running_tests_finished";
|
|
1139
|
+
Events["REMOVE_FIELD"] = "remove_field";
|
|
1140
|
+
Events["RESET_FIELD"] = "reset_field";
|
|
1141
|
+
Events["RESET_SUITE"] = "reset_suite";
|
|
1142
|
+
Events["SUITE_RUN_STARTED"] = "suite_run_started";
|
|
1143
|
+
Events["SUITE_CALLBACK_RUN_FINISHED"] = "SUITE_CALLBACK_RUN_FINISHED";
|
|
1144
|
+
Events["DONE_TEST_OMISSION_PASS"] = "DONE_TEST_OMISSION_PASS";
|
|
1145
|
+
})(Events || (Events = {}));
|
|
1258
1146
|
|
|
1259
|
-
function
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
matchAll: match === true,
|
|
1264
|
-
});
|
|
1265
|
-
}
|
|
1266
|
-
class FocusSelectors {
|
|
1267
|
-
static isSkipFocused(focus, fieldName) {
|
|
1268
|
-
return ((focus === null || focus === void 0 ? void 0 : focus.data.focusMode) === FocusModes.SKIP &&
|
|
1269
|
-
(hasFocus(focus, fieldName) || focus.data.matchAll === true));
|
|
1270
|
-
}
|
|
1271
|
-
static isOnlyFocused(focus, fieldName) {
|
|
1272
|
-
return ((focus === null || focus === void 0 ? void 0 : focus.data.focusMode) === FocusModes.ONLY && hasFocus(focus, fieldName));
|
|
1147
|
+
function IsolateTest(callback, input, key) {
|
|
1148
|
+
const payload = Object.assign(Object.assign({}, IsolateTestBase()), { fieldName: input.fieldName, testFn: input.testFn });
|
|
1149
|
+
if (input.groupName) {
|
|
1150
|
+
payload.groupName = input.groupName;
|
|
1273
1151
|
}
|
|
1274
|
-
|
|
1275
|
-
|
|
1152
|
+
if (input.message) {
|
|
1153
|
+
payload.message = input.message;
|
|
1276
1154
|
}
|
|
1155
|
+
const isolate = vestjsRuntime.Isolate.create(VestIsolateType.Test, callback, payload, key !== null && key !== void 0 ? key : null);
|
|
1156
|
+
return isolate;
|
|
1277
1157
|
}
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
return
|
|
1158
|
+
function IsolateTestBase() {
|
|
1159
|
+
return {
|
|
1160
|
+
severity: TestSeverity.Error,
|
|
1161
|
+
status: IsolateTestStateMachine.initial(),
|
|
1162
|
+
};
|
|
1163
|
+
}
|
|
1164
|
+
|
|
1165
|
+
function shouldUseErrorAsMessage(message, error) {
|
|
1166
|
+
// kind of cheating with this safe guard, but it does the job
|
|
1167
|
+
return vestUtils.isUndefined(message) && vestUtils.isStringValue(error);
|
|
1288
1168
|
}
|
|
1169
|
+
|
|
1289
1170
|
/**
|
|
1290
|
-
*
|
|
1171
|
+
* Sets the current execution mode for the current suite.
|
|
1172
|
+
*
|
|
1173
|
+
* Supported modes:
|
|
1174
|
+
* - `EAGER` - (default) Runs all tests, but stops on first failure for each given field.
|
|
1175
|
+
* - `ALL` - Runs all tests, regardless of failures.
|
|
1176
|
+
* - `ONE` - Stops suite execution on first failure of any field.
|
|
1291
1177
|
*
|
|
1292
1178
|
* @example
|
|
1179
|
+
* ```js
|
|
1180
|
+
* import {Modes, create} from 'vest';
|
|
1293
1181
|
*
|
|
1294
|
-
*
|
|
1182
|
+
* const suite = create('suite_name', () => {
|
|
1183
|
+
* vest.mode(Modes.ALL);
|
|
1184
|
+
*
|
|
1185
|
+
* // ...
|
|
1186
|
+
* });
|
|
1187
|
+
* ```
|
|
1188
|
+
* @param 'ALL' | 'EAGER' | 'ONE' mode - The mode to set.
|
|
1295
1189
|
*/
|
|
1296
1190
|
// @vx-allow use-use
|
|
1297
|
-
function
|
|
1298
|
-
|
|
1191
|
+
function mode(mode) {
|
|
1192
|
+
const [, setMode] = useMode();
|
|
1193
|
+
setMode(mode);
|
|
1299
1194
|
}
|
|
1300
|
-
function
|
|
1301
|
-
|
|
1195
|
+
function useIsMode(mode) {
|
|
1196
|
+
const [currentMode] = useMode();
|
|
1197
|
+
return currentMode === mode;
|
|
1302
1198
|
}
|
|
1303
|
-
function
|
|
1304
|
-
|
|
1305
|
-
return (vestUtils.isNotEmpty(focus === null || focus === void 0 ? void 0 : focus.data.match) &&
|
|
1306
|
-
(fieldName ? (_b = (_a = focus === null || focus === void 0 ? void 0 : focus.data.match) === null || _a === void 0 ? void 0 : _a.includes(fieldName)) !== null && _b !== void 0 ? _b : true : true));
|
|
1199
|
+
function useIsEager() {
|
|
1200
|
+
return useIsMode(exports.Modes.EAGER);
|
|
1307
1201
|
}
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
return
|
|
1317
|
-
}
|
|
1202
|
+
function useIsOne() {
|
|
1203
|
+
return useIsMode(exports.Modes.ONE);
|
|
1204
|
+
}
|
|
1205
|
+
function useShouldSkipBasedOnMode(testData) {
|
|
1206
|
+
if (useIsOne()) {
|
|
1207
|
+
return hasErrorsByTestObjects();
|
|
1208
|
+
}
|
|
1209
|
+
if (useIsEager()) {
|
|
1210
|
+
return hasErrorsByTestObjects(testData.fieldName);
|
|
1211
|
+
}
|
|
1212
|
+
return false;
|
|
1318
1213
|
}
|
|
1319
1214
|
|
|
1320
1215
|
//Checks whether a certain test profile excluded by any of the exclusion groups.
|
|
@@ -1383,304 +1278,409 @@ function useForceSkipIfInSkipWhen(testNode) {
|
|
|
1383
1278
|
return testNode;
|
|
1384
1279
|
}
|
|
1385
1280
|
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1281
|
+
// eslint-disable-next-line max-statements
|
|
1282
|
+
function useAttemptRunTest(testObject) {
|
|
1283
|
+
useVerifyTestRun(testObject);
|
|
1284
|
+
if (VestTest.isUntested(testObject)) {
|
|
1285
|
+
return useRunTest(testObject);
|
|
1389
1286
|
}
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1287
|
+
if (!VestTest.isNonActionable(testObject)) {
|
|
1288
|
+
// Probably unreachable. If we get here, it means that
|
|
1289
|
+
// something was really wrong and should be reported.
|
|
1290
|
+
/* istanbul ignore next */
|
|
1291
|
+
vestUtils.deferThrow(vestUtils.text(ErrorStrings.UNEXPECTED_TEST_REGISTRATION_ERROR, {
|
|
1292
|
+
testObject: JSON.stringify(testObject),
|
|
1293
|
+
}));
|
|
1394
1294
|
}
|
|
1395
1295
|
}
|
|
1396
|
-
function
|
|
1397
|
-
|
|
1398
|
-
|
|
1296
|
+
function runSyncTest(testObject) {
|
|
1297
|
+
return SuiteContext.run({ currentTest: testObject }, () => {
|
|
1298
|
+
let result;
|
|
1299
|
+
const { message, testFn } = VestTest.getData(testObject);
|
|
1300
|
+
try {
|
|
1301
|
+
result = testFn({ signal: testObject.abortController.signal });
|
|
1302
|
+
}
|
|
1303
|
+
catch (error) {
|
|
1304
|
+
if (shouldUseErrorAsMessage(message, error)) {
|
|
1305
|
+
VestTest.getData(testObject).message = error;
|
|
1306
|
+
}
|
|
1307
|
+
result = false;
|
|
1308
|
+
}
|
|
1309
|
+
if (result === false) {
|
|
1310
|
+
VestTest.fail(testObject);
|
|
1311
|
+
}
|
|
1312
|
+
return result;
|
|
1313
|
+
});
|
|
1399
1314
|
}
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1315
|
+
/**
|
|
1316
|
+
* runs test, if async - adds to pending array
|
|
1317
|
+
*/
|
|
1318
|
+
function useRunTest(testObject) {
|
|
1319
|
+
// Run test callback.
|
|
1320
|
+
// If a promise is returned, set as async and
|
|
1321
|
+
// Move to pending list.
|
|
1322
|
+
const result = runSyncTest(testObject);
|
|
1323
|
+
try {
|
|
1324
|
+
// try catch for safe property access
|
|
1325
|
+
// in case object is an enforce chain
|
|
1326
|
+
if (vestUtils.isPromise(result)) {
|
|
1327
|
+
VestTest.getData(testObject).asyncTest = result;
|
|
1328
|
+
return useRunAsyncTest(testObject);
|
|
1329
|
+
}
|
|
1330
|
+
onTestCompleted(testObject);
|
|
1407
1331
|
}
|
|
1408
|
-
|
|
1409
|
-
//
|
|
1410
|
-
//
|
|
1332
|
+
catch (e) {
|
|
1333
|
+
// Probably unreachable. If we get here, it means that
|
|
1334
|
+
// something was really wrong and should be reported.
|
|
1411
1335
|
/* istanbul ignore next */
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
// In short: if the node was omitted in the previous run,
|
|
1417
|
-
// we want to re-evaluate it. The reason is that we may incorrectly
|
|
1418
|
-
// identify it is "optional" because it was omitted in the previous run.
|
|
1419
|
-
// There may be a better way to handle this. Need to revisit this.
|
|
1420
|
-
if (VestTest.isOmitted(prevNode)) {
|
|
1421
|
-
return newNode;
|
|
1422
|
-
}
|
|
1423
|
-
return prevNode;
|
|
1424
|
-
}
|
|
1425
|
-
function cancelOverriddenPendingTestOnTestReRun(nextNode, currentNode, prevTestObject) {
|
|
1426
|
-
if (nextNode === currentNode && VestTest.is(currentNode)) {
|
|
1427
|
-
cancelOverriddenPendingTest(prevTestObject, currentNode);
|
|
1336
|
+
throw new Error(vestUtils.text(ErrorStrings.UNEXPECTED_TEST_REGISTRATION_ERROR, {
|
|
1337
|
+
testObject: JSON.stringify(testObject),
|
|
1338
|
+
error: e,
|
|
1339
|
+
}));
|
|
1428
1340
|
}
|
|
1429
1341
|
}
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
function
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1342
|
+
/**
|
|
1343
|
+
* Runs async test.
|
|
1344
|
+
*/
|
|
1345
|
+
function useRunAsyncTest(testObject) {
|
|
1346
|
+
const { asyncTest, message } = VestTest.getData(testObject);
|
|
1347
|
+
if (!vestUtils.isPromise(asyncTest))
|
|
1348
|
+
return;
|
|
1349
|
+
// VestTest.setPending(testObject);
|
|
1350
|
+
const done = vestjsRuntime.VestRuntime.persist(() => {
|
|
1351
|
+
onTestCompleted(testObject);
|
|
1352
|
+
});
|
|
1353
|
+
const fail = vestjsRuntime.VestRuntime.persist((rejectionMessage) => {
|
|
1354
|
+
if (VestTest.isCanceled(testObject)) {
|
|
1355
|
+
return;
|
|
1356
|
+
}
|
|
1357
|
+
VestTest.getData(testObject).message = vestUtils.isStringValue(rejectionMessage)
|
|
1358
|
+
? rejectionMessage
|
|
1359
|
+
: message;
|
|
1360
|
+
VestTest.fail(testObject);
|
|
1361
|
+
done();
|
|
1362
|
+
});
|
|
1363
|
+
return asyncTest.then(done, fail);
|
|
1364
|
+
}
|
|
1365
|
+
function onTestCompleted(testObject) {
|
|
1366
|
+
// Attempts passing if the test is not already failed.
|
|
1367
|
+
// or is not canceled/omitted.
|
|
1368
|
+
VestTest.pass(testObject);
|
|
1369
|
+
}
|
|
1370
|
+
|
|
1371
|
+
// @vx-allow use-use
|
|
1372
|
+
function wrapTestMemo(test) {
|
|
1373
|
+
function memo(fieldName, ...args) {
|
|
1374
|
+
const [deps, testFn, msg] = args.reverse();
|
|
1375
|
+
// Implicit dependency for better specificity
|
|
1376
|
+
const dependencies = [
|
|
1377
|
+
useSuiteId(),
|
|
1378
|
+
fieldName,
|
|
1379
|
+
vestjsRuntime.VestRuntime.useCurrentCursor(),
|
|
1380
|
+
].concat(deps);
|
|
1381
|
+
return useGetTestFromCache(dependencies, cacheAction);
|
|
1382
|
+
function cacheAction() {
|
|
1383
|
+
return test(fieldName, msg, testFn);
|
|
1384
|
+
}
|
|
1385
|
+
}
|
|
1386
|
+
return memo;
|
|
1387
|
+
}
|
|
1388
|
+
function useGetTestFromCache(dependencies, cacheAction) {
|
|
1389
|
+
const cache = useTestMemoCache();
|
|
1390
|
+
const cached = cache.get(dependencies);
|
|
1391
|
+
if (vestUtils.isNull(cached)) {
|
|
1392
|
+
// cache miss
|
|
1393
|
+
return cache(dependencies, cacheAction);
|
|
1394
|
+
}
|
|
1395
|
+
const [, cachedValue] = cached;
|
|
1396
|
+
if (VestTest.isCanceled(cachedValue)) {
|
|
1397
|
+
// cache hit, but test is canceled
|
|
1398
|
+
cache.invalidate(dependencies);
|
|
1399
|
+
return cache(dependencies, cacheAction);
|
|
1400
|
+
}
|
|
1401
|
+
vestjsRuntime.VestRuntime.addNodeToHistory(cachedValue);
|
|
1402
|
+
return cachedValue;
|
|
1403
|
+
}
|
|
1404
|
+
|
|
1405
|
+
// @vx-allow use-use
|
|
1406
|
+
function vestTest(fieldName, ...args) {
|
|
1407
|
+
const [message, testFn, key] = (vestUtils.isFunction(args[1]) ? args : [undefined, ...args]);
|
|
1408
|
+
validateTestParams(fieldName, testFn);
|
|
1409
|
+
const groupName = useGroupName();
|
|
1410
|
+
const testObjectInput = { fieldName, groupName, message, testFn };
|
|
1411
|
+
// This invalidates the suite cache.
|
|
1412
|
+
vestjsRuntime.Bus.useEmit(Events.TEST_RUN_STARTED);
|
|
1413
|
+
return IsolateTest(useAttemptRunTest, testObjectInput, key);
|
|
1414
|
+
}
|
|
1415
|
+
const test = vestUtils.assign(vestTest, {
|
|
1416
|
+
memo: wrapTestMemo(vestTest),
|
|
1417
|
+
});
|
|
1418
|
+
function validateTestParams(fieldName, testFn) {
|
|
1419
|
+
const fnName = 'test';
|
|
1420
|
+
vestUtils.invariant(vestUtils.isStringValue(fieldName), vestUtils.text(ErrorStrings.INVALID_PARAM_PASSED_TO_FUNCTION, {
|
|
1421
|
+
fn_name: fnName,
|
|
1422
|
+
param: 'fieldName',
|
|
1423
|
+
expected: 'string',
|
|
1424
|
+
}));
|
|
1425
|
+
vestUtils.invariant(vestUtils.isFunction(testFn), vestUtils.text(ErrorStrings.INVALID_PARAM_PASSED_TO_FUNCTION, {
|
|
1426
|
+
fn_name: fnName,
|
|
1427
|
+
param: 'callback',
|
|
1428
|
+
expected: 'function',
|
|
1442
1429
|
}));
|
|
1443
1430
|
}
|
|
1444
1431
|
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
return
|
|
1448
|
-
|
|
1432
|
+
// import { optional, skipWhen, omitWhen, IsolateTest, group } from 'vest';
|
|
1433
|
+
function getTypedMethods() {
|
|
1434
|
+
return {
|
|
1435
|
+
group,
|
|
1436
|
+
include,
|
|
1437
|
+
omitWhen,
|
|
1438
|
+
only,
|
|
1439
|
+
optional,
|
|
1440
|
+
skip,
|
|
1441
|
+
skipWhen,
|
|
1442
|
+
test,
|
|
1443
|
+
};
|
|
1449
1444
|
}
|
|
1450
1445
|
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1446
|
+
/**
|
|
1447
|
+
* This module gets triggered once the suite is done running its sync tests.
|
|
1448
|
+
*
|
|
1449
|
+
* It goes over all the tests in the state, and checks if they need to be omitted.
|
|
1450
|
+
*/
|
|
1451
|
+
function useOmitOptionalFields() {
|
|
1452
|
+
const root = vestjsRuntime.VestRuntime.useAvailableRoot();
|
|
1453
|
+
const optionalFields = SuiteOptionalFields.getOptionalFields(root);
|
|
1454
|
+
// If there are no optional fields, we don't need to do anything
|
|
1455
|
+
if (vestUtils.isEmpty(optionalFields)) {
|
|
1456
|
+
return;
|
|
1457
|
+
}
|
|
1458
|
+
// Create an object to store the fields that need to be omitted
|
|
1459
|
+
const shouldOmit = new Set();
|
|
1460
|
+
// iterate over each of the tests in the state
|
|
1461
|
+
TestWalker.walkTests(testObject => {
|
|
1462
|
+
if (VestTest.isPending(testObject)) {
|
|
1463
|
+
return;
|
|
1464
|
+
}
|
|
1465
|
+
const { fieldName } = VestTest.getData(testObject);
|
|
1466
|
+
// If we already added the current field (not this test specifically)
|
|
1467
|
+
// no need for further checks, go and omit the test
|
|
1468
|
+
if (shouldOmit.has(fieldName)) {
|
|
1469
|
+
verifyAndOmit(testObject);
|
|
1470
|
+
}
|
|
1471
|
+
else {
|
|
1472
|
+
// check if the field has an optional function
|
|
1473
|
+
// if so, run it and verify/omit the test
|
|
1474
|
+
runOptionalConfig(testObject);
|
|
1475
|
+
}
|
|
1455
1476
|
});
|
|
1477
|
+
vestjsRuntime.Bus.useEmit(Events.DONE_TEST_OMISSION_PASS);
|
|
1478
|
+
function verifyAndOmit(testObject) {
|
|
1479
|
+
const { fieldName } = VestTest.getData(testObject);
|
|
1480
|
+
if (shouldOmit.has(fieldName)) {
|
|
1481
|
+
VestTest.omit(testObject);
|
|
1482
|
+
SuiteOptionalFields.setOptionalField(root, fieldName, current => (Object.assign(Object.assign({}, current), { applied: true })));
|
|
1483
|
+
}
|
|
1484
|
+
}
|
|
1485
|
+
function runOptionalConfig(testObject) {
|
|
1486
|
+
const { fieldName } = VestTest.getData(testObject);
|
|
1487
|
+
// Ge the optional configuration for the given field
|
|
1488
|
+
const optionalConfig = SuiteOptionalFields.getOptionalField(root, fieldName);
|
|
1489
|
+
// If the optional was set to a function or a boolean, run it and verify/omit the test
|
|
1490
|
+
if (vestUtils.optionalFunctionValue(optionalConfig.rule) === true) {
|
|
1491
|
+
shouldOmit.add(fieldName);
|
|
1492
|
+
}
|
|
1493
|
+
verifyAndOmit(testObject);
|
|
1494
|
+
}
|
|
1456
1495
|
}
|
|
1457
1496
|
|
|
1458
1497
|
/**
|
|
1459
|
-
*
|
|
1460
|
-
*
|
|
1461
|
-
* @param {string} fieldName - The name of the field to include for testing.
|
|
1462
|
-
*
|
|
1463
|
-
* @example
|
|
1464
|
-
* include('confirm').when('password');
|
|
1465
|
-
* // Includes the "confirm" field for testing when the "password" field is included
|
|
1466
|
-
*
|
|
1467
|
-
* include('confirm').when(someValue);
|
|
1468
|
-
* // Includes the "confirm" field for testing when the value of `someValue` is true
|
|
1469
|
-
*
|
|
1470
|
-
* include('confirm').when(() => someValue);
|
|
1471
|
-
* // Includes the "confirm" field for testing when the callback function returns true
|
|
1472
|
-
*
|
|
1473
|
-
* include('username').when(result => result.hasErrors('username'));
|
|
1474
|
-
* // Includes the "username" field for testing when there are errors associated with it in the current suite result
|
|
1498
|
+
* Runs done callback per field when async tests are finished running.
|
|
1475
1499
|
*/
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1500
|
+
function useRunFieldCallbacks(fieldName) {
|
|
1501
|
+
const [fieldCallbacks] = useFieldCallbacks();
|
|
1502
|
+
if (fieldName &&
|
|
1503
|
+
!SuiteWalker.hasRemainingWithTestNameMatching(fieldName) &&
|
|
1504
|
+
vestUtils.isArray(fieldCallbacks[fieldName])) {
|
|
1505
|
+
vestUtils.callEach(fieldCallbacks[fieldName]);
|
|
1506
|
+
}
|
|
1507
|
+
}
|
|
1508
|
+
/**
|
|
1509
|
+
* Runs unlabelled done callback when async tests are finished running.
|
|
1510
|
+
*/
|
|
1511
|
+
function useRunDoneCallbacks() {
|
|
1512
|
+
const [doneCallbacks] = useDoneCallbacks();
|
|
1513
|
+
vestUtils.callEach(doneCallbacks);
|
|
1514
|
+
}
|
|
1515
|
+
|
|
1516
|
+
// eslint-disable-next-line max-statements, max-lines-per-function
|
|
1517
|
+
function useInitVestBus() {
|
|
1518
|
+
const VestBus = vestjsRuntime.Bus.useBus();
|
|
1519
|
+
// Report a the completion of a test. There may be other tests with the same
|
|
1520
|
+
// name that are still running, or not yet started.
|
|
1521
|
+
on(Events.TEST_COMPLETED, (testObject) => {
|
|
1522
|
+
if (VestTest.isCanceled(testObject)) {
|
|
1523
|
+
return;
|
|
1524
|
+
}
|
|
1525
|
+
const { fieldName } = VestTest.getData(testObject);
|
|
1526
|
+
useRunFieldCallbacks(fieldName);
|
|
1527
|
+
});
|
|
1528
|
+
on(Events.TEST_RUN_STARTED, () => {
|
|
1529
|
+
/* Let's just invalidate the suite cache for now */
|
|
1530
|
+
});
|
|
1531
|
+
on(vestjsRuntime.RuntimeEvents.ISOLATE_PENDING, (isolate) => {
|
|
1532
|
+
if (VestTest.is(isolate)) {
|
|
1533
|
+
VestTest.setPending(isolate);
|
|
1534
|
+
}
|
|
1535
|
+
setPending(isolate);
|
|
1536
|
+
});
|
|
1537
|
+
on(vestjsRuntime.RuntimeEvents.ISOLATE_DONE, (isolate) => {
|
|
1538
|
+
if (VestTest.is(isolate)) {
|
|
1539
|
+
VestBus.emit(Events.TEST_COMPLETED, isolate);
|
|
1540
|
+
}
|
|
1541
|
+
setDone(isolate);
|
|
1542
|
+
if (!SuiteWalker.hasPending()) {
|
|
1543
|
+
// When no more tests are running, emit the done event
|
|
1544
|
+
VestBus.emit(Events.ALL_RUNNING_TESTS_FINISHED);
|
|
1545
|
+
}
|
|
1546
|
+
});
|
|
1547
|
+
on(Events.DONE_TEST_OMISSION_PASS, () => {
|
|
1548
|
+
/* We NEED to refresh the cache here. Don't ask */
|
|
1549
|
+
});
|
|
1550
|
+
// Called when all the tests, including async, are done running
|
|
1551
|
+
on(Events.ALL_RUNNING_TESTS_FINISHED, () => {
|
|
1552
|
+
// Small optimization. We don't need to run this if there are no async tests
|
|
1553
|
+
// The reason is that we run this function immediately after the suite callback
|
|
1554
|
+
// is run, so if the suite is only comprised of sync tests, we don't need to
|
|
1555
|
+
// run this function twice since we know for a fact the state is up to date
|
|
1556
|
+
if (TestWalker.someTests(VestTest.isAsyncTest)) {
|
|
1557
|
+
useOmitOptionalFields();
|
|
1558
|
+
}
|
|
1559
|
+
useRunDoneCallbacks();
|
|
1560
|
+
});
|
|
1561
|
+
on(Events.RESET_FIELD, (fieldName) => {
|
|
1562
|
+
TestWalker.resetField(fieldName);
|
|
1563
|
+
});
|
|
1564
|
+
on(Events.SUITE_RUN_STARTED, () => {
|
|
1565
|
+
useResetCallbacks();
|
|
1566
|
+
});
|
|
1567
|
+
on(Events.SUITE_CALLBACK_RUN_FINISHED, () => {
|
|
1568
|
+
useOmitOptionalFields();
|
|
1569
|
+
});
|
|
1570
|
+
on(Events.REMOVE_FIELD, (fieldName) => {
|
|
1571
|
+
TestWalker.removeTestByFieldName(fieldName);
|
|
1572
|
+
});
|
|
1573
|
+
on(Events.RESET_SUITE, () => {
|
|
1574
|
+
useResetSuite();
|
|
1575
|
+
});
|
|
1576
|
+
return {
|
|
1577
|
+
subscribe,
|
|
1578
|
+
};
|
|
1579
|
+
function subscribe(cb) {
|
|
1580
|
+
return VestBus.on('*', () => {
|
|
1581
|
+
cb();
|
|
1582
|
+
}).off;
|
|
1583
|
+
}
|
|
1584
|
+
function on(event, cb) {
|
|
1585
|
+
VestBus.on(event, (...args) => {
|
|
1586
|
+
// This is more concise, but it might be an overkill
|
|
1587
|
+
// if we're adding events that don't need to invalidate the cache
|
|
1588
|
+
useExpireSuiteResultCache();
|
|
1589
|
+
cb(...args);
|
|
1590
|
+
});
|
|
1495
1591
|
}
|
|
1496
1592
|
}
|
|
1497
1593
|
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
payload.groupName = input.groupName;
|
|
1594
|
+
class IsolateReconciler {
|
|
1595
|
+
static match(_currentNode, _historyNode) {
|
|
1596
|
+
return false;
|
|
1502
1597
|
}
|
|
1503
|
-
|
|
1504
|
-
|
|
1598
|
+
static reconcile(currentNode, historyNode) {
|
|
1599
|
+
return (currentNode !== null && currentNode !== void 0 ? currentNode : historyNode);
|
|
1505
1600
|
}
|
|
1506
|
-
const isolate = vestjsRuntime.Isolate.create(VestIsolateType.Test, callback, payload, key !== null && key !== void 0 ? key : null);
|
|
1507
|
-
return isolate;
|
|
1508
1601
|
}
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1602
|
+
|
|
1603
|
+
function isSameProfileTest(testObject1, testObject2) {
|
|
1604
|
+
const { groupName: gn1 } = VestTest.getData(testObject1);
|
|
1605
|
+
const { groupName: gn2, fieldName: fn2 } = VestTest.getData(testObject2);
|
|
1606
|
+
return (matchingFieldName(VestTest.getData(testObject1), fn2) &&
|
|
1607
|
+
gn1 === gn2 &&
|
|
1608
|
+
// Specifically using == here. The reason is that when serializing
|
|
1609
|
+
// suite result, empty key gets removed, but it can also be null.
|
|
1610
|
+
testObject1.key == testObject2.key);
|
|
1514
1611
|
}
|
|
1515
1612
|
|
|
1516
|
-
function
|
|
1517
|
-
|
|
1518
|
-
|
|
1613
|
+
function cancelOverriddenPendingTest(prevRunTestObject, currentRunTestObject) {
|
|
1614
|
+
if (currentRunTestObject !== prevRunTestObject &&
|
|
1615
|
+
isSameProfileTest(prevRunTestObject, currentRunTestObject) &&
|
|
1616
|
+
VestTest.isPending(prevRunTestObject)) {
|
|
1617
|
+
VestTest.cancel(prevRunTestObject);
|
|
1618
|
+
}
|
|
1519
1619
|
}
|
|
1520
1620
|
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
if (VestTest.isUntested(testObject)) {
|
|
1525
|
-
return useRunTest(testObject);
|
|
1621
|
+
class IsolateTestReconciler extends IsolateReconciler {
|
|
1622
|
+
static match(currentNode, historyNode) {
|
|
1623
|
+
return VestTest.is(currentNode) && VestTest.is(historyNode);
|
|
1526
1624
|
}
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
vestUtils.deferThrow(vestUtils.text(ErrorStrings.UNEXPECTED_TEST_REGISTRATION_ERROR, {
|
|
1532
|
-
testObject: JSON.stringify(testObject),
|
|
1533
|
-
}));
|
|
1625
|
+
static reconcile(currentNode, historyNode) {
|
|
1626
|
+
const reconcilerOutput = usePickNode(historyNode, currentNode);
|
|
1627
|
+
cancelOverriddenPendingTestOnTestReRun(reconcilerOutput, currentNode, historyNode);
|
|
1628
|
+
return reconcilerOutput;
|
|
1534
1629
|
}
|
|
1535
1630
|
}
|
|
1536
|
-
function
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
const { message, testFn } = VestTest.getData(testObject);
|
|
1540
|
-
try {
|
|
1541
|
-
result = testFn({ signal: testObject.abortController.signal });
|
|
1542
|
-
}
|
|
1543
|
-
catch (error) {
|
|
1544
|
-
if (shouldUseErrorAsMessage(message, error)) {
|
|
1545
|
-
VestTest.getData(testObject).message = error;
|
|
1546
|
-
}
|
|
1547
|
-
result = false;
|
|
1548
|
-
}
|
|
1549
|
-
if (result === false) {
|
|
1550
|
-
VestTest.fail(testObject);
|
|
1551
|
-
}
|
|
1552
|
-
return result;
|
|
1553
|
-
});
|
|
1631
|
+
function usePickNode(historyNode, currentNode) {
|
|
1632
|
+
const collisionResult = handleCollision(currentNode, historyNode);
|
|
1633
|
+
return useVerifyTestRun(currentNode, collisionResult);
|
|
1554
1634
|
}
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
function useRunTest(testObject) {
|
|
1559
|
-
// Run test callback.
|
|
1560
|
-
// If a promise is returned, set as async and
|
|
1561
|
-
// Move to pending list.
|
|
1562
|
-
const result = runSyncTest(testObject);
|
|
1563
|
-
try {
|
|
1564
|
-
// try catch for safe property access
|
|
1565
|
-
// in case object is an enforce chain
|
|
1566
|
-
if (vestUtils.isPromise(result)) {
|
|
1567
|
-
VestTest.getData(testObject).asyncTest = result;
|
|
1568
|
-
return useRunAsyncTest(testObject);
|
|
1569
|
-
}
|
|
1570
|
-
onTestCompleted(testObject);
|
|
1635
|
+
function handleCollision(newNode, prevNode) {
|
|
1636
|
+
if (vestjsRuntime.IsolateInspector.usesKey(newNode)) {
|
|
1637
|
+
return VestTest.cast(vestjsRuntime.Reconciler.handleIsolateNodeWithKey(newNode, VestTest.isNonActionable));
|
|
1571
1638
|
}
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1639
|
+
if (vestjsRuntime.Reconciler.dropNextNodesOnReorder(nodeReorderDetected, newNode, prevNode)) {
|
|
1640
|
+
throwTestOrderError(newNode, prevNode);
|
|
1641
|
+
return newNode;
|
|
1642
|
+
}
|
|
1643
|
+
if (!VestTest.is(prevNode)) {
|
|
1644
|
+
// I believe we cannot actually reach this point.
|
|
1645
|
+
// Because it should already be handled by nodeReorderDetected.
|
|
1575
1646
|
/* istanbul ignore next */
|
|
1576
|
-
|
|
1577
|
-
testObject: JSON.stringify(testObject),
|
|
1578
|
-
error: e,
|
|
1579
|
-
}));
|
|
1647
|
+
return newNode;
|
|
1580
1648
|
}
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
if (
|
|
1588
|
-
return;
|
|
1589
|
-
// VestTest.setPending(testObject);
|
|
1590
|
-
const done = vestjsRuntime.VestRuntime.persist(() => {
|
|
1591
|
-
onTestCompleted(testObject);
|
|
1592
|
-
});
|
|
1593
|
-
const fail = vestjsRuntime.VestRuntime.persist((rejectionMessage) => {
|
|
1594
|
-
if (VestTest.isCanceled(testObject)) {
|
|
1595
|
-
return;
|
|
1596
|
-
}
|
|
1597
|
-
VestTest.getData(testObject).message = vestUtils.isStringValue(rejectionMessage)
|
|
1598
|
-
? rejectionMessage
|
|
1599
|
-
: message;
|
|
1600
|
-
VestTest.fail(testObject);
|
|
1601
|
-
done();
|
|
1602
|
-
});
|
|
1603
|
-
return asyncTest.then(done, fail);
|
|
1604
|
-
}
|
|
1605
|
-
function onTestCompleted(testObject) {
|
|
1606
|
-
// Attempts passing if the test is not already failed.
|
|
1607
|
-
// or is not canceled/omitted.
|
|
1608
|
-
VestTest.pass(testObject);
|
|
1609
|
-
}
|
|
1610
|
-
|
|
1611
|
-
// @vx-allow use-use
|
|
1612
|
-
function wrapTestMemo(test) {
|
|
1613
|
-
function memo(fieldName, ...args) {
|
|
1614
|
-
const [deps, testFn, msg] = args.reverse();
|
|
1615
|
-
// Implicit dependency for better specificity
|
|
1616
|
-
const dependencies = [
|
|
1617
|
-
useSuiteId(),
|
|
1618
|
-
fieldName,
|
|
1619
|
-
vestjsRuntime.VestRuntime.useCurrentCursor(),
|
|
1620
|
-
].concat(deps);
|
|
1621
|
-
return useGetTestFromCache(dependencies, cacheAction);
|
|
1622
|
-
function cacheAction() {
|
|
1623
|
-
return test(fieldName, msg, testFn);
|
|
1624
|
-
}
|
|
1649
|
+
// FIXME: May-13-2023
|
|
1650
|
+
// This may not be the most ideal solution.
|
|
1651
|
+
// In short: if the node was omitted in the previous run,
|
|
1652
|
+
// we want to re-evaluate it. The reason is that we may incorrectly
|
|
1653
|
+
// identify it is "optional" because it was omitted in the previous run.
|
|
1654
|
+
// There may be a better way to handle this. Need to revisit this.
|
|
1655
|
+
if (VestTest.isOmitted(prevNode)) {
|
|
1656
|
+
return newNode;
|
|
1625
1657
|
}
|
|
1626
|
-
return
|
|
1658
|
+
return prevNode;
|
|
1627
1659
|
}
|
|
1628
|
-
function
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
if (vestUtils.isNull(cached)) {
|
|
1632
|
-
// cache miss
|
|
1633
|
-
return cache(dependencies, cacheAction);
|
|
1634
|
-
}
|
|
1635
|
-
const [, cachedValue] = cached;
|
|
1636
|
-
if (VestTest.isCanceled(cachedValue)) {
|
|
1637
|
-
// cache hit, but test is canceled
|
|
1638
|
-
cache.invalidate(dependencies);
|
|
1639
|
-
return cache(dependencies, cacheAction);
|
|
1660
|
+
function cancelOverriddenPendingTestOnTestReRun(nextNode, currentNode, prevTestObject) {
|
|
1661
|
+
if (nextNode === currentNode && VestTest.is(currentNode)) {
|
|
1662
|
+
cancelOverriddenPendingTest(prevTestObject, currentNode);
|
|
1640
1663
|
}
|
|
1641
|
-
vestjsRuntime.VestRuntime.addNodeToHistory(cachedValue);
|
|
1642
|
-
return cachedValue;
|
|
1643
1664
|
}
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
function vestTest(fieldName, ...args) {
|
|
1647
|
-
const [message, testFn, key] = (vestUtils.isFunction(args[1]) ? args : [undefined, ...args]);
|
|
1648
|
-
validateTestParams(fieldName, testFn);
|
|
1649
|
-
const groupName = useGroupName();
|
|
1650
|
-
const testObjectInput = { fieldName, groupName, message, testFn };
|
|
1651
|
-
// This invalidates the suite cache.
|
|
1652
|
-
vestjsRuntime.Bus.useEmit(Events.TEST_RUN_STARTED);
|
|
1653
|
-
return IsolateTest(useAttemptRunTest, testObjectInput, key);
|
|
1665
|
+
function nodeReorderDetected(newNode, prevNode) {
|
|
1666
|
+
return VestTest.is(prevNode) && !isSameProfileTest(prevNode, newNode);
|
|
1654
1667
|
}
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
}));
|
|
1665
|
-
vestUtils.invariant(vestUtils.isFunction(testFn), vestUtils.text(ErrorStrings.INVALID_PARAM_PASSED_TO_FUNCTION, {
|
|
1666
|
-
fn_name: fnName,
|
|
1667
|
-
param: 'callback',
|
|
1668
|
-
expected: 'function',
|
|
1668
|
+
function throwTestOrderError(newNode, prevNode) {
|
|
1669
|
+
if (vestjsRuntime.IsolateInspector.canReorder(newNode)) {
|
|
1670
|
+
return;
|
|
1671
|
+
}
|
|
1672
|
+
vestUtils.deferThrow(vestUtils.text(ErrorStrings.TESTS_CALLED_IN_DIFFERENT_ORDER, {
|
|
1673
|
+
fieldName: VestTest.getData(newNode).fieldName,
|
|
1674
|
+
prevName: VestTest.is(prevNode)
|
|
1675
|
+
? VestTest.getData(prevNode).fieldName
|
|
1676
|
+
: undefined,
|
|
1669
1677
|
}));
|
|
1670
1678
|
}
|
|
1671
1679
|
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
return
|
|
1675
|
-
|
|
1676
|
-
include,
|
|
1677
|
-
omitWhen,
|
|
1678
|
-
only,
|
|
1679
|
-
optional,
|
|
1680
|
-
skip,
|
|
1681
|
-
skipWhen,
|
|
1682
|
-
test,
|
|
1683
|
-
};
|
|
1680
|
+
function VestReconciler(currentNode, historyNode) {
|
|
1681
|
+
var _a, _b;
|
|
1682
|
+
return ((_b = (_a = [IsolateTestReconciler]
|
|
1683
|
+
.find(reconciler => reconciler.match(currentNode, historyNode))) === null || _a === void 0 ? void 0 : _a.reconcile(currentNode, historyNode)) !== null && _b !== void 0 ? _b : null);
|
|
1684
1684
|
}
|
|
1685
1685
|
|
|
1686
1686
|
function useDeferDoneCallback(doneCallback, fieldName) {
|
|
@@ -1735,6 +1735,7 @@ function validateSuiteCallback(suiteCallback) {
|
|
|
1735
1735
|
}
|
|
1736
1736
|
|
|
1737
1737
|
// @vx-allow use-use
|
|
1738
|
+
// eslint-disable-next-line max-lines-per-function
|
|
1738
1739
|
function createSuite(...args) {
|
|
1739
1740
|
const [suiteCallback, suiteName] = args.reverse();
|
|
1740
1741
|
validateSuiteCallback(suiteCallback);
|
|
@@ -1749,6 +1750,7 @@ function createSuite(...args) {
|
|
|
1749
1750
|
return IsolateSuite(useRunSuiteCallback(suiteCallback, ...args));
|
|
1750
1751
|
}).output;
|
|
1751
1752
|
}
|
|
1753
|
+
const mountedStatic = staticSuite(...args);
|
|
1752
1754
|
// Assign methods to the suite
|
|
1753
1755
|
// We do this within the VestRuntime so that the suite methods
|
|
1754
1756
|
// will be bound to the suite's stateRef and be able to access it.
|
|
@@ -1758,7 +1760,7 @@ function createSuite(...args) {
|
|
|
1758
1760
|
return vestUtils.assign(
|
|
1759
1761
|
// We're also binding the suite to the stateRef, so that the suite
|
|
1760
1762
|
// can access the stateRef when it's called.
|
|
1761
|
-
vestjsRuntime.VestRuntime.persist(suite), Object.assign(Object.assign({ dump: vestjsRuntime.VestRuntime.persist(() => vestjsRuntime.VestRuntime.useAvailableRoot()), get: vestjsRuntime.VestRuntime.persist(useCreateSuiteResult), remove: vestjsRuntime.Bus.usePrepareEmitter(Events.REMOVE_FIELD), reset: vestjsRuntime.Bus.usePrepareEmitter(Events.RESET_SUITE), resetField: vestjsRuntime.Bus.usePrepareEmitter(Events.RESET_FIELD), resume: vestjsRuntime.VestRuntime.persist(useLoadSuite), subscribe: VestBus.subscribe }, bindSuiteSelectors(vestjsRuntime.VestRuntime.persist(useCreateSuiteResult))), getTypedMethods()));
|
|
1763
|
+
vestjsRuntime.VestRuntime.persist(suite), Object.assign(Object.assign({ dump: vestjsRuntime.VestRuntime.persist(() => vestjsRuntime.VestRuntime.useAvailableRoot()), get: vestjsRuntime.VestRuntime.persist(useCreateSuiteResult), remove: vestjsRuntime.Bus.usePrepareEmitter(Events.REMOVE_FIELD), reset: vestjsRuntime.Bus.usePrepareEmitter(Events.RESET_SUITE), resetField: vestjsRuntime.Bus.usePrepareEmitter(Events.RESET_FIELD), resume: vestjsRuntime.VestRuntime.persist(useLoadSuite), runStatic: (...args) => mountedStatic(...args), subscribe: VestBus.subscribe }, bindSuiteSelectors(vestjsRuntime.VestRuntime.persist(useCreateSuiteResult))), getTypedMethods()));
|
|
1762
1764
|
});
|
|
1763
1765
|
}
|
|
1764
1766
|
function useRunSuiteCallback(suiteCallback, ...args) {
|
|
@@ -1769,6 +1771,17 @@ function useRunSuiteCallback(suiteCallback, ...args) {
|
|
|
1769
1771
|
return useSuiteRunResult();
|
|
1770
1772
|
};
|
|
1771
1773
|
}
|
|
1774
|
+
// @vx-allow use-use
|
|
1775
|
+
// eslint-disable-next-line max-lines-per-function
|
|
1776
|
+
function staticSuite(...createArgs) {
|
|
1777
|
+
return vestUtils.assign((...args) => {
|
|
1778
|
+
const suite = createSuite(...createArgs);
|
|
1779
|
+
const result = suite(...args);
|
|
1780
|
+
return Object.freeze(vestUtils.assign({
|
|
1781
|
+
dump: suite.dump,
|
|
1782
|
+
}, result));
|
|
1783
|
+
}, Object.assign({}, getTypedMethods()));
|
|
1784
|
+
}
|
|
1772
1785
|
|
|
1773
1786
|
function IsolateEach(callback) {
|
|
1774
1787
|
return vestjsRuntime.Isolate.create(VestIsolateType.Each, callback, {
|
|
@@ -1798,33 +1811,6 @@ function each(list, callback) {
|
|
|
1798
1811
|
});
|
|
1799
1812
|
}
|
|
1800
1813
|
|
|
1801
|
-
/**
|
|
1802
|
-
* Creates a static suite for server-side validation.
|
|
1803
|
-
*
|
|
1804
|
-
* @param {Function} validationFn - The validation function that defines the suite's tests.
|
|
1805
|
-
* @returns {Function} - A function that runs the validations defined in the suite.
|
|
1806
|
-
*
|
|
1807
|
-
* @example
|
|
1808
|
-
* import { staticSuite, test, enforce } from 'vest';
|
|
1809
|
-
*
|
|
1810
|
-
* const suite = staticSuite(data => {
|
|
1811
|
-
* test('username', 'username is required', () => {
|
|
1812
|
-
* enforce(data.username).isNotEmpty();
|
|
1813
|
-
* });
|
|
1814
|
-
* });
|
|
1815
|
-
*
|
|
1816
|
-
* suite(data);
|
|
1817
|
-
*/
|
|
1818
|
-
function staticSuite(suiteCallback) {
|
|
1819
|
-
return vestUtils.assign((...args) => {
|
|
1820
|
-
const suite = createSuite(suiteCallback);
|
|
1821
|
-
const result = suite(...args);
|
|
1822
|
-
return Object.freeze(vestUtils.assign({
|
|
1823
|
-
dump: suite.dump,
|
|
1824
|
-
}, result));
|
|
1825
|
-
}, Object.assign({}, getTypedMethods()));
|
|
1826
|
-
}
|
|
1827
|
-
|
|
1828
1814
|
const ERROR_OUTSIDE_OF_TEST = ErrorStrings.WARN_MUST_BE_CALLED_FROM_TEST;
|
|
1829
1815
|
/**
|
|
1830
1816
|
* Sets the severity level of a test to `warn`, allowing it to fail without marking the suite as invalid.
|