vest 4.0.0-dev-366a8b → 4.0.0-dev-e266d9
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 -49
- 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 +608 -1097
- 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 +602 -1097
- 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 -2185
- 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
|
@@ -2,63 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
Permission to use, copy, modify, and/or distribute this software for any
|
|
9
|
-
purpose with or without fee is hereby granted.
|
|
10
|
-
|
|
11
|
-
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
12
|
-
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
13
|
-
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
14
|
-
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
15
|
-
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
16
|
-
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
17
|
-
PERFORMANCE OF THIS SOFTWARE.
|
|
18
|
-
***************************************************************************** */
|
|
19
|
-
|
|
20
|
-
var __assign = function() {
|
|
21
|
-
__assign = Object.assign || function __assign(t) {
|
|
22
|
-
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
23
|
-
s = arguments[i];
|
|
24
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
|
|
25
|
-
}
|
|
26
|
-
return t;
|
|
27
|
-
};
|
|
28
|
-
return __assign.apply(this, arguments);
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
function __spreadArray(to, from, pack) {
|
|
32
|
-
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
33
|
-
if (ar || !(i in from)) {
|
|
34
|
-
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
35
|
-
ar[i] = from[i];
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
return to.concat(ar || from);
|
|
39
|
-
}
|
|
5
|
+
var n4s = require('n4s');
|
|
6
|
+
var context$1 = require('context');
|
|
40
7
|
|
|
41
8
|
var assign = Object.assign;
|
|
42
9
|
|
|
10
|
+
/**
|
|
11
|
+
* @returns a unique numeric id.
|
|
12
|
+
*/
|
|
13
|
+
var genId = (function (n) { return function () {
|
|
14
|
+
return "" + n++;
|
|
15
|
+
}; })(0);
|
|
16
|
+
|
|
43
17
|
function isFunction(value) {
|
|
44
18
|
return typeof value === 'function';
|
|
45
19
|
}
|
|
46
20
|
|
|
47
|
-
function mapFirst(array, callback) {
|
|
48
|
-
var broke = false;
|
|
49
|
-
var breakoutValue = null;
|
|
50
|
-
for (var i = 0; i < array.length; i++) {
|
|
51
|
-
callback(array[i], breakout, i);
|
|
52
|
-
if (broke) {
|
|
53
|
-
return breakoutValue;
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
function breakout(value) {
|
|
57
|
-
broke = true;
|
|
58
|
-
breakoutValue = value;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
21
|
function optionalFunctionValue(value) {
|
|
63
22
|
var args = [];
|
|
64
23
|
for (var _i = 1; _i < arguments.length; _i++) {
|
|
@@ -72,380 +31,6 @@ function defaultTo(callback, defaultValue) {
|
|
|
72
31
|
return (_a = optionalFunctionValue(callback)) !== null && _a !== void 0 ? _a : defaultValue;
|
|
73
32
|
}
|
|
74
33
|
|
|
75
|
-
function ruleReturn(pass, message) {
|
|
76
|
-
var output = { pass: pass };
|
|
77
|
-
if (message) {
|
|
78
|
-
output.message = message;
|
|
79
|
-
}
|
|
80
|
-
return output;
|
|
81
|
-
}
|
|
82
|
-
function failing() {
|
|
83
|
-
return ruleReturn(false);
|
|
84
|
-
}
|
|
85
|
-
function passing() {
|
|
86
|
-
return ruleReturn(true);
|
|
87
|
-
}
|
|
88
|
-
function defaultToFailing(callback) {
|
|
89
|
-
return defaultTo(callback, failing());
|
|
90
|
-
}
|
|
91
|
-
function defaultToPassing(callback) {
|
|
92
|
-
return defaultTo(callback, passing());
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
function runLazyRule(lazyRule, currentValue) {
|
|
96
|
-
try {
|
|
97
|
-
return lazyRule.run(currentValue);
|
|
98
|
-
}
|
|
99
|
-
catch (_a) {
|
|
100
|
-
return failing();
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
function allOf(value) {
|
|
105
|
-
var rules = [];
|
|
106
|
-
for (var _i = 1; _i < arguments.length; _i++) {
|
|
107
|
-
rules[_i - 1] = arguments[_i];
|
|
108
|
-
}
|
|
109
|
-
return defaultToPassing(mapFirst(rules, function (rule, breakout) {
|
|
110
|
-
var res = runLazyRule(rule, value);
|
|
111
|
-
if (!res.pass) {
|
|
112
|
-
breakout(res);
|
|
113
|
-
}
|
|
114
|
-
}));
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
function anyOf(value) {
|
|
118
|
-
var rules = [];
|
|
119
|
-
for (var _i = 1; _i < arguments.length; _i++) {
|
|
120
|
-
rules[_i - 1] = arguments[_i];
|
|
121
|
-
}
|
|
122
|
-
return defaultToFailing(mapFirst(rules, function (rule, breakout) {
|
|
123
|
-
var res = runLazyRule(rule, value);
|
|
124
|
-
if (res.pass) {
|
|
125
|
-
breakout(res);
|
|
126
|
-
}
|
|
127
|
-
}));
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
function noneOf(value) {
|
|
131
|
-
var rules = [];
|
|
132
|
-
for (var _i = 1; _i < arguments.length; _i++) {
|
|
133
|
-
rules[_i - 1] = arguments[_i];
|
|
134
|
-
}
|
|
135
|
-
return defaultToPassing(mapFirst(rules, function (rule, breakout) {
|
|
136
|
-
var res = runLazyRule(rule, value);
|
|
137
|
-
if (res.pass) {
|
|
138
|
-
breakout(failing());
|
|
139
|
-
}
|
|
140
|
-
}));
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
function bindNot(fn) {
|
|
144
|
-
return function () {
|
|
145
|
-
var args = [];
|
|
146
|
-
for (var _i = 0; _i < arguments.length; _i++) {
|
|
147
|
-
args[_i] = arguments[_i];
|
|
148
|
-
}
|
|
149
|
-
return !fn.apply(void 0, args);
|
|
150
|
-
};
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
function lengthEquals(value, arg1) {
|
|
154
|
-
return value.length === Number(arg1);
|
|
155
|
-
}
|
|
156
|
-
var lengthNotEquals = bindNot(lengthEquals);
|
|
157
|
-
|
|
158
|
-
function longerThan(value, arg1) {
|
|
159
|
-
return value.length > Number(arg1);
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
function oneOf(value) {
|
|
163
|
-
var rules = [];
|
|
164
|
-
for (var _i = 1; _i < arguments.length; _i++) {
|
|
165
|
-
rules[_i - 1] = arguments[_i];
|
|
166
|
-
}
|
|
167
|
-
var passing = [];
|
|
168
|
-
rules.some(function (rule) {
|
|
169
|
-
if (longerThan(passing, 1)) {
|
|
170
|
-
return false;
|
|
171
|
-
}
|
|
172
|
-
var res = runLazyRule(rule, value);
|
|
173
|
-
if (res.pass) {
|
|
174
|
-
passing.push(res);
|
|
175
|
-
}
|
|
176
|
-
});
|
|
177
|
-
return ruleReturn(lengthEquals(passing, 1));
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
function isNull(value) {
|
|
181
|
-
return value === null;
|
|
182
|
-
}
|
|
183
|
-
var isNotNull = bindNot(isNull);
|
|
184
|
-
|
|
185
|
-
function isUndefined(value) {
|
|
186
|
-
return value === undefined;
|
|
187
|
-
}
|
|
188
|
-
var isNotUndefined = bindNot(isUndefined);
|
|
189
|
-
|
|
190
|
-
function optional$1(value, ruleChain) {
|
|
191
|
-
if (isUndefined(value) || isNull(value)) {
|
|
192
|
-
return passing();
|
|
193
|
-
}
|
|
194
|
-
return runLazyRule(ruleChain, value);
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
function compounds() {
|
|
198
|
-
return { allOf: allOf, anyOf: anyOf, noneOf: noneOf, oneOf: oneOf, optional: optional$1 };
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
function isStringValue(v) {
|
|
202
|
-
return String(v) === v;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
function endsWith(value, arg1) {
|
|
206
|
-
return isStringValue(value) && isStringValue(arg1) && value.endsWith(arg1);
|
|
207
|
-
}
|
|
208
|
-
var doesNotEndWith = bindNot(endsWith);
|
|
209
|
-
|
|
210
|
-
function equals(value, arg1) {
|
|
211
|
-
return value === arg1;
|
|
212
|
-
}
|
|
213
|
-
var notEquals = bindNot(equals);
|
|
214
|
-
|
|
215
|
-
function isNumeric(value) {
|
|
216
|
-
var str = String(value);
|
|
217
|
-
var num = Number(value);
|
|
218
|
-
var result = !isNaN(parseFloat(str)) && !isNaN(Number(value)) && isFinite(num);
|
|
219
|
-
return Boolean(result);
|
|
220
|
-
}
|
|
221
|
-
var isNotNumeric = bindNot(isNumeric);
|
|
222
|
-
|
|
223
|
-
function greaterThan(value, gt) {
|
|
224
|
-
return isNumeric(value) && isNumeric(gt) && Number(value) > Number(gt);
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
function greaterThanOrEquals(value, gte) {
|
|
228
|
-
return isNumeric(value) && isNumeric(gte) && Number(value) >= Number(gte);
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
// The module is named "isArrayValue" since it
|
|
232
|
-
// is conflicting with a nested npm dependency.
|
|
233
|
-
// We may need to revisit this in the future.
|
|
234
|
-
function isArray(value) {
|
|
235
|
-
return Boolean(Array.isArray(value));
|
|
236
|
-
}
|
|
237
|
-
var isNotArray = bindNot(isArray);
|
|
238
|
-
|
|
239
|
-
function inside(value, arg1) {
|
|
240
|
-
if (isArray(arg1)) {
|
|
241
|
-
return arg1.indexOf(value) !== -1;
|
|
242
|
-
}
|
|
243
|
-
// both value and arg1 are strings
|
|
244
|
-
if (isStringValue(arg1) && isStringValue(value)) {
|
|
245
|
-
return arg1.indexOf(value) !== -1;
|
|
246
|
-
}
|
|
247
|
-
return false;
|
|
248
|
-
}
|
|
249
|
-
var notInside = bindNot(inside);
|
|
250
|
-
|
|
251
|
-
function lessThanOrEquals(value, lte) {
|
|
252
|
-
return isNumeric(value) && isNumeric(lte) && Number(value) <= Number(lte);
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
function isBetween(value, min, max) {
|
|
256
|
-
return greaterThanOrEquals(value, min) && lessThanOrEquals(value, max);
|
|
257
|
-
}
|
|
258
|
-
var isNotBetween = bindNot(isBetween);
|
|
259
|
-
|
|
260
|
-
function isBlank(value) {
|
|
261
|
-
return isStringValue(value) && !value.trim();
|
|
262
|
-
}
|
|
263
|
-
var isNotBlank = bindNot(isBlank);
|
|
264
|
-
|
|
265
|
-
function isBoolean(value) {
|
|
266
|
-
return !!value === value;
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
var isNotBoolean = bindNot(isBoolean);
|
|
270
|
-
|
|
271
|
-
/**
|
|
272
|
-
* A safe hasOwnProperty access
|
|
273
|
-
*/
|
|
274
|
-
function hasOwnProperty(obj, key) {
|
|
275
|
-
return Object.prototype.hasOwnProperty.call(obj, key);
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
function isNumber(value) {
|
|
279
|
-
return Boolean(typeof value === 'number');
|
|
280
|
-
}
|
|
281
|
-
var isNotNumber = bindNot(isNumber);
|
|
282
|
-
|
|
283
|
-
function isEmpty(value) {
|
|
284
|
-
if (!value) {
|
|
285
|
-
return true;
|
|
286
|
-
}
|
|
287
|
-
else if (isNumber(value)) {
|
|
288
|
-
return value === 0;
|
|
289
|
-
}
|
|
290
|
-
else if (hasOwnProperty(value, 'length')) {
|
|
291
|
-
return lengthEquals(value, 0);
|
|
292
|
-
}
|
|
293
|
-
else if (typeof value === 'object') {
|
|
294
|
-
return lengthEquals(Object.keys(value), 0);
|
|
295
|
-
}
|
|
296
|
-
return true;
|
|
297
|
-
}
|
|
298
|
-
var isNotEmpty = bindNot(isEmpty);
|
|
299
|
-
|
|
300
|
-
/**
|
|
301
|
-
* Validates that a given value is an even number
|
|
302
|
-
*/
|
|
303
|
-
var isEven = function (value) {
|
|
304
|
-
if (isNumeric(value)) {
|
|
305
|
-
return value % 2 === 0;
|
|
306
|
-
}
|
|
307
|
-
return false;
|
|
308
|
-
};
|
|
309
|
-
|
|
310
|
-
function isNaN$1(value) {
|
|
311
|
-
return Number.isNaN(value);
|
|
312
|
-
}
|
|
313
|
-
var isNotNaN = bindNot(isNaN$1);
|
|
314
|
-
|
|
315
|
-
function isNegative(value) {
|
|
316
|
-
if (isNumeric(value)) {
|
|
317
|
-
return Number(value) < 0;
|
|
318
|
-
}
|
|
319
|
-
return false;
|
|
320
|
-
}
|
|
321
|
-
var isPositive = bindNot(isNegative);
|
|
322
|
-
|
|
323
|
-
/**
|
|
324
|
-
* Validates that a given value is an odd number
|
|
325
|
-
*/
|
|
326
|
-
var isOdd = function (value) {
|
|
327
|
-
if (isNumeric(value)) {
|
|
328
|
-
return value % 2 !== 0;
|
|
329
|
-
}
|
|
330
|
-
return false;
|
|
331
|
-
};
|
|
332
|
-
|
|
333
|
-
var isNotString = bindNot(isStringValue);
|
|
334
|
-
|
|
335
|
-
function isTruthy(value) {
|
|
336
|
-
return !!value;
|
|
337
|
-
}
|
|
338
|
-
var isFalsy = bindNot(isTruthy);
|
|
339
|
-
|
|
340
|
-
function lessThan(value, lt) {
|
|
341
|
-
return isNumeric(value) && isNumeric(lt) && Number(value) < Number(lt);
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
function longerThanOrEquals(value, arg1) {
|
|
345
|
-
return value.length >= Number(arg1);
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
function matches(value, regex) {
|
|
349
|
-
if (regex instanceof RegExp) {
|
|
350
|
-
return regex.test(value);
|
|
351
|
-
}
|
|
352
|
-
else if (isStringValue(regex)) {
|
|
353
|
-
return new RegExp(regex).test(value);
|
|
354
|
-
}
|
|
355
|
-
else {
|
|
356
|
-
return false;
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
var notMatches = bindNot(matches);
|
|
360
|
-
|
|
361
|
-
function numberEquals(value, eq) {
|
|
362
|
-
return isNumeric(value) && isNumeric(eq) && Number(value) === Number(eq);
|
|
363
|
-
}
|
|
364
|
-
var numberNotEquals = bindNot(numberEquals);
|
|
365
|
-
|
|
366
|
-
function condition(value, callback) {
|
|
367
|
-
try {
|
|
368
|
-
return callback(value);
|
|
369
|
-
}
|
|
370
|
-
catch (_a) {
|
|
371
|
-
return false;
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
function shorterThan(value, arg1) {
|
|
376
|
-
return value.length < Number(arg1);
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
function shorterThanOrEquals(value, arg1) {
|
|
380
|
-
return value.length <= Number(arg1);
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
function startsWith(value, arg1) {
|
|
384
|
-
return isStringValue(value) && isStringValue(arg1) && value.startsWith(arg1);
|
|
385
|
-
}
|
|
386
|
-
var doesNotStartWith = bindNot(startsWith);
|
|
387
|
-
|
|
388
|
-
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, max-lines-per-function
|
|
389
|
-
function rules() {
|
|
390
|
-
return {
|
|
391
|
-
condition: condition,
|
|
392
|
-
doesNotEndWith: doesNotEndWith,
|
|
393
|
-
doesNotStartWith: doesNotStartWith,
|
|
394
|
-
endsWith: endsWith,
|
|
395
|
-
equals: equals,
|
|
396
|
-
greaterThan: greaterThan,
|
|
397
|
-
greaterThanOrEquals: greaterThanOrEquals,
|
|
398
|
-
gt: greaterThan,
|
|
399
|
-
gte: greaterThanOrEquals,
|
|
400
|
-
inside: inside,
|
|
401
|
-
isArray: isArray,
|
|
402
|
-
isBetween: isBetween,
|
|
403
|
-
isBlank: isBlank,
|
|
404
|
-
isBoolean: isBoolean,
|
|
405
|
-
isEmpty: isEmpty,
|
|
406
|
-
isEven: isEven,
|
|
407
|
-
isFalsy: isFalsy,
|
|
408
|
-
isNaN: isNaN$1,
|
|
409
|
-
isNegative: isNegative,
|
|
410
|
-
isNotArray: isNotArray,
|
|
411
|
-
isNotBetween: isNotBetween,
|
|
412
|
-
isNotBlank: isNotBlank,
|
|
413
|
-
isNotBoolean: isNotBoolean,
|
|
414
|
-
isNotEmpty: isNotEmpty,
|
|
415
|
-
isNotNaN: isNotNaN,
|
|
416
|
-
isNotNull: isNotNull,
|
|
417
|
-
isNotNumber: isNotNumber,
|
|
418
|
-
isNotNumeric: isNotNumeric,
|
|
419
|
-
isNotString: isNotString,
|
|
420
|
-
isNotUndefined: isNotUndefined,
|
|
421
|
-
isNull: isNull,
|
|
422
|
-
isNumber: isNumber,
|
|
423
|
-
isNumeric: isNumeric,
|
|
424
|
-
isOdd: isOdd,
|
|
425
|
-
isPositive: isPositive,
|
|
426
|
-
isString: isStringValue,
|
|
427
|
-
isTruthy: isTruthy,
|
|
428
|
-
isUndefined: isUndefined,
|
|
429
|
-
lengthEquals: lengthEquals,
|
|
430
|
-
lengthNotEquals: lengthNotEquals,
|
|
431
|
-
lessThan: lessThan,
|
|
432
|
-
lessThanOrEquals: lessThanOrEquals,
|
|
433
|
-
longerThan: longerThan,
|
|
434
|
-
longerThanOrEquals: longerThanOrEquals,
|
|
435
|
-
lt: lessThan,
|
|
436
|
-
lte: lessThanOrEquals,
|
|
437
|
-
matches: matches,
|
|
438
|
-
notEquals: notEquals,
|
|
439
|
-
notInside: notInside,
|
|
440
|
-
notMatches: notMatches,
|
|
441
|
-
numberEquals: numberEquals,
|
|
442
|
-
numberNotEquals: numberNotEquals,
|
|
443
|
-
shorterThan: shorterThan,
|
|
444
|
-
shorterThanOrEquals: shorterThanOrEquals,
|
|
445
|
-
startsWith: startsWith
|
|
446
|
-
};
|
|
447
|
-
}
|
|
448
|
-
|
|
449
34
|
/**
|
|
450
35
|
* Throws a timed out error.
|
|
451
36
|
*/
|
|
@@ -458,349 +43,6 @@ function throwErrorDeferred(devMessage, productionMessage) {
|
|
|
458
43
|
}, 0);
|
|
459
44
|
}
|
|
460
45
|
|
|
461
|
-
// eslint-disable-next-line max-lines-per-function
|
|
462
|
-
function createContext(init) {
|
|
463
|
-
var storage = { ancestry: [] };
|
|
464
|
-
return {
|
|
465
|
-
bind: bind,
|
|
466
|
-
run: run,
|
|
467
|
-
use: use,
|
|
468
|
-
useX: useX
|
|
469
|
-
};
|
|
470
|
-
function useX(errorMessage) {
|
|
471
|
-
var _a;
|
|
472
|
-
return ((_a = storage.ctx) !== null && _a !== void 0 ? _a : throwError(defaultTo(errorMessage, 'Context was used after it was closed')));
|
|
473
|
-
}
|
|
474
|
-
function run(ctxRef, fn) {
|
|
475
|
-
var _a;
|
|
476
|
-
var parentContext = use();
|
|
477
|
-
var out = assign({}, parentContext ? parentContext : {}, (_a = init === null || init === void 0 ? void 0 : init(ctxRef, parentContext)) !== null && _a !== void 0 ? _a : ctxRef);
|
|
478
|
-
var ctx = set(Object.freeze(out));
|
|
479
|
-
storage.ancestry.unshift(ctx);
|
|
480
|
-
var res = fn(ctx);
|
|
481
|
-
clear();
|
|
482
|
-
return res;
|
|
483
|
-
}
|
|
484
|
-
function bind(ctxRef, fn) {
|
|
485
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
486
|
-
// @ts-ignore - this one's pretty hard to get right
|
|
487
|
-
var returnedFn = function () {
|
|
488
|
-
var runTimeArgs = [];
|
|
489
|
-
for (var _i = 0; _i < arguments.length; _i++) {
|
|
490
|
-
runTimeArgs[_i] = arguments[_i];
|
|
491
|
-
}
|
|
492
|
-
return run(ctxRef, function () {
|
|
493
|
-
return fn.apply(void 0, runTimeArgs);
|
|
494
|
-
});
|
|
495
|
-
};
|
|
496
|
-
return returnedFn;
|
|
497
|
-
}
|
|
498
|
-
function use() {
|
|
499
|
-
return storage.ctx;
|
|
500
|
-
}
|
|
501
|
-
function set(value) {
|
|
502
|
-
return (storage.ctx = value);
|
|
503
|
-
}
|
|
504
|
-
function clear() {
|
|
505
|
-
var _a;
|
|
506
|
-
storage.ancestry.shift();
|
|
507
|
-
set((_a = storage.ancestry[0]) !== null && _a !== void 0 ? _a : null);
|
|
508
|
-
}
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
var ctx$1 = createContext(function (ctxRef, parentContext) {
|
|
512
|
-
var base = {
|
|
513
|
-
value: ctxRef.value,
|
|
514
|
-
meta: ctxRef.meta || {}
|
|
515
|
-
};
|
|
516
|
-
if (!parentContext) {
|
|
517
|
-
return assign(base, {
|
|
518
|
-
parent: emptyParent
|
|
519
|
-
});
|
|
520
|
-
}
|
|
521
|
-
else if (ctxRef.set) {
|
|
522
|
-
return assign(base, {
|
|
523
|
-
parent: function () { return stripContext(parentContext); }
|
|
524
|
-
});
|
|
525
|
-
}
|
|
526
|
-
return parentContext;
|
|
527
|
-
});
|
|
528
|
-
function stripContext(ctx) {
|
|
529
|
-
if (!ctx) {
|
|
530
|
-
return ctx;
|
|
531
|
-
}
|
|
532
|
-
return {
|
|
533
|
-
value: ctx.value,
|
|
534
|
-
meta: ctx.meta,
|
|
535
|
-
parent: ctx.parent
|
|
536
|
-
};
|
|
537
|
-
}
|
|
538
|
-
function emptyParent() {
|
|
539
|
-
return null;
|
|
540
|
-
}
|
|
541
|
-
|
|
542
|
-
function isArrayOf(inputArray, currentRule) {
|
|
543
|
-
return defaultToPassing(mapFirst(inputArray, function (currentValue, breakout, index) {
|
|
544
|
-
var res = ctx$1.run({ value: currentValue, set: true, meta: { index: index } }, function () { return runLazyRule(currentRule, currentValue); });
|
|
545
|
-
if (!res.pass) {
|
|
546
|
-
breakout(res);
|
|
547
|
-
}
|
|
548
|
-
}));
|
|
549
|
-
}
|
|
550
|
-
|
|
551
|
-
function loose(inputObject, shapeObject) {
|
|
552
|
-
var _loop_1 = function (key) {
|
|
553
|
-
var currentValue = inputObject[key];
|
|
554
|
-
var currentRule = shapeObject[key];
|
|
555
|
-
var res = ctx$1.run({ value: currentValue, set: true, meta: { key: key } }, function () {
|
|
556
|
-
return runLazyRule(currentRule, currentValue);
|
|
557
|
-
});
|
|
558
|
-
if (!res.pass) {
|
|
559
|
-
return { value: res };
|
|
560
|
-
}
|
|
561
|
-
};
|
|
562
|
-
for (var key in shapeObject) {
|
|
563
|
-
var state_1 = _loop_1(key);
|
|
564
|
-
if (typeof state_1 === "object")
|
|
565
|
-
return state_1.value;
|
|
566
|
-
}
|
|
567
|
-
return passing();
|
|
568
|
-
}
|
|
569
|
-
|
|
570
|
-
function shape(inputObject, shapeObject) {
|
|
571
|
-
var baseRes = loose(inputObject, shapeObject);
|
|
572
|
-
if (!baseRes.pass) {
|
|
573
|
-
return baseRes;
|
|
574
|
-
}
|
|
575
|
-
for (var key in inputObject) {
|
|
576
|
-
if (!hasOwnProperty(shapeObject, key)) {
|
|
577
|
-
return failing();
|
|
578
|
-
}
|
|
579
|
-
}
|
|
580
|
-
return passing();
|
|
581
|
-
}
|
|
582
|
-
|
|
583
|
-
function schema() {
|
|
584
|
-
return { shape: shape, loose: loose, isArrayOf: isArrayOf };
|
|
585
|
-
}
|
|
586
|
-
|
|
587
|
-
var baseRules = assign(rules(), compounds(), schema());
|
|
588
|
-
function getRule(ruleName) {
|
|
589
|
-
return baseRules[ruleName];
|
|
590
|
-
}
|
|
591
|
-
|
|
592
|
-
function eachEnforceRule(action) {
|
|
593
|
-
for (var ruleName in baseRules) {
|
|
594
|
-
var ruleFn = getRule(ruleName);
|
|
595
|
-
if (isFunction(ruleFn)) {
|
|
596
|
-
action(ruleName, ruleFn);
|
|
597
|
-
}
|
|
598
|
-
}
|
|
599
|
-
}
|
|
600
|
-
|
|
601
|
-
function isProxySupported() {
|
|
602
|
-
try {
|
|
603
|
-
return typeof Proxy === 'function';
|
|
604
|
-
}
|
|
605
|
-
catch (_a) {
|
|
606
|
-
return false;
|
|
607
|
-
}
|
|
608
|
-
}
|
|
609
|
-
|
|
610
|
-
/**
|
|
611
|
-
* Transform the result of a rule into a standard format
|
|
612
|
-
*/
|
|
613
|
-
function transformResult(result, ruleName, value) {
|
|
614
|
-
var args = [];
|
|
615
|
-
for (var _i = 3; _i < arguments.length; _i++) {
|
|
616
|
-
args[_i - 3] = arguments[_i];
|
|
617
|
-
}
|
|
618
|
-
validateResult(result);
|
|
619
|
-
// if result is boolean
|
|
620
|
-
if (isBoolean(result)) {
|
|
621
|
-
return ruleReturn(result);
|
|
622
|
-
}
|
|
623
|
-
else {
|
|
624
|
-
return ruleReturn(result.pass, optionalFunctionValue.apply(void 0, __spreadArray([result.message, ruleName, value], args)));
|
|
625
|
-
}
|
|
626
|
-
}
|
|
627
|
-
function validateResult(result) {
|
|
628
|
-
// if result is boolean, or if result.pass is boolean
|
|
629
|
-
if (isBoolean(result) || (result && isBoolean(result.pass))) {
|
|
630
|
-
return;
|
|
631
|
-
}
|
|
632
|
-
throwError('Incorrect return value for rule: ' + JSON.stringify(result));
|
|
633
|
-
}
|
|
634
|
-
|
|
635
|
-
function enforceEager(value) {
|
|
636
|
-
var target = {};
|
|
637
|
-
if (!isProxySupported()) {
|
|
638
|
-
eachEnforceRule(function (ruleName, ruleFn) {
|
|
639
|
-
target[ruleName] = genRuleCall(target, ruleFn, ruleName);
|
|
640
|
-
});
|
|
641
|
-
return target;
|
|
642
|
-
}
|
|
643
|
-
var proxy = new Proxy(target, {
|
|
644
|
-
get: function (_, ruleName) {
|
|
645
|
-
var rule = getRule(ruleName);
|
|
646
|
-
if (rule) {
|
|
647
|
-
return genRuleCall(proxy, rule, ruleName);
|
|
648
|
-
}
|
|
649
|
-
}
|
|
650
|
-
});
|
|
651
|
-
return proxy;
|
|
652
|
-
function genRuleCall(target, rule, ruleName) {
|
|
653
|
-
return function ruleCall() {
|
|
654
|
-
var args = [];
|
|
655
|
-
for (var _i = 0; _i < arguments.length; _i++) {
|
|
656
|
-
args[_i] = arguments[_i];
|
|
657
|
-
}
|
|
658
|
-
var transformedResult = transformResult.apply(void 0, __spreadArray([ctx$1.run({ value: value }, function () { return rule.apply(void 0, __spreadArray([value], args)); }),
|
|
659
|
-
ruleName,
|
|
660
|
-
value], args));
|
|
661
|
-
if (!transformedResult.pass) {
|
|
662
|
-
if (isEmpty(transformedResult.message)) {
|
|
663
|
-
throwError("enforce/" + ruleName + " failed with " + JSON.stringify(value));
|
|
664
|
-
}
|
|
665
|
-
else {
|
|
666
|
-
// Explicitly throw a string so that vest.test can pick it up as the validation error message
|
|
667
|
-
throw transformedResult.message;
|
|
668
|
-
}
|
|
669
|
-
}
|
|
670
|
-
return target;
|
|
671
|
-
};
|
|
672
|
-
}
|
|
673
|
-
}
|
|
674
|
-
|
|
675
|
-
// eslint-disable-next-line max-lines-per-function
|
|
676
|
-
function genEnforceLazy(key) {
|
|
677
|
-
var registeredRules = [];
|
|
678
|
-
var lazyMessage;
|
|
679
|
-
return addLazyRule(key);
|
|
680
|
-
// eslint-disable-next-line max-lines-per-function
|
|
681
|
-
function addLazyRule(ruleName) {
|
|
682
|
-
// eslint-disable-next-line max-lines-per-function
|
|
683
|
-
return function () {
|
|
684
|
-
var args = [];
|
|
685
|
-
for (var _i = 0; _i < arguments.length; _i++) {
|
|
686
|
-
args[_i] = arguments[_i];
|
|
687
|
-
}
|
|
688
|
-
var rule = getRule(ruleName);
|
|
689
|
-
registeredRules.push(function (value) {
|
|
690
|
-
return transformResult.apply(void 0, __spreadArray([rule.apply(void 0, __spreadArray([value], args)), ruleName, value], args));
|
|
691
|
-
});
|
|
692
|
-
var proxy = {
|
|
693
|
-
run: function (value) {
|
|
694
|
-
return defaultToPassing(mapFirst(registeredRules, function (rule, breakout) {
|
|
695
|
-
var _a;
|
|
696
|
-
var res = ctx$1.run({ value: value }, function () { return rule(value); });
|
|
697
|
-
if (!res.pass) {
|
|
698
|
-
breakout(ruleReturn(!!res.pass, (_a = optionalFunctionValue(lazyMessage, value, res.message)) !== null && _a !== void 0 ? _a : res.message));
|
|
699
|
-
}
|
|
700
|
-
}));
|
|
701
|
-
},
|
|
702
|
-
test: function (value) { return proxy.run(value).pass; },
|
|
703
|
-
message: function (message) {
|
|
704
|
-
if (message) {
|
|
705
|
-
lazyMessage = message;
|
|
706
|
-
}
|
|
707
|
-
return proxy;
|
|
708
|
-
}
|
|
709
|
-
};
|
|
710
|
-
if (!isProxySupported()) {
|
|
711
|
-
eachEnforceRule(function (ruleName) {
|
|
712
|
-
proxy[ruleName] = addLazyRule(ruleName);
|
|
713
|
-
});
|
|
714
|
-
return proxy;
|
|
715
|
-
}
|
|
716
|
-
// reassigning the proxy here is not pretty
|
|
717
|
-
// but it's a cleaner way of getting `run` and `test` for free
|
|
718
|
-
proxy = new Proxy(proxy, {
|
|
719
|
-
get: function (target, key) {
|
|
720
|
-
if (getRule(key)) {
|
|
721
|
-
return addLazyRule(key);
|
|
722
|
-
}
|
|
723
|
-
return target[key]; // already has `run` and `test` on it
|
|
724
|
-
}
|
|
725
|
-
});
|
|
726
|
-
return proxy;
|
|
727
|
-
};
|
|
728
|
-
}
|
|
729
|
-
}
|
|
730
|
-
|
|
731
|
-
// Help needed improving the typings of this file.
|
|
732
|
-
// Ideally, we'd be able to extend TShapeObject, but that's not possible.
|
|
733
|
-
function partial(shapeObject) {
|
|
734
|
-
var output = {};
|
|
735
|
-
for (var key in shapeObject) {
|
|
736
|
-
output[key] = enforce.optional(shapeObject[key]);
|
|
737
|
-
}
|
|
738
|
-
return output;
|
|
739
|
-
}
|
|
740
|
-
|
|
741
|
-
function modifiers() {
|
|
742
|
-
return { partial: partial };
|
|
743
|
-
}
|
|
744
|
-
|
|
745
|
-
/**
|
|
746
|
-
* Enforce is quite complicated, I want to explain it in detail.
|
|
747
|
-
* It is dynamic in nature, so a lot of proxy objects are involved.
|
|
748
|
-
*
|
|
749
|
-
* Enforce has two main interfaces
|
|
750
|
-
* 1. eager
|
|
751
|
-
* 2. lazy
|
|
752
|
-
*
|
|
753
|
-
* The eager interface is the most commonly used, and the easier to understand.
|
|
754
|
-
* It throws an error when a rule is not satisfied.
|
|
755
|
-
* The eager interface is declared in enforceEager.ts and it is quite simple to understand.
|
|
756
|
-
* enforce is called with a value, and the return value is a proxy object that points back to all the rules.
|
|
757
|
-
* When a rule is called, the value is mapped as its first argument, and if the rule passes, the same
|
|
758
|
-
* proxy object is returned. Otherwise, an error is thrown.
|
|
759
|
-
*
|
|
760
|
-
* The lazy interface works quite differently. It is declared in genEnforceLazy.ts.
|
|
761
|
-
* Rather than calling enforce directly, the lazy interface has all the rules as "methods" (only by proxy).
|
|
762
|
-
* Calling the first function in the chain will initialize an array of calls. It stores the different rule calls
|
|
763
|
-
* and the parameters passed to them. None of the rules are called yet.
|
|
764
|
-
* The rules are only invoked in sequence once either of these chained functions are called:
|
|
765
|
-
* 1. test(value)
|
|
766
|
-
* 2. run(value)
|
|
767
|
-
*
|
|
768
|
-
* Calling run or test will call all the rules in sequence, with the difference that test will only return a boolean value,
|
|
769
|
-
* while run will return an object with the validation result and an optional message created by the rule.
|
|
770
|
-
*/
|
|
771
|
-
function genEnforce() {
|
|
772
|
-
var target = __assign({ context: function () { return ctx$1.useX(); }, extend: function (customRules) {
|
|
773
|
-
assign(baseRules, customRules);
|
|
774
|
-
} }, modifiers());
|
|
775
|
-
if (!isProxySupported()) {
|
|
776
|
-
eachEnforceRule(function (ruleName) {
|
|
777
|
-
// Only on the first rule access - start the chain of calls
|
|
778
|
-
target[ruleName] = genEnforceLazy(ruleName);
|
|
779
|
-
});
|
|
780
|
-
return target;
|
|
781
|
-
}
|
|
782
|
-
return new Proxy(assign(enforceEager, target), {
|
|
783
|
-
get: function (target, key) {
|
|
784
|
-
if (key in target) {
|
|
785
|
-
return target[key];
|
|
786
|
-
}
|
|
787
|
-
if (!getRule(key)) {
|
|
788
|
-
return;
|
|
789
|
-
}
|
|
790
|
-
// Only on the first rule access - start the chain of calls
|
|
791
|
-
return genEnforceLazy(key);
|
|
792
|
-
}
|
|
793
|
-
});
|
|
794
|
-
}
|
|
795
|
-
var enforce = genEnforce();
|
|
796
|
-
|
|
797
|
-
/**
|
|
798
|
-
* @returns a unique numeric id.
|
|
799
|
-
*/
|
|
800
|
-
var genId = (function (n) { return function () {
|
|
801
|
-
return "" + n++;
|
|
802
|
-
}; })(0);
|
|
803
|
-
|
|
804
46
|
// eslint-disable-next-line max-lines-per-function
|
|
805
47
|
function createState(onStateChange) {
|
|
806
48
|
var state = {
|
|
@@ -875,17 +117,18 @@ var IsolateTypes;
|
|
|
875
117
|
})(IsolateTypes || (IsolateTypes = {}));
|
|
876
118
|
|
|
877
119
|
function createStateRef(state, _a) {
|
|
878
|
-
var suiteId = _a.suiteId;
|
|
120
|
+
var suiteId = _a.suiteId, suiteName = _a.suiteName;
|
|
879
121
|
return {
|
|
880
122
|
optionalFields: state.registerStateKey(function () { return ({}); }),
|
|
881
123
|
suiteId: state.registerStateKey(suiteId),
|
|
124
|
+
suiteName: state.registerStateKey(suiteName),
|
|
882
125
|
testCallbacks: state.registerStateKey(function () { return ({
|
|
883
126
|
fieldCallbacks: {},
|
|
884
127
|
doneCallbacks: []
|
|
885
128
|
}); }),
|
|
886
129
|
testObjects: state.registerStateKey(function (prev) {
|
|
887
130
|
return {
|
|
888
|
-
prev:
|
|
131
|
+
prev: prev ? prev.current : [],
|
|
889
132
|
current: []
|
|
890
133
|
};
|
|
891
134
|
})
|
|
@@ -898,8 +141,7 @@ function asArray(possibleArg) {
|
|
|
898
141
|
|
|
899
142
|
function last(values) {
|
|
900
143
|
var valuesArray = asArray(values);
|
|
901
|
-
|
|
902
|
-
return lastValue;
|
|
144
|
+
return valuesArray[valuesArray.length - 1];
|
|
903
145
|
}
|
|
904
146
|
|
|
905
147
|
function createCursor() {
|
|
@@ -936,36 +178,62 @@ function createCursor() {
|
|
|
936
178
|
};
|
|
937
179
|
}
|
|
938
180
|
|
|
939
|
-
var
|
|
940
|
-
return parentContext
|
|
941
|
-
? null
|
|
942
|
-
: assign({}, {
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
}
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
181
|
+
var context = context$1.createContext(function (ctxRef, parentContext) {
|
|
182
|
+
return parentContext
|
|
183
|
+
? null
|
|
184
|
+
: assign({}, {
|
|
185
|
+
exclusion: {
|
|
186
|
+
tests: {},
|
|
187
|
+
groups: {}
|
|
188
|
+
},
|
|
189
|
+
isolate: {
|
|
190
|
+
type: IsolateTypes.DEFAULT,
|
|
191
|
+
keys: {
|
|
192
|
+
current: {},
|
|
193
|
+
prev: {}
|
|
194
|
+
}
|
|
195
|
+
},
|
|
196
|
+
testCursor: createCursor()
|
|
197
|
+
}, ctxRef);
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
function bindNot(fn) {
|
|
201
|
+
return function () {
|
|
202
|
+
var args = [];
|
|
203
|
+
for (var _i = 0; _i < arguments.length; _i++) {
|
|
204
|
+
args[_i] = arguments[_i];
|
|
205
|
+
}
|
|
206
|
+
return !fn.apply(void 0, args);
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// The module is named "isArrayValue" since it
|
|
211
|
+
// is conflicting with a nested npm dependency.
|
|
212
|
+
// We may need to revisit this in the future.
|
|
213
|
+
function isArray(value) {
|
|
214
|
+
return Boolean(Array.isArray(value));
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
function isNull(value) {
|
|
218
|
+
return value === null;
|
|
959
219
|
}
|
|
960
|
-
|
|
220
|
+
var isNotNull = bindNot(isNull);
|
|
221
|
+
|
|
222
|
+
// This is sort of a map/filter in one function.
|
|
223
|
+
// Normally, behaves like a nested-array map
|
|
224
|
+
// Returning `null` will drop the element from the array
|
|
225
|
+
function transform(array, cb) {
|
|
961
226
|
var res = [];
|
|
962
227
|
for (var _i = 0, array_1 = array; _i < array_1.length; _i++) {
|
|
963
228
|
var v = array_1[_i];
|
|
964
229
|
if (isArray(v)) {
|
|
965
|
-
res.push(
|
|
230
|
+
res.push(transform(v, cb));
|
|
966
231
|
}
|
|
967
|
-
else
|
|
968
|
-
|
|
232
|
+
else {
|
|
233
|
+
var output = cb(v);
|
|
234
|
+
if (isNotNull(output)) {
|
|
235
|
+
res.push(output);
|
|
236
|
+
}
|
|
969
237
|
}
|
|
970
238
|
}
|
|
971
239
|
return res;
|
|
@@ -986,11 +254,6 @@ function flatten(values) {
|
|
|
986
254
|
return asArray(acc).concat(value);
|
|
987
255
|
}, []);
|
|
988
256
|
}
|
|
989
|
-
function removeAtPath(array, path) {
|
|
990
|
-
var current = getCurrent(array, path);
|
|
991
|
-
current.splice(path[last(path)], 1);
|
|
992
|
-
return array;
|
|
993
|
-
}
|
|
994
257
|
function getCurrent(array, path) {
|
|
995
258
|
var current = array;
|
|
996
259
|
for (var _i = 0, _a = path.slice(0, -1); _i < _a.length; _i++) {
|
|
@@ -1001,6 +264,31 @@ function getCurrent(array, path) {
|
|
|
1001
264
|
return current;
|
|
1002
265
|
}
|
|
1003
266
|
|
|
267
|
+
function isUndefined(value) {
|
|
268
|
+
return value === undefined;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
function isNullish(value) {
|
|
272
|
+
return isNull(value) || isUndefined(value);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
function isStringValue(v) {
|
|
276
|
+
return String(v) === v;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
function shouldUseErrorAsMessage(message, error) {
|
|
280
|
+
// kind of cheating with this safe guard, but it does the job
|
|
281
|
+
return isUndefined(message) && isStringValue(error);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
function lengthEquals(value, arg1) {
|
|
285
|
+
return value.length === Number(arg1);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
function longerThan(value, arg1) {
|
|
289
|
+
return value.length > Number(arg1);
|
|
290
|
+
}
|
|
291
|
+
|
|
1004
292
|
/**
|
|
1005
293
|
* Creates a cache function
|
|
1006
294
|
*/
|
|
@@ -1042,11 +330,14 @@ function createCache(maxSize) {
|
|
|
1042
330
|
// STATE REF
|
|
1043
331
|
function useStateRef() {
|
|
1044
332
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
1045
|
-
return
|
|
333
|
+
return context.useX().stateRef; // I should revisit this
|
|
1046
334
|
}
|
|
1047
335
|
// STATE KEYS
|
|
1048
336
|
function useSuiteId() {
|
|
1049
|
-
return useStateRef().suiteId();
|
|
337
|
+
return useStateRef().suiteId()[0];
|
|
338
|
+
}
|
|
339
|
+
function useSuiteName() {
|
|
340
|
+
return useStateRef().suiteName()[0];
|
|
1050
341
|
}
|
|
1051
342
|
function useTestCallbacks() {
|
|
1052
343
|
return useStateRef().testCallbacks();
|
|
@@ -1081,7 +372,9 @@ function useSetTests(handler) {
|
|
|
1081
372
|
// Derived state
|
|
1082
373
|
function useAllIncomplete() {
|
|
1083
374
|
var current = useTestObjects()[0].current;
|
|
1084
|
-
return flatten(
|
|
375
|
+
return flatten(transform(current, function (testObject) {
|
|
376
|
+
return testObject.isPending() ? testObject : null;
|
|
377
|
+
}));
|
|
1085
378
|
}
|
|
1086
379
|
function useOmittedFields() {
|
|
1087
380
|
var testObjects = useTestsFlat();
|
|
@@ -1101,25 +394,187 @@ function useTestsFlat() {
|
|
|
1101
394
|
return flatCache([current], function () { return flatten(current); });
|
|
1102
395
|
}
|
|
1103
396
|
|
|
397
|
+
var TestSeverity;
|
|
398
|
+
(function (TestSeverity) {
|
|
399
|
+
TestSeverity["Error"] = "error";
|
|
400
|
+
TestSeverity["Warning"] = "warning";
|
|
401
|
+
})(TestSeverity || (TestSeverity = {}));
|
|
402
|
+
var VestTest = /** @class */ (function () {
|
|
403
|
+
function VestTest(fieldName, testFn, _a) {
|
|
404
|
+
var _b = _a === void 0 ? {} : _a, message = _b.message, groupName = _b.groupName, key = _b.key;
|
|
405
|
+
this.key = null;
|
|
406
|
+
this.id = genId();
|
|
407
|
+
this.severity = TestSeverity.Error;
|
|
408
|
+
this.status = STATUS_UNTESTED;
|
|
409
|
+
this.fieldName = fieldName;
|
|
410
|
+
this.testFn = testFn;
|
|
411
|
+
if (groupName) {
|
|
412
|
+
this.groupName = groupName;
|
|
413
|
+
}
|
|
414
|
+
if (message) {
|
|
415
|
+
this.message = message;
|
|
416
|
+
}
|
|
417
|
+
if (key) {
|
|
418
|
+
this.key = key;
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
VestTest.prototype.run = function () {
|
|
422
|
+
var result;
|
|
423
|
+
try {
|
|
424
|
+
result = this.testFn();
|
|
425
|
+
}
|
|
426
|
+
catch (error) {
|
|
427
|
+
if (shouldUseErrorAsMessage(this.message, error)) {
|
|
428
|
+
this.message = error;
|
|
429
|
+
}
|
|
430
|
+
result = false;
|
|
431
|
+
}
|
|
432
|
+
if (result === false) {
|
|
433
|
+
this.fail();
|
|
434
|
+
}
|
|
435
|
+
return result;
|
|
436
|
+
};
|
|
437
|
+
VestTest.prototype.setStatus = function (status) {
|
|
438
|
+
if (this.isFinalStatus() && status !== STATUS_OMITTED) {
|
|
439
|
+
return;
|
|
440
|
+
}
|
|
441
|
+
this.status = status;
|
|
442
|
+
};
|
|
443
|
+
VestTest.prototype.warns = function () {
|
|
444
|
+
return this.severity === TestSeverity.Warning;
|
|
445
|
+
};
|
|
446
|
+
VestTest.prototype.setPending = function () {
|
|
447
|
+
this.setStatus(STATUS_PENDING);
|
|
448
|
+
};
|
|
449
|
+
VestTest.prototype.fail = function () {
|
|
450
|
+
this.setStatus(this.warns() ? STATUS_WARNING : STATUS_FAILED);
|
|
451
|
+
};
|
|
452
|
+
VestTest.prototype.done = function () {
|
|
453
|
+
if (this.isFinalStatus()) {
|
|
454
|
+
return;
|
|
455
|
+
}
|
|
456
|
+
this.setStatus(STATUS_PASSING);
|
|
457
|
+
};
|
|
458
|
+
VestTest.prototype.warn = function () {
|
|
459
|
+
this.severity = TestSeverity.Warning;
|
|
460
|
+
};
|
|
461
|
+
VestTest.prototype.isFinalStatus = function () {
|
|
462
|
+
return this.hasFailures() || this.isCanceled() || this.isPassing();
|
|
463
|
+
};
|
|
464
|
+
VestTest.prototype.skip = function (force) {
|
|
465
|
+
if (this.isPending() && !force) {
|
|
466
|
+
// Without this condition, the test will be marked as skipped even if it is pending.
|
|
467
|
+
// This means that it will not be counted in "allIncomplete" and its done callbacks
|
|
468
|
+
// will not be called, or will be called prematurely.
|
|
469
|
+
// What this mostly say is that when we have a pending test for one field, and we then
|
|
470
|
+
// start typing in a different field - the pending test will be canceled, which
|
|
471
|
+
// is usually an unwanted behavior.
|
|
472
|
+
// The only scenario in which we DO want to cancel the async test regardless
|
|
473
|
+
// is when we specifically skip a test with `skipWhen`, which is handled by the
|
|
474
|
+
// "force" boolean flag.
|
|
475
|
+
// I am not a fan of this flag, but it gets the job done.
|
|
476
|
+
return;
|
|
477
|
+
}
|
|
478
|
+
this.setStatus(STATUS_SKIPPED);
|
|
479
|
+
};
|
|
480
|
+
VestTest.prototype.cancel = function () {
|
|
481
|
+
this.setStatus(STATUS_CANCELED);
|
|
482
|
+
useRefreshTestObjects();
|
|
483
|
+
};
|
|
484
|
+
VestTest.prototype.omit = function () {
|
|
485
|
+
this.setStatus(STATUS_OMITTED);
|
|
486
|
+
};
|
|
487
|
+
VestTest.prototype.valueOf = function () {
|
|
488
|
+
return !this.isFailing();
|
|
489
|
+
};
|
|
490
|
+
VestTest.prototype.hasFailures = function () {
|
|
491
|
+
return this.isFailing() || this.isWarning();
|
|
492
|
+
};
|
|
493
|
+
VestTest.prototype.isPending = function () {
|
|
494
|
+
return this.status === STATUS_PENDING;
|
|
495
|
+
};
|
|
496
|
+
VestTest.prototype.isTested = function () {
|
|
497
|
+
return this.hasFailures() || this.isPassing();
|
|
498
|
+
};
|
|
499
|
+
VestTest.prototype.isOmitted = function () {
|
|
500
|
+
return this.status === STATUS_OMITTED;
|
|
501
|
+
};
|
|
502
|
+
VestTest.prototype.isUntested = function () {
|
|
503
|
+
return this.status === STATUS_UNTESTED;
|
|
504
|
+
};
|
|
505
|
+
VestTest.prototype.isFailing = function () {
|
|
506
|
+
return this.status === STATUS_FAILED;
|
|
507
|
+
};
|
|
508
|
+
VestTest.prototype.isCanceled = function () {
|
|
509
|
+
return this.status === STATUS_CANCELED;
|
|
510
|
+
};
|
|
511
|
+
VestTest.prototype.isSkipped = function () {
|
|
512
|
+
return this.status === STATUS_SKIPPED;
|
|
513
|
+
};
|
|
514
|
+
VestTest.prototype.isPassing = function () {
|
|
515
|
+
return this.status === STATUS_PASSING;
|
|
516
|
+
};
|
|
517
|
+
VestTest.prototype.isWarning = function () {
|
|
518
|
+
return this.status === STATUS_WARNING;
|
|
519
|
+
};
|
|
520
|
+
return VestTest;
|
|
521
|
+
}());
|
|
522
|
+
var STATUS_UNTESTED = 'UNTESTED';
|
|
523
|
+
var STATUS_SKIPPED = 'SKIPPED';
|
|
524
|
+
var STATUS_FAILED = 'FAILED';
|
|
525
|
+
var STATUS_WARNING = 'WARNING';
|
|
526
|
+
var STATUS_PASSING = 'PASSING';
|
|
527
|
+
var STATUS_PENDING = 'PENDING';
|
|
528
|
+
var STATUS_CANCELED = 'CANCELED';
|
|
529
|
+
var STATUS_OMITTED = 'OMITTED';
|
|
530
|
+
|
|
1104
531
|
function usePath() {
|
|
1105
|
-
var context =
|
|
1106
|
-
return context.testCursor.getCursor();
|
|
532
|
+
var context$1 = context.useX();
|
|
533
|
+
return context$1.testCursor.getCursor();
|
|
1107
534
|
}
|
|
1108
535
|
function useCursorAt() {
|
|
1109
|
-
var context =
|
|
1110
|
-
return context.testCursor.cursorAt();
|
|
536
|
+
var context$1 = context.useX();
|
|
537
|
+
return context$1.testCursor.cursorAt();
|
|
1111
538
|
}
|
|
1112
539
|
function moveForward() {
|
|
1113
|
-
var context =
|
|
1114
|
-
return context.testCursor.next();
|
|
540
|
+
var context$1 = context.useX();
|
|
541
|
+
return context$1.testCursor.next();
|
|
1115
542
|
}
|
|
1116
543
|
function addLevel() {
|
|
1117
|
-
var context =
|
|
1118
|
-
context.testCursor.addLevel();
|
|
544
|
+
var context$1 = context.useX();
|
|
545
|
+
context$1.testCursor.addLevel();
|
|
1119
546
|
}
|
|
1120
547
|
function removeLevel() {
|
|
1121
|
-
var context =
|
|
1122
|
-
context.testCursor.removeLevel();
|
|
548
|
+
var context$1 = context.useX();
|
|
549
|
+
context$1.testCursor.removeLevel();
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
function usePrevKeys() {
|
|
553
|
+
var prev = useTestObjects()[0].prev;
|
|
554
|
+
return asArray(getCurrent(prev, usePath())).reduce(function (prevKeys, testObject) {
|
|
555
|
+
if (!(testObject instanceof VestTest)) {
|
|
556
|
+
return prevKeys;
|
|
557
|
+
}
|
|
558
|
+
if (isNullish(testObject.key)) {
|
|
559
|
+
return prevKeys;
|
|
560
|
+
}
|
|
561
|
+
prevKeys[testObject.key] = testObject;
|
|
562
|
+
return prevKeys;
|
|
563
|
+
}, {});
|
|
564
|
+
}
|
|
565
|
+
function usePrevTestByKey(key) {
|
|
566
|
+
var prev = context.useX().isolate.keys.prev;
|
|
567
|
+
return prev[key];
|
|
568
|
+
}
|
|
569
|
+
function useRetainTestKey(key, testObject) {
|
|
570
|
+
var context$1 = context.useX();
|
|
571
|
+
var current = context$1.isolate.keys.current;
|
|
572
|
+
if (isNullish(current[key])) {
|
|
573
|
+
current[key] = testObject;
|
|
574
|
+
}
|
|
575
|
+
else {
|
|
576
|
+
throwErrorDeferred("Encountered the same test key \"" + key + "\" twice. This may lead to tests overriding each other's results, or to tests being unexpectedly omitted.");
|
|
577
|
+
}
|
|
1123
578
|
}
|
|
1124
579
|
|
|
1125
580
|
function isolate(_a, callback) {
|
|
@@ -1127,9 +582,14 @@ function isolate(_a, callback) {
|
|
|
1127
582
|
if (!isFunction(callback)) {
|
|
1128
583
|
return;
|
|
1129
584
|
}
|
|
585
|
+
var keys = {
|
|
586
|
+
current: {},
|
|
587
|
+
prev: {}
|
|
588
|
+
};
|
|
1130
589
|
var path = usePath();
|
|
1131
|
-
return
|
|
590
|
+
return context.run({ isolate: { type: type, keys: keys } }, function () {
|
|
1132
591
|
addLevel();
|
|
592
|
+
keys.prev = usePrevKeys();
|
|
1133
593
|
useSetTests(function (tests) { return setValueAtPath(tests, path, []); });
|
|
1134
594
|
var res = callback();
|
|
1135
595
|
removeLevel();
|
|
@@ -1138,43 +598,42 @@ function isolate(_a, callback) {
|
|
|
1138
598
|
});
|
|
1139
599
|
}
|
|
1140
600
|
function shouldAllowReorder() {
|
|
1141
|
-
return
|
|
601
|
+
return context.useX().isolate.type === IsolateTypes.EACH;
|
|
1142
602
|
}
|
|
1143
603
|
|
|
1144
|
-
|
|
1145
|
-
|
|
604
|
+
/**
|
|
605
|
+
* A safe hasOwnProperty access
|
|
606
|
+
*/
|
|
607
|
+
function hasOwnProperty(obj, key) {
|
|
608
|
+
return Object.prototype.hasOwnProperty.call(obj, key);
|
|
1146
609
|
}
|
|
1147
|
-
|
|
1148
|
-
|
|
610
|
+
|
|
611
|
+
function isNumber(value) {
|
|
612
|
+
return Boolean(typeof value === 'number');
|
|
1149
613
|
}
|
|
1150
614
|
|
|
1151
|
-
function
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
return;
|
|
615
|
+
function isEmpty(value) {
|
|
616
|
+
if (!value) {
|
|
617
|
+
return true;
|
|
1155
618
|
}
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
omit(testObject);
|
|
1162
|
-
}
|
|
1163
|
-
else {
|
|
1164
|
-
var optionalConfig = optionalFields[fieldName];
|
|
1165
|
-
if (isFunction(optionalConfig)) {
|
|
1166
|
-
shouldOmit[fieldName] = optionalConfig();
|
|
1167
|
-
omit(testObject);
|
|
1168
|
-
}
|
|
1169
|
-
}
|
|
1170
|
-
return testObject;
|
|
1171
|
-
});
|
|
1172
|
-
});
|
|
1173
|
-
function omit(testObject) {
|
|
1174
|
-
if (shouldOmit[testObject.fieldName]) {
|
|
1175
|
-
testObject.omit();
|
|
1176
|
-
}
|
|
619
|
+
else if (isNumber(value)) {
|
|
620
|
+
return value === 0;
|
|
621
|
+
}
|
|
622
|
+
else if (hasOwnProperty(value, 'length')) {
|
|
623
|
+
return lengthEquals(value, 0);
|
|
1177
624
|
}
|
|
625
|
+
else if (typeof value === 'object') {
|
|
626
|
+
return lengthEquals(Object.keys(value), 0);
|
|
627
|
+
}
|
|
628
|
+
return true;
|
|
629
|
+
}
|
|
630
|
+
var isNotEmpty = bindNot(isEmpty);
|
|
631
|
+
|
|
632
|
+
function nonMatchingFieldName(testObject, fieldName) {
|
|
633
|
+
return !!fieldName && !matchingFieldName(testObject, fieldName);
|
|
634
|
+
}
|
|
635
|
+
function matchingFieldName(testObject, fieldName) {
|
|
636
|
+
return !!(fieldName && testObject.fieldName === fieldName);
|
|
1178
637
|
}
|
|
1179
638
|
|
|
1180
639
|
/**
|
|
@@ -1257,6 +716,42 @@ function genTestObject(summaryKey, testObject) {
|
|
|
1257
716
|
return testKey;
|
|
1258
717
|
}
|
|
1259
718
|
|
|
719
|
+
/*! *****************************************************************************
|
|
720
|
+
Copyright (c) Microsoft Corporation.
|
|
721
|
+
|
|
722
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
723
|
+
purpose with or without fee is hereby granted.
|
|
724
|
+
|
|
725
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
726
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
727
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
728
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
729
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
730
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
731
|
+
PERFORMANCE OF THIS SOFTWARE.
|
|
732
|
+
***************************************************************************** */
|
|
733
|
+
|
|
734
|
+
var __assign = function() {
|
|
735
|
+
__assign = Object.assign || function __assign(t) {
|
|
736
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
737
|
+
s = arguments[i];
|
|
738
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
|
|
739
|
+
}
|
|
740
|
+
return t;
|
|
741
|
+
};
|
|
742
|
+
return __assign.apply(this, arguments);
|
|
743
|
+
};
|
|
744
|
+
|
|
745
|
+
function __spreadArray(to, from, pack) {
|
|
746
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
747
|
+
if (ar || !(i in from)) {
|
|
748
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
749
|
+
ar[i] = from[i];
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
return to.concat(ar || from);
|
|
753
|
+
}
|
|
754
|
+
|
|
1260
755
|
function either(a, b) {
|
|
1261
756
|
return !!a !== !!b;
|
|
1262
757
|
}
|
|
@@ -1265,7 +760,7 @@ function either(a, b) {
|
|
|
1265
760
|
* Checks that a given test object matches the currently specified severity level
|
|
1266
761
|
*/
|
|
1267
762
|
function nonMatchingSeverityProfile(severity, testObject) {
|
|
1268
|
-
return either(severity === 'warnings', testObject.warns);
|
|
763
|
+
return either(severity === 'warnings', testObject.warns());
|
|
1269
764
|
}
|
|
1270
765
|
|
|
1271
766
|
function collectFailureMessages(severity, testObjects, options) {
|
|
@@ -1450,19 +945,21 @@ var cache$1 = createCache(20);
|
|
|
1450
945
|
function produceDraft() {
|
|
1451
946
|
var testObjects = useTestsFlat();
|
|
1452
947
|
var ctxRef = { stateRef: useStateRef() };
|
|
1453
|
-
return cache$1([testObjects],
|
|
948
|
+
return cache$1([testObjects], context.bind(ctxRef, function () {
|
|
949
|
+
var suiteName = useSuiteName();
|
|
1454
950
|
return assign(genTestsSummary(), {
|
|
1455
|
-
getErrors:
|
|
1456
|
-
getErrorsByGroup:
|
|
1457
|
-
getWarnings:
|
|
1458
|
-
getWarningsByGroup:
|
|
1459
|
-
hasErrors:
|
|
1460
|
-
hasErrorsByGroup:
|
|
1461
|
-
hasWarnings:
|
|
1462
|
-
hasWarningsByGroup:
|
|
1463
|
-
isValid:
|
|
951
|
+
getErrors: context.bind(ctxRef, getErrors),
|
|
952
|
+
getErrorsByGroup: context.bind(ctxRef, getErrorsByGroup),
|
|
953
|
+
getWarnings: context.bind(ctxRef, getWarnings),
|
|
954
|
+
getWarningsByGroup: context.bind(ctxRef, getWarningsByGroup),
|
|
955
|
+
hasErrors: context.bind(ctxRef, hasErrors),
|
|
956
|
+
hasErrorsByGroup: context.bind(ctxRef, hasErrorsByGroup),
|
|
957
|
+
hasWarnings: context.bind(ctxRef, hasWarnings),
|
|
958
|
+
hasWarningsByGroup: context.bind(ctxRef, hasWarningsByGroup),
|
|
959
|
+
isValid: context.bind(ctxRef, function (fieldName) {
|
|
1464
960
|
return isValid(produceDraft(), fieldName);
|
|
1465
|
-
})
|
|
961
|
+
}),
|
|
962
|
+
suiteName: suiteName
|
|
1466
963
|
});
|
|
1467
964
|
}));
|
|
1468
965
|
}
|
|
@@ -1471,9 +968,9 @@ var cache = createCache(20);
|
|
|
1471
968
|
function produceFullResult() {
|
|
1472
969
|
var testObjects = useTestsFlat();
|
|
1473
970
|
var ctxRef = { stateRef: useStateRef() };
|
|
1474
|
-
return cache([testObjects],
|
|
971
|
+
return cache([testObjects], context.bind(ctxRef, function () {
|
|
1475
972
|
return assign({}, produceDraft(), {
|
|
1476
|
-
done:
|
|
973
|
+
done: context.bind(ctxRef, done)
|
|
1477
974
|
});
|
|
1478
975
|
}));
|
|
1479
976
|
}
|
|
@@ -1484,7 +981,7 @@ function shouldSkipDoneRegistration(callback, fieldName, output) {
|
|
|
1484
981
|
// If we do not have any test runs for the current field
|
|
1485
982
|
return !!(!isFunction(callback) ||
|
|
1486
983
|
(fieldName &&
|
|
1487
|
-
(!output.tests[fieldName] || output.tests[fieldName].testCount
|
|
984
|
+
(!output.tests[fieldName] || isEmpty(output.tests[fieldName].testCount))));
|
|
1488
985
|
}
|
|
1489
986
|
function shouldRunDoneCallback(fieldName) {
|
|
1490
987
|
// is suite finished || field name exists, and test is finished;
|
|
@@ -1514,7 +1011,7 @@ var done = function done() {
|
|
|
1514
1011
|
return output;
|
|
1515
1012
|
};
|
|
1516
1013
|
function deferDoneCallback(doneCallback, fieldName) {
|
|
1517
|
-
var deferredCallback =
|
|
1014
|
+
var deferredCallback = context.bind({}, doneCallback);
|
|
1518
1015
|
var _a = useTestCallbacks(), setTestCallbacks = _a[1];
|
|
1519
1016
|
setTestCallbacks(function (current) {
|
|
1520
1017
|
if (fieldName) {
|
|
@@ -1527,13 +1024,6 @@ function deferDoneCallback(doneCallback, fieldName) {
|
|
|
1527
1024
|
});
|
|
1528
1025
|
}
|
|
1529
1026
|
|
|
1530
|
-
/**
|
|
1531
|
-
* Removes test object from suite state
|
|
1532
|
-
*/
|
|
1533
|
-
function removeTestFromState (testObject) {
|
|
1534
|
-
useSetTests(function (tests) { return filter(tests, function (test) { return testObject !== test; }); });
|
|
1535
|
-
}
|
|
1536
|
-
|
|
1537
1027
|
function createBus() {
|
|
1538
1028
|
var listeners = {};
|
|
1539
1029
|
return {
|
|
@@ -1559,6 +1049,44 @@ function createBus() {
|
|
|
1559
1049
|
};
|
|
1560
1050
|
}
|
|
1561
1051
|
|
|
1052
|
+
function omitOptionalTests() {
|
|
1053
|
+
var optionalFields = useOptionalFields()[0];
|
|
1054
|
+
if (isEmpty(optionalFields)) {
|
|
1055
|
+
return;
|
|
1056
|
+
}
|
|
1057
|
+
var shouldOmit = {};
|
|
1058
|
+
useSetTests(function (tests) {
|
|
1059
|
+
return transform(tests, function (testObject) {
|
|
1060
|
+
var fieldName = testObject.fieldName;
|
|
1061
|
+
if (shouldOmit.hasOwnProperty(fieldName)) {
|
|
1062
|
+
omit(testObject);
|
|
1063
|
+
}
|
|
1064
|
+
else {
|
|
1065
|
+
var optionalConfig = optionalFields[fieldName];
|
|
1066
|
+
if (isFunction(optionalConfig)) {
|
|
1067
|
+
shouldOmit[fieldName] = optionalConfig();
|
|
1068
|
+
omit(testObject);
|
|
1069
|
+
}
|
|
1070
|
+
}
|
|
1071
|
+
return testObject;
|
|
1072
|
+
});
|
|
1073
|
+
});
|
|
1074
|
+
function omit(testObject) {
|
|
1075
|
+
if (shouldOmit[testObject.fieldName]) {
|
|
1076
|
+
testObject.omit();
|
|
1077
|
+
}
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
1080
|
+
|
|
1081
|
+
/**
|
|
1082
|
+
* Removes test object from suite state
|
|
1083
|
+
*/
|
|
1084
|
+
function removeTestFromState (testObject) {
|
|
1085
|
+
useSetTests(function (tests) {
|
|
1086
|
+
return transform(tests, function (test) { return (testObject !== test ? test : null); });
|
|
1087
|
+
});
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1562
1090
|
function callEach(arr) {
|
|
1563
1091
|
return arr.forEach(function (fn) { return fn(); });
|
|
1564
1092
|
}
|
|
@@ -1586,6 +1114,8 @@ function runDoneCallbacks() {
|
|
|
1586
1114
|
|
|
1587
1115
|
function initBus() {
|
|
1588
1116
|
var bus = createBus();
|
|
1117
|
+
// Report a the completion of a test. There may be other tests with the same
|
|
1118
|
+
// name that are still running, or not yet started.
|
|
1589
1119
|
bus.on(Events.TEST_COMPLETED, function (testObject) {
|
|
1590
1120
|
if (testObject.isCanceled()) {
|
|
1591
1121
|
return;
|
|
@@ -1594,58 +1124,96 @@ function initBus() {
|
|
|
1594
1124
|
runFieldCallbacks(testObject.fieldName);
|
|
1595
1125
|
runDoneCallbacks();
|
|
1596
1126
|
});
|
|
1127
|
+
// Report that the suite completed its synchronous test run.
|
|
1128
|
+
// Async operations may still be running.
|
|
1129
|
+
bus.on(Events.SUITE_COMPLETED, function () {
|
|
1130
|
+
// Remove tests that are optional and need to be omitted
|
|
1131
|
+
omitOptionalTests();
|
|
1132
|
+
});
|
|
1133
|
+
// Removes a certain field from the state.
|
|
1134
|
+
bus.on(Events.REMOVE_FIELD, function (fieldName) {
|
|
1135
|
+
var testObjects = useTestsFlat();
|
|
1136
|
+
testObjects.forEach(function (testObject) {
|
|
1137
|
+
if (matchingFieldName(testObject, fieldName)) {
|
|
1138
|
+
testObject.cancel();
|
|
1139
|
+
removeTestFromState(testObject);
|
|
1140
|
+
}
|
|
1141
|
+
});
|
|
1142
|
+
});
|
|
1597
1143
|
return bus;
|
|
1598
1144
|
}
|
|
1599
1145
|
function useBus() {
|
|
1600
|
-
var context =
|
|
1601
|
-
if (!context.bus) {
|
|
1146
|
+
var context$1 = context.useX();
|
|
1147
|
+
if (!context$1.bus) {
|
|
1602
1148
|
throwError();
|
|
1603
1149
|
}
|
|
1604
|
-
return context.bus;
|
|
1150
|
+
return context$1.bus;
|
|
1605
1151
|
}
|
|
1606
1152
|
var Events;
|
|
1607
1153
|
(function (Events) {
|
|
1608
1154
|
Events["TEST_COMPLETED"] = "test_completed";
|
|
1155
|
+
Events["REMOVE_FIELD"] = "remove_field";
|
|
1156
|
+
Events["SUITE_COMPLETED"] = "suite_completed";
|
|
1609
1157
|
})(Events || (Events = {}));
|
|
1610
1158
|
|
|
1611
1159
|
// eslint-disable-next-line max-lines-per-function
|
|
1612
|
-
function create(
|
|
1160
|
+
function create() {
|
|
1161
|
+
var args = [];
|
|
1162
|
+
for (var _i = 0; _i < arguments.length; _i++) {
|
|
1163
|
+
args[_i] = arguments[_i];
|
|
1164
|
+
}
|
|
1165
|
+
var _a = args.reverse(), suiteCallback = _a[0], suiteName = _a[1];
|
|
1613
1166
|
if (!isFunction(suiteCallback)) {
|
|
1614
|
-
throwError('
|
|
1167
|
+
throwError('vest.create: Expected callback to be a function.');
|
|
1615
1168
|
}
|
|
1169
|
+
// Event bus initialization
|
|
1616
1170
|
var bus = initBus();
|
|
1171
|
+
// State initialization
|
|
1617
1172
|
var state = createState();
|
|
1618
|
-
|
|
1619
|
-
var
|
|
1173
|
+
// State reference - this holds the actual state values
|
|
1174
|
+
var stateRef = createStateRef(state, { suiteId: genId(), suiteName: suiteName });
|
|
1175
|
+
// Create base context reference. All hooks will derive their data from this
|
|
1176
|
+
var ctxRef = { stateRef: stateRef, bus: bus };
|
|
1177
|
+
var suite = assign(
|
|
1178
|
+
// Bind the suite body to the context
|
|
1179
|
+
context.bind(ctxRef, function () {
|
|
1620
1180
|
var args = [];
|
|
1621
1181
|
for (var _i = 0; _i < arguments.length; _i++) {
|
|
1622
1182
|
args[_i] = arguments[_i];
|
|
1623
1183
|
}
|
|
1184
|
+
// Reset the state. Migrates current test objects to `prev` array.
|
|
1624
1185
|
state.reset();
|
|
1625
|
-
//
|
|
1186
|
+
// Create a top level isolate
|
|
1626
1187
|
isolate({ type: IsolateTypes.SUITE }, function () {
|
|
1188
|
+
// Run the consumer's callback
|
|
1627
1189
|
suiteCallback.apply(void 0, args);
|
|
1628
1190
|
});
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1191
|
+
// Report the suite is done registering tests
|
|
1192
|
+
// Async tests may still be running
|
|
1193
|
+
bus.emit(Events.SUITE_COMPLETED);
|
|
1194
|
+
// Return the result
|
|
1195
|
+
return produceFullResult();
|
|
1632
1196
|
}), {
|
|
1633
|
-
get:
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
if (matchingFieldName(testObject, name)) {
|
|
1639
|
-
testObject.cancel();
|
|
1640
|
-
removeTestFromState(testObject);
|
|
1641
|
-
}
|
|
1642
|
-
});
|
|
1643
|
-
}),
|
|
1644
|
-
reset: state.reset
|
|
1197
|
+
get: context.bind(ctxRef, produceDraft),
|
|
1198
|
+
reset: state.reset,
|
|
1199
|
+
remove: context.bind(ctxRef, function (fieldName) {
|
|
1200
|
+
bus.emit(Events.REMOVE_FIELD, fieldName);
|
|
1201
|
+
})
|
|
1645
1202
|
});
|
|
1646
1203
|
return suite;
|
|
1647
1204
|
}
|
|
1648
1205
|
|
|
1206
|
+
function each(list, callback) {
|
|
1207
|
+
if (!isFunction(callback)) {
|
|
1208
|
+
throwError('callback must be a function');
|
|
1209
|
+
}
|
|
1210
|
+
isolate({ type: IsolateTypes.EACH }, function () {
|
|
1211
|
+
list.forEach(function (arg, index) {
|
|
1212
|
+
callback(arg, index);
|
|
1213
|
+
});
|
|
1214
|
+
});
|
|
1215
|
+
}
|
|
1216
|
+
|
|
1649
1217
|
/**
|
|
1650
1218
|
* Error message to display when a hook was called outside of context.
|
|
1651
1219
|
*/
|
|
@@ -1655,24 +1223,31 @@ var ERROR_HOOK_CALLED_OUTSIDE = 'hook called outside of a running suite.';
|
|
|
1655
1223
|
* Adds a field or multiple fields to inclusion group.
|
|
1656
1224
|
*/
|
|
1657
1225
|
function only(item) {
|
|
1658
|
-
return addTo(
|
|
1226
|
+
return addTo(0 /* ONLY */, 'tests', item);
|
|
1659
1227
|
}
|
|
1660
|
-
only.group = function (item) {
|
|
1228
|
+
only.group = function (item) {
|
|
1229
|
+
return addTo(0 /* ONLY */, 'groups', item);
|
|
1230
|
+
};
|
|
1661
1231
|
/**
|
|
1662
1232
|
* Adds a field or multiple fields to exclusion group.
|
|
1663
1233
|
*/
|
|
1664
1234
|
function skip(item) {
|
|
1665
|
-
return addTo(
|
|
1235
|
+
return addTo(1 /* SKIP */, 'tests', item);
|
|
1236
|
+
}
|
|
1237
|
+
skip.group = function (item) {
|
|
1238
|
+
return addTo(1 /* SKIP */, 'groups', item);
|
|
1239
|
+
};
|
|
1240
|
+
function isExcludedIndividually() {
|
|
1241
|
+
return !!context.useX().skipped;
|
|
1666
1242
|
}
|
|
1667
|
-
skip.group = function (item) { return addTo('skip', 'groups', item); };
|
|
1668
1243
|
//Checks whether a certain test profile excluded by any of the exclusion groups.
|
|
1669
1244
|
// eslint-disable-next-line complexity, max-statements
|
|
1670
1245
|
function isExcluded(testObject) {
|
|
1671
1246
|
var fieldName = testObject.fieldName, groupName = testObject.groupName;
|
|
1672
|
-
|
|
1673
|
-
if (context.skipped)
|
|
1247
|
+
if (isExcludedIndividually())
|
|
1674
1248
|
return true;
|
|
1675
|
-
var
|
|
1249
|
+
var context$1 = context.useX();
|
|
1250
|
+
var exclusion = context$1.exclusion;
|
|
1676
1251
|
var keyTests = exclusion.tests;
|
|
1677
1252
|
var testValue = keyTests[fieldName];
|
|
1678
1253
|
// if test is skipped
|
|
@@ -1695,6 +1270,9 @@ function isExcluded(testObject) {
|
|
|
1695
1270
|
return keyTests[fieldName] === false;
|
|
1696
1271
|
}
|
|
1697
1272
|
}
|
|
1273
|
+
if (isMissingFromIncludedGroup(groupName)) {
|
|
1274
|
+
return true;
|
|
1275
|
+
}
|
|
1698
1276
|
// if field is only'ed
|
|
1699
1277
|
if (isTestIncluded)
|
|
1700
1278
|
return false;
|
|
@@ -1702,12 +1280,40 @@ function isExcluded(testObject) {
|
|
|
1702
1280
|
// Otherwise return false
|
|
1703
1281
|
return hasIncludedTests(keyTests);
|
|
1704
1282
|
}
|
|
1283
|
+
// eslint-disable-next-line max-statements
|
|
1284
|
+
function isMissingFromIncludedGroup(groupName) {
|
|
1285
|
+
var context$1 = context.useX();
|
|
1286
|
+
var exclusion = context$1.exclusion;
|
|
1287
|
+
if (!hasIncludedGroups()) {
|
|
1288
|
+
return false;
|
|
1289
|
+
}
|
|
1290
|
+
if (!groupName) {
|
|
1291
|
+
return true;
|
|
1292
|
+
}
|
|
1293
|
+
if (groupName in exclusion.groups) {
|
|
1294
|
+
if (exclusion.groups[groupName]) {
|
|
1295
|
+
return false;
|
|
1296
|
+
}
|
|
1297
|
+
return true;
|
|
1298
|
+
}
|
|
1299
|
+
return true;
|
|
1300
|
+
}
|
|
1301
|
+
function hasIncludedGroups() {
|
|
1302
|
+
var context$1 = context.useX();
|
|
1303
|
+
var exclusion = context$1.exclusion;
|
|
1304
|
+
for (var group in exclusion.groups) {
|
|
1305
|
+
if (exclusion.groups[group]) {
|
|
1306
|
+
return true;
|
|
1307
|
+
}
|
|
1308
|
+
}
|
|
1309
|
+
return false;
|
|
1310
|
+
}
|
|
1705
1311
|
/**
|
|
1706
1312
|
* Checks whether a given group is excluded from running.
|
|
1707
1313
|
*/
|
|
1708
1314
|
function isGroupExcluded(groupName) {
|
|
1709
|
-
var context =
|
|
1710
|
-
var exclusion = context.exclusion;
|
|
1315
|
+
var context$1 = context.useX();
|
|
1316
|
+
var exclusion = context$1.exclusion;
|
|
1711
1317
|
var keyGroups = exclusion.groups;
|
|
1712
1318
|
var groupPresent = hasOwnProperty(keyGroups, groupName);
|
|
1713
1319
|
// When group is either only'ed or skipped
|
|
@@ -1728,7 +1334,7 @@ function isGroupExcluded(groupName) {
|
|
|
1728
1334
|
* Adds fields to a specified exclusion group.
|
|
1729
1335
|
*/
|
|
1730
1336
|
function addTo(exclusionGroup, itemType, item) {
|
|
1731
|
-
var context =
|
|
1337
|
+
var context$1 = context.useX(ERROR_HOOK_CALLED_OUTSIDE);
|
|
1732
1338
|
if (!item) {
|
|
1733
1339
|
return;
|
|
1734
1340
|
}
|
|
@@ -1736,7 +1342,8 @@ function addTo(exclusionGroup, itemType, item) {
|
|
|
1736
1342
|
if (!isStringValue(itemName)) {
|
|
1737
1343
|
return;
|
|
1738
1344
|
}
|
|
1739
|
-
context.exclusion[itemType][itemName] =
|
|
1345
|
+
context$1.exclusion[itemType][itemName] =
|
|
1346
|
+
exclusionGroup === 0 /* ONLY */;
|
|
1740
1347
|
});
|
|
1741
1348
|
}
|
|
1742
1349
|
/**
|
|
@@ -1751,25 +1358,6 @@ function hasIncludedTests(keyTests) {
|
|
|
1751
1358
|
return false;
|
|
1752
1359
|
}
|
|
1753
1360
|
|
|
1754
|
-
function skipWhen(conditional, callback) {
|
|
1755
|
-
isolate({ type: IsolateTypes.SKIP_WHEN }, function () {
|
|
1756
|
-
ctx.run({ skipped: optionalFunctionValue(conditional) }, function () { return callback(); });
|
|
1757
|
-
});
|
|
1758
|
-
}
|
|
1759
|
-
|
|
1760
|
-
var ERROR_OUTSIDE_OF_TEST = "warn hook called outside of a test callback. It won't have an effect."
|
|
1761
|
-
;
|
|
1762
|
-
/**
|
|
1763
|
-
* Sets a running test to warn only mode.
|
|
1764
|
-
*/
|
|
1765
|
-
function warn() {
|
|
1766
|
-
var ctx$1 = ctx.useX('warn ' + ERROR_HOOK_CALLED_OUTSIDE);
|
|
1767
|
-
if (!ctx$1.currentTest) {
|
|
1768
|
-
throwError(ERROR_OUTSIDE_OF_TEST);
|
|
1769
|
-
}
|
|
1770
|
-
ctx$1.currentTest.warn();
|
|
1771
|
-
}
|
|
1772
|
-
|
|
1773
1361
|
/**
|
|
1774
1362
|
* Runs a group callback.
|
|
1775
1363
|
*/
|
|
@@ -1782,7 +1370,7 @@ function group(groupName, tests) {
|
|
|
1782
1370
|
}
|
|
1783
1371
|
// Running with the context applied
|
|
1784
1372
|
isolate({ type: IsolateTypes.GROUP }, function () {
|
|
1785
|
-
|
|
1373
|
+
context.run({ groupName: groupName }, tests);
|
|
1786
1374
|
});
|
|
1787
1375
|
}
|
|
1788
1376
|
function throwGroupError(error) {
|
|
@@ -1808,119 +1396,15 @@ function optional(optionals) {
|
|
|
1808
1396
|
});
|
|
1809
1397
|
}
|
|
1810
1398
|
|
|
1811
|
-
function
|
|
1812
|
-
|
|
1813
|
-
|
|
1399
|
+
function skipWhen(conditional, callback) {
|
|
1400
|
+
isolate({ type: IsolateTypes.SKIP_WHEN }, function () {
|
|
1401
|
+
context.run({
|
|
1402
|
+
skipped: optionalFunctionValue(conditional, optionalFunctionValue(produceDraft))
|
|
1403
|
+
}, function () { return callback(); });
|
|
1404
|
+
});
|
|
1814
1405
|
}
|
|
1815
1406
|
|
|
1816
|
-
var
|
|
1817
|
-
function VestTest(fieldName, testFn, _a) {
|
|
1818
|
-
var _b = _a === void 0 ? {} : _a, message = _b.message, groupName = _b.groupName;
|
|
1819
|
-
this.id = genId();
|
|
1820
|
-
this.warns = false;
|
|
1821
|
-
this.status = STATUS_UNTESTED;
|
|
1822
|
-
this.fieldName = fieldName;
|
|
1823
|
-
this.testFn = testFn;
|
|
1824
|
-
if (groupName) {
|
|
1825
|
-
this.groupName = groupName;
|
|
1826
|
-
}
|
|
1827
|
-
if (message) {
|
|
1828
|
-
this.message = message;
|
|
1829
|
-
}
|
|
1830
|
-
}
|
|
1831
|
-
VestTest.prototype.run = function () {
|
|
1832
|
-
var result;
|
|
1833
|
-
try {
|
|
1834
|
-
result = this.testFn();
|
|
1835
|
-
}
|
|
1836
|
-
catch (error) {
|
|
1837
|
-
if (shouldUseErrorAsMessage(this.message, error)) {
|
|
1838
|
-
this.message = error;
|
|
1839
|
-
}
|
|
1840
|
-
result = false;
|
|
1841
|
-
}
|
|
1842
|
-
if (result === false) {
|
|
1843
|
-
this.fail();
|
|
1844
|
-
}
|
|
1845
|
-
return result;
|
|
1846
|
-
};
|
|
1847
|
-
VestTest.prototype.setStatus = function (status) {
|
|
1848
|
-
if (this.isFinalStatus() && status !== STATUS_OMITTED) {
|
|
1849
|
-
return;
|
|
1850
|
-
}
|
|
1851
|
-
this.status = status;
|
|
1852
|
-
};
|
|
1853
|
-
VestTest.prototype.setPending = function () {
|
|
1854
|
-
this.setStatus(STATUS_PENDING);
|
|
1855
|
-
};
|
|
1856
|
-
VestTest.prototype.fail = function () {
|
|
1857
|
-
this.setStatus(this.warns ? STATUS_WARNING : STATUS_FAILED);
|
|
1858
|
-
};
|
|
1859
|
-
VestTest.prototype.done = function () {
|
|
1860
|
-
if (this.isFinalStatus()) {
|
|
1861
|
-
return;
|
|
1862
|
-
}
|
|
1863
|
-
this.setStatus(STATUS_PASSING);
|
|
1864
|
-
};
|
|
1865
|
-
VestTest.prototype.warn = function () {
|
|
1866
|
-
this.warns = true;
|
|
1867
|
-
};
|
|
1868
|
-
VestTest.prototype.isFinalStatus = function () {
|
|
1869
|
-
return this.hasFailures() || this.isCanceled() || this.isPassing();
|
|
1870
|
-
};
|
|
1871
|
-
VestTest.prototype.skip = function () {
|
|
1872
|
-
this.setStatus(STATUS_SKIPPED);
|
|
1873
|
-
};
|
|
1874
|
-
VestTest.prototype.cancel = function () {
|
|
1875
|
-
this.setStatus(STATUS_CANCELED);
|
|
1876
|
-
useRefreshTestObjects();
|
|
1877
|
-
};
|
|
1878
|
-
VestTest.prototype.omit = function () {
|
|
1879
|
-
this.setStatus(STATUS_OMITTED);
|
|
1880
|
-
};
|
|
1881
|
-
VestTest.prototype.valueOf = function () {
|
|
1882
|
-
return !this.isFailing();
|
|
1883
|
-
};
|
|
1884
|
-
VestTest.prototype.hasFailures = function () {
|
|
1885
|
-
return this.isFailing() || this.isWarning();
|
|
1886
|
-
};
|
|
1887
|
-
VestTest.prototype.isPending = function () {
|
|
1888
|
-
return this.status === STATUS_PENDING;
|
|
1889
|
-
};
|
|
1890
|
-
VestTest.prototype.isTested = function () {
|
|
1891
|
-
return this.hasFailures() || this.isPassing();
|
|
1892
|
-
};
|
|
1893
|
-
VestTest.prototype.isOmitted = function () {
|
|
1894
|
-
return this.status === STATUS_OMITTED;
|
|
1895
|
-
};
|
|
1896
|
-
VestTest.prototype.isUntested = function () {
|
|
1897
|
-
return this.status === STATUS_UNTESTED;
|
|
1898
|
-
};
|
|
1899
|
-
VestTest.prototype.isFailing = function () {
|
|
1900
|
-
return this.status === STATUS_FAILED;
|
|
1901
|
-
};
|
|
1902
|
-
VestTest.prototype.isCanceled = function () {
|
|
1903
|
-
return this.status === STATUS_CANCELED;
|
|
1904
|
-
};
|
|
1905
|
-
VestTest.prototype.isSkipped = function () {
|
|
1906
|
-
return this.status === STATUS_SKIPPED;
|
|
1907
|
-
};
|
|
1908
|
-
VestTest.prototype.isPassing = function () {
|
|
1909
|
-
return this.status === STATUS_PASSING;
|
|
1910
|
-
};
|
|
1911
|
-
VestTest.prototype.isWarning = function () {
|
|
1912
|
-
return this.status === STATUS_WARNING;
|
|
1913
|
-
};
|
|
1914
|
-
return VestTest;
|
|
1915
|
-
}());
|
|
1916
|
-
var STATUS_UNTESTED = 'UNTESTED';
|
|
1917
|
-
var STATUS_SKIPPED = 'SKIPPED';
|
|
1918
|
-
var STATUS_FAILED = 'FAILED';
|
|
1919
|
-
var STATUS_WARNING = 'WARNING';
|
|
1920
|
-
var STATUS_PASSING = 'PASSING';
|
|
1921
|
-
var STATUS_PENDING = 'PENDING';
|
|
1922
|
-
var STATUS_CANCELED = 'CANCELED';
|
|
1923
|
-
var STATUS_OMITTED = 'OMITTED';
|
|
1407
|
+
var isNotString = bindNot(isStringValue);
|
|
1924
1408
|
|
|
1925
1409
|
function isPromise(value) {
|
|
1926
1410
|
return value && isFunction(value.then);
|
|
@@ -1948,12 +1432,12 @@ function runAsyncTest(testObject) {
|
|
|
1948
1432
|
return;
|
|
1949
1433
|
var emit = useBus().emit;
|
|
1950
1434
|
var stateRef = useStateRef();
|
|
1951
|
-
var done =
|
|
1435
|
+
var done = context.bind({ stateRef: stateRef }, function () {
|
|
1952
1436
|
// invalidating the "produce" cache
|
|
1953
1437
|
useRefreshTestObjects();
|
|
1954
1438
|
emit(Events.TEST_COMPLETED, testObject);
|
|
1955
1439
|
});
|
|
1956
|
-
var fail =
|
|
1440
|
+
var fail = context.bind({ stateRef: stateRef }, function (rejectionMessage) {
|
|
1957
1441
|
if (testObject.isCanceled()) {
|
|
1958
1442
|
return;
|
|
1959
1443
|
}
|
|
@@ -1975,7 +1459,7 @@ function runAsyncTest(testObject) {
|
|
|
1975
1459
|
* Runs sync tests - or extracts promise.
|
|
1976
1460
|
*/
|
|
1977
1461
|
function runSyncTest(testObject) {
|
|
1978
|
-
return
|
|
1462
|
+
return context.run({ currentTest: testObject }, function () {
|
|
1979
1463
|
var result;
|
|
1980
1464
|
try {
|
|
1981
1465
|
result = testObject.testFn();
|
|
@@ -1997,7 +1481,7 @@ function runSyncTest(testObject) {
|
|
|
1997
1481
|
* Registers test, if async - adds to pending array
|
|
1998
1482
|
*/
|
|
1999
1483
|
function registerTest(testObject) {
|
|
2000
|
-
var
|
|
1484
|
+
var bus = useBus();
|
|
2001
1485
|
// Run test callback.
|
|
2002
1486
|
// If a promise is returned, set as async and
|
|
2003
1487
|
// Move to pending list.
|
|
@@ -2011,50 +1495,64 @@ function registerTest(testObject) {
|
|
|
2011
1495
|
runAsyncTest(testObject);
|
|
2012
1496
|
}
|
|
2013
1497
|
else {
|
|
2014
|
-
emit(Events.TEST_COMPLETED, testObject);
|
|
1498
|
+
bus.emit(Events.TEST_COMPLETED, testObject);
|
|
2015
1499
|
}
|
|
2016
1500
|
}
|
|
2017
1501
|
catch (e) {
|
|
2018
|
-
throwError("Your test function " + testObject.fieldName + " returned
|
|
1502
|
+
throwError("Your test function " + testObject.fieldName + " returned a value. Only \"false\" or Promise returns are supported.");
|
|
2019
1503
|
}
|
|
2020
1504
|
}
|
|
2021
1505
|
|
|
2022
|
-
|
|
1506
|
+
/**
|
|
1507
|
+
* This module serves as the "collision detection" mechanism for Vest.
|
|
1508
|
+
* It is used to ensure that tests are not called in a different order than
|
|
1509
|
+
* they were called in the previous run.
|
|
1510
|
+
* If they are, it will throw a deferred error unless explicitly allowed.
|
|
1511
|
+
*
|
|
1512
|
+
* For now it seems pretty safe, and it covers most common use cases, but it can
|
|
1513
|
+
* be improved in the future both in terms of performance and scenarios it covers.
|
|
1514
|
+
*/
|
|
1515
|
+
// eslint-disable-next-line max-statements, max-lines-per-function
|
|
2023
1516
|
function useTestAtCursor(newTestObject) {
|
|
2024
|
-
var
|
|
1517
|
+
var testObjects = useTestObjects()[0];
|
|
2025
1518
|
var prevTests = testObjects.prev;
|
|
2026
1519
|
if (isEmpty(prevTests)) {
|
|
2027
1520
|
useSetTestAtCursor(newTestObject);
|
|
2028
1521
|
return newTestObject;
|
|
2029
1522
|
}
|
|
2030
1523
|
var prevTest = useGetTestAtCursor(prevTests);
|
|
1524
|
+
if (!isNullish(newTestObject.key)) {
|
|
1525
|
+
var nextTest_1 = handleKeyTest(newTestObject.key, newTestObject);
|
|
1526
|
+
useSetTestAtCursor(nextTest_1);
|
|
1527
|
+
return nextTest_1;
|
|
1528
|
+
}
|
|
2031
1529
|
if (shouldPurgePrevTest(prevTest, newTestObject)) {
|
|
2032
1530
|
throwTestOrderError(prevTest, newTestObject);
|
|
2033
|
-
|
|
2034
|
-
//
|
|
2035
|
-
|
|
2036
|
-
// A viable solution would be to use something like React's key prop to identify tests regardless
|
|
2037
|
-
// of their position in the suite. https://reactjs.org/docs/lists-and-keys.html#keys
|
|
2038
|
-
while (shouldPurgePrevTest(prevTest, newTestObject)) {
|
|
2039
|
-
var testObjects_1 = useTestObjects()[0];
|
|
2040
|
-
prevTests = removeAtPath(testObjects_1.prev, usePath());
|
|
2041
|
-
prevTest = useGetTestAtCursor(prevTests);
|
|
2042
|
-
}
|
|
2043
|
-
// We actually don't mind mutating the state directly (as we do above). There is no harm in it
|
|
2044
|
-
// since we're only touching the "prev" state. The reason we still use the setter function is
|
|
2045
|
-
// to prevent future headaches if we ever do need to rely on prev-state immutability.
|
|
2046
|
-
setTestObjects(function (_a) {
|
|
2047
|
-
var current = _a.current;
|
|
2048
|
-
return ({
|
|
2049
|
-
prev: prevTests,
|
|
2050
|
-
current: current
|
|
2051
|
-
});
|
|
2052
|
-
});
|
|
1531
|
+
removeAllNextTestsInIsolate();
|
|
1532
|
+
// Need to see if this has any effect at all.
|
|
1533
|
+
prevTest = null;
|
|
2053
1534
|
}
|
|
2054
1535
|
var nextTest = defaultTo(prevTest, newTestObject);
|
|
2055
1536
|
useSetTestAtCursor(nextTest);
|
|
2056
1537
|
return nextTest;
|
|
2057
1538
|
}
|
|
1539
|
+
function removeAllNextTestsInIsolate() {
|
|
1540
|
+
var _a = useTestObjects(), testObjects = _a[0], setTestObjects = _a[1];
|
|
1541
|
+
var prevTests = testObjects.prev;
|
|
1542
|
+
var current = getCurrent(prevTests, usePath());
|
|
1543
|
+
var cursorAt = useCursorAt();
|
|
1544
|
+
current.splice(cursorAt);
|
|
1545
|
+
// We actually don't mind mutating the state directly (as can be seen above). There is no harm in it
|
|
1546
|
+
// since we're only touching the "prev" state. The reason we still use the setter function is
|
|
1547
|
+
// to prevent future headaches if we ever do need to rely on prev-state immutability.
|
|
1548
|
+
setTestObjects(function (_a) {
|
|
1549
|
+
var current = _a.current;
|
|
1550
|
+
return ({
|
|
1551
|
+
prev: prevTests,
|
|
1552
|
+
current: current
|
|
1553
|
+
});
|
|
1554
|
+
});
|
|
1555
|
+
}
|
|
2058
1556
|
function useSetTestAtCursor(testObject) {
|
|
2059
1557
|
var cursorPath = usePath();
|
|
2060
1558
|
useSetTests(function (tests) {
|
|
@@ -2072,13 +1570,26 @@ function throwTestOrderError(prevTest, newTestObject) {
|
|
|
2072
1570
|
if (shouldAllowReorder()) {
|
|
2073
1571
|
return;
|
|
2074
1572
|
}
|
|
2075
|
-
throwErrorDeferred("Vest Critical Error: Tests called in different order than previous run.\n expected: " + prevTest.fieldName + "\n received: " + newTestObject.fieldName + "\n This
|
|
1573
|
+
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.");
|
|
1574
|
+
}
|
|
1575
|
+
function handleKeyTest(key, newTestObject) {
|
|
1576
|
+
var prevTestByKey = usePrevTestByKey(key);
|
|
1577
|
+
var nextTest = newTestObject;
|
|
1578
|
+
if (prevTestByKey) {
|
|
1579
|
+
nextTest = prevTestByKey;
|
|
1580
|
+
}
|
|
1581
|
+
useRetainTestKey(key, nextTest);
|
|
1582
|
+
return nextTest;
|
|
2076
1583
|
}
|
|
2077
1584
|
|
|
2078
1585
|
function registerPrevRunTest(testObject) {
|
|
2079
1586
|
var prevRunTest = useTestAtCursor(testObject);
|
|
2080
1587
|
if (isExcluded(testObject)) {
|
|
2081
|
-
|
|
1588
|
+
// We're forcing skipping the pending test
|
|
1589
|
+
// if we're directly within a skipWhen block
|
|
1590
|
+
// This mostly means that we're probably giving
|
|
1591
|
+
// up on this async test intentionally.
|
|
1592
|
+
prevRunTest.skip(isExcludedIndividually());
|
|
2082
1593
|
moveForward();
|
|
2083
1594
|
return prevRunTest;
|
|
2084
1595
|
}
|
|
@@ -2098,33 +1609,6 @@ function registerTestObjectByTier(testObject) {
|
|
|
2098
1609
|
}
|
|
2099
1610
|
}
|
|
2100
1611
|
|
|
2101
|
-
function bindTestEach(test) {
|
|
2102
|
-
/**
|
|
2103
|
-
* Run multiple tests using a parameter table
|
|
2104
|
-
*/
|
|
2105
|
-
function each(table) {
|
|
2106
|
-
if (!isArray(table)) {
|
|
2107
|
-
throwError('test.each: Expected table to be an array.');
|
|
2108
|
-
}
|
|
2109
|
-
function eachReturn(fieldName) {
|
|
2110
|
-
var args = [];
|
|
2111
|
-
for (var _i = 1; _i < arguments.length; _i++) {
|
|
2112
|
-
args[_i - 1] = arguments[_i];
|
|
2113
|
-
}
|
|
2114
|
-
var _a = args.reverse(), testFn = _a[0], message = _a[1];
|
|
2115
|
-
return isolate({ type: IsolateTypes.EACH }, function () {
|
|
2116
|
-
return table.map(function (item) {
|
|
2117
|
-
item = asArray(item);
|
|
2118
|
-
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
|
|
2119
|
-
);
|
|
2120
|
-
});
|
|
2121
|
-
});
|
|
2122
|
-
}
|
|
2123
|
-
return eachReturn;
|
|
2124
|
-
}
|
|
2125
|
-
return each;
|
|
2126
|
-
}
|
|
2127
|
-
|
|
2128
1612
|
// eslint-disable-next-line max-lines-per-function
|
|
2129
1613
|
function bindTestMemo(test) {
|
|
2130
1614
|
var cache = createCache(100); // arbitrary cache size
|
|
@@ -2134,11 +1618,10 @@ function bindTestMemo(test) {
|
|
|
2134
1618
|
for (var _i = 1; _i < arguments.length; _i++) {
|
|
2135
1619
|
args[_i - 1] = arguments[_i];
|
|
2136
1620
|
}
|
|
2137
|
-
var suiteId = useSuiteId()[0];
|
|
2138
1621
|
var cursorAt = useCursorAt();
|
|
2139
1622
|
var _a = args.reverse(), deps = _a[0], testFn = _a[1], msg = _a[2];
|
|
2140
1623
|
// Implicit dependency for more specificity
|
|
2141
|
-
var dependencies = [
|
|
1624
|
+
var dependencies = [useSuiteId(), fieldName, cursorAt].concat(deps);
|
|
2142
1625
|
var cached = cache.get(dependencies);
|
|
2143
1626
|
if (isNull(cached)) {
|
|
2144
1627
|
// cache miss
|
|
@@ -2159,24 +1642,52 @@ function testBase(fieldName) {
|
|
|
2159
1642
|
for (var _i = 1; _i < arguments.length; _i++) {
|
|
2160
1643
|
args[_i - 1] = arguments[_i];
|
|
2161
1644
|
}
|
|
2162
|
-
var _a = args
|
|
2163
|
-
|
|
1645
|
+
var _a = (isFunction(args[1]) ? args : __spreadArray([undefined], args)), message = _a[0], testFn = _a[1], key = _a[2];
|
|
1646
|
+
if (isNotString(fieldName)) {
|
|
1647
|
+
throwIncompatibleParamsError('fieldName', 'string');
|
|
1648
|
+
}
|
|
1649
|
+
if (!isFunction(testFn)) {
|
|
1650
|
+
throwIncompatibleParamsError('Test callback', 'function');
|
|
1651
|
+
}
|
|
1652
|
+
var context$1 = context.useX();
|
|
2164
1653
|
var testObject = new VestTest(fieldName, testFn, {
|
|
2165
1654
|
message: message,
|
|
2166
|
-
groupName: context
|
|
1655
|
+
groupName: context$1.groupName,
|
|
1656
|
+
key: key
|
|
2167
1657
|
});
|
|
2168
1658
|
return registerPrevRunTest(testObject);
|
|
2169
1659
|
}
|
|
2170
1660
|
var test = assign(testBase, {
|
|
2171
|
-
each: bindTestEach(testBase),
|
|
2172
1661
|
memo: bindTestMemo(testBase)
|
|
2173
1662
|
});
|
|
1663
|
+
function throwIncompatibleParamsError(name, expected) {
|
|
1664
|
+
throwError("Incompatible params passed to test function. " + name + " must be a " + expected);
|
|
1665
|
+
}
|
|
1666
|
+
|
|
1667
|
+
var ERROR_OUTSIDE_OF_TEST = "warn hook called outside of a test callback. It won't have an effect."
|
|
1668
|
+
;
|
|
1669
|
+
/**
|
|
1670
|
+
* Sets a running test to warn only mode.
|
|
1671
|
+
*/
|
|
1672
|
+
function warn() {
|
|
1673
|
+
var ctx = context.useX('warn ' + ERROR_HOOK_CALLED_OUTSIDE);
|
|
1674
|
+
if (!ctx.currentTest) {
|
|
1675
|
+
throwError(ERROR_OUTSIDE_OF_TEST);
|
|
1676
|
+
}
|
|
1677
|
+
ctx.currentTest.warn();
|
|
1678
|
+
}
|
|
2174
1679
|
|
|
2175
|
-
var VERSION = "4.0.0-dev-
|
|
1680
|
+
var VERSION = "4.0.0-dev-e266d9";
|
|
2176
1681
|
|
|
1682
|
+
Object.defineProperty(exports, 'enforce', {
|
|
1683
|
+
enumerable: true,
|
|
1684
|
+
get: function () {
|
|
1685
|
+
return n4s.enforce;
|
|
1686
|
+
}
|
|
1687
|
+
});
|
|
2177
1688
|
exports.VERSION = VERSION;
|
|
2178
1689
|
exports.create = create;
|
|
2179
|
-
exports.
|
|
1690
|
+
exports.each = each;
|
|
2180
1691
|
exports.group = group;
|
|
2181
1692
|
exports.only = only;
|
|
2182
1693
|
exports.optional = optional;
|