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