vest 4.0.0-dev-7acb76 → 4.0.0-dev-1aae50
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/CHANGELOG.md +70 -50
- package/README.md +2 -112
- package/dist/cjs/classnames.development.js +3 -3
- package/dist/cjs/classnames.production.js +1 -1
- package/dist/cjs/compose.js +7 -0
- package/dist/cjs/compounds.js +7 -0
- package/dist/cjs/enforce/compose.development.js +139 -0
- package/dist/cjs/enforce/compose.production.js +1 -0
- package/dist/cjs/enforce/compounds.development.js +132 -0
- package/dist/cjs/enforce/compounds.production.js +1 -0
- package/dist/cjs/enforce/package.json +1 -0
- package/dist/cjs/enforce/schema.development.js +144 -0
- package/dist/cjs/enforce/schema.production.js +1 -0
- package/dist/cjs/promisify.development.js +1 -1
- package/dist/cjs/promisify.production.js +1 -1
- package/dist/cjs/schema.js +7 -0
- package/dist/cjs/vest.development.js +582 -1083
- package/dist/cjs/vest.production.js +1 -1
- package/dist/es/classnames.development.js +3 -3
- package/dist/es/classnames.production.js +1 -1
- package/dist/es/enforce/compose.development.js +137 -0
- package/dist/es/enforce/compose.production.js +1 -0
- package/dist/es/enforce/compounds.development.js +130 -0
- package/dist/es/enforce/compounds.production.js +1 -0
- package/dist/es/enforce/package.json +1 -0
- package/dist/es/enforce/schema.development.js +140 -0
- package/dist/es/enforce/schema.production.js +1 -0
- package/dist/es/promisify.development.js +1 -1
- package/dist/es/promisify.production.js +1 -1
- package/dist/es/vest.development.js +577 -1084
- package/dist/es/vest.production.js +1 -1
- package/dist/umd/classnames.development.js +3 -3
- package/dist/umd/classnames.production.js +1 -1
- package/dist/umd/enforce/compose.development.js +143 -0
- package/dist/umd/enforce/compose.production.js +1 -0
- package/dist/umd/enforce/compounds.development.js +136 -0
- package/dist/umd/enforce/compounds.production.js +1 -0
- package/dist/umd/enforce/schema.development.js +148 -0
- package/dist/umd/enforce/schema.production.js +1 -0
- package/dist/umd/promisify.development.js +1 -1
- package/dist/umd/promisify.production.js +1 -1
- package/dist/umd/vest.development.js +1693 -2197
- package/dist/umd/vest.production.js +1 -1
- package/enforce/compose/package.json +7 -0
- package/enforce/compounds/package.json +7 -0
- package/enforce/schema/package.json +7 -0
- package/package.json +107 -13
- package/testUtils/mockThrowError.ts +16 -0
- package/types/classnames.d.ts +2 -2
- package/types/enforce/compose.d.ts +134 -0
- package/types/enforce/compounds.d.ts +146 -0
- package/types/enforce/schema.d.ts +151 -0
- package/types/vest.d.ts +31 -196
- package/docs/.nojekyll +0 -0
- package/docs/README.md +0 -113
- package/docs/_assets/favicon.ico +0 -0
- package/docs/_assets/vest-logo.png +0 -0
- package/docs/_sidebar.md +0 -14
- package/docs/cross_field_validations.md +0 -33
- package/docs/enforce.md +0 -11
- package/docs/exclusion.md +0 -129
- package/docs/getting_started.md +0 -72
- package/docs/group.md +0 -142
- package/docs/index.html +0 -41
- package/docs/migration.md +0 -202
- package/docs/n4s/rules.md +0 -1282
- package/docs/node.md +0 -36
- package/docs/optional.md +0 -103
- package/docs/result.md +0 -249
- package/docs/state.md +0 -102
- package/docs/test.md +0 -172
- package/docs/utilities.md +0 -109
- package/docs/warn.md +0 -82
|
@@ -1,2204 +1,1700 @@
|
|
|
1
1
|
(function (global, factory) {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
}(this, (function (exports) { 'use strict';
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
2
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('n4s'), require('context')) :
|
|
3
|
+
typeof define === 'function' && define.amd ? define(['exports', 'n4s', 'context'], factory) :
|
|
4
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.vest = {}, global.n4s, global.context));
|
|
5
|
+
}(this, (function (exports, n4s, context$1) { 'use strict';
|
|
6
|
+
|
|
7
|
+
var assign = Object.assign;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @returns a unique numeric id.
|
|
11
|
+
*/
|
|
12
|
+
var genId = (function (n) { return function () {
|
|
13
|
+
return "" + n++;
|
|
14
|
+
}; })(0);
|
|
15
|
+
|
|
16
|
+
function isFunction(value) {
|
|
17
|
+
return typeof value === 'function';
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function optionalFunctionValue(value) {
|
|
21
|
+
var args = [];
|
|
22
|
+
for (var _i = 1; _i < arguments.length; _i++) {
|
|
23
|
+
args[_i - 1] = arguments[_i];
|
|
24
|
+
}
|
|
25
|
+
return isFunction(value) ? value.apply(void 0, args) : value;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function defaultTo(callback, defaultValue) {
|
|
29
|
+
var _a;
|
|
30
|
+
return (_a = optionalFunctionValue(callback)) !== null && _a !== void 0 ? _a : defaultValue;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Throws a timed out error.
|
|
35
|
+
*/
|
|
36
|
+
function throwError(devMessage, productionMessage) {
|
|
37
|
+
throw new Error(devMessage );
|
|
38
|
+
}
|
|
39
|
+
function throwErrorDeferred(devMessage, productionMessage) {
|
|
40
|
+
setTimeout(function () {
|
|
41
|
+
throwError(devMessage);
|
|
42
|
+
}, 0);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// eslint-disable-next-line max-lines-per-function
|
|
46
|
+
function createState(onStateChange) {
|
|
47
|
+
var state = {
|
|
48
|
+
references: []
|
|
49
|
+
};
|
|
50
|
+
var registrations = [];
|
|
51
|
+
return {
|
|
52
|
+
registerStateKey: registerStateKey,
|
|
53
|
+
reset: reset
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Registers a new key in the state, takes the initial value (may be a function that returns the initial value), returns a function.
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
*
|
|
60
|
+
* const useColor = state.registerStateKey("blue");
|
|
61
|
+
*
|
|
62
|
+
* let [color, setColor] = useColor(); // -> ["blue", Function]
|
|
63
|
+
*
|
|
64
|
+
* setColor("green");
|
|
65
|
+
*
|
|
66
|
+
* useColor()[0]; -> "green"
|
|
67
|
+
*/
|
|
68
|
+
function registerStateKey(initialState, onUpdate) {
|
|
69
|
+
var key = registrations.length;
|
|
70
|
+
registrations.push([initialState, onUpdate]);
|
|
71
|
+
return initKey(key, initialState);
|
|
72
|
+
}
|
|
73
|
+
function reset() {
|
|
74
|
+
var prev = current();
|
|
75
|
+
state.references = [];
|
|
76
|
+
registrations.forEach(function (_a, index) {
|
|
77
|
+
var initialValue = _a[0];
|
|
78
|
+
return initKey(index, initialValue, prev[index]);
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
function initKey(key, initialState, prevState) {
|
|
82
|
+
current().push();
|
|
83
|
+
set(key, optionalFunctionValue(initialState, prevState));
|
|
84
|
+
return function useStateKey() {
|
|
85
|
+
return [
|
|
86
|
+
current()[key],
|
|
87
|
+
function (nextState) {
|
|
88
|
+
return set(key, optionalFunctionValue(nextState, current()[key]));
|
|
89
|
+
},
|
|
90
|
+
];
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
function current() {
|
|
94
|
+
return state.references;
|
|
95
|
+
}
|
|
96
|
+
function set(index, value) {
|
|
97
|
+
var prevValue = state.references[index];
|
|
98
|
+
state.references[index] = value;
|
|
99
|
+
var _a = registrations[index], onUpdate = _a[1];
|
|
100
|
+
if (isFunction(onUpdate)) {
|
|
101
|
+
onUpdate(value, prevValue);
|
|
102
|
+
}
|
|
103
|
+
if (isFunction(onStateChange)) {
|
|
104
|
+
onStateChange();
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
var IsolateTypes;
|
|
110
|
+
(function (IsolateTypes) {
|
|
111
|
+
IsolateTypes[IsolateTypes["DEFAULT"] = 0] = "DEFAULT";
|
|
112
|
+
IsolateTypes[IsolateTypes["SUITE"] = 1] = "SUITE";
|
|
113
|
+
IsolateTypes[IsolateTypes["EACH"] = 2] = "EACH";
|
|
114
|
+
IsolateTypes[IsolateTypes["SKIP_WHEN"] = 3] = "SKIP_WHEN";
|
|
115
|
+
IsolateTypes[IsolateTypes["GROUP"] = 4] = "GROUP";
|
|
116
|
+
})(IsolateTypes || (IsolateTypes = {}));
|
|
117
|
+
|
|
118
|
+
function createStateRef(state, _a) {
|
|
119
|
+
var suiteId = _a.suiteId, suiteName = _a.suiteName;
|
|
120
|
+
return {
|
|
121
|
+
optionalFields: state.registerStateKey(function () { return ({}); }),
|
|
122
|
+
suiteId: state.registerStateKey(suiteId),
|
|
123
|
+
suiteName: state.registerStateKey(suiteName),
|
|
124
|
+
testCallbacks: state.registerStateKey(function () { return ({
|
|
125
|
+
fieldCallbacks: {},
|
|
126
|
+
doneCallbacks: []
|
|
127
|
+
}); }),
|
|
128
|
+
testObjects: state.registerStateKey(function (prev) {
|
|
129
|
+
return {
|
|
130
|
+
prev: prev ? prev.current : [],
|
|
131
|
+
current: []
|
|
132
|
+
};
|
|
133
|
+
})
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function asArray(possibleArg) {
|
|
138
|
+
return [].concat(possibleArg);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function last(values) {
|
|
142
|
+
var valuesArray = asArray(values);
|
|
143
|
+
return valuesArray[valuesArray.length - 1];
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function createCursor() {
|
|
147
|
+
var storage = {
|
|
148
|
+
cursor: []
|
|
149
|
+
};
|
|
150
|
+
function addLevel() {
|
|
151
|
+
storage.cursor.push(0);
|
|
152
|
+
}
|
|
153
|
+
function removeLevel() {
|
|
154
|
+
storage.cursor.pop();
|
|
155
|
+
}
|
|
156
|
+
function cursorAt() {
|
|
157
|
+
return last(storage.cursor);
|
|
158
|
+
}
|
|
159
|
+
function getCursor() {
|
|
160
|
+
return asArray(storage.cursor);
|
|
161
|
+
}
|
|
162
|
+
function next() {
|
|
163
|
+
storage.cursor[storage.cursor.length - 1]++;
|
|
164
|
+
return last(storage.cursor);
|
|
165
|
+
}
|
|
166
|
+
function reset() {
|
|
167
|
+
storage.cursor = [0];
|
|
168
|
+
}
|
|
169
|
+
reset();
|
|
170
|
+
return {
|
|
171
|
+
addLevel: addLevel,
|
|
172
|
+
cursorAt: cursorAt,
|
|
173
|
+
getCursor: getCursor,
|
|
174
|
+
next: next,
|
|
175
|
+
removeLevel: removeLevel,
|
|
176
|
+
reset: reset
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
var context = context$1.createContext(function (ctxRef, parentContext) {
|
|
181
|
+
return parentContext
|
|
182
|
+
? null
|
|
183
|
+
: assign({}, {
|
|
184
|
+
exclusion: {
|
|
185
|
+
tests: {},
|
|
186
|
+
groups: {}
|
|
187
|
+
},
|
|
188
|
+
isolate: {
|
|
189
|
+
type: IsolateTypes.DEFAULT,
|
|
190
|
+
keys: {
|
|
191
|
+
current: {},
|
|
192
|
+
prev: {}
|
|
193
|
+
}
|
|
194
|
+
},
|
|
195
|
+
testCursor: createCursor()
|
|
196
|
+
}, ctxRef);
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
function bindNot(fn) {
|
|
200
|
+
return function () {
|
|
201
|
+
var args = [];
|
|
202
|
+
for (var _i = 0; _i < arguments.length; _i++) {
|
|
203
|
+
args[_i] = arguments[_i];
|
|
204
|
+
}
|
|
205
|
+
return !fn.apply(void 0, args);
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// The module is named "isArrayValue" since it
|
|
210
|
+
// is conflicting with a nested npm dependency.
|
|
211
|
+
// We may need to revisit this in the future.
|
|
212
|
+
function isArray(value) {
|
|
213
|
+
return Boolean(Array.isArray(value));
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
function isNull(value) {
|
|
217
|
+
return value === null;
|
|
218
|
+
}
|
|
219
|
+
var isNotNull = bindNot(isNull);
|
|
220
|
+
|
|
221
|
+
// This is sort of a map/filter in one function.
|
|
222
|
+
// Normally, behaves like a nested-array map
|
|
223
|
+
// Returning `null` will drop the element from the array
|
|
224
|
+
function transform(array, cb) {
|
|
225
|
+
var res = [];
|
|
226
|
+
for (var _i = 0, array_1 = array; _i < array_1.length; _i++) {
|
|
227
|
+
var v = array_1[_i];
|
|
228
|
+
if (isArray(v)) {
|
|
229
|
+
res.push(transform(v, cb));
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
232
|
+
var output = cb(v);
|
|
233
|
+
if (isNotNull(output)) {
|
|
234
|
+
res.push(output);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
return res;
|
|
239
|
+
}
|
|
240
|
+
function valueAtPath(array, path) {
|
|
241
|
+
return getCurrent(array, path)[last(path)];
|
|
242
|
+
}
|
|
243
|
+
function setValueAtPath(array, path, value) {
|
|
244
|
+
var current = getCurrent(array, path);
|
|
245
|
+
current[last(path)] = value;
|
|
246
|
+
return array;
|
|
247
|
+
}
|
|
248
|
+
function flatten(values) {
|
|
249
|
+
return asArray(values).reduce(function (acc, value) {
|
|
250
|
+
if (isArray(value)) {
|
|
251
|
+
return acc.concat(flatten(value));
|
|
252
|
+
}
|
|
253
|
+
return asArray(acc).concat(value);
|
|
254
|
+
}, []);
|
|
255
|
+
}
|
|
256
|
+
function getCurrent(array, path) {
|
|
257
|
+
var current = array;
|
|
258
|
+
for (var _i = 0, _a = path.slice(0, -1); _i < _a.length; _i++) {
|
|
259
|
+
var p = _a[_i];
|
|
260
|
+
current[p] = defaultTo(current[p], []);
|
|
261
|
+
current = current[p];
|
|
262
|
+
}
|
|
263
|
+
return current;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
function isUndefined(value) {
|
|
267
|
+
return value === undefined;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
function isNullish(value) {
|
|
271
|
+
return isNull(value) || isUndefined(value);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
function isStringValue(v) {
|
|
275
|
+
return String(v) === v;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
function shouldUseErrorAsMessage(message, error) {
|
|
279
|
+
// kind of cheating with this safe guard, but it does the job
|
|
280
|
+
return isUndefined(message) && isStringValue(error);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
function lengthEquals(value, arg1) {
|
|
284
|
+
return value.length === Number(arg1);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
function longerThan(value, arg1) {
|
|
288
|
+
return value.length > Number(arg1);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Creates a cache function
|
|
293
|
+
*/
|
|
294
|
+
function createCache(maxSize) {
|
|
295
|
+
if (maxSize === void 0) { maxSize = 1; }
|
|
296
|
+
var cacheStorage = [];
|
|
297
|
+
var cache = function (deps, cacheAction) {
|
|
298
|
+
var cacheHit = cache.get(deps);
|
|
299
|
+
// cache hit is not null
|
|
300
|
+
if (cacheHit)
|
|
301
|
+
return cacheHit[1];
|
|
302
|
+
var result = cacheAction();
|
|
303
|
+
cacheStorage.unshift([deps.concat(), result]);
|
|
304
|
+
if (longerThan(cacheStorage, maxSize))
|
|
305
|
+
cacheStorage.length = maxSize;
|
|
306
|
+
return result;
|
|
307
|
+
};
|
|
308
|
+
// invalidate an item in the cache by its dependencies
|
|
309
|
+
cache.invalidate = function (deps) {
|
|
310
|
+
var index = cacheStorage.findIndex(function (_a) {
|
|
311
|
+
var cachedDeps = _a[0];
|
|
312
|
+
return lengthEquals(deps, cachedDeps.length) &&
|
|
313
|
+
deps.every(function (dep, i) { return dep === cachedDeps[i]; });
|
|
314
|
+
});
|
|
315
|
+
if (index > -1)
|
|
316
|
+
cacheStorage.splice(index, 1);
|
|
317
|
+
};
|
|
318
|
+
// Retrieves an item from the cache.
|
|
319
|
+
cache.get = function (deps) {
|
|
320
|
+
return cacheStorage[cacheStorage.findIndex(function (_a) {
|
|
321
|
+
var cachedDeps = _a[0];
|
|
322
|
+
return lengthEquals(deps, cachedDeps.length) &&
|
|
323
|
+
deps.every(function (dep, i) { return dep === cachedDeps[i]; });
|
|
324
|
+
})] || null;
|
|
325
|
+
};
|
|
326
|
+
return cache;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
// STATE REF
|
|
330
|
+
function useStateRef() {
|
|
331
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
332
|
+
return context.useX().stateRef; // I should revisit this
|
|
333
|
+
}
|
|
334
|
+
// STATE KEYS
|
|
335
|
+
function useSuiteId() {
|
|
336
|
+
return useStateRef().suiteId()[0];
|
|
337
|
+
}
|
|
338
|
+
function useSuiteName() {
|
|
339
|
+
return useStateRef().suiteName()[0];
|
|
340
|
+
}
|
|
341
|
+
function useTestCallbacks() {
|
|
342
|
+
return useStateRef().testCallbacks();
|
|
343
|
+
}
|
|
344
|
+
function useOptionalFields() {
|
|
345
|
+
return useStateRef().optionalFields();
|
|
346
|
+
}
|
|
347
|
+
function useTestObjects() {
|
|
348
|
+
return useStateRef().testObjects();
|
|
349
|
+
}
|
|
350
|
+
// STATE ACTIONS
|
|
351
|
+
function useRefreshTestObjects() {
|
|
352
|
+
var _a = useTestObjects(), setTestObjects = _a[1];
|
|
353
|
+
setTestObjects(function (_a) {
|
|
354
|
+
var current = _a.current, prev = _a.prev;
|
|
355
|
+
return ({
|
|
356
|
+
prev: prev,
|
|
357
|
+
current: asArray(current)
|
|
358
|
+
});
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
function useSetTests(handler) {
|
|
362
|
+
var _a = useTestObjects(), testObjects = _a[1];
|
|
363
|
+
testObjects(function (_a) {
|
|
364
|
+
var current = _a.current, prev = _a.prev;
|
|
365
|
+
return ({
|
|
366
|
+
prev: prev,
|
|
367
|
+
current: asArray(handler(current))
|
|
368
|
+
});
|
|
369
|
+
});
|
|
370
|
+
}
|
|
371
|
+
// Derived state
|
|
372
|
+
function useAllIncomplete() {
|
|
373
|
+
var current = useTestObjects()[0].current;
|
|
374
|
+
return flatten(transform(current, function (testObject) {
|
|
375
|
+
return testObject.isPending() ? testObject : null;
|
|
376
|
+
}));
|
|
377
|
+
}
|
|
378
|
+
function useOmittedFields() {
|
|
379
|
+
var testObjects = useTestsFlat();
|
|
380
|
+
return testObjects.reduce(function (omittedFields, testObject) {
|
|
381
|
+
if (omittedFields[testObject.fieldName]) {
|
|
382
|
+
return omittedFields;
|
|
383
|
+
}
|
|
384
|
+
if (testObject.isOmitted()) {
|
|
385
|
+
omittedFields[testObject.fieldName] = true;
|
|
386
|
+
}
|
|
387
|
+
return omittedFields;
|
|
388
|
+
}, {});
|
|
389
|
+
}
|
|
390
|
+
var flatCache = createCache();
|
|
391
|
+
function useTestsFlat() {
|
|
392
|
+
var current = useTestObjects()[0].current;
|
|
393
|
+
return flatCache([current], function () { return flatten(current); });
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
var TestSeverity;
|
|
397
|
+
(function (TestSeverity) {
|
|
398
|
+
TestSeverity["Error"] = "error";
|
|
399
|
+
TestSeverity["Warning"] = "warning";
|
|
400
|
+
})(TestSeverity || (TestSeverity = {}));
|
|
401
|
+
var VestTest = /** @class */ (function () {
|
|
402
|
+
function VestTest(fieldName, testFn, _a) {
|
|
403
|
+
var _b = _a === void 0 ? {} : _a, message = _b.message, groupName = _b.groupName, key = _b.key;
|
|
404
|
+
this.key = null;
|
|
405
|
+
this.id = genId();
|
|
406
|
+
this.severity = TestSeverity.Error;
|
|
407
|
+
this.status = STATUS_UNTESTED;
|
|
408
|
+
this.fieldName = fieldName;
|
|
409
|
+
this.testFn = testFn;
|
|
410
|
+
if (groupName) {
|
|
411
|
+
this.groupName = groupName;
|
|
412
|
+
}
|
|
413
|
+
if (message) {
|
|
414
|
+
this.message = message;
|
|
415
|
+
}
|
|
416
|
+
if (key) {
|
|
417
|
+
this.key = key;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
VestTest.prototype.run = function () {
|
|
421
|
+
var result;
|
|
422
|
+
try {
|
|
423
|
+
result = this.testFn();
|
|
424
|
+
}
|
|
425
|
+
catch (error) {
|
|
426
|
+
if (shouldUseErrorAsMessage(this.message, error)) {
|
|
427
|
+
this.message = error;
|
|
428
|
+
}
|
|
429
|
+
result = false;
|
|
430
|
+
}
|
|
431
|
+
if (result === false) {
|
|
432
|
+
this.fail();
|
|
433
|
+
}
|
|
434
|
+
return result;
|
|
435
|
+
};
|
|
436
|
+
VestTest.prototype.setStatus = function (status) {
|
|
437
|
+
if (this.isFinalStatus() && status !== STATUS_OMITTED) {
|
|
438
|
+
return;
|
|
439
|
+
}
|
|
440
|
+
this.status = status;
|
|
441
|
+
};
|
|
442
|
+
VestTest.prototype.warns = function () {
|
|
443
|
+
return this.severity === TestSeverity.Warning;
|
|
444
|
+
};
|
|
445
|
+
VestTest.prototype.setPending = function () {
|
|
446
|
+
this.setStatus(STATUS_PENDING);
|
|
447
|
+
};
|
|
448
|
+
VestTest.prototype.fail = function () {
|
|
449
|
+
this.setStatus(this.warns() ? STATUS_WARNING : STATUS_FAILED);
|
|
450
|
+
};
|
|
451
|
+
VestTest.prototype.done = function () {
|
|
452
|
+
if (this.isFinalStatus()) {
|
|
453
|
+
return;
|
|
454
|
+
}
|
|
455
|
+
this.setStatus(STATUS_PASSING);
|
|
456
|
+
};
|
|
457
|
+
VestTest.prototype.warn = function () {
|
|
458
|
+
this.severity = TestSeverity.Warning;
|
|
459
|
+
};
|
|
460
|
+
VestTest.prototype.isFinalStatus = function () {
|
|
461
|
+
return this.hasFailures() || this.isCanceled() || this.isPassing();
|
|
462
|
+
};
|
|
463
|
+
VestTest.prototype.skip = function (force) {
|
|
464
|
+
if (this.isPending() && !force) {
|
|
465
|
+
// Without this condition, the test will be marked as skipped even if it is pending.
|
|
466
|
+
// This means that it will not be counted in "allIncomplete" and its done callbacks
|
|
467
|
+
// will not be called, or will be called prematurely.
|
|
468
|
+
// What this mostly say is that when we have a pending test for one field, and we then
|
|
469
|
+
// start typing in a different field - the pending test will be canceled, which
|
|
470
|
+
// is usually an unwanted behavior.
|
|
471
|
+
// The only scenario in which we DO want to cancel the async test regardless
|
|
472
|
+
// is when we specifically skip a test with `skipWhen`, which is handled by the
|
|
473
|
+
// "force" boolean flag.
|
|
474
|
+
// I am not a fan of this flag, but it gets the job done.
|
|
475
|
+
return;
|
|
476
|
+
}
|
|
477
|
+
this.setStatus(STATUS_SKIPPED);
|
|
478
|
+
};
|
|
479
|
+
VestTest.prototype.cancel = function () {
|
|
480
|
+
this.setStatus(STATUS_CANCELED);
|
|
481
|
+
useRefreshTestObjects();
|
|
482
|
+
};
|
|
483
|
+
VestTest.prototype.omit = function () {
|
|
484
|
+
this.setStatus(STATUS_OMITTED);
|
|
485
|
+
};
|
|
486
|
+
VestTest.prototype.valueOf = function () {
|
|
487
|
+
return !this.isFailing();
|
|
488
|
+
};
|
|
489
|
+
VestTest.prototype.hasFailures = function () {
|
|
490
|
+
return this.isFailing() || this.isWarning();
|
|
491
|
+
};
|
|
492
|
+
VestTest.prototype.isPending = function () {
|
|
493
|
+
return this.status === STATUS_PENDING;
|
|
494
|
+
};
|
|
495
|
+
VestTest.prototype.isTested = function () {
|
|
496
|
+
return this.hasFailures() || this.isPassing();
|
|
497
|
+
};
|
|
498
|
+
VestTest.prototype.isOmitted = function () {
|
|
499
|
+
return this.status === STATUS_OMITTED;
|
|
500
|
+
};
|
|
501
|
+
VestTest.prototype.isUntested = function () {
|
|
502
|
+
return this.status === STATUS_UNTESTED;
|
|
503
|
+
};
|
|
504
|
+
VestTest.prototype.isFailing = function () {
|
|
505
|
+
return this.status === STATUS_FAILED;
|
|
506
|
+
};
|
|
507
|
+
VestTest.prototype.isCanceled = function () {
|
|
508
|
+
return this.status === STATUS_CANCELED;
|
|
509
|
+
};
|
|
510
|
+
VestTest.prototype.isSkipped = function () {
|
|
511
|
+
return this.status === STATUS_SKIPPED;
|
|
512
|
+
};
|
|
513
|
+
VestTest.prototype.isPassing = function () {
|
|
514
|
+
return this.status === STATUS_PASSING;
|
|
515
|
+
};
|
|
516
|
+
VestTest.prototype.isWarning = function () {
|
|
517
|
+
return this.status === STATUS_WARNING;
|
|
518
|
+
};
|
|
519
|
+
return VestTest;
|
|
520
|
+
}());
|
|
521
|
+
var STATUS_UNTESTED = 'UNTESTED';
|
|
522
|
+
var STATUS_SKIPPED = 'SKIPPED';
|
|
523
|
+
var STATUS_FAILED = 'FAILED';
|
|
524
|
+
var STATUS_WARNING = 'WARNING';
|
|
525
|
+
var STATUS_PASSING = 'PASSING';
|
|
526
|
+
var STATUS_PENDING = 'PENDING';
|
|
527
|
+
var STATUS_CANCELED = 'CANCELED';
|
|
528
|
+
var STATUS_OMITTED = 'OMITTED';
|
|
529
|
+
|
|
530
|
+
function usePath() {
|
|
531
|
+
var context$1 = context.useX();
|
|
532
|
+
return context$1.testCursor.getCursor();
|
|
533
|
+
}
|
|
534
|
+
function useCursorAt() {
|
|
535
|
+
var context$1 = context.useX();
|
|
536
|
+
return context$1.testCursor.cursorAt();
|
|
537
|
+
}
|
|
538
|
+
function moveForward() {
|
|
539
|
+
var context$1 = context.useX();
|
|
540
|
+
return context$1.testCursor.next();
|
|
541
|
+
}
|
|
542
|
+
function addLevel() {
|
|
543
|
+
var context$1 = context.useX();
|
|
544
|
+
context$1.testCursor.addLevel();
|
|
545
|
+
}
|
|
546
|
+
function removeLevel() {
|
|
547
|
+
var context$1 = context.useX();
|
|
548
|
+
context$1.testCursor.removeLevel();
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
function usePrevKeys() {
|
|
552
|
+
var prev = useTestObjects()[0].prev;
|
|
553
|
+
return asArray(getCurrent(prev, usePath())).reduce(function (prevKeys, testObject) {
|
|
554
|
+
if (!(testObject instanceof VestTest)) {
|
|
555
|
+
return prevKeys;
|
|
556
|
+
}
|
|
557
|
+
if (isNullish(testObject.key)) {
|
|
558
|
+
return prevKeys;
|
|
559
|
+
}
|
|
560
|
+
prevKeys[testObject.key] = testObject;
|
|
561
|
+
return prevKeys;
|
|
562
|
+
}, {});
|
|
563
|
+
}
|
|
564
|
+
function usePrevTestByKey(key) {
|
|
565
|
+
var prev = context.useX().isolate.keys.prev;
|
|
566
|
+
return prev[key];
|
|
567
|
+
}
|
|
568
|
+
function useRetainTestKey(key, testObject) {
|
|
569
|
+
var context$1 = context.useX();
|
|
570
|
+
var current = context$1.isolate.keys.current;
|
|
571
|
+
if (isNullish(current[key])) {
|
|
572
|
+
current[key] = testObject;
|
|
573
|
+
}
|
|
574
|
+
else {
|
|
575
|
+
throwErrorDeferred("Encountered the same test key \"" + key + "\" twice. This may lead to tests overriding each other's results, or to tests being unexpectedly omitted.");
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
function isolate(_a, callback) {
|
|
580
|
+
var _b = _a.type, type = _b === void 0 ? IsolateTypes.DEFAULT : _b;
|
|
581
|
+
if (!isFunction(callback)) {
|
|
582
|
+
return;
|
|
583
|
+
}
|
|
584
|
+
var keys = {
|
|
585
|
+
current: {},
|
|
586
|
+
prev: {}
|
|
587
|
+
};
|
|
588
|
+
var path = usePath();
|
|
589
|
+
return context.run({ isolate: { type: type, keys: keys } }, function () {
|
|
590
|
+
addLevel();
|
|
591
|
+
keys.prev = usePrevKeys();
|
|
592
|
+
useSetTests(function (tests) { return setValueAtPath(tests, path, []); });
|
|
593
|
+
var res = callback();
|
|
594
|
+
removeLevel();
|
|
595
|
+
moveForward();
|
|
596
|
+
return res;
|
|
597
|
+
});
|
|
598
|
+
}
|
|
599
|
+
function shouldAllowReorder() {
|
|
600
|
+
return context.useX().isolate.type === IsolateTypes.EACH;
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
/**
|
|
604
|
+
* A safe hasOwnProperty access
|
|
605
|
+
*/
|
|
606
|
+
function hasOwnProperty(obj, key) {
|
|
607
|
+
return Object.prototype.hasOwnProperty.call(obj, key);
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
function isNumber(value) {
|
|
611
|
+
return Boolean(typeof value === 'number');
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
function isEmpty(value) {
|
|
615
|
+
if (!value) {
|
|
616
|
+
return true;
|
|
617
|
+
}
|
|
618
|
+
else if (isNumber(value)) {
|
|
619
|
+
return value === 0;
|
|
620
|
+
}
|
|
621
|
+
else if (hasOwnProperty(value, 'length')) {
|
|
622
|
+
return lengthEquals(value, 0);
|
|
623
|
+
}
|
|
624
|
+
else if (typeof value === 'object') {
|
|
625
|
+
return lengthEquals(Object.keys(value), 0);
|
|
626
|
+
}
|
|
627
|
+
return true;
|
|
628
|
+
}
|
|
629
|
+
var isNotEmpty = bindNot(isEmpty);
|
|
630
|
+
|
|
631
|
+
function nonMatchingFieldName(testObject, fieldName) {
|
|
632
|
+
return !!fieldName && !matchingFieldName(testObject, fieldName);
|
|
633
|
+
}
|
|
634
|
+
function matchingFieldName(testObject, fieldName) {
|
|
635
|
+
return !!(fieldName && testObject.fieldName === fieldName);
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
/**
|
|
639
|
+
* Checks if a given field, or the suite as a whole still have remaining tests.
|
|
640
|
+
*/
|
|
641
|
+
function hasRemainingTests(fieldName) {
|
|
642
|
+
var allIncomplete = useAllIncomplete();
|
|
643
|
+
if (isEmpty(allIncomplete)) {
|
|
644
|
+
return false;
|
|
645
|
+
}
|
|
646
|
+
if (fieldName) {
|
|
647
|
+
return allIncomplete.some(function (testObject) {
|
|
648
|
+
return matchingFieldName(testObject, fieldName);
|
|
649
|
+
});
|
|
650
|
+
}
|
|
651
|
+
return isNotEmpty(allIncomplete);
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
/**
|
|
655
|
+
* Reads the testObjects list and gets full validation result from it.
|
|
656
|
+
*/
|
|
657
|
+
function genTestsSummary() {
|
|
658
|
+
var testObjects = useTestsFlat();
|
|
659
|
+
var summary = {
|
|
660
|
+
errorCount: 0,
|
|
661
|
+
groups: {},
|
|
662
|
+
testCount: 0,
|
|
663
|
+
tests: {},
|
|
664
|
+
warnCount: 0
|
|
665
|
+
};
|
|
666
|
+
appendSummary(testObjects);
|
|
667
|
+
return countFailures(summary);
|
|
668
|
+
function appendSummary(testObjects) {
|
|
669
|
+
testObjects.forEach(function (testObject) {
|
|
670
|
+
var fieldName = testObject.fieldName, groupName = testObject.groupName;
|
|
671
|
+
summary.tests[fieldName] = genTestObject(summary.tests, testObject);
|
|
672
|
+
if (groupName) {
|
|
673
|
+
summary.groups[groupName] = summary.groups[groupName] || {};
|
|
674
|
+
summary.groups[groupName][fieldName] = genTestObject(summary.groups[groupName], testObject);
|
|
675
|
+
}
|
|
676
|
+
});
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
/**
|
|
680
|
+
* Counts the failed tests and adds global counters
|
|
681
|
+
*/
|
|
682
|
+
function countFailures(summary) {
|
|
683
|
+
for (var test in summary.tests) {
|
|
684
|
+
summary.errorCount += summary.tests[test].errorCount;
|
|
685
|
+
summary.warnCount += summary.tests[test].warnCount;
|
|
686
|
+
summary.testCount += summary.tests[test].testCount;
|
|
687
|
+
}
|
|
688
|
+
return summary;
|
|
689
|
+
}
|
|
690
|
+
// eslint-disable-next-line max-statements
|
|
691
|
+
function genTestObject(summaryKey, testObject) {
|
|
692
|
+
var fieldName = testObject.fieldName, message = testObject.message;
|
|
693
|
+
summaryKey[fieldName] = summaryKey[fieldName] || {
|
|
694
|
+
errorCount: 0,
|
|
695
|
+
warnCount: 0,
|
|
696
|
+
testCount: 0
|
|
697
|
+
};
|
|
698
|
+
var testKey = summaryKey[fieldName];
|
|
699
|
+
if (testObject.isSkipped())
|
|
700
|
+
return testKey;
|
|
701
|
+
summaryKey[fieldName].testCount++;
|
|
702
|
+
// Adds to severity group
|
|
703
|
+
function addTo(countKey, group) {
|
|
704
|
+
testKey[countKey]++;
|
|
705
|
+
if (message) {
|
|
706
|
+
testKey[group] = (testKey[group] || []).concat(message);
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
if (testObject.isFailing()) {
|
|
710
|
+
addTo('errorCount', 'errors');
|
|
711
|
+
}
|
|
712
|
+
else if (testObject.isWarning()) {
|
|
713
|
+
addTo('warnCount', 'warnings');
|
|
714
|
+
}
|
|
715
|
+
return testKey;
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
/*! *****************************************************************************
|
|
719
|
+
Copyright (c) Microsoft Corporation.
|
|
9
720
|
|
|
10
|
-
|
|
11
|
-
|
|
721
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
722
|
+
purpose with or without fee is hereby granted.
|
|
12
723
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
724
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
725
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
726
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
727
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
728
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
729
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
730
|
+
PERFORMANCE OF THIS SOFTWARE.
|
|
731
|
+
***************************************************************************** */
|
|
21
732
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
733
|
+
var __assign = function() {
|
|
734
|
+
__assign = Object.assign || function __assign(t) {
|
|
735
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
736
|
+
s = arguments[i];
|
|
737
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
|
|
738
|
+
}
|
|
739
|
+
return t;
|
|
740
|
+
};
|
|
741
|
+
return __assign.apply(this, arguments);
|
|
742
|
+
};
|
|
32
743
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
}
|
|
989
|
-
function getCurrent(array, path) {
|
|
990
|
-
var current = array;
|
|
991
|
-
for (var _i = 0, _a = path.slice(0, -1); _i < _a.length; _i++) {
|
|
992
|
-
var p = _a[_i];
|
|
993
|
-
current[p] = defaultTo(current[p], []);
|
|
994
|
-
current = current[p];
|
|
995
|
-
}
|
|
996
|
-
return current;
|
|
997
|
-
}
|
|
998
|
-
|
|
999
|
-
/**
|
|
1000
|
-
* Creates a cache function
|
|
1001
|
-
*/
|
|
1002
|
-
function createCache(maxSize) {
|
|
1003
|
-
if (maxSize === void 0) { maxSize = 1; }
|
|
1004
|
-
var cacheStorage = [];
|
|
1005
|
-
var cache = function (deps, cacheAction) {
|
|
1006
|
-
var cacheHit = cache.get(deps);
|
|
1007
|
-
// cache hit is not null
|
|
1008
|
-
if (cacheHit)
|
|
1009
|
-
return cacheHit[1];
|
|
1010
|
-
var result = cacheAction();
|
|
1011
|
-
cacheStorage.unshift([deps.concat(), result]);
|
|
1012
|
-
if (longerThan(cacheStorage, maxSize))
|
|
1013
|
-
cacheStorage.length = maxSize;
|
|
1014
|
-
return result;
|
|
1015
|
-
};
|
|
1016
|
-
// invalidate an item in the cache by its dependencies
|
|
1017
|
-
cache.invalidate = function (deps) {
|
|
1018
|
-
var index = cacheStorage.findIndex(function (_a) {
|
|
1019
|
-
var cachedDeps = _a[0];
|
|
1020
|
-
return lengthEquals(deps, cachedDeps.length) &&
|
|
1021
|
-
deps.every(function (dep, i) { return dep === cachedDeps[i]; });
|
|
1022
|
-
});
|
|
1023
|
-
if (index > -1)
|
|
1024
|
-
cacheStorage.splice(index, 1);
|
|
1025
|
-
};
|
|
1026
|
-
// Retrieves an item from the cache.
|
|
1027
|
-
cache.get = function (deps) {
|
|
1028
|
-
return cacheStorage[cacheStorage.findIndex(function (_a) {
|
|
1029
|
-
var cachedDeps = _a[0];
|
|
1030
|
-
return lengthEquals(deps, cachedDeps.length) &&
|
|
1031
|
-
deps.every(function (dep, i) { return dep === cachedDeps[i]; });
|
|
1032
|
-
})] || null;
|
|
1033
|
-
};
|
|
1034
|
-
return cache;
|
|
1035
|
-
}
|
|
1036
|
-
|
|
1037
|
-
// STATE REF
|
|
1038
|
-
function useStateRef() {
|
|
1039
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
1040
|
-
return ctx.useX().stateRef; // I should revisit this
|
|
1041
|
-
}
|
|
1042
|
-
// STATE KEYS
|
|
1043
|
-
function useSuiteId() {
|
|
1044
|
-
return useStateRef().suiteId();
|
|
1045
|
-
}
|
|
1046
|
-
function useTestCallbacks() {
|
|
1047
|
-
return useStateRef().testCallbacks();
|
|
1048
|
-
}
|
|
1049
|
-
function useOptionalFields() {
|
|
1050
|
-
return useStateRef().optionalFields();
|
|
1051
|
-
}
|
|
1052
|
-
function useTestObjects() {
|
|
1053
|
-
return useStateRef().testObjects();
|
|
1054
|
-
}
|
|
1055
|
-
// STATE ACTIONS
|
|
1056
|
-
function useRefreshTestObjects() {
|
|
1057
|
-
var _a = useTestObjects(), setTestObjects = _a[1];
|
|
1058
|
-
setTestObjects(function (_a) {
|
|
1059
|
-
var current = _a.current, prev = _a.prev;
|
|
1060
|
-
return ({
|
|
1061
|
-
prev: prev,
|
|
1062
|
-
current: asArray(current)
|
|
1063
|
-
});
|
|
1064
|
-
});
|
|
1065
|
-
}
|
|
1066
|
-
function useSetTests(handler) {
|
|
1067
|
-
var _a = useTestObjects(), testObjects = _a[1];
|
|
1068
|
-
testObjects(function (_a) {
|
|
1069
|
-
var current = _a.current, prev = _a.prev;
|
|
1070
|
-
return ({
|
|
1071
|
-
prev: prev,
|
|
1072
|
-
current: asArray(handler(current))
|
|
1073
|
-
});
|
|
1074
|
-
});
|
|
1075
|
-
}
|
|
1076
|
-
// Derived state
|
|
1077
|
-
function useAllIncomplete() {
|
|
1078
|
-
var current = useTestObjects()[0].current;
|
|
1079
|
-
return flatten(transform(current, function (testObject) {
|
|
1080
|
-
return testObject.isPending() ? testObject : null;
|
|
1081
|
-
}));
|
|
1082
|
-
}
|
|
1083
|
-
function useOmittedFields() {
|
|
1084
|
-
var testObjects = useTestsFlat();
|
|
1085
|
-
return testObjects.reduce(function (omittedFields, testObject) {
|
|
1086
|
-
if (omittedFields[testObject.fieldName]) {
|
|
1087
|
-
return omittedFields;
|
|
1088
|
-
}
|
|
1089
|
-
if (testObject.isOmitted()) {
|
|
1090
|
-
omittedFields[testObject.fieldName] = true;
|
|
1091
|
-
}
|
|
1092
|
-
return omittedFields;
|
|
1093
|
-
}, {});
|
|
1094
|
-
}
|
|
1095
|
-
var flatCache = createCache();
|
|
1096
|
-
function useTestsFlat() {
|
|
1097
|
-
var current = useTestObjects()[0].current;
|
|
1098
|
-
return flatCache([current], function () { return flatten(current); });
|
|
1099
|
-
}
|
|
1100
|
-
|
|
1101
|
-
function usePath() {
|
|
1102
|
-
var context = ctx.useX();
|
|
1103
|
-
return context.testCursor.getCursor();
|
|
1104
|
-
}
|
|
1105
|
-
function useCursorAt() {
|
|
1106
|
-
var context = ctx.useX();
|
|
1107
|
-
return context.testCursor.cursorAt();
|
|
1108
|
-
}
|
|
1109
|
-
function moveForward() {
|
|
1110
|
-
var context = ctx.useX();
|
|
1111
|
-
return context.testCursor.next();
|
|
1112
|
-
}
|
|
1113
|
-
function addLevel() {
|
|
1114
|
-
var context = ctx.useX();
|
|
1115
|
-
context.testCursor.addLevel();
|
|
1116
|
-
}
|
|
1117
|
-
function removeLevel() {
|
|
1118
|
-
var context = ctx.useX();
|
|
1119
|
-
context.testCursor.removeLevel();
|
|
1120
|
-
}
|
|
1121
|
-
|
|
1122
|
-
function isolate(_a, callback) {
|
|
1123
|
-
var _b = _a.type, type = _b === void 0 ? IsolateTypes.DEFAULT : _b;
|
|
1124
|
-
if (!isFunction(callback)) {
|
|
1125
|
-
return;
|
|
1126
|
-
}
|
|
1127
|
-
var path = usePath();
|
|
1128
|
-
return ctx.run({ isolate: { type: type } }, function () {
|
|
1129
|
-
addLevel();
|
|
1130
|
-
useSetTests(function (tests) { return setValueAtPath(tests, path, []); });
|
|
1131
|
-
var res = callback();
|
|
1132
|
-
removeLevel();
|
|
1133
|
-
moveForward();
|
|
1134
|
-
return res;
|
|
1135
|
-
});
|
|
1136
|
-
}
|
|
1137
|
-
function shouldAllowReorder() {
|
|
1138
|
-
return ctx.useX().isolate.type === IsolateTypes.EACH;
|
|
1139
|
-
}
|
|
1140
|
-
|
|
1141
|
-
function nonMatchingFieldName(testObject, fieldName) {
|
|
1142
|
-
return !!fieldName && !matchingFieldName(testObject, fieldName);
|
|
1143
|
-
}
|
|
1144
|
-
function matchingFieldName(testObject, fieldName) {
|
|
1145
|
-
return !!(fieldName && testObject.fieldName === fieldName);
|
|
1146
|
-
}
|
|
1147
|
-
|
|
1148
|
-
function omitOptionalTests() {
|
|
1149
|
-
var optionalFields = useOptionalFields()[0];
|
|
1150
|
-
if (isEmpty(optionalFields)) {
|
|
1151
|
-
return;
|
|
1152
|
-
}
|
|
1153
|
-
var shouldOmit = {};
|
|
1154
|
-
useSetTests(function (tests) {
|
|
1155
|
-
return transform(tests, function (testObject) {
|
|
1156
|
-
var fieldName = testObject.fieldName;
|
|
1157
|
-
if (shouldOmit.hasOwnProperty(fieldName)) {
|
|
1158
|
-
omit(testObject);
|
|
1159
|
-
}
|
|
1160
|
-
else {
|
|
1161
|
-
var optionalConfig = optionalFields[fieldName];
|
|
1162
|
-
if (isFunction(optionalConfig)) {
|
|
1163
|
-
shouldOmit[fieldName] = optionalConfig();
|
|
1164
|
-
omit(testObject);
|
|
1165
|
-
}
|
|
1166
|
-
}
|
|
1167
|
-
return testObject;
|
|
1168
|
-
});
|
|
1169
|
-
});
|
|
1170
|
-
function omit(testObject) {
|
|
1171
|
-
if (shouldOmit[testObject.fieldName]) {
|
|
1172
|
-
testObject.omit();
|
|
1173
|
-
}
|
|
1174
|
-
}
|
|
1175
|
-
}
|
|
1176
|
-
|
|
1177
|
-
/**
|
|
1178
|
-
* Checks if a given field, or the suite as a whole still have remaining tests.
|
|
1179
|
-
*/
|
|
1180
|
-
function hasRemainingTests(fieldName) {
|
|
1181
|
-
var allIncomplete = useAllIncomplete();
|
|
1182
|
-
if (isEmpty(allIncomplete)) {
|
|
1183
|
-
return false;
|
|
1184
|
-
}
|
|
1185
|
-
if (fieldName) {
|
|
1186
|
-
return allIncomplete.some(function (testObject) {
|
|
1187
|
-
return matchingFieldName(testObject, fieldName);
|
|
1188
|
-
});
|
|
1189
|
-
}
|
|
1190
|
-
return isNotEmpty(allIncomplete);
|
|
1191
|
-
}
|
|
1192
|
-
|
|
1193
|
-
/**
|
|
1194
|
-
* Reads the testObjects list and gets full validation result from it.
|
|
1195
|
-
*/
|
|
1196
|
-
function genTestsSummary() {
|
|
1197
|
-
var testObjects = useTestsFlat();
|
|
1198
|
-
var summary = {
|
|
1199
|
-
errorCount: 0,
|
|
1200
|
-
groups: {},
|
|
1201
|
-
testCount: 0,
|
|
1202
|
-
tests: {},
|
|
1203
|
-
warnCount: 0
|
|
1204
|
-
};
|
|
1205
|
-
appendSummary(testObjects);
|
|
1206
|
-
return countFailures(summary);
|
|
1207
|
-
function appendSummary(testObjects) {
|
|
1208
|
-
testObjects.forEach(function (testObject) {
|
|
1209
|
-
var fieldName = testObject.fieldName, groupName = testObject.groupName;
|
|
1210
|
-
summary.tests[fieldName] = genTestObject(summary.tests, testObject);
|
|
1211
|
-
if (groupName) {
|
|
1212
|
-
summary.groups[groupName] = summary.groups[groupName] || {};
|
|
1213
|
-
summary.groups[groupName][fieldName] = genTestObject(summary.groups[groupName], testObject);
|
|
1214
|
-
}
|
|
1215
|
-
});
|
|
1216
|
-
}
|
|
1217
|
-
}
|
|
1218
|
-
/**
|
|
1219
|
-
* Counts the failed tests and adds global counters
|
|
1220
|
-
*/
|
|
1221
|
-
function countFailures(summary) {
|
|
1222
|
-
for (var test in summary.tests) {
|
|
1223
|
-
summary.errorCount += summary.tests[test].errorCount;
|
|
1224
|
-
summary.warnCount += summary.tests[test].warnCount;
|
|
1225
|
-
summary.testCount += summary.tests[test].testCount;
|
|
1226
|
-
}
|
|
1227
|
-
return summary;
|
|
1228
|
-
}
|
|
1229
|
-
// eslint-disable-next-line max-statements
|
|
1230
|
-
function genTestObject(summaryKey, testObject) {
|
|
1231
|
-
var fieldName = testObject.fieldName, message = testObject.message;
|
|
1232
|
-
summaryKey[fieldName] = summaryKey[fieldName] || {
|
|
1233
|
-
errorCount: 0,
|
|
1234
|
-
warnCount: 0,
|
|
1235
|
-
testCount: 0
|
|
1236
|
-
};
|
|
1237
|
-
var testKey = summaryKey[fieldName];
|
|
1238
|
-
if (testObject.isSkipped())
|
|
1239
|
-
return testKey;
|
|
1240
|
-
summaryKey[fieldName].testCount++;
|
|
1241
|
-
// Adds to severity group
|
|
1242
|
-
function addTo(countKey, group) {
|
|
1243
|
-
testKey[countKey]++;
|
|
1244
|
-
if (message) {
|
|
1245
|
-
testKey[group] = (testKey[group] || []).concat(message);
|
|
1246
|
-
}
|
|
1247
|
-
}
|
|
1248
|
-
if (testObject.isFailing()) {
|
|
1249
|
-
addTo('errorCount', 'errors');
|
|
1250
|
-
}
|
|
1251
|
-
else if (testObject.isWarning()) {
|
|
1252
|
-
addTo('warnCount', 'warnings');
|
|
1253
|
-
}
|
|
1254
|
-
return testKey;
|
|
1255
|
-
}
|
|
1256
|
-
|
|
1257
|
-
function either(a, b) {
|
|
1258
|
-
return !!a !== !!b;
|
|
1259
|
-
}
|
|
1260
|
-
|
|
1261
|
-
/**
|
|
1262
|
-
* Checks that a given test object matches the currently specified severity level
|
|
1263
|
-
*/
|
|
1264
|
-
function nonMatchingSeverityProfile(severity, testObject) {
|
|
1265
|
-
return either(severity === 'warnings', testObject.warns);
|
|
1266
|
-
}
|
|
1267
|
-
|
|
1268
|
-
function collectFailureMessages(severity, testObjects, options) {
|
|
1269
|
-
var _a;
|
|
1270
|
-
if (options === void 0) { options = {}; }
|
|
1271
|
-
var _b = options || {}, group = _b.group, fieldName = _b.fieldName;
|
|
1272
|
-
var res = testObjects.reduce(function (collector, testObject) {
|
|
1273
|
-
if (noMatch(testObject, severity, group, fieldName)) {
|
|
1274
|
-
return collector;
|
|
1275
|
-
}
|
|
1276
|
-
if (!testObject.hasFailures()) {
|
|
1277
|
-
return collector;
|
|
1278
|
-
}
|
|
1279
|
-
collector[testObject.fieldName] = (collector[testObject.fieldName] || []).concat(testObject.message || []);
|
|
1280
|
-
return collector;
|
|
1281
|
-
}, __assign({}, (fieldName && (_a = {}, _a[fieldName] = [], _a))));
|
|
1282
|
-
return res;
|
|
1283
|
-
}
|
|
1284
|
-
function noGroupMatch(testObject, groupName) {
|
|
1285
|
-
return !!(groupName && testObject.groupName !== groupName);
|
|
1286
|
-
}
|
|
1287
|
-
function noMatch(testObject, severity, group, fieldName) {
|
|
1288
|
-
if (noGroupMatch(testObject, group)) {
|
|
1289
|
-
return true;
|
|
1290
|
-
}
|
|
1291
|
-
if (nonMatchingFieldName(testObject, fieldName)) {
|
|
1292
|
-
return true;
|
|
1293
|
-
}
|
|
1294
|
-
if (nonMatchingSeverityProfile(severity, testObject)) {
|
|
1295
|
-
return true;
|
|
1296
|
-
}
|
|
1297
|
-
return false;
|
|
1298
|
-
}
|
|
1299
|
-
|
|
1300
|
-
function getFailuresArrayOrObject(group, fieldName) {
|
|
1301
|
-
if (fieldName) {
|
|
1302
|
-
return group[fieldName];
|
|
1303
|
-
}
|
|
1304
|
-
return group;
|
|
1305
|
-
}
|
|
1306
|
-
|
|
1307
|
-
function getErrors(fieldName) {
|
|
1308
|
-
return getFailures('errors', fieldName);
|
|
1309
|
-
}
|
|
1310
|
-
function getWarnings(fieldName) {
|
|
1311
|
-
return getFailures('warnings', fieldName);
|
|
1312
|
-
}
|
|
1313
|
-
/**
|
|
1314
|
-
* @returns suite or field's errors or warnings.
|
|
1315
|
-
*/
|
|
1316
|
-
function getFailures(severityKey, fieldName) {
|
|
1317
|
-
var testObjects = useTestsFlat();
|
|
1318
|
-
var failureMessages = collectFailureMessages(severityKey, testObjects, {
|
|
1319
|
-
fieldName: fieldName
|
|
1320
|
-
});
|
|
1321
|
-
return getFailuresArrayOrObject(failureMessages, fieldName);
|
|
1322
|
-
}
|
|
1323
|
-
|
|
1324
|
-
function getErrorsByGroup(groupName, fieldName) {
|
|
1325
|
-
var errors = getByGroup('errors', groupName, fieldName);
|
|
1326
|
-
return getFailuresArrayOrObject(errors, fieldName);
|
|
1327
|
-
}
|
|
1328
|
-
function getWarningsByGroup(groupName, fieldName) {
|
|
1329
|
-
var warnings = getByGroup('warnings', groupName, fieldName);
|
|
1330
|
-
return getFailuresArrayOrObject(warnings, fieldName);
|
|
1331
|
-
}
|
|
1332
|
-
/**
|
|
1333
|
-
* Gets failure messages by group.
|
|
1334
|
-
*/
|
|
1335
|
-
function getByGroup(severityKey, group, fieldName) {
|
|
1336
|
-
if (!group) {
|
|
1337
|
-
throwError("get" + severityKey[0].toUpperCase() + severityKey.slice(1) + "ByGroup requires a group name. Received `" + group + "` instead.");
|
|
1338
|
-
}
|
|
1339
|
-
var testObjects = useTestsFlat();
|
|
1340
|
-
var failureMessages = collectFailureMessages(severityKey, testObjects, {
|
|
1341
|
-
group: group,
|
|
1342
|
-
fieldName: fieldName
|
|
1343
|
-
});
|
|
1344
|
-
return failureMessages;
|
|
1345
|
-
}
|
|
1346
|
-
|
|
1347
|
-
/**
|
|
1348
|
-
* Determines whether a certain test profile has failures.
|
|
1349
|
-
*/
|
|
1350
|
-
function hasFailuresLogic(testObject, severityKey, fieldName) {
|
|
1351
|
-
if (!testObject.hasFailures()) {
|
|
1352
|
-
return false;
|
|
1353
|
-
}
|
|
1354
|
-
if (nonMatchingFieldName(testObject, fieldName)) {
|
|
1355
|
-
return false;
|
|
1356
|
-
}
|
|
1357
|
-
if (nonMatchingSeverityProfile(severityKey, testObject)) {
|
|
1358
|
-
return false;
|
|
1359
|
-
}
|
|
1360
|
-
return true;
|
|
1361
|
-
}
|
|
1362
|
-
|
|
1363
|
-
function hasErrors(fieldName) {
|
|
1364
|
-
return has('errors', fieldName);
|
|
1365
|
-
}
|
|
1366
|
-
function hasWarnings(fieldName) {
|
|
1367
|
-
return has('warnings', fieldName);
|
|
1368
|
-
}
|
|
1369
|
-
function has(severityKey, fieldName) {
|
|
1370
|
-
var testObjects = useTestsFlat();
|
|
1371
|
-
return testObjects.some(function (testObject) {
|
|
1372
|
-
return hasFailuresLogic(testObject, severityKey, fieldName);
|
|
1373
|
-
});
|
|
1374
|
-
}
|
|
1375
|
-
|
|
1376
|
-
function hasErrorsByGroup(groupName, fieldName) {
|
|
1377
|
-
return hasByGroup('errors', groupName, fieldName);
|
|
1378
|
-
}
|
|
1379
|
-
function hasWarningsByGroup(groupName, fieldName) {
|
|
1380
|
-
return hasByGroup('warnings', groupName, fieldName);
|
|
1381
|
-
}
|
|
1382
|
-
/**
|
|
1383
|
-
* Checks whether there are failures in a given group.
|
|
1384
|
-
*/
|
|
1385
|
-
function hasByGroup(severityKey, group, fieldName) {
|
|
1386
|
-
var testObjects = useTestsFlat();
|
|
1387
|
-
return testObjects.some(function (testObject) {
|
|
1388
|
-
return group === testObject.groupName
|
|
1389
|
-
? hasFailuresLogic(testObject, severityKey, fieldName)
|
|
1390
|
-
: false;
|
|
1391
|
-
});
|
|
1392
|
-
}
|
|
1393
|
-
|
|
1394
|
-
// eslint-disable-next-line max-statements, complexity
|
|
1395
|
-
function isValid(result, fieldName) {
|
|
1396
|
-
if (fieldIsOmitted(fieldName)) {
|
|
1397
|
-
return true;
|
|
1398
|
-
}
|
|
1399
|
-
if (result.hasErrors(fieldName)) {
|
|
1400
|
-
return false;
|
|
1401
|
-
}
|
|
1402
|
-
var testObjects = useTestsFlat();
|
|
1403
|
-
if (isEmpty(testObjects)) {
|
|
1404
|
-
return false;
|
|
1405
|
-
}
|
|
1406
|
-
if (fieldDoesNotExist(result, fieldName)) {
|
|
1407
|
-
return false;
|
|
1408
|
-
}
|
|
1409
|
-
if (hasNonOptionalIncomplete(fieldName)) {
|
|
1410
|
-
return false;
|
|
1411
|
-
}
|
|
1412
|
-
return noMissingTests(fieldName);
|
|
1413
|
-
}
|
|
1414
|
-
function fieldIsOmitted(fieldName) {
|
|
1415
|
-
var omittedFields = useOmittedFields();
|
|
1416
|
-
if (!fieldName) {
|
|
1417
|
-
return false;
|
|
1418
|
-
}
|
|
1419
|
-
return !!omittedFields[fieldName];
|
|
1420
|
-
}
|
|
1421
|
-
function hasNonOptionalIncomplete(fieldName) {
|
|
1422
|
-
var optionalFields = useOptionalFields()[0];
|
|
1423
|
-
return isNotEmpty(useAllIncomplete().filter(function (testObject) {
|
|
1424
|
-
if (nonMatchingFieldName(testObject, fieldName)) {
|
|
1425
|
-
return false;
|
|
1426
|
-
}
|
|
1427
|
-
return optionalFields[testObject.fieldName] !== true;
|
|
1428
|
-
}));
|
|
1429
|
-
}
|
|
1430
|
-
function fieldDoesNotExist(result, fieldName) {
|
|
1431
|
-
return !!fieldName && isEmpty(result.tests[fieldName]);
|
|
1432
|
-
}
|
|
1433
|
-
function noMissingTests(fieldName) {
|
|
1434
|
-
var testObjects = useTestsFlat();
|
|
1435
|
-
var optionalFields = useOptionalFields()[0];
|
|
1436
|
-
return testObjects.every(function (testObject) {
|
|
1437
|
-
if (nonMatchingFieldName(testObject, fieldName)) {
|
|
1438
|
-
return true;
|
|
1439
|
-
}
|
|
1440
|
-
return (optionalFields[testObject.fieldName] === true ||
|
|
1441
|
-
testObject.isTested() ||
|
|
1442
|
-
testObject.isOmitted());
|
|
1443
|
-
});
|
|
1444
|
-
}
|
|
1445
|
-
|
|
1446
|
-
var cache$1 = createCache(20);
|
|
1447
|
-
function produceDraft() {
|
|
1448
|
-
var testObjects = useTestsFlat();
|
|
1449
|
-
var ctxRef = { stateRef: useStateRef() };
|
|
1450
|
-
return cache$1([testObjects], ctx.bind(ctxRef, function () {
|
|
1451
|
-
return assign(genTestsSummary(), {
|
|
1452
|
-
getErrors: ctx.bind(ctxRef, getErrors),
|
|
1453
|
-
getErrorsByGroup: ctx.bind(ctxRef, getErrorsByGroup),
|
|
1454
|
-
getWarnings: ctx.bind(ctxRef, getWarnings),
|
|
1455
|
-
getWarningsByGroup: ctx.bind(ctxRef, getWarningsByGroup),
|
|
1456
|
-
hasErrors: ctx.bind(ctxRef, hasErrors),
|
|
1457
|
-
hasErrorsByGroup: ctx.bind(ctxRef, hasErrorsByGroup),
|
|
1458
|
-
hasWarnings: ctx.bind(ctxRef, hasWarnings),
|
|
1459
|
-
hasWarningsByGroup: ctx.bind(ctxRef, hasWarningsByGroup),
|
|
1460
|
-
isValid: ctx.bind(ctxRef, function (fieldName) {
|
|
1461
|
-
return isValid(produceDraft(), fieldName);
|
|
1462
|
-
})
|
|
1463
|
-
});
|
|
1464
|
-
}));
|
|
1465
|
-
}
|
|
1466
|
-
|
|
1467
|
-
var cache = createCache(20);
|
|
1468
|
-
function produceFullResult() {
|
|
1469
|
-
var testObjects = useTestsFlat();
|
|
1470
|
-
var ctxRef = { stateRef: useStateRef() };
|
|
1471
|
-
return cache([testObjects], ctx.bind(ctxRef, function () {
|
|
1472
|
-
return assign({}, produceDraft(), {
|
|
1473
|
-
done: ctx.bind(ctxRef, done)
|
|
1474
|
-
});
|
|
1475
|
-
}));
|
|
1476
|
-
}
|
|
1477
|
-
/**
|
|
1478
|
-
* DONE is here and not in its own module to prevent circular dependency issues.
|
|
1479
|
-
*/
|
|
1480
|
-
function shouldSkipDoneRegistration(callback, fieldName, output) {
|
|
1481
|
-
// If we do not have any test runs for the current field
|
|
1482
|
-
return !!(!isFunction(callback) ||
|
|
1483
|
-
(fieldName &&
|
|
1484
|
-
(!output.tests[fieldName] || output.tests[fieldName].testCount === 0)));
|
|
1485
|
-
}
|
|
1486
|
-
function shouldRunDoneCallback(fieldName) {
|
|
1487
|
-
// is suite finished || field name exists, and test is finished;
|
|
1488
|
-
return !!(!hasRemainingTests() ||
|
|
1489
|
-
(fieldName && !hasRemainingTests(fieldName)));
|
|
1490
|
-
}
|
|
1491
|
-
/**
|
|
1492
|
-
* Registers done callbacks.
|
|
1493
|
-
* @register {Object} Vest output object.
|
|
1494
|
-
*/
|
|
1495
|
-
var done = function done() {
|
|
1496
|
-
var args = [];
|
|
1497
|
-
for (var _i = 0; _i < arguments.length; _i++) {
|
|
1498
|
-
args[_i] = arguments[_i];
|
|
1499
|
-
}
|
|
1500
|
-
var _a = args.reverse(), callback = _a[0], fieldName = _a[1];
|
|
1501
|
-
var output = produceFullResult();
|
|
1502
|
-
if (shouldSkipDoneRegistration(callback, fieldName, output)) {
|
|
1503
|
-
return output;
|
|
1504
|
-
}
|
|
1505
|
-
var doneCallback = function () { return callback(produceDraft()); };
|
|
1506
|
-
if (shouldRunDoneCallback(fieldName)) {
|
|
1507
|
-
doneCallback();
|
|
1508
|
-
return output;
|
|
1509
|
-
}
|
|
1510
|
-
deferDoneCallback(doneCallback, fieldName);
|
|
1511
|
-
return output;
|
|
1512
|
-
};
|
|
1513
|
-
function deferDoneCallback(doneCallback, fieldName) {
|
|
1514
|
-
var deferredCallback = ctx.bind({}, doneCallback);
|
|
1515
|
-
var _a = useTestCallbacks(), setTestCallbacks = _a[1];
|
|
1516
|
-
setTestCallbacks(function (current) {
|
|
1517
|
-
if (fieldName) {
|
|
1518
|
-
current.fieldCallbacks[fieldName] = (current.fieldCallbacks[fieldName] || []).concat(deferredCallback);
|
|
1519
|
-
}
|
|
1520
|
-
else {
|
|
1521
|
-
current.doneCallbacks.push(deferredCallback);
|
|
1522
|
-
}
|
|
1523
|
-
return current;
|
|
1524
|
-
});
|
|
1525
|
-
}
|
|
1526
|
-
|
|
1527
|
-
/**
|
|
1528
|
-
* Removes test object from suite state
|
|
1529
|
-
*/
|
|
1530
|
-
function removeTestFromState (testObject) {
|
|
1531
|
-
useSetTests(function (tests) {
|
|
1532
|
-
return transform(tests, function (test) { return (testObject !== test ? test : null); });
|
|
1533
|
-
});
|
|
1534
|
-
}
|
|
1535
|
-
|
|
1536
|
-
function createBus() {
|
|
1537
|
-
var listeners = {};
|
|
1538
|
-
return {
|
|
1539
|
-
emit: function (event, data) {
|
|
1540
|
-
if (!listeners[event]) {
|
|
1541
|
-
return;
|
|
1542
|
-
}
|
|
1543
|
-
listeners[event].forEach(function (listener) {
|
|
1544
|
-
listener(data);
|
|
1545
|
-
});
|
|
1546
|
-
},
|
|
1547
|
-
on: function (event, handler) {
|
|
1548
|
-
if (!listeners[event]) {
|
|
1549
|
-
listeners[event] = [];
|
|
1550
|
-
}
|
|
1551
|
-
listeners[event].push(handler);
|
|
1552
|
-
return {
|
|
1553
|
-
off: function () {
|
|
1554
|
-
listeners[event] = listeners[event].filter(function (h) { return h !== handler; });
|
|
1555
|
-
}
|
|
1556
|
-
};
|
|
1557
|
-
}
|
|
1558
|
-
};
|
|
1559
|
-
}
|
|
1560
|
-
|
|
1561
|
-
function callEach(arr) {
|
|
1562
|
-
return arr.forEach(function (fn) { return fn(); });
|
|
1563
|
-
}
|
|
1564
|
-
|
|
1565
|
-
/**
|
|
1566
|
-
* Runs done callback per field when async tests are finished running.
|
|
1567
|
-
*/
|
|
1568
|
-
function runFieldCallbacks(fieldName) {
|
|
1569
|
-
var fieldCallbacks = useTestCallbacks()[0].fieldCallbacks;
|
|
1570
|
-
if (fieldName) {
|
|
1571
|
-
if (!hasRemainingTests(fieldName) && isArray(fieldCallbacks[fieldName])) {
|
|
1572
|
-
callEach(fieldCallbacks[fieldName]);
|
|
1573
|
-
}
|
|
1574
|
-
}
|
|
1575
|
-
}
|
|
1576
|
-
/**
|
|
1577
|
-
* Runs unlabelled done callback when async tests are finished running.
|
|
1578
|
-
*/
|
|
1579
|
-
function runDoneCallbacks() {
|
|
1580
|
-
var doneCallbacks = useTestCallbacks()[0].doneCallbacks;
|
|
1581
|
-
if (!hasRemainingTests()) {
|
|
1582
|
-
callEach(doneCallbacks);
|
|
1583
|
-
}
|
|
1584
|
-
}
|
|
1585
|
-
|
|
1586
|
-
function initBus() {
|
|
1587
|
-
var bus = createBus();
|
|
1588
|
-
bus.on(Events.TEST_COMPLETED, function (testObject) {
|
|
1589
|
-
if (testObject.isCanceled()) {
|
|
1590
|
-
return;
|
|
1591
|
-
}
|
|
1592
|
-
testObject.done();
|
|
1593
|
-
runFieldCallbacks(testObject.fieldName);
|
|
1594
|
-
runDoneCallbacks();
|
|
1595
|
-
});
|
|
1596
|
-
return bus;
|
|
1597
|
-
}
|
|
1598
|
-
function useBus() {
|
|
1599
|
-
var context = ctx.useX();
|
|
1600
|
-
if (!context.bus) {
|
|
1601
|
-
throwError();
|
|
1602
|
-
}
|
|
1603
|
-
return context.bus;
|
|
1604
|
-
}
|
|
1605
|
-
var Events;
|
|
1606
|
-
(function (Events) {
|
|
1607
|
-
Events["TEST_COMPLETED"] = "test_completed";
|
|
1608
|
-
})(Events || (Events = {}));
|
|
1609
|
-
|
|
1610
|
-
// eslint-disable-next-line max-lines-per-function
|
|
1611
|
-
function create(suiteCallback) {
|
|
1612
|
-
if (!isFunction(suiteCallback)) {
|
|
1613
|
-
throwError('Suite initialization error. Expected `tests` to be a function.');
|
|
1614
|
-
}
|
|
1615
|
-
var bus = initBus();
|
|
1616
|
-
var state = createState();
|
|
1617
|
-
var stateRef = createStateRef(state, { suiteId: genId() });
|
|
1618
|
-
var suite = assign(ctx.bind({ stateRef: stateRef, bus: bus }, function () {
|
|
1619
|
-
var args = [];
|
|
1620
|
-
for (var _i = 0; _i < arguments.length; _i++) {
|
|
1621
|
-
args[_i] = arguments[_i];
|
|
1622
|
-
}
|
|
1623
|
-
state.reset();
|
|
1624
|
-
// Run the consumer's callback
|
|
1625
|
-
isolate({ type: IsolateTypes.SUITE }, function () {
|
|
1626
|
-
suiteCallback.apply(void 0, args);
|
|
1627
|
-
});
|
|
1628
|
-
omitOptionalTests();
|
|
1629
|
-
var res = produceFullResult();
|
|
1630
|
-
return res;
|
|
1631
|
-
}), {
|
|
1632
|
-
get: ctx.bind({ stateRef: stateRef }, produceDraft),
|
|
1633
|
-
remove: ctx.bind({ stateRef: stateRef }, function (name) {
|
|
1634
|
-
var testObjects = useTestsFlat();
|
|
1635
|
-
// We're mutating the array in `cancel`, so we have to first copy it.
|
|
1636
|
-
testObjects.forEach(function (testObject) {
|
|
1637
|
-
if (matchingFieldName(testObject, name)) {
|
|
1638
|
-
testObject.cancel();
|
|
1639
|
-
removeTestFromState(testObject);
|
|
1640
|
-
}
|
|
1641
|
-
});
|
|
1642
|
-
}),
|
|
1643
|
-
reset: state.reset
|
|
1644
|
-
});
|
|
1645
|
-
return suite;
|
|
1646
|
-
}
|
|
1647
|
-
|
|
1648
|
-
/**
|
|
1649
|
-
* Error message to display when a hook was called outside of context.
|
|
1650
|
-
*/
|
|
1651
|
-
var ERROR_HOOK_CALLED_OUTSIDE = 'hook called outside of a running suite.';
|
|
1652
|
-
|
|
1653
|
-
/**
|
|
1654
|
-
* Adds a field or multiple fields to inclusion group.
|
|
1655
|
-
*/
|
|
1656
|
-
function only(item) {
|
|
1657
|
-
return addTo('only', 'tests', item);
|
|
1658
|
-
}
|
|
1659
|
-
only.group = function (item) { return addTo('only', 'groups', item); };
|
|
1660
|
-
/**
|
|
1661
|
-
* Adds a field or multiple fields to exclusion group.
|
|
1662
|
-
*/
|
|
1663
|
-
function skip(item) {
|
|
1664
|
-
return addTo('skip', 'tests', item);
|
|
1665
|
-
}
|
|
1666
|
-
skip.group = function (item) { return addTo('skip', 'groups', item); };
|
|
1667
|
-
//Checks whether a certain test profile excluded by any of the exclusion groups.
|
|
1668
|
-
// eslint-disable-next-line complexity, max-statements
|
|
1669
|
-
function isExcluded(testObject) {
|
|
1670
|
-
var fieldName = testObject.fieldName, groupName = testObject.groupName;
|
|
1671
|
-
var context = ctx.useX();
|
|
1672
|
-
if (context.skipped)
|
|
1673
|
-
return true;
|
|
1674
|
-
var exclusion = context.exclusion;
|
|
1675
|
-
var keyTests = exclusion.tests;
|
|
1676
|
-
var testValue = keyTests[fieldName];
|
|
1677
|
-
// if test is skipped
|
|
1678
|
-
// no need to proceed
|
|
1679
|
-
if (testValue === false)
|
|
1680
|
-
return true;
|
|
1681
|
-
var isTestIncluded = testValue === true;
|
|
1682
|
-
// If inside a group
|
|
1683
|
-
if (groupName) {
|
|
1684
|
-
if (isGroupExcluded(groupName)) {
|
|
1685
|
-
return true; // field excluded by group
|
|
1686
|
-
// if group is `only`ed
|
|
1687
|
-
}
|
|
1688
|
-
else if (exclusion.groups[groupName] === true) {
|
|
1689
|
-
if (isTestIncluded)
|
|
1690
|
-
return false;
|
|
1691
|
-
// If there is _ANY_ `only`ed test (and we already know this one isn't)
|
|
1692
|
-
if (hasIncludedTests(keyTests))
|
|
1693
|
-
return true; // Excluded implicitly
|
|
1694
|
-
return keyTests[fieldName] === false;
|
|
1695
|
-
}
|
|
1696
|
-
}
|
|
1697
|
-
// if field is only'ed
|
|
1698
|
-
if (isTestIncluded)
|
|
1699
|
-
return false;
|
|
1700
|
-
// If there is _ANY_ `only`ed test (and we already know this one isn't) return true
|
|
1701
|
-
// Otherwise return false
|
|
1702
|
-
return hasIncludedTests(keyTests);
|
|
1703
|
-
}
|
|
1704
|
-
/**
|
|
1705
|
-
* Checks whether a given group is excluded from running.
|
|
1706
|
-
*/
|
|
1707
|
-
function isGroupExcluded(groupName) {
|
|
1708
|
-
var context = ctx.useX();
|
|
1709
|
-
var exclusion = context.exclusion;
|
|
1710
|
-
var keyGroups = exclusion.groups;
|
|
1711
|
-
var groupPresent = hasOwnProperty(keyGroups, groupName);
|
|
1712
|
-
// When group is either only'ed or skipped
|
|
1713
|
-
if (groupPresent) {
|
|
1714
|
-
// Return true if group is skipped and false if only'ed
|
|
1715
|
-
return keyGroups[groupName] === false;
|
|
1716
|
-
}
|
|
1717
|
-
// Group is not present
|
|
1718
|
-
for (var group in keyGroups) {
|
|
1719
|
-
// If any other group is only'ed
|
|
1720
|
-
if (keyGroups[group] === true) {
|
|
1721
|
-
return true;
|
|
1722
|
-
}
|
|
1723
|
-
}
|
|
1724
|
-
return false;
|
|
1725
|
-
}
|
|
1726
|
-
/**
|
|
1727
|
-
* Adds fields to a specified exclusion group.
|
|
1728
|
-
*/
|
|
1729
|
-
function addTo(exclusionGroup, itemType, item) {
|
|
1730
|
-
var context = ctx.useX(ERROR_HOOK_CALLED_OUTSIDE);
|
|
1731
|
-
if (!item) {
|
|
1732
|
-
return;
|
|
1733
|
-
}
|
|
1734
|
-
asArray(item).forEach(function (itemName) {
|
|
1735
|
-
if (!isStringValue(itemName)) {
|
|
1736
|
-
return;
|
|
1737
|
-
}
|
|
1738
|
-
context.exclusion[itemType][itemName] = exclusionGroup === 'only';
|
|
1739
|
-
});
|
|
1740
|
-
}
|
|
1741
|
-
/**
|
|
1742
|
-
* Checks if context has included tests
|
|
1743
|
-
*/
|
|
1744
|
-
function hasIncludedTests(keyTests) {
|
|
1745
|
-
for (var test in keyTests) {
|
|
1746
|
-
if (keyTests[test] === true) {
|
|
1747
|
-
return true; // excluded implicitly
|
|
1748
|
-
}
|
|
1749
|
-
}
|
|
1750
|
-
return false;
|
|
1751
|
-
}
|
|
1752
|
-
|
|
1753
|
-
function skipWhen(conditional, callback) {
|
|
1754
|
-
isolate({ type: IsolateTypes.SKIP_WHEN }, function () {
|
|
1755
|
-
ctx.run({ skipped: optionalFunctionValue(conditional) }, function () { return callback(); });
|
|
1756
|
-
});
|
|
1757
|
-
}
|
|
1758
|
-
|
|
1759
|
-
var ERROR_OUTSIDE_OF_TEST = "warn hook called outside of a test callback. It won't have an effect."
|
|
1760
|
-
;
|
|
1761
|
-
/**
|
|
1762
|
-
* Sets a running test to warn only mode.
|
|
1763
|
-
*/
|
|
1764
|
-
function warn() {
|
|
1765
|
-
var ctx$1 = ctx.useX('warn ' + ERROR_HOOK_CALLED_OUTSIDE);
|
|
1766
|
-
if (!ctx$1.currentTest) {
|
|
1767
|
-
throwError(ERROR_OUTSIDE_OF_TEST);
|
|
1768
|
-
}
|
|
1769
|
-
ctx$1.currentTest.warn();
|
|
1770
|
-
}
|
|
1771
|
-
|
|
1772
|
-
/**
|
|
1773
|
-
* Runs a group callback.
|
|
1774
|
-
*/
|
|
1775
|
-
function group(groupName, tests) {
|
|
1776
|
-
if (!isStringValue(groupName)) {
|
|
1777
|
-
throwGroupError('name must be a string');
|
|
1778
|
-
}
|
|
1779
|
-
if (!isFunction(tests)) {
|
|
1780
|
-
throwGroupError('callback must be a function');
|
|
1781
|
-
}
|
|
1782
|
-
// Running with the context applied
|
|
1783
|
-
isolate({ type: IsolateTypes.GROUP }, function () {
|
|
1784
|
-
ctx.run({ groupName: groupName }, tests);
|
|
1785
|
-
});
|
|
1786
|
-
}
|
|
1787
|
-
function throwGroupError(error) {
|
|
1788
|
-
throwError("Wrong arguments passed to group. Group " + error + ".");
|
|
1789
|
-
}
|
|
1790
|
-
|
|
1791
|
-
function optional(optionals) {
|
|
1792
|
-
var _a = useOptionalFields(), setOptionalFields = _a[1];
|
|
1793
|
-
setOptionalFields(function (state) {
|
|
1794
|
-
if (!isArray(optionals) && !isStringValue(optionals)) {
|
|
1795
|
-
var optionalFunctions = optionals;
|
|
1796
|
-
for (var field in optionalFunctions) {
|
|
1797
|
-
var predicate = optionalFunctions[field];
|
|
1798
|
-
state[field] = predicate;
|
|
1799
|
-
}
|
|
1800
|
-
}
|
|
1801
|
-
else {
|
|
1802
|
-
asArray(optionals).forEach(function (optionalField) {
|
|
1803
|
-
state[optionalField] = true;
|
|
1804
|
-
});
|
|
1805
|
-
}
|
|
1806
|
-
return state;
|
|
1807
|
-
});
|
|
1808
|
-
}
|
|
1809
|
-
|
|
1810
|
-
function shouldUseErrorAsMessage(message, error) {
|
|
1811
|
-
// kind of cheating with this safe guard, but it does the job
|
|
1812
|
-
return isUndefined(message) && isStringValue(error);
|
|
1813
|
-
}
|
|
1814
|
-
|
|
1815
|
-
var VestTest = /** @class */ (function () {
|
|
1816
|
-
function VestTest(fieldName, testFn, _a) {
|
|
1817
|
-
var _b = _a === void 0 ? {} : _a, message = _b.message, groupName = _b.groupName;
|
|
1818
|
-
this.id = genId();
|
|
1819
|
-
this.warns = false;
|
|
1820
|
-
this.status = STATUS_UNTESTED;
|
|
1821
|
-
this.fieldName = fieldName;
|
|
1822
|
-
this.testFn = testFn;
|
|
1823
|
-
if (groupName) {
|
|
1824
|
-
this.groupName = groupName;
|
|
1825
|
-
}
|
|
1826
|
-
if (message) {
|
|
1827
|
-
this.message = message;
|
|
1828
|
-
}
|
|
1829
|
-
}
|
|
1830
|
-
VestTest.prototype.run = function () {
|
|
1831
|
-
var result;
|
|
1832
|
-
try {
|
|
1833
|
-
result = this.testFn();
|
|
1834
|
-
}
|
|
1835
|
-
catch (error) {
|
|
1836
|
-
if (shouldUseErrorAsMessage(this.message, error)) {
|
|
1837
|
-
this.message = error;
|
|
1838
|
-
}
|
|
1839
|
-
result = false;
|
|
1840
|
-
}
|
|
1841
|
-
if (result === false) {
|
|
1842
|
-
this.fail();
|
|
1843
|
-
}
|
|
1844
|
-
return result;
|
|
1845
|
-
};
|
|
1846
|
-
VestTest.prototype.setStatus = function (status) {
|
|
1847
|
-
if (this.isFinalStatus() && status !== STATUS_OMITTED) {
|
|
1848
|
-
return;
|
|
1849
|
-
}
|
|
1850
|
-
this.status = status;
|
|
1851
|
-
};
|
|
1852
|
-
VestTest.prototype.setPending = function () {
|
|
1853
|
-
this.setStatus(STATUS_PENDING);
|
|
1854
|
-
};
|
|
1855
|
-
VestTest.prototype.fail = function () {
|
|
1856
|
-
this.setStatus(this.warns ? STATUS_WARNING : STATUS_FAILED);
|
|
1857
|
-
};
|
|
1858
|
-
VestTest.prototype.done = function () {
|
|
1859
|
-
if (this.isFinalStatus()) {
|
|
1860
|
-
return;
|
|
1861
|
-
}
|
|
1862
|
-
this.setStatus(STATUS_PASSING);
|
|
1863
|
-
};
|
|
1864
|
-
VestTest.prototype.warn = function () {
|
|
1865
|
-
this.warns = true;
|
|
1866
|
-
};
|
|
1867
|
-
VestTest.prototype.isFinalStatus = function () {
|
|
1868
|
-
return this.hasFailures() || this.isCanceled() || this.isPassing();
|
|
1869
|
-
};
|
|
1870
|
-
VestTest.prototype.skip = function () {
|
|
1871
|
-
if (this.isPending()) {
|
|
1872
|
-
// Without this condition, the test will be marked as skipped even if it is pending.
|
|
1873
|
-
// This means that it will not be counted in "allIncomplete" and its done callbacks
|
|
1874
|
-
// will not be called, or will be called prematurely.
|
|
1875
|
-
return;
|
|
1876
|
-
}
|
|
1877
|
-
this.setStatus(STATUS_SKIPPED);
|
|
1878
|
-
};
|
|
1879
|
-
VestTest.prototype.cancel = function () {
|
|
1880
|
-
this.setStatus(STATUS_CANCELED);
|
|
1881
|
-
useRefreshTestObjects();
|
|
1882
|
-
};
|
|
1883
|
-
VestTest.prototype.omit = function () {
|
|
1884
|
-
this.setStatus(STATUS_OMITTED);
|
|
1885
|
-
};
|
|
1886
|
-
VestTest.prototype.valueOf = function () {
|
|
1887
|
-
return !this.isFailing();
|
|
1888
|
-
};
|
|
1889
|
-
VestTest.prototype.hasFailures = function () {
|
|
1890
|
-
return this.isFailing() || this.isWarning();
|
|
1891
|
-
};
|
|
1892
|
-
VestTest.prototype.isPending = function () {
|
|
1893
|
-
return this.status === STATUS_PENDING;
|
|
1894
|
-
};
|
|
1895
|
-
VestTest.prototype.isTested = function () {
|
|
1896
|
-
return this.hasFailures() || this.isPassing();
|
|
1897
|
-
};
|
|
1898
|
-
VestTest.prototype.isOmitted = function () {
|
|
1899
|
-
return this.status === STATUS_OMITTED;
|
|
1900
|
-
};
|
|
1901
|
-
VestTest.prototype.isUntested = function () {
|
|
1902
|
-
return this.status === STATUS_UNTESTED;
|
|
1903
|
-
};
|
|
1904
|
-
VestTest.prototype.isFailing = function () {
|
|
1905
|
-
return this.status === STATUS_FAILED;
|
|
1906
|
-
};
|
|
1907
|
-
VestTest.prototype.isCanceled = function () {
|
|
1908
|
-
return this.status === STATUS_CANCELED;
|
|
1909
|
-
};
|
|
1910
|
-
VestTest.prototype.isSkipped = function () {
|
|
1911
|
-
return this.status === STATUS_SKIPPED;
|
|
1912
|
-
};
|
|
1913
|
-
VestTest.prototype.isPassing = function () {
|
|
1914
|
-
return this.status === STATUS_PASSING;
|
|
1915
|
-
};
|
|
1916
|
-
VestTest.prototype.isWarning = function () {
|
|
1917
|
-
return this.status === STATUS_WARNING;
|
|
1918
|
-
};
|
|
1919
|
-
return VestTest;
|
|
1920
|
-
}());
|
|
1921
|
-
var STATUS_UNTESTED = 'UNTESTED';
|
|
1922
|
-
var STATUS_SKIPPED = 'SKIPPED';
|
|
1923
|
-
var STATUS_FAILED = 'FAILED';
|
|
1924
|
-
var STATUS_WARNING = 'WARNING';
|
|
1925
|
-
var STATUS_PASSING = 'PASSING';
|
|
1926
|
-
var STATUS_PENDING = 'PENDING';
|
|
1927
|
-
var STATUS_CANCELED = 'CANCELED';
|
|
1928
|
-
var STATUS_OMITTED = 'OMITTED';
|
|
1929
|
-
|
|
1930
|
-
function isPromise(value) {
|
|
1931
|
-
return value && isFunction(value.then);
|
|
1932
|
-
}
|
|
1933
|
-
|
|
1934
|
-
function isSameProfileTest(testObject1, testObject2) {
|
|
1935
|
-
return (testObject1.fieldName === testObject2.fieldName &&
|
|
1936
|
-
testObject1.groupName === testObject2.groupName);
|
|
1937
|
-
}
|
|
1938
|
-
|
|
1939
|
-
function cancelOverriddenPendingTest(prevRunTestObject, currentRunTestObject) {
|
|
1940
|
-
if (currentRunTestObject !== prevRunTestObject &&
|
|
1941
|
-
isSameProfileTest(prevRunTestObject, currentRunTestObject) &&
|
|
1942
|
-
prevRunTestObject.isPending()) {
|
|
1943
|
-
prevRunTestObject.cancel();
|
|
1944
|
-
}
|
|
1945
|
-
}
|
|
1946
|
-
|
|
1947
|
-
/**
|
|
1948
|
-
* Runs async test.
|
|
1949
|
-
*/
|
|
1950
|
-
function runAsyncTest(testObject) {
|
|
1951
|
-
var asyncTest = testObject.asyncTest, message = testObject.message;
|
|
1952
|
-
if (!isPromise(asyncTest))
|
|
1953
|
-
return;
|
|
1954
|
-
var emit = useBus().emit;
|
|
1955
|
-
var stateRef = useStateRef();
|
|
1956
|
-
var done = ctx.bind({ stateRef: stateRef }, function () {
|
|
1957
|
-
// invalidating the "produce" cache
|
|
1958
|
-
useRefreshTestObjects();
|
|
1959
|
-
emit(Events.TEST_COMPLETED, testObject);
|
|
1960
|
-
});
|
|
1961
|
-
var fail = ctx.bind({ stateRef: stateRef }, function (rejectionMessage) {
|
|
1962
|
-
if (testObject.isCanceled()) {
|
|
1963
|
-
return;
|
|
1964
|
-
}
|
|
1965
|
-
testObject.message = isStringValue(rejectionMessage)
|
|
1966
|
-
? rejectionMessage
|
|
1967
|
-
: message;
|
|
1968
|
-
testObject.fail();
|
|
1969
|
-
done();
|
|
1970
|
-
});
|
|
1971
|
-
try {
|
|
1972
|
-
asyncTest.then(done, fail);
|
|
1973
|
-
}
|
|
1974
|
-
catch (e) {
|
|
1975
|
-
fail();
|
|
1976
|
-
}
|
|
1977
|
-
}
|
|
1978
|
-
|
|
1979
|
-
/**
|
|
1980
|
-
* Runs sync tests - or extracts promise.
|
|
1981
|
-
*/
|
|
1982
|
-
function runSyncTest(testObject) {
|
|
1983
|
-
return ctx.run({ currentTest: testObject }, function () {
|
|
1984
|
-
var result;
|
|
1985
|
-
try {
|
|
1986
|
-
result = testObject.testFn();
|
|
1987
|
-
}
|
|
1988
|
-
catch (e) {
|
|
1989
|
-
if (shouldUseErrorAsMessage(testObject.message, e)) {
|
|
1990
|
-
testObject.message = e;
|
|
1991
|
-
}
|
|
1992
|
-
result = false;
|
|
1993
|
-
}
|
|
1994
|
-
if (result === false) {
|
|
1995
|
-
testObject.fail();
|
|
1996
|
-
}
|
|
1997
|
-
return result;
|
|
1998
|
-
});
|
|
1999
|
-
}
|
|
2000
|
-
|
|
2001
|
-
/**
|
|
2002
|
-
* Registers test, if async - adds to pending array
|
|
2003
|
-
*/
|
|
2004
|
-
function registerTest(testObject) {
|
|
2005
|
-
var emit = useBus().emit;
|
|
2006
|
-
// Run test callback.
|
|
2007
|
-
// If a promise is returned, set as async and
|
|
2008
|
-
// Move to pending list.
|
|
2009
|
-
var result = runSyncTest(testObject);
|
|
2010
|
-
try {
|
|
2011
|
-
// try catch for safe property access
|
|
2012
|
-
// in case object is an enforce chain
|
|
2013
|
-
if (isPromise(result)) {
|
|
2014
|
-
testObject.asyncTest = result;
|
|
2015
|
-
testObject.setPending();
|
|
2016
|
-
runAsyncTest(testObject);
|
|
2017
|
-
}
|
|
2018
|
-
else {
|
|
2019
|
-
emit(Events.TEST_COMPLETED, testObject);
|
|
2020
|
-
}
|
|
2021
|
-
}
|
|
2022
|
-
catch (e) {
|
|
2023
|
-
throwError("Your test function " + testObject.fieldName + " returned " + JSON.stringify(result) + ". Only \"false\" or a Promise are supported. Return values may cause unexpected behavior.");
|
|
2024
|
-
}
|
|
2025
|
-
}
|
|
2026
|
-
|
|
2027
|
-
/**
|
|
2028
|
-
* This module serves as the "collision detection" mechanism for Vest.
|
|
2029
|
-
* It is used to ensure that tests are not called in a different order than
|
|
2030
|
-
* they were called in the previous run.
|
|
2031
|
-
* If they are, it will throw a deferred error unless explicitly allowed.
|
|
2032
|
-
*
|
|
2033
|
-
* For now it seems pretty safe, and it covers most common use cases, but it can
|
|
2034
|
-
* be improved in the future both in terms of performance and scenarios it covers.
|
|
2035
|
-
*/
|
|
2036
|
-
// eslint-disable-next-line max-statements, max-lines-per-function
|
|
2037
|
-
function useTestAtCursor(newTestObject) {
|
|
2038
|
-
var _a = useTestObjects(), testObjects = _a[0], setTestObjects = _a[1];
|
|
2039
|
-
var prevTests = testObjects.prev;
|
|
2040
|
-
if (isEmpty(prevTests)) {
|
|
2041
|
-
useSetTestAtCursor(newTestObject);
|
|
2042
|
-
return newTestObject;
|
|
2043
|
-
}
|
|
2044
|
-
var prevTest = useGetTestAtCursor(prevTests);
|
|
2045
|
-
if (shouldPurgePrevTest(prevTest, newTestObject)) {
|
|
2046
|
-
throwTestOrderError(prevTest, newTestObject);
|
|
2047
|
-
// Here we handle just the omission of tests in the middle of the test suite.
|
|
2048
|
-
// We need to also handle a case in which tests are added in between other tests.
|
|
2049
|
-
// At the moment all we can do is just splice the tests out of the array when this happens.
|
|
2050
|
-
// A viable solution would be to use something like React's key prop to identify tests regardless
|
|
2051
|
-
// of their position in the suite. https://reactjs.org/docs/lists-and-keys.html#keys
|
|
2052
|
-
var current = getCurrent(prevTests, usePath());
|
|
2053
|
-
var cursorAt = useCursorAt();
|
|
2054
|
-
current.splice(cursorAt);
|
|
2055
|
-
// We actually don't mind mutating the state directly (as can be seen above). There is no harm in it
|
|
2056
|
-
// since we're only touching the "prev" state. The reason we still use the setter function is
|
|
2057
|
-
// to prevent future headaches if we ever do need to rely on prev-state immutability.
|
|
2058
|
-
setTestObjects(function (_a) {
|
|
2059
|
-
var current = _a.current;
|
|
2060
|
-
return ({
|
|
2061
|
-
prev: prevTests,
|
|
2062
|
-
current: current
|
|
2063
|
-
});
|
|
2064
|
-
});
|
|
2065
|
-
// Need to see if this has any effect at all.
|
|
2066
|
-
prevTest = null;
|
|
2067
|
-
}
|
|
2068
|
-
var nextTest = defaultTo(prevTest, newTestObject);
|
|
2069
|
-
useSetTestAtCursor(nextTest);
|
|
2070
|
-
return nextTest;
|
|
2071
|
-
}
|
|
2072
|
-
function useSetTestAtCursor(testObject) {
|
|
2073
|
-
var cursorPath = usePath();
|
|
2074
|
-
useSetTests(function (tests) {
|
|
2075
|
-
return setValueAtPath(tests, cursorPath, testObject);
|
|
2076
|
-
});
|
|
2077
|
-
}
|
|
2078
|
-
function useGetTestAtCursor(tests) {
|
|
2079
|
-
var cursorPath = usePath();
|
|
2080
|
-
return valueAtPath(tests, cursorPath);
|
|
2081
|
-
}
|
|
2082
|
-
function shouldPurgePrevTest(prevTest, newTest) {
|
|
2083
|
-
return isNotEmpty(prevTest) && !isSameProfileTest(prevTest, newTest);
|
|
2084
|
-
}
|
|
2085
|
-
function throwTestOrderError(prevTest, newTestObject) {
|
|
2086
|
-
if (shouldAllowReorder()) {
|
|
2087
|
-
return;
|
|
2088
|
-
}
|
|
2089
|
-
throwErrorDeferred("Vest Critical Error: Tests called in different order than previous run.\n expected: " + prevTest.fieldName + "\n received: " + newTestObject.fieldName + "\n This happens when you conditionally call your tests using if/else.\n This might lead to incorrect validation results.\n Replacing if/else with skipWhen solves these issues.");
|
|
2090
|
-
}
|
|
2091
|
-
|
|
2092
|
-
function registerPrevRunTest(testObject) {
|
|
2093
|
-
var prevRunTest = useTestAtCursor(testObject);
|
|
2094
|
-
if (isExcluded(testObject)) {
|
|
2095
|
-
testObject.skip();
|
|
2096
|
-
moveForward();
|
|
2097
|
-
return prevRunTest;
|
|
2098
|
-
}
|
|
2099
|
-
cancelOverriddenPendingTest(prevRunTest, testObject);
|
|
2100
|
-
useSetTestAtCursor(testObject);
|
|
2101
|
-
moveForward();
|
|
2102
|
-
registerTestObjectByTier(testObject);
|
|
2103
|
-
return testObject;
|
|
2104
|
-
}
|
|
2105
|
-
function registerTestObjectByTier(testObject) {
|
|
2106
|
-
if (testObject.isUntested()) {
|
|
2107
|
-
registerTest(testObject);
|
|
2108
|
-
}
|
|
2109
|
-
else if (isPromise(testObject.asyncTest)) {
|
|
2110
|
-
testObject.setPending();
|
|
2111
|
-
runAsyncTest(testObject);
|
|
2112
|
-
}
|
|
2113
|
-
}
|
|
2114
|
-
|
|
2115
|
-
function bindTestEach(test) {
|
|
2116
|
-
/**
|
|
2117
|
-
* Run multiple tests using a parameter table
|
|
2118
|
-
*/
|
|
2119
|
-
function each(table) {
|
|
2120
|
-
if (!isArray(table)) {
|
|
2121
|
-
throwError('test.each: Expected table to be an array.');
|
|
2122
|
-
}
|
|
2123
|
-
function eachReturn(fieldName) {
|
|
2124
|
-
var args = [];
|
|
2125
|
-
for (var _i = 1; _i < arguments.length; _i++) {
|
|
2126
|
-
args[_i - 1] = arguments[_i];
|
|
2127
|
-
}
|
|
2128
|
-
var _a = args.reverse(), testFn = _a[0], message = _a[1];
|
|
2129
|
-
return isolate({ type: IsolateTypes.EACH }, function () {
|
|
2130
|
-
return table.map(function (item) {
|
|
2131
|
-
item = asArray(item);
|
|
2132
|
-
return test(optionalFunctionValue.apply(void 0, __spreadArray([fieldName], item)), optionalFunctionValue.apply(void 0, __spreadArray([message], item)), function () { return testFn.apply(void 0, item); } // eslint-disable-line max-nested-callbacks
|
|
2133
|
-
);
|
|
2134
|
-
});
|
|
2135
|
-
});
|
|
2136
|
-
}
|
|
2137
|
-
return eachReturn;
|
|
2138
|
-
}
|
|
2139
|
-
return each;
|
|
2140
|
-
}
|
|
2141
|
-
|
|
2142
|
-
// eslint-disable-next-line max-lines-per-function
|
|
2143
|
-
function bindTestMemo(test) {
|
|
2144
|
-
var cache = createCache(100); // arbitrary cache size
|
|
2145
|
-
// eslint-disable-next-line max-statements
|
|
2146
|
-
function memo(fieldName) {
|
|
2147
|
-
var args = [];
|
|
2148
|
-
for (var _i = 1; _i < arguments.length; _i++) {
|
|
2149
|
-
args[_i - 1] = arguments[_i];
|
|
2150
|
-
}
|
|
2151
|
-
var suiteId = useSuiteId()[0];
|
|
2152
|
-
var cursorAt = useCursorAt();
|
|
2153
|
-
var _a = args.reverse(), deps = _a[0], testFn = _a[1], msg = _a[2];
|
|
2154
|
-
// Implicit dependency for more specificity
|
|
2155
|
-
var dependencies = [suiteId, fieldName, cursorAt].concat(deps);
|
|
2156
|
-
var cached = cache.get(dependencies);
|
|
2157
|
-
if (isNull(cached)) {
|
|
2158
|
-
// cache miss
|
|
2159
|
-
return cache(dependencies, function () { return test(fieldName, msg, testFn); });
|
|
2160
|
-
}
|
|
2161
|
-
if (cached[1].isCanceled()) {
|
|
2162
|
-
// cache hit, but test is canceled
|
|
2163
|
-
cache.invalidate(dependencies);
|
|
2164
|
-
return cache(dependencies, function () { return test(fieldName, msg, testFn); });
|
|
2165
|
-
}
|
|
2166
|
-
return registerPrevRunTest(cached[1]);
|
|
2167
|
-
}
|
|
2168
|
-
return memo;
|
|
2169
|
-
}
|
|
2170
|
-
|
|
2171
|
-
function testBase(fieldName) {
|
|
2172
|
-
var args = [];
|
|
2173
|
-
for (var _i = 1; _i < arguments.length; _i++) {
|
|
2174
|
-
args[_i - 1] = arguments[_i];
|
|
2175
|
-
}
|
|
2176
|
-
var _a = args.reverse(), testFn = _a[0], message = _a[1];
|
|
2177
|
-
var context = ctx.useX();
|
|
2178
|
-
var testObject = new VestTest(fieldName, testFn, {
|
|
2179
|
-
message: message,
|
|
2180
|
-
groupName: context === null || context === void 0 ? void 0 : context.groupName
|
|
2181
|
-
});
|
|
2182
|
-
return registerPrevRunTest(testObject);
|
|
2183
|
-
}
|
|
2184
|
-
var test = assign(testBase, {
|
|
2185
|
-
each: bindTestEach(testBase),
|
|
2186
|
-
memo: bindTestMemo(testBase)
|
|
2187
|
-
});
|
|
2188
|
-
|
|
2189
|
-
var VERSION = "4.0.0-dev-7acb76";
|
|
2190
|
-
|
|
2191
|
-
exports.VERSION = VERSION;
|
|
2192
|
-
exports.create = create;
|
|
2193
|
-
exports.enforce = enforce;
|
|
2194
|
-
exports.group = group;
|
|
2195
|
-
exports.only = only;
|
|
2196
|
-
exports.optional = optional;
|
|
2197
|
-
exports.skip = skip;
|
|
2198
|
-
exports.skipWhen = skipWhen;
|
|
2199
|
-
exports.test = test;
|
|
2200
|
-
exports.warn = warn;
|
|
2201
|
-
|
|
2202
|
-
Object.defineProperty(exports, '__esModule', { value: true });
|
|
744
|
+
function __spreadArray(to, from, pack) {
|
|
745
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
746
|
+
if (ar || !(i in from)) {
|
|
747
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
748
|
+
ar[i] = from[i];
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
return to.concat(ar || from);
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
function either(a, b) {
|
|
755
|
+
return !!a !== !!b;
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
/**
|
|
759
|
+
* Checks that a given test object matches the currently specified severity level
|
|
760
|
+
*/
|
|
761
|
+
function nonMatchingSeverityProfile(severity, testObject) {
|
|
762
|
+
return either(severity === 'warnings', testObject.warns());
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
function collectFailureMessages(severity, testObjects, options) {
|
|
766
|
+
var _a;
|
|
767
|
+
if (options === void 0) { options = {}; }
|
|
768
|
+
var _b = options || {}, group = _b.group, fieldName = _b.fieldName;
|
|
769
|
+
var res = testObjects.reduce(function (collector, testObject) {
|
|
770
|
+
if (noMatch(testObject, severity, group, fieldName)) {
|
|
771
|
+
return collector;
|
|
772
|
+
}
|
|
773
|
+
if (!testObject.hasFailures()) {
|
|
774
|
+
return collector;
|
|
775
|
+
}
|
|
776
|
+
collector[testObject.fieldName] = (collector[testObject.fieldName] || []).concat(testObject.message || []);
|
|
777
|
+
return collector;
|
|
778
|
+
}, __assign({}, (fieldName && (_a = {}, _a[fieldName] = [], _a))));
|
|
779
|
+
return res;
|
|
780
|
+
}
|
|
781
|
+
function noGroupMatch(testObject, groupName) {
|
|
782
|
+
return !!(groupName && testObject.groupName !== groupName);
|
|
783
|
+
}
|
|
784
|
+
function noMatch(testObject, severity, group, fieldName) {
|
|
785
|
+
if (noGroupMatch(testObject, group)) {
|
|
786
|
+
return true;
|
|
787
|
+
}
|
|
788
|
+
if (nonMatchingFieldName(testObject, fieldName)) {
|
|
789
|
+
return true;
|
|
790
|
+
}
|
|
791
|
+
if (nonMatchingSeverityProfile(severity, testObject)) {
|
|
792
|
+
return true;
|
|
793
|
+
}
|
|
794
|
+
return false;
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
function getFailuresArrayOrObject(group, fieldName) {
|
|
798
|
+
if (fieldName) {
|
|
799
|
+
return group[fieldName];
|
|
800
|
+
}
|
|
801
|
+
return group;
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
function getErrors(fieldName) {
|
|
805
|
+
return getFailures('errors', fieldName);
|
|
806
|
+
}
|
|
807
|
+
function getWarnings(fieldName) {
|
|
808
|
+
return getFailures('warnings', fieldName);
|
|
809
|
+
}
|
|
810
|
+
/**
|
|
811
|
+
* @returns suite or field's errors or warnings.
|
|
812
|
+
*/
|
|
813
|
+
function getFailures(severityKey, fieldName) {
|
|
814
|
+
var testObjects = useTestsFlat();
|
|
815
|
+
var failureMessages = collectFailureMessages(severityKey, testObjects, {
|
|
816
|
+
fieldName: fieldName
|
|
817
|
+
});
|
|
818
|
+
return getFailuresArrayOrObject(failureMessages, fieldName);
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
function getErrorsByGroup(groupName, fieldName) {
|
|
822
|
+
var errors = getByGroup('errors', groupName, fieldName);
|
|
823
|
+
return getFailuresArrayOrObject(errors, fieldName);
|
|
824
|
+
}
|
|
825
|
+
function getWarningsByGroup(groupName, fieldName) {
|
|
826
|
+
var warnings = getByGroup('warnings', groupName, fieldName);
|
|
827
|
+
return getFailuresArrayOrObject(warnings, fieldName);
|
|
828
|
+
}
|
|
829
|
+
/**
|
|
830
|
+
* Gets failure messages by group.
|
|
831
|
+
*/
|
|
832
|
+
function getByGroup(severityKey, group, fieldName) {
|
|
833
|
+
if (!group) {
|
|
834
|
+
throwError("get" + severityKey[0].toUpperCase() + severityKey.slice(1) + "ByGroup requires a group name. Received `" + group + "` instead.");
|
|
835
|
+
}
|
|
836
|
+
var testObjects = useTestsFlat();
|
|
837
|
+
var failureMessages = collectFailureMessages(severityKey, testObjects, {
|
|
838
|
+
group: group,
|
|
839
|
+
fieldName: fieldName
|
|
840
|
+
});
|
|
841
|
+
return failureMessages;
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
/**
|
|
845
|
+
* Determines whether a certain test profile has failures.
|
|
846
|
+
*/
|
|
847
|
+
function hasFailuresLogic(testObject, severityKey, fieldName) {
|
|
848
|
+
if (!testObject.hasFailures()) {
|
|
849
|
+
return false;
|
|
850
|
+
}
|
|
851
|
+
if (nonMatchingFieldName(testObject, fieldName)) {
|
|
852
|
+
return false;
|
|
853
|
+
}
|
|
854
|
+
if (nonMatchingSeverityProfile(severityKey, testObject)) {
|
|
855
|
+
return false;
|
|
856
|
+
}
|
|
857
|
+
return true;
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
function hasErrors(fieldName) {
|
|
861
|
+
return has('errors', fieldName);
|
|
862
|
+
}
|
|
863
|
+
function hasWarnings(fieldName) {
|
|
864
|
+
return has('warnings', fieldName);
|
|
865
|
+
}
|
|
866
|
+
function has(severityKey, fieldName) {
|
|
867
|
+
var testObjects = useTestsFlat();
|
|
868
|
+
return testObjects.some(function (testObject) {
|
|
869
|
+
return hasFailuresLogic(testObject, severityKey, fieldName);
|
|
870
|
+
});
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
function hasErrorsByGroup(groupName, fieldName) {
|
|
874
|
+
return hasByGroup('errors', groupName, fieldName);
|
|
875
|
+
}
|
|
876
|
+
function hasWarningsByGroup(groupName, fieldName) {
|
|
877
|
+
return hasByGroup('warnings', groupName, fieldName);
|
|
878
|
+
}
|
|
879
|
+
/**
|
|
880
|
+
* Checks whether there are failures in a given group.
|
|
881
|
+
*/
|
|
882
|
+
function hasByGroup(severityKey, group, fieldName) {
|
|
883
|
+
var testObjects = useTestsFlat();
|
|
884
|
+
return testObjects.some(function (testObject) {
|
|
885
|
+
return group === testObject.groupName
|
|
886
|
+
? hasFailuresLogic(testObject, severityKey, fieldName)
|
|
887
|
+
: false;
|
|
888
|
+
});
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
// eslint-disable-next-line max-statements, complexity
|
|
892
|
+
function isValid(result, fieldName) {
|
|
893
|
+
if (fieldIsOmitted(fieldName)) {
|
|
894
|
+
return true;
|
|
895
|
+
}
|
|
896
|
+
if (result.hasErrors(fieldName)) {
|
|
897
|
+
return false;
|
|
898
|
+
}
|
|
899
|
+
var testObjects = useTestsFlat();
|
|
900
|
+
if (isEmpty(testObjects)) {
|
|
901
|
+
return false;
|
|
902
|
+
}
|
|
903
|
+
if (fieldDoesNotExist(result, fieldName)) {
|
|
904
|
+
return false;
|
|
905
|
+
}
|
|
906
|
+
if (hasNonOptionalIncomplete(fieldName)) {
|
|
907
|
+
return false;
|
|
908
|
+
}
|
|
909
|
+
return noMissingTests(fieldName);
|
|
910
|
+
}
|
|
911
|
+
function fieldIsOmitted(fieldName) {
|
|
912
|
+
var omittedFields = useOmittedFields();
|
|
913
|
+
if (!fieldName) {
|
|
914
|
+
return false;
|
|
915
|
+
}
|
|
916
|
+
return !!omittedFields[fieldName];
|
|
917
|
+
}
|
|
918
|
+
function hasNonOptionalIncomplete(fieldName) {
|
|
919
|
+
var optionalFields = useOptionalFields()[0];
|
|
920
|
+
return isNotEmpty(useAllIncomplete().filter(function (testObject) {
|
|
921
|
+
if (nonMatchingFieldName(testObject, fieldName)) {
|
|
922
|
+
return false;
|
|
923
|
+
}
|
|
924
|
+
return optionalFields[testObject.fieldName] !== true;
|
|
925
|
+
}));
|
|
926
|
+
}
|
|
927
|
+
function fieldDoesNotExist(result, fieldName) {
|
|
928
|
+
return !!fieldName && isEmpty(result.tests[fieldName]);
|
|
929
|
+
}
|
|
930
|
+
function noMissingTests(fieldName) {
|
|
931
|
+
var testObjects = useTestsFlat();
|
|
932
|
+
var optionalFields = useOptionalFields()[0];
|
|
933
|
+
return testObjects.every(function (testObject) {
|
|
934
|
+
if (nonMatchingFieldName(testObject, fieldName)) {
|
|
935
|
+
return true;
|
|
936
|
+
}
|
|
937
|
+
return (optionalFields[testObject.fieldName] === true ||
|
|
938
|
+
testObject.isTested() ||
|
|
939
|
+
testObject.isOmitted());
|
|
940
|
+
});
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
var cache$1 = createCache(20);
|
|
944
|
+
function produceDraft() {
|
|
945
|
+
var testObjects = useTestsFlat();
|
|
946
|
+
var ctxRef = { stateRef: useStateRef() };
|
|
947
|
+
return cache$1([testObjects], context.bind(ctxRef, function () {
|
|
948
|
+
var suiteName = useSuiteName();
|
|
949
|
+
return assign(genTestsSummary(), {
|
|
950
|
+
getErrors: context.bind(ctxRef, getErrors),
|
|
951
|
+
getErrorsByGroup: context.bind(ctxRef, getErrorsByGroup),
|
|
952
|
+
getWarnings: context.bind(ctxRef, getWarnings),
|
|
953
|
+
getWarningsByGroup: context.bind(ctxRef, getWarningsByGroup),
|
|
954
|
+
hasErrors: context.bind(ctxRef, hasErrors),
|
|
955
|
+
hasErrorsByGroup: context.bind(ctxRef, hasErrorsByGroup),
|
|
956
|
+
hasWarnings: context.bind(ctxRef, hasWarnings),
|
|
957
|
+
hasWarningsByGroup: context.bind(ctxRef, hasWarningsByGroup),
|
|
958
|
+
isValid: context.bind(ctxRef, function (fieldName) {
|
|
959
|
+
return isValid(produceDraft(), fieldName);
|
|
960
|
+
}),
|
|
961
|
+
suiteName: suiteName
|
|
962
|
+
});
|
|
963
|
+
}));
|
|
964
|
+
}
|
|
965
|
+
|
|
966
|
+
var cache = createCache(20);
|
|
967
|
+
function produceFullResult() {
|
|
968
|
+
var testObjects = useTestsFlat();
|
|
969
|
+
var ctxRef = { stateRef: useStateRef() };
|
|
970
|
+
return cache([testObjects], context.bind(ctxRef, function () {
|
|
971
|
+
return assign({}, produceDraft(), {
|
|
972
|
+
done: context.bind(ctxRef, done)
|
|
973
|
+
});
|
|
974
|
+
}));
|
|
975
|
+
}
|
|
976
|
+
/**
|
|
977
|
+
* DONE is here and not in its own module to prevent circular dependency issues.
|
|
978
|
+
*/
|
|
979
|
+
function shouldSkipDoneRegistration(callback, fieldName, output) {
|
|
980
|
+
// If we do not have any test runs for the current field
|
|
981
|
+
return !!(!isFunction(callback) ||
|
|
982
|
+
(fieldName &&
|
|
983
|
+
(!output.tests[fieldName] || isEmpty(output.tests[fieldName].testCount))));
|
|
984
|
+
}
|
|
985
|
+
function shouldRunDoneCallback(fieldName) {
|
|
986
|
+
// is suite finished || field name exists, and test is finished;
|
|
987
|
+
return !!(!hasRemainingTests() ||
|
|
988
|
+
(fieldName && !hasRemainingTests(fieldName)));
|
|
989
|
+
}
|
|
990
|
+
/**
|
|
991
|
+
* Registers done callbacks.
|
|
992
|
+
* @register {Object} Vest output object.
|
|
993
|
+
*/
|
|
994
|
+
var done = function done() {
|
|
995
|
+
var args = [];
|
|
996
|
+
for (var _i = 0; _i < arguments.length; _i++) {
|
|
997
|
+
args[_i] = arguments[_i];
|
|
998
|
+
}
|
|
999
|
+
var _a = args.reverse(), callback = _a[0], fieldName = _a[1];
|
|
1000
|
+
var output = produceFullResult();
|
|
1001
|
+
if (shouldSkipDoneRegistration(callback, fieldName, output)) {
|
|
1002
|
+
return output;
|
|
1003
|
+
}
|
|
1004
|
+
var doneCallback = function () { return callback(produceDraft()); };
|
|
1005
|
+
if (shouldRunDoneCallback(fieldName)) {
|
|
1006
|
+
doneCallback();
|
|
1007
|
+
return output;
|
|
1008
|
+
}
|
|
1009
|
+
deferDoneCallback(doneCallback, fieldName);
|
|
1010
|
+
return output;
|
|
1011
|
+
};
|
|
1012
|
+
function deferDoneCallback(doneCallback, fieldName) {
|
|
1013
|
+
var deferredCallback = context.bind({}, doneCallback);
|
|
1014
|
+
var _a = useTestCallbacks(), setTestCallbacks = _a[1];
|
|
1015
|
+
setTestCallbacks(function (current) {
|
|
1016
|
+
if (fieldName) {
|
|
1017
|
+
current.fieldCallbacks[fieldName] = (current.fieldCallbacks[fieldName] || []).concat(deferredCallback);
|
|
1018
|
+
}
|
|
1019
|
+
else {
|
|
1020
|
+
current.doneCallbacks.push(deferredCallback);
|
|
1021
|
+
}
|
|
1022
|
+
return current;
|
|
1023
|
+
});
|
|
1024
|
+
}
|
|
1025
|
+
|
|
1026
|
+
function createBus() {
|
|
1027
|
+
var listeners = {};
|
|
1028
|
+
return {
|
|
1029
|
+
emit: function (event, data) {
|
|
1030
|
+
if (!listeners[event]) {
|
|
1031
|
+
return;
|
|
1032
|
+
}
|
|
1033
|
+
listeners[event].forEach(function (listener) {
|
|
1034
|
+
listener(data);
|
|
1035
|
+
});
|
|
1036
|
+
},
|
|
1037
|
+
on: function (event, handler) {
|
|
1038
|
+
if (!listeners[event]) {
|
|
1039
|
+
listeners[event] = [];
|
|
1040
|
+
}
|
|
1041
|
+
listeners[event].push(handler);
|
|
1042
|
+
return {
|
|
1043
|
+
off: function () {
|
|
1044
|
+
listeners[event] = listeners[event].filter(function (h) { return h !== handler; });
|
|
1045
|
+
}
|
|
1046
|
+
};
|
|
1047
|
+
}
|
|
1048
|
+
};
|
|
1049
|
+
}
|
|
1050
|
+
|
|
1051
|
+
function omitOptionalTests() {
|
|
1052
|
+
var optionalFields = useOptionalFields()[0];
|
|
1053
|
+
if (isEmpty(optionalFields)) {
|
|
1054
|
+
return;
|
|
1055
|
+
}
|
|
1056
|
+
var shouldOmit = {};
|
|
1057
|
+
useSetTests(function (tests) {
|
|
1058
|
+
return transform(tests, function (testObject) {
|
|
1059
|
+
var fieldName = testObject.fieldName;
|
|
1060
|
+
if (shouldOmit.hasOwnProperty(fieldName)) {
|
|
1061
|
+
omit(testObject);
|
|
1062
|
+
}
|
|
1063
|
+
else {
|
|
1064
|
+
var optionalConfig = optionalFields[fieldName];
|
|
1065
|
+
if (isFunction(optionalConfig)) {
|
|
1066
|
+
shouldOmit[fieldName] = optionalConfig();
|
|
1067
|
+
omit(testObject);
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1070
|
+
return testObject;
|
|
1071
|
+
});
|
|
1072
|
+
});
|
|
1073
|
+
function omit(testObject) {
|
|
1074
|
+
if (shouldOmit[testObject.fieldName]) {
|
|
1075
|
+
testObject.omit();
|
|
1076
|
+
}
|
|
1077
|
+
}
|
|
1078
|
+
}
|
|
1079
|
+
|
|
1080
|
+
/**
|
|
1081
|
+
* Removes test object from suite state
|
|
1082
|
+
*/
|
|
1083
|
+
function removeTestFromState (testObject) {
|
|
1084
|
+
useSetTests(function (tests) {
|
|
1085
|
+
return transform(tests, function (test) { return (testObject !== test ? test : null); });
|
|
1086
|
+
});
|
|
1087
|
+
}
|
|
1088
|
+
|
|
1089
|
+
function callEach(arr) {
|
|
1090
|
+
return arr.forEach(function (fn) { return fn(); });
|
|
1091
|
+
}
|
|
1092
|
+
|
|
1093
|
+
/**
|
|
1094
|
+
* Runs done callback per field when async tests are finished running.
|
|
1095
|
+
*/
|
|
1096
|
+
function runFieldCallbacks(fieldName) {
|
|
1097
|
+
var fieldCallbacks = useTestCallbacks()[0].fieldCallbacks;
|
|
1098
|
+
if (fieldName) {
|
|
1099
|
+
if (!hasRemainingTests(fieldName) && isArray(fieldCallbacks[fieldName])) {
|
|
1100
|
+
callEach(fieldCallbacks[fieldName]);
|
|
1101
|
+
}
|
|
1102
|
+
}
|
|
1103
|
+
}
|
|
1104
|
+
/**
|
|
1105
|
+
* Runs unlabelled done callback when async tests are finished running.
|
|
1106
|
+
*/
|
|
1107
|
+
function runDoneCallbacks() {
|
|
1108
|
+
var doneCallbacks = useTestCallbacks()[0].doneCallbacks;
|
|
1109
|
+
if (!hasRemainingTests()) {
|
|
1110
|
+
callEach(doneCallbacks);
|
|
1111
|
+
}
|
|
1112
|
+
}
|
|
1113
|
+
|
|
1114
|
+
function initBus() {
|
|
1115
|
+
var bus = createBus();
|
|
1116
|
+
// Report a the completion of a test. There may be other tests with the same
|
|
1117
|
+
// name that are still running, or not yet started.
|
|
1118
|
+
bus.on(Events.TEST_COMPLETED, function (testObject) {
|
|
1119
|
+
if (testObject.isCanceled()) {
|
|
1120
|
+
return;
|
|
1121
|
+
}
|
|
1122
|
+
testObject.done();
|
|
1123
|
+
runFieldCallbacks(testObject.fieldName);
|
|
1124
|
+
runDoneCallbacks();
|
|
1125
|
+
});
|
|
1126
|
+
// Report that the suite completed its synchronous test run.
|
|
1127
|
+
// Async operations may still be running.
|
|
1128
|
+
bus.on(Events.SUITE_COMPLETED, function () {
|
|
1129
|
+
// Remove tests that are optional and need to be omitted
|
|
1130
|
+
omitOptionalTests();
|
|
1131
|
+
});
|
|
1132
|
+
// Removes a certain field from the state.
|
|
1133
|
+
bus.on(Events.REMOVE_FIELD, function (fieldName) {
|
|
1134
|
+
var testObjects = useTestsFlat();
|
|
1135
|
+
testObjects.forEach(function (testObject) {
|
|
1136
|
+
if (matchingFieldName(testObject, fieldName)) {
|
|
1137
|
+
testObject.cancel();
|
|
1138
|
+
removeTestFromState(testObject);
|
|
1139
|
+
}
|
|
1140
|
+
});
|
|
1141
|
+
});
|
|
1142
|
+
return bus;
|
|
1143
|
+
}
|
|
1144
|
+
function useBus() {
|
|
1145
|
+
var context$1 = context.useX();
|
|
1146
|
+
if (!context$1.bus) {
|
|
1147
|
+
throwError();
|
|
1148
|
+
}
|
|
1149
|
+
return context$1.bus;
|
|
1150
|
+
}
|
|
1151
|
+
var Events;
|
|
1152
|
+
(function (Events) {
|
|
1153
|
+
Events["TEST_COMPLETED"] = "test_completed";
|
|
1154
|
+
Events["REMOVE_FIELD"] = "remove_field";
|
|
1155
|
+
Events["SUITE_COMPLETED"] = "suite_completed";
|
|
1156
|
+
})(Events || (Events = {}));
|
|
1157
|
+
|
|
1158
|
+
// eslint-disable-next-line max-lines-per-function
|
|
1159
|
+
function create() {
|
|
1160
|
+
var args = [];
|
|
1161
|
+
for (var _i = 0; _i < arguments.length; _i++) {
|
|
1162
|
+
args[_i] = arguments[_i];
|
|
1163
|
+
}
|
|
1164
|
+
var _a = args.reverse(), suiteCallback = _a[0], suiteName = _a[1];
|
|
1165
|
+
if (!isFunction(suiteCallback)) {
|
|
1166
|
+
throwError('vest.create: Expected callback to be a function.');
|
|
1167
|
+
}
|
|
1168
|
+
// Event bus initialization
|
|
1169
|
+
var bus = initBus();
|
|
1170
|
+
// State initialization
|
|
1171
|
+
var state = createState();
|
|
1172
|
+
// State reference - this holds the actual state values
|
|
1173
|
+
var stateRef = createStateRef(state, { suiteId: genId(), suiteName: suiteName });
|
|
1174
|
+
// Create base context reference. All hooks will derive their data from this
|
|
1175
|
+
var ctxRef = { stateRef: stateRef, bus: bus };
|
|
1176
|
+
var suite = assign(
|
|
1177
|
+
// Bind the suite body to the context
|
|
1178
|
+
context.bind(ctxRef, function () {
|
|
1179
|
+
var args = [];
|
|
1180
|
+
for (var _i = 0; _i < arguments.length; _i++) {
|
|
1181
|
+
args[_i] = arguments[_i];
|
|
1182
|
+
}
|
|
1183
|
+
// Reset the state. Migrates current test objects to `prev` array.
|
|
1184
|
+
state.reset();
|
|
1185
|
+
// Create a top level isolate
|
|
1186
|
+
isolate({ type: IsolateTypes.SUITE }, function () {
|
|
1187
|
+
// Run the consumer's callback
|
|
1188
|
+
suiteCallback.apply(void 0, args);
|
|
1189
|
+
});
|
|
1190
|
+
// Report the suite is done registering tests
|
|
1191
|
+
// Async tests may still be running
|
|
1192
|
+
bus.emit(Events.SUITE_COMPLETED);
|
|
1193
|
+
// Return the result
|
|
1194
|
+
return produceFullResult();
|
|
1195
|
+
}), {
|
|
1196
|
+
get: context.bind(ctxRef, produceDraft),
|
|
1197
|
+
reset: state.reset,
|
|
1198
|
+
remove: context.bind(ctxRef, function (fieldName) {
|
|
1199
|
+
bus.emit(Events.REMOVE_FIELD, fieldName);
|
|
1200
|
+
})
|
|
1201
|
+
});
|
|
1202
|
+
return suite;
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1205
|
+
function each(list, callback) {
|
|
1206
|
+
if (!isFunction(callback)) {
|
|
1207
|
+
throwError('callback must be a function');
|
|
1208
|
+
}
|
|
1209
|
+
isolate({ type: IsolateTypes.EACH }, function () {
|
|
1210
|
+
list.forEach(function (arg, index) {
|
|
1211
|
+
callback(arg, index);
|
|
1212
|
+
});
|
|
1213
|
+
});
|
|
1214
|
+
}
|
|
1215
|
+
|
|
1216
|
+
/**
|
|
1217
|
+
* Error message to display when a hook was called outside of context.
|
|
1218
|
+
*/
|
|
1219
|
+
var ERROR_HOOK_CALLED_OUTSIDE = 'hook called outside of a running suite.';
|
|
1220
|
+
|
|
1221
|
+
/**
|
|
1222
|
+
* Adds a field or multiple fields to inclusion group.
|
|
1223
|
+
*/
|
|
1224
|
+
function only(item) {
|
|
1225
|
+
return addTo(0 /* ONLY */, 'tests', item);
|
|
1226
|
+
}
|
|
1227
|
+
only.group = function (item) {
|
|
1228
|
+
return addTo(0 /* ONLY */, 'groups', item);
|
|
1229
|
+
};
|
|
1230
|
+
/**
|
|
1231
|
+
* Adds a field or multiple fields to exclusion group.
|
|
1232
|
+
*/
|
|
1233
|
+
function skip(item) {
|
|
1234
|
+
return addTo(1 /* SKIP */, 'tests', item);
|
|
1235
|
+
}
|
|
1236
|
+
skip.group = function (item) {
|
|
1237
|
+
return addTo(1 /* SKIP */, 'groups', item);
|
|
1238
|
+
};
|
|
1239
|
+
function isExcludedIndividually() {
|
|
1240
|
+
return !!context.useX().skipped;
|
|
1241
|
+
}
|
|
1242
|
+
//Checks whether a certain test profile excluded by any of the exclusion groups.
|
|
1243
|
+
// eslint-disable-next-line complexity, max-statements
|
|
1244
|
+
function isExcluded(testObject) {
|
|
1245
|
+
var fieldName = testObject.fieldName, groupName = testObject.groupName;
|
|
1246
|
+
if (isExcludedIndividually())
|
|
1247
|
+
return true;
|
|
1248
|
+
var context$1 = context.useX();
|
|
1249
|
+
var exclusion = context$1.exclusion;
|
|
1250
|
+
var keyTests = exclusion.tests;
|
|
1251
|
+
var testValue = keyTests[fieldName];
|
|
1252
|
+
// if test is skipped
|
|
1253
|
+
// no need to proceed
|
|
1254
|
+
if (testValue === false)
|
|
1255
|
+
return true;
|
|
1256
|
+
var isTestIncluded = testValue === true;
|
|
1257
|
+
// If inside a group
|
|
1258
|
+
if (groupName) {
|
|
1259
|
+
if (isGroupExcluded(groupName)) {
|
|
1260
|
+
return true; // field excluded by group
|
|
1261
|
+
// if group is `only`ed
|
|
1262
|
+
}
|
|
1263
|
+
else if (exclusion.groups[groupName] === true) {
|
|
1264
|
+
if (isTestIncluded)
|
|
1265
|
+
return false;
|
|
1266
|
+
// If there is _ANY_ `only`ed test (and we already know this one isn't)
|
|
1267
|
+
if (hasIncludedTests(keyTests))
|
|
1268
|
+
return true; // Excluded implicitly
|
|
1269
|
+
return keyTests[fieldName] === false;
|
|
1270
|
+
}
|
|
1271
|
+
}
|
|
1272
|
+
if (isMissingFromIncludedGroup(groupName)) {
|
|
1273
|
+
return true;
|
|
1274
|
+
}
|
|
1275
|
+
// if field is only'ed
|
|
1276
|
+
if (isTestIncluded)
|
|
1277
|
+
return false;
|
|
1278
|
+
// If there is _ANY_ `only`ed test (and we already know this one isn't) return true
|
|
1279
|
+
// Otherwise return false
|
|
1280
|
+
return hasIncludedTests(keyTests);
|
|
1281
|
+
}
|
|
1282
|
+
// eslint-disable-next-line max-statements
|
|
1283
|
+
function isMissingFromIncludedGroup(groupName) {
|
|
1284
|
+
var context$1 = context.useX();
|
|
1285
|
+
var exclusion = context$1.exclusion;
|
|
1286
|
+
if (!hasIncludedGroups()) {
|
|
1287
|
+
return false;
|
|
1288
|
+
}
|
|
1289
|
+
if (!groupName) {
|
|
1290
|
+
return true;
|
|
1291
|
+
}
|
|
1292
|
+
if (groupName in exclusion.groups) {
|
|
1293
|
+
if (exclusion.groups[groupName]) {
|
|
1294
|
+
return false;
|
|
1295
|
+
}
|
|
1296
|
+
return true;
|
|
1297
|
+
}
|
|
1298
|
+
return true;
|
|
1299
|
+
}
|
|
1300
|
+
function hasIncludedGroups() {
|
|
1301
|
+
var context$1 = context.useX();
|
|
1302
|
+
var exclusion = context$1.exclusion;
|
|
1303
|
+
for (var group in exclusion.groups) {
|
|
1304
|
+
if (exclusion.groups[group]) {
|
|
1305
|
+
return true;
|
|
1306
|
+
}
|
|
1307
|
+
}
|
|
1308
|
+
return false;
|
|
1309
|
+
}
|
|
1310
|
+
/**
|
|
1311
|
+
* Checks whether a given group is excluded from running.
|
|
1312
|
+
*/
|
|
1313
|
+
function isGroupExcluded(groupName) {
|
|
1314
|
+
var context$1 = context.useX();
|
|
1315
|
+
var exclusion = context$1.exclusion;
|
|
1316
|
+
var keyGroups = exclusion.groups;
|
|
1317
|
+
var groupPresent = hasOwnProperty(keyGroups, groupName);
|
|
1318
|
+
// When group is either only'ed or skipped
|
|
1319
|
+
if (groupPresent) {
|
|
1320
|
+
// Return true if group is skipped and false if only'ed
|
|
1321
|
+
return keyGroups[groupName] === false;
|
|
1322
|
+
}
|
|
1323
|
+
// Group is not present
|
|
1324
|
+
for (var group in keyGroups) {
|
|
1325
|
+
// If any other group is only'ed
|
|
1326
|
+
if (keyGroups[group] === true) {
|
|
1327
|
+
return true;
|
|
1328
|
+
}
|
|
1329
|
+
}
|
|
1330
|
+
return false;
|
|
1331
|
+
}
|
|
1332
|
+
/**
|
|
1333
|
+
* Adds fields to a specified exclusion group.
|
|
1334
|
+
*/
|
|
1335
|
+
function addTo(exclusionGroup, itemType, item) {
|
|
1336
|
+
var context$1 = context.useX(ERROR_HOOK_CALLED_OUTSIDE);
|
|
1337
|
+
if (!item) {
|
|
1338
|
+
return;
|
|
1339
|
+
}
|
|
1340
|
+
asArray(item).forEach(function (itemName) {
|
|
1341
|
+
if (!isStringValue(itemName)) {
|
|
1342
|
+
return;
|
|
1343
|
+
}
|
|
1344
|
+
context$1.exclusion[itemType][itemName] =
|
|
1345
|
+
exclusionGroup === 0 /* ONLY */;
|
|
1346
|
+
});
|
|
1347
|
+
}
|
|
1348
|
+
/**
|
|
1349
|
+
* Checks if context has included tests
|
|
1350
|
+
*/
|
|
1351
|
+
function hasIncludedTests(keyTests) {
|
|
1352
|
+
for (var test in keyTests) {
|
|
1353
|
+
if (keyTests[test] === true) {
|
|
1354
|
+
return true; // excluded implicitly
|
|
1355
|
+
}
|
|
1356
|
+
}
|
|
1357
|
+
return false;
|
|
1358
|
+
}
|
|
1359
|
+
|
|
1360
|
+
/**
|
|
1361
|
+
* Runs a group callback.
|
|
1362
|
+
*/
|
|
1363
|
+
function group(groupName, tests) {
|
|
1364
|
+
if (!isStringValue(groupName)) {
|
|
1365
|
+
throwGroupError('name must be a string');
|
|
1366
|
+
}
|
|
1367
|
+
if (!isFunction(tests)) {
|
|
1368
|
+
throwGroupError('callback must be a function');
|
|
1369
|
+
}
|
|
1370
|
+
// Running with the context applied
|
|
1371
|
+
isolate({ type: IsolateTypes.GROUP }, function () {
|
|
1372
|
+
context.run({ groupName: groupName }, tests);
|
|
1373
|
+
});
|
|
1374
|
+
}
|
|
1375
|
+
function throwGroupError(error) {
|
|
1376
|
+
throwError("Wrong arguments passed to group. Group " + error + ".");
|
|
1377
|
+
}
|
|
1378
|
+
|
|
1379
|
+
function optional(optionals) {
|
|
1380
|
+
var _a = useOptionalFields(), setOptionalFields = _a[1];
|
|
1381
|
+
setOptionalFields(function (state) {
|
|
1382
|
+
if (!isArray(optionals) && !isStringValue(optionals)) {
|
|
1383
|
+
var optionalFunctions = optionals;
|
|
1384
|
+
for (var field in optionalFunctions) {
|
|
1385
|
+
var predicate = optionalFunctions[field];
|
|
1386
|
+
state[field] = predicate;
|
|
1387
|
+
}
|
|
1388
|
+
}
|
|
1389
|
+
else {
|
|
1390
|
+
asArray(optionals).forEach(function (optionalField) {
|
|
1391
|
+
state[optionalField] = true;
|
|
1392
|
+
});
|
|
1393
|
+
}
|
|
1394
|
+
return state;
|
|
1395
|
+
});
|
|
1396
|
+
}
|
|
1397
|
+
|
|
1398
|
+
function skipWhen(conditional, callback) {
|
|
1399
|
+
isolate({ type: IsolateTypes.SKIP_WHEN }, function () {
|
|
1400
|
+
context.run({
|
|
1401
|
+
skipped: optionalFunctionValue(conditional, optionalFunctionValue(produceDraft))
|
|
1402
|
+
}, function () { return callback(); });
|
|
1403
|
+
});
|
|
1404
|
+
}
|
|
1405
|
+
|
|
1406
|
+
var isNotString = bindNot(isStringValue);
|
|
1407
|
+
|
|
1408
|
+
function isPromise(value) {
|
|
1409
|
+
return value && isFunction(value.then);
|
|
1410
|
+
}
|
|
1411
|
+
|
|
1412
|
+
function isSameProfileTest(testObject1, testObject2) {
|
|
1413
|
+
return (testObject1.fieldName === testObject2.fieldName &&
|
|
1414
|
+
testObject1.groupName === testObject2.groupName);
|
|
1415
|
+
}
|
|
1416
|
+
|
|
1417
|
+
function cancelOverriddenPendingTest(prevRunTestObject, currentRunTestObject) {
|
|
1418
|
+
if (currentRunTestObject !== prevRunTestObject &&
|
|
1419
|
+
isSameProfileTest(prevRunTestObject, currentRunTestObject) &&
|
|
1420
|
+
prevRunTestObject.isPending()) {
|
|
1421
|
+
prevRunTestObject.cancel();
|
|
1422
|
+
}
|
|
1423
|
+
}
|
|
1424
|
+
|
|
1425
|
+
/**
|
|
1426
|
+
* Runs async test.
|
|
1427
|
+
*/
|
|
1428
|
+
function runAsyncTest(testObject) {
|
|
1429
|
+
var asyncTest = testObject.asyncTest, message = testObject.message;
|
|
1430
|
+
if (!isPromise(asyncTest))
|
|
1431
|
+
return;
|
|
1432
|
+
var emit = useBus().emit;
|
|
1433
|
+
var stateRef = useStateRef();
|
|
1434
|
+
var done = context.bind({ stateRef: stateRef }, function () {
|
|
1435
|
+
// invalidating the "produce" cache
|
|
1436
|
+
useRefreshTestObjects();
|
|
1437
|
+
emit(Events.TEST_COMPLETED, testObject);
|
|
1438
|
+
});
|
|
1439
|
+
var fail = context.bind({ stateRef: stateRef }, function (rejectionMessage) {
|
|
1440
|
+
if (testObject.isCanceled()) {
|
|
1441
|
+
return;
|
|
1442
|
+
}
|
|
1443
|
+
testObject.message = isStringValue(rejectionMessage)
|
|
1444
|
+
? rejectionMessage
|
|
1445
|
+
: message;
|
|
1446
|
+
testObject.fail();
|
|
1447
|
+
done();
|
|
1448
|
+
});
|
|
1449
|
+
try {
|
|
1450
|
+
asyncTest.then(done, fail);
|
|
1451
|
+
}
|
|
1452
|
+
catch (e) {
|
|
1453
|
+
fail();
|
|
1454
|
+
}
|
|
1455
|
+
}
|
|
1456
|
+
|
|
1457
|
+
/**
|
|
1458
|
+
* Runs sync tests - or extracts promise.
|
|
1459
|
+
*/
|
|
1460
|
+
function runSyncTest(testObject) {
|
|
1461
|
+
return context.run({ currentTest: testObject }, function () {
|
|
1462
|
+
var result;
|
|
1463
|
+
try {
|
|
1464
|
+
result = testObject.testFn();
|
|
1465
|
+
}
|
|
1466
|
+
catch (e) {
|
|
1467
|
+
if (shouldUseErrorAsMessage(testObject.message, e)) {
|
|
1468
|
+
testObject.message = e;
|
|
1469
|
+
}
|
|
1470
|
+
result = false;
|
|
1471
|
+
}
|
|
1472
|
+
if (result === false) {
|
|
1473
|
+
testObject.fail();
|
|
1474
|
+
}
|
|
1475
|
+
return result;
|
|
1476
|
+
});
|
|
1477
|
+
}
|
|
1478
|
+
|
|
1479
|
+
/**
|
|
1480
|
+
* Registers test, if async - adds to pending array
|
|
1481
|
+
*/
|
|
1482
|
+
function registerTest(testObject) {
|
|
1483
|
+
var bus = useBus();
|
|
1484
|
+
// Run test callback.
|
|
1485
|
+
// If a promise is returned, set as async and
|
|
1486
|
+
// Move to pending list.
|
|
1487
|
+
var result = runSyncTest(testObject);
|
|
1488
|
+
try {
|
|
1489
|
+
// try catch for safe property access
|
|
1490
|
+
// in case object is an enforce chain
|
|
1491
|
+
if (isPromise(result)) {
|
|
1492
|
+
testObject.asyncTest = result;
|
|
1493
|
+
testObject.setPending();
|
|
1494
|
+
runAsyncTest(testObject);
|
|
1495
|
+
}
|
|
1496
|
+
else {
|
|
1497
|
+
bus.emit(Events.TEST_COMPLETED, testObject);
|
|
1498
|
+
}
|
|
1499
|
+
}
|
|
1500
|
+
catch (e) {
|
|
1501
|
+
throwError("Your test function " + testObject.fieldName + " returned a value. Only \"false\" or Promise returns are supported.");
|
|
1502
|
+
}
|
|
1503
|
+
}
|
|
1504
|
+
|
|
1505
|
+
/**
|
|
1506
|
+
* This module serves as the "collision detection" mechanism for Vest.
|
|
1507
|
+
* It is used to ensure that tests are not called in a different order than
|
|
1508
|
+
* they were called in the previous run.
|
|
1509
|
+
* If they are, it will throw a deferred error unless explicitly allowed.
|
|
1510
|
+
*
|
|
1511
|
+
* For now it seems pretty safe, and it covers most common use cases, but it can
|
|
1512
|
+
* be improved in the future both in terms of performance and scenarios it covers.
|
|
1513
|
+
*/
|
|
1514
|
+
// eslint-disable-next-line max-statements, max-lines-per-function
|
|
1515
|
+
function useTestAtCursor(newTestObject) {
|
|
1516
|
+
var testObjects = useTestObjects()[0];
|
|
1517
|
+
var prevTests = testObjects.prev;
|
|
1518
|
+
if (isEmpty(prevTests)) {
|
|
1519
|
+
useSetTestAtCursor(newTestObject);
|
|
1520
|
+
return newTestObject;
|
|
1521
|
+
}
|
|
1522
|
+
var prevTest = useGetTestAtCursor(prevTests);
|
|
1523
|
+
if (!isNullish(newTestObject.key)) {
|
|
1524
|
+
var nextTest_1 = handleKeyTest(newTestObject.key, newTestObject);
|
|
1525
|
+
useSetTestAtCursor(nextTest_1);
|
|
1526
|
+
return nextTest_1;
|
|
1527
|
+
}
|
|
1528
|
+
if (shouldPurgePrevTest(prevTest, newTestObject)) {
|
|
1529
|
+
throwTestOrderError(prevTest, newTestObject);
|
|
1530
|
+
removeAllNextTestsInIsolate();
|
|
1531
|
+
// Need to see if this has any effect at all.
|
|
1532
|
+
prevTest = null;
|
|
1533
|
+
}
|
|
1534
|
+
var nextTest = defaultTo(prevTest, newTestObject);
|
|
1535
|
+
useSetTestAtCursor(nextTest);
|
|
1536
|
+
return nextTest;
|
|
1537
|
+
}
|
|
1538
|
+
function removeAllNextTestsInIsolate() {
|
|
1539
|
+
var _a = useTestObjects(), testObjects = _a[0], setTestObjects = _a[1];
|
|
1540
|
+
var prevTests = testObjects.prev;
|
|
1541
|
+
var current = getCurrent(prevTests, usePath());
|
|
1542
|
+
var cursorAt = useCursorAt();
|
|
1543
|
+
current.splice(cursorAt);
|
|
1544
|
+
// We actually don't mind mutating the state directly (as can be seen above). There is no harm in it
|
|
1545
|
+
// since we're only touching the "prev" state. The reason we still use the setter function is
|
|
1546
|
+
// to prevent future headaches if we ever do need to rely on prev-state immutability.
|
|
1547
|
+
setTestObjects(function (_a) {
|
|
1548
|
+
var current = _a.current;
|
|
1549
|
+
return ({
|
|
1550
|
+
prev: prevTests,
|
|
1551
|
+
current: current
|
|
1552
|
+
});
|
|
1553
|
+
});
|
|
1554
|
+
}
|
|
1555
|
+
function useSetTestAtCursor(testObject) {
|
|
1556
|
+
var cursorPath = usePath();
|
|
1557
|
+
useSetTests(function (tests) {
|
|
1558
|
+
return setValueAtPath(tests, cursorPath, testObject);
|
|
1559
|
+
});
|
|
1560
|
+
}
|
|
1561
|
+
function useGetTestAtCursor(tests) {
|
|
1562
|
+
var cursorPath = usePath();
|
|
1563
|
+
return valueAtPath(tests, cursorPath);
|
|
1564
|
+
}
|
|
1565
|
+
function shouldPurgePrevTest(prevTest, newTest) {
|
|
1566
|
+
return isNotEmpty(prevTest) && !isSameProfileTest(prevTest, newTest);
|
|
1567
|
+
}
|
|
1568
|
+
function throwTestOrderError(prevTest, newTestObject) {
|
|
1569
|
+
if (shouldAllowReorder()) {
|
|
1570
|
+
return;
|
|
1571
|
+
}
|
|
1572
|
+
throwErrorDeferred("Vest Critical Error: Tests called in different order than previous run.\n expected: " + prevTest.fieldName + "\n received: " + newTestObject.fieldName + "\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.");
|
|
1573
|
+
}
|
|
1574
|
+
function handleKeyTest(key, newTestObject) {
|
|
1575
|
+
var prevTestByKey = usePrevTestByKey(key);
|
|
1576
|
+
var nextTest = newTestObject;
|
|
1577
|
+
if (prevTestByKey) {
|
|
1578
|
+
nextTest = prevTestByKey;
|
|
1579
|
+
}
|
|
1580
|
+
useRetainTestKey(key, nextTest);
|
|
1581
|
+
return nextTest;
|
|
1582
|
+
}
|
|
1583
|
+
|
|
1584
|
+
function registerPrevRunTest(testObject) {
|
|
1585
|
+
var prevRunTest = useTestAtCursor(testObject);
|
|
1586
|
+
if (isExcluded(testObject)) {
|
|
1587
|
+
// We're forcing skipping the pending test
|
|
1588
|
+
// if we're directly within a skipWhen block
|
|
1589
|
+
// This mostly means that we're probably giving
|
|
1590
|
+
// up on this async test intentionally.
|
|
1591
|
+
prevRunTest.skip(isExcludedIndividually());
|
|
1592
|
+
moveForward();
|
|
1593
|
+
return prevRunTest;
|
|
1594
|
+
}
|
|
1595
|
+
cancelOverriddenPendingTest(prevRunTest, testObject);
|
|
1596
|
+
useSetTestAtCursor(testObject);
|
|
1597
|
+
moveForward();
|
|
1598
|
+
registerTestObjectByTier(testObject);
|
|
1599
|
+
return testObject;
|
|
1600
|
+
}
|
|
1601
|
+
function registerTestObjectByTier(testObject) {
|
|
1602
|
+
if (testObject.isUntested()) {
|
|
1603
|
+
registerTest(testObject);
|
|
1604
|
+
}
|
|
1605
|
+
else if (isPromise(testObject.asyncTest)) {
|
|
1606
|
+
testObject.setPending();
|
|
1607
|
+
runAsyncTest(testObject);
|
|
1608
|
+
}
|
|
1609
|
+
}
|
|
1610
|
+
|
|
1611
|
+
// eslint-disable-next-line max-lines-per-function
|
|
1612
|
+
function bindTestMemo(test) {
|
|
1613
|
+
var cache = createCache(100); // arbitrary cache size
|
|
1614
|
+
// eslint-disable-next-line max-statements
|
|
1615
|
+
function memo(fieldName) {
|
|
1616
|
+
var args = [];
|
|
1617
|
+
for (var _i = 1; _i < arguments.length; _i++) {
|
|
1618
|
+
args[_i - 1] = arguments[_i];
|
|
1619
|
+
}
|
|
1620
|
+
var cursorAt = useCursorAt();
|
|
1621
|
+
var _a = args.reverse(), deps = _a[0], testFn = _a[1], msg = _a[2];
|
|
1622
|
+
// Implicit dependency for more specificity
|
|
1623
|
+
var dependencies = [useSuiteId(), fieldName, cursorAt].concat(deps);
|
|
1624
|
+
var cached = cache.get(dependencies);
|
|
1625
|
+
if (isNull(cached)) {
|
|
1626
|
+
// cache miss
|
|
1627
|
+
return cache(dependencies, function () { return test(fieldName, msg, testFn); });
|
|
1628
|
+
}
|
|
1629
|
+
if (cached[1].isCanceled()) {
|
|
1630
|
+
// cache hit, but test is canceled
|
|
1631
|
+
cache.invalidate(dependencies);
|
|
1632
|
+
return cache(dependencies, function () { return test(fieldName, msg, testFn); });
|
|
1633
|
+
}
|
|
1634
|
+
return registerPrevRunTest(cached[1]);
|
|
1635
|
+
}
|
|
1636
|
+
return memo;
|
|
1637
|
+
}
|
|
1638
|
+
|
|
1639
|
+
function testBase(fieldName) {
|
|
1640
|
+
var args = [];
|
|
1641
|
+
for (var _i = 1; _i < arguments.length; _i++) {
|
|
1642
|
+
args[_i - 1] = arguments[_i];
|
|
1643
|
+
}
|
|
1644
|
+
var _a = (isFunction(args[1]) ? args : __spreadArray([undefined], args)), message = _a[0], testFn = _a[1], key = _a[2];
|
|
1645
|
+
if (isNotString(fieldName)) {
|
|
1646
|
+
throwIncompatibleParamsError('fieldName', 'string');
|
|
1647
|
+
}
|
|
1648
|
+
if (!isFunction(testFn)) {
|
|
1649
|
+
throwIncompatibleParamsError('Test callback', 'function');
|
|
1650
|
+
}
|
|
1651
|
+
var context$1 = context.useX();
|
|
1652
|
+
var testObject = new VestTest(fieldName, testFn, {
|
|
1653
|
+
message: message,
|
|
1654
|
+
groupName: context$1.groupName,
|
|
1655
|
+
key: key
|
|
1656
|
+
});
|
|
1657
|
+
return registerPrevRunTest(testObject);
|
|
1658
|
+
}
|
|
1659
|
+
var test = assign(testBase, {
|
|
1660
|
+
memo: bindTestMemo(testBase)
|
|
1661
|
+
});
|
|
1662
|
+
function throwIncompatibleParamsError(name, expected) {
|
|
1663
|
+
throwError("Incompatible params passed to test function. " + name + " must be a " + expected);
|
|
1664
|
+
}
|
|
1665
|
+
|
|
1666
|
+
var ERROR_OUTSIDE_OF_TEST = "warn hook called outside of a test callback. It won't have an effect."
|
|
1667
|
+
;
|
|
1668
|
+
/**
|
|
1669
|
+
* Sets a running test to warn only mode.
|
|
1670
|
+
*/
|
|
1671
|
+
function warn() {
|
|
1672
|
+
var ctx = context.useX('warn ' + ERROR_HOOK_CALLED_OUTSIDE);
|
|
1673
|
+
if (!ctx.currentTest) {
|
|
1674
|
+
throwError(ERROR_OUTSIDE_OF_TEST);
|
|
1675
|
+
}
|
|
1676
|
+
ctx.currentTest.warn();
|
|
1677
|
+
}
|
|
1678
|
+
|
|
1679
|
+
var VERSION = "4.0.0-dev-1aae50";
|
|
1680
|
+
|
|
1681
|
+
Object.defineProperty(exports, 'enforce', {
|
|
1682
|
+
enumerable: true,
|
|
1683
|
+
get: function () {
|
|
1684
|
+
return n4s.enforce;
|
|
1685
|
+
}
|
|
1686
|
+
});
|
|
1687
|
+
exports.VERSION = VERSION;
|
|
1688
|
+
exports.create = create;
|
|
1689
|
+
exports.each = each;
|
|
1690
|
+
exports.group = group;
|
|
1691
|
+
exports.only = only;
|
|
1692
|
+
exports.optional = optional;
|
|
1693
|
+
exports.skip = skip;
|
|
1694
|
+
exports.skipWhen = skipWhen;
|
|
1695
|
+
exports.test = test;
|
|
1696
|
+
exports.warn = warn;
|
|
1697
|
+
|
|
1698
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
2203
1699
|
|
|
2204
1700
|
})));
|