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