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