vest 4.3.3 → 4.4.0

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.
@@ -180,40 +180,6 @@ function getCurrent(array, path) {
180
180
  return current;
181
181
  }
182
182
 
183
- function createCursor() {
184
- var storage = {
185
- cursor: []
186
- };
187
- function addLevel() {
188
- storage.cursor.push(0);
189
- }
190
- function removeLevel() {
191
- storage.cursor.pop();
192
- }
193
- function cursorAt() {
194
- return last(storage.cursor);
195
- }
196
- function getCursor() {
197
- return asArray(storage.cursor);
198
- }
199
- function next() {
200
- storage.cursor[storage.cursor.length - 1]++;
201
- return last(storage.cursor);
202
- }
203
- function reset() {
204
- storage.cursor = [0];
205
- }
206
- reset();
207
- return {
208
- addLevel: addLevel,
209
- cursorAt: cursorAt,
210
- getCursor: getCursor,
211
- next: next,
212
- removeLevel: removeLevel,
213
- reset: reset
214
- };
215
- }
216
-
217
183
  var IsolateTypes;
218
184
  (function (IsolateTypes) {
219
185
  IsolateTypes[IsolateTypes["DEFAULT"] = 0] = "DEFAULT";
@@ -230,6 +196,133 @@ var Modes;
230
196
  Modes[Modes["EAGER"] = 1] = "EAGER";
231
197
  })(Modes || (Modes = {}));
232
198
 
199
+ function invariant(condition,
200
+ // eslint-disable-next-line @typescript-eslint/ban-types
201
+ message) {
202
+ if (condition) {
203
+ return;
204
+ }
205
+ // If message is a string object (rather than string literal)
206
+ // Throw the value directly as a string
207
+ // Alternatively, throw an error with the message
208
+ throw message instanceof String
209
+ ? message.valueOf()
210
+ : new Error(message ? optionalFunctionValue(message) : message);
211
+ }
212
+
213
+ function createIsolateCursor() {
214
+ var cursor = {
215
+ value: 0
216
+ };
217
+ return {
218
+ current: current,
219
+ next: next
220
+ };
221
+ /**
222
+ * @returns {number} The current value of the cursor
223
+ */
224
+ function current() {
225
+ return cursor.value;
226
+ }
227
+ /**
228
+ * Moves the isolate cursor forward by 1
229
+ */
230
+ function next() {
231
+ cursor.value++;
232
+ }
233
+ }
234
+
235
+ function isNullish(value) {
236
+ return isNull(value) || isUndefined(value);
237
+ }
238
+
239
+ function deferThrow(message) {
240
+ setTimeout(function () {
241
+ throw new Error(message);
242
+ }, 0);
243
+ }
244
+
245
+ function usePrevKeys() {
246
+ var prev = useTestObjects()[0].prev;
247
+ return asArray(getCurrent(prev, useCurrentPath())).reduce(function (prevKeys, testObject) {
248
+ if (!(testObject instanceof VestTest)) {
249
+ return prevKeys;
250
+ }
251
+ if (isNullish(testObject.key)) {
252
+ return prevKeys;
253
+ }
254
+ prevKeys[testObject.key] = testObject;
255
+ return prevKeys;
256
+ }, {});
257
+ }
258
+ function usePrevTestByKey(key) {
259
+ var prev = context.useX().isolate.keys.prev;
260
+ return prev[key];
261
+ }
262
+ function useRetainTestKey(key, testObject) {
263
+ var context$1 = context.useX();
264
+ var current = context$1.isolate.keys.current;
265
+ if (isNullish(current[key])) {
266
+ current[key] = testObject;
267
+ }
268
+ else {
269
+ deferThrow("Encountered the same test key \"".concat(key, "\" twice. This may lead to tests overriding each other's results, or to tests being unexpectedly omitted."));
270
+ }
271
+ }
272
+
273
+ function isolate(_a, callback) {
274
+ var _b = _a.type, type = _b === void 0 ? IsolateTypes.DEFAULT : _b;
275
+ invariant(isFunction(callback));
276
+ // Generate a new Isolate layer, with its own cursor
277
+ var isolate = generateIsolate(type, useCurrentPath());
278
+ var output = context.run({ isolate: isolate }, function () {
279
+ isolate.keys.prev = usePrevKeys();
280
+ useSetTests(function (tests) { return setValueAtPath(tests, isolate.path, []); });
281
+ var res = callback();
282
+ return res;
283
+ });
284
+ // Move the parent cursor forward once we're done
285
+ useCursor().next();
286
+ return output;
287
+ }
288
+ /**
289
+ * @returns {Isolate} The current isolate layer
290
+ */
291
+ function useIsolate() {
292
+ return context.useX().isolate;
293
+ }
294
+ /**
295
+ * @returns {boolean} Whether or not the current isolate allows tests to be reordered
296
+ */
297
+ function shouldAllowReorder() {
298
+ return context.useX().isolate.type === IsolateTypes.EACH;
299
+ }
300
+ /**
301
+ * @returns {number[]} The current cursor path of the isolate tree
302
+ */
303
+ function useCurrentPath() {
304
+ var isolate = useIsolate();
305
+ return isolate.path.concat(isolate.cursor.current());
306
+ }
307
+ /**
308
+ * @returns {IsolateCursor} The cursor object for the current isolate
309
+ */
310
+ function useCursor() {
311
+ return useIsolate().cursor;
312
+ }
313
+ function generateIsolate(type, path) {
314
+ if (path === void 0) { path = []; }
315
+ return {
316
+ cursor: createIsolateCursor(),
317
+ keys: {
318
+ current: {},
319
+ prev: {}
320
+ },
321
+ path: path,
322
+ type: type
323
+ };
324
+ }
325
+
233
326
  var context = context$1.createContext(function (ctxRef, parentContext) {
234
327
  return parentContext
235
328
  ? null
@@ -239,15 +332,8 @@ var context = context$1.createContext(function (ctxRef, parentContext) {
239
332
  groups: {}
240
333
  },
241
334
  inclusion: {},
242
- isolate: {
243
- type: IsolateTypes.DEFAULT,
244
- keys: {
245
- current: {},
246
- prev: {}
247
- }
248
- },
249
- mode: [Modes.ALL],
250
- testCursor: createCursor()
335
+ isolate: generateIsolate(IsolateTypes.DEFAULT),
336
+ mode: [Modes.ALL]
251
337
  }, ctxRef);
252
338
  });
253
339
 
@@ -466,20 +552,6 @@ var STATUS_PENDING = 'PENDING';
466
552
  var STATUS_CANCELED = 'CANCELED';
467
553
  var STATUS_OMITTED = 'OMITTED';
468
554
 
469
- function invariant(condition,
470
- // eslint-disable-next-line @typescript-eslint/ban-types
471
- message) {
472
- if (condition) {
473
- return;
474
- }
475
- // If message is a string object (rather than string literal)
476
- // Throw the value directly as a string
477
- // Alternatively, throw an error with the message
478
- throw message instanceof String
479
- ? message.valueOf()
480
- : new Error(message ? optionalFunctionValue(message) : message);
481
- }
482
-
483
555
  // eslint-disable-next-line max-lines-per-function
484
556
  function createState(onStateChange) {
485
557
  var state = {
@@ -563,87 +635,6 @@ function createStateRef(state, _a) {
563
635
  };
564
636
  }
565
637
 
566
- function isNullish(value) {
567
- return isNull(value) || isUndefined(value);
568
- }
569
-
570
- function deferThrow(message) {
571
- setTimeout(function () {
572
- throw new Error(message);
573
- }, 0);
574
- }
575
-
576
- function usePath() {
577
- var context$1 = context.useX();
578
- return context$1.testCursor.getCursor();
579
- }
580
- function useCursorAt() {
581
- var context$1 = context.useX();
582
- return context$1.testCursor.cursorAt();
583
- }
584
- function moveForward() {
585
- var context$1 = context.useX();
586
- return context$1.testCursor.next();
587
- }
588
- function addLevel() {
589
- var context$1 = context.useX();
590
- context$1.testCursor.addLevel();
591
- }
592
- function removeLevel() {
593
- var context$1 = context.useX();
594
- context$1.testCursor.removeLevel();
595
- }
596
-
597
- function usePrevKeys() {
598
- var prev = useTestObjects()[0].prev;
599
- return asArray(getCurrent(prev, usePath())).reduce(function (prevKeys, testObject) {
600
- if (!(testObject instanceof VestTest)) {
601
- return prevKeys;
602
- }
603
- if (isNullish(testObject.key)) {
604
- return prevKeys;
605
- }
606
- prevKeys[testObject.key] = testObject;
607
- return prevKeys;
608
- }, {});
609
- }
610
- function usePrevTestByKey(key) {
611
- var prev = context.useX().isolate.keys.prev;
612
- return prev[key];
613
- }
614
- function useRetainTestKey(key, testObject) {
615
- var context$1 = context.useX();
616
- var current = context$1.isolate.keys.current;
617
- if (isNullish(current[key])) {
618
- current[key] = testObject;
619
- }
620
- else {
621
- deferThrow("Encountered the same test key \"".concat(key, "\" twice. This may lead to tests overriding each other's results, or to tests being unexpectedly omitted."));
622
- }
623
- }
624
-
625
- function isolate(_a, callback) {
626
- var _b = _a.type, type = _b === void 0 ? IsolateTypes.DEFAULT : _b;
627
- invariant(isFunction(callback));
628
- var keys = {
629
- current: {},
630
- prev: {}
631
- };
632
- var path = usePath();
633
- return context.run({ isolate: { type: type, keys: keys } }, function () {
634
- addLevel();
635
- keys.prev = usePrevKeys();
636
- useSetTests(function (tests) { return setValueAtPath(tests, path, []); });
637
- var res = callback();
638
- removeLevel();
639
- moveForward();
640
- return res;
641
- });
642
- }
643
- function shouldAllowReorder() {
644
- return context.useX().isolate.type === IsolateTypes.EACH;
645
- }
646
-
647
638
  var Severity;
648
639
  (function (Severity) {
649
640
  Severity["WARNINGS"] = "warnings";
@@ -695,6 +686,11 @@ function matchingFieldName(testObject, fieldName) {
695
686
  return !!(fieldName && testObject.fieldName === fieldName);
696
687
  }
697
688
 
689
+ var nonMatchingGroupName = bindNot(matchingGroupName);
690
+ function matchingGroupName(testObject, groupName) {
691
+ return testObject.groupName === groupName;
692
+ }
693
+
698
694
  function either(a, b) {
699
695
  return !!a !== !!b;
700
696
  }
@@ -719,6 +715,15 @@ function hasFailuresByTestObjects(severityKey, fieldName) {
719
715
  return hasFailuresByTestObject(testObject, severityKey, fieldName);
720
716
  });
721
717
  }
718
+ function hasGroupFailuresByTestObjects(severityKey, groupName, fieldName) {
719
+ var testObjects = useTestsFlat();
720
+ return testObjects.some(function (testObject) {
721
+ if (nonMatchingGroupName(testObject, groupName)) {
722
+ return false;
723
+ }
724
+ return hasFailuresByTestObject(testObject, severityKey, fieldName);
725
+ });
726
+ }
722
727
  /**
723
728
  * Determines whether a certain test profile has failures.
724
729
  */
@@ -736,7 +741,7 @@ function hasFailuresByTestObject(testObject, severityKey, fieldName) {
736
741
  }
737
742
 
738
743
  // eslint-disable-next-line max-statements, complexity
739
- function shouldAddValidProp(fieldName) {
744
+ function shouldAddValidProperty(fieldName) {
740
745
  if (fieldIsOmitted(fieldName)) {
741
746
  return true;
742
747
  }
@@ -747,36 +752,78 @@ function shouldAddValidProp(fieldName) {
747
752
  if (isEmpty(testObjects)) {
748
753
  return false;
749
754
  }
755
+ // Does the given field have any pending tests that are not optional?
750
756
  if (hasNonOptionalIncomplete(fieldName)) {
751
757
  return false;
752
758
  }
753
759
  return noMissingTests(fieldName);
754
760
  }
761
+ function shouldAddValidPropertyInGroup(groupName, fieldName) {
762
+ if (fieldIsOmitted(fieldName)) {
763
+ return true;
764
+ }
765
+ if (hasGroupFailuresByTestObjects(Severity.ERRORS, groupName, fieldName)) {
766
+ return false;
767
+ }
768
+ // Do the given group/field have any pending tests that are not optional?
769
+ if (hasNonOptionalIncompleteByGroup(groupName, fieldName)) {
770
+ return false;
771
+ }
772
+ return noMissingTestsByGroup(groupName, fieldName);
773
+ }
755
774
  function fieldIsOmitted(fieldName) {
756
775
  if (!fieldName) {
757
776
  return false;
758
777
  }
759
778
  return useOptionalFieldApplied(fieldName) === true;
760
779
  }
780
+ // Does the given field have any pending tests that are not optional?
761
781
  function hasNonOptionalIncomplete(fieldName) {
762
782
  return isNotEmpty(useAllIncomplete().filter(function (testObject) {
763
- if (nonMatchingFieldName(testObject, fieldName)) {
783
+ return isOptionalFieldIncomplete(testObject, fieldName);
784
+ }));
785
+ }
786
+ // Do the given group/field have any pending tests that are not optional?
787
+ function hasNonOptionalIncompleteByGroup(groupName, fieldName) {
788
+ return isNotEmpty(useAllIncomplete().filter(function (testObject) {
789
+ if (nonMatchingGroupName(testObject, groupName)) {
764
790
  return false;
765
791
  }
766
- return useOptionalFieldConfig(testObject.fieldName) !== true;
792
+ return isOptionalFieldIncomplete(testObject, fieldName);
767
793
  }));
768
794
  }
795
+ function isOptionalFieldIncomplete(testObject, fieldName) {
796
+ if (nonMatchingFieldName(testObject, fieldName)) {
797
+ return false;
798
+ }
799
+ return useOptionalFieldConfig(testObject.fieldName) !== true;
800
+ }
769
801
  function noMissingTests(fieldName) {
770
802
  var testObjects = useTestsFlat();
771
803
  return testObjects.every(function (testObject) {
772
804
  if (nonMatchingFieldName(testObject, fieldName)) {
773
805
  return true;
774
806
  }
775
- return (useOptionalFieldConfig(testObject.fieldName) === true ||
776
- testObject.isTested() ||
777
- testObject.isOmitted());
807
+ return missingTestsLogic(testObject, fieldName);
808
+ });
809
+ }
810
+ function noMissingTestsByGroup(groupName, fieldName) {
811
+ var testObjects = useTestsFlat();
812
+ return testObjects.every(function (testObject) {
813
+ if (nonMatchingGroupName(testObject, groupName)) {
814
+ return true;
815
+ }
816
+ return missingTestsLogic(testObject, fieldName);
778
817
  });
779
818
  }
819
+ function missingTestsLogic(testObject, fieldName) {
820
+ if (nonMatchingFieldName(testObject, fieldName)) {
821
+ return true;
822
+ }
823
+ return (useOptionalFieldConfig(testObject.fieldName) === true ||
824
+ testObject.isTested() ||
825
+ testObject.isOmitted());
826
+ }
780
827
 
781
828
  function useSummary() {
782
829
  var summary = context.useX().summary;
@@ -798,7 +845,7 @@ function genTestsSummary() {
798
845
  appendToGroup(summary.groups, testObject);
799
846
  return summary;
800
847
  }, summary);
801
- summary.valid = shouldAddValidProp();
848
+ summary.valid = shouldAddValidProperty();
802
849
  return countFailures(summary);
803
850
  }
804
851
  function appendToTest(tests, testObject) {
@@ -807,7 +854,7 @@ function appendToTest(tests, testObject) {
807
854
  tests[testObject.fieldName].valid =
808
855
  tests[testObject.fieldName].valid === false
809
856
  ? false
810
- : shouldAddValidProp(testObject.fieldName);
857
+ : shouldAddValidProperty(testObject.fieldName);
811
858
  }
812
859
  /**
813
860
  * Appends to a group object if within a group
@@ -819,6 +866,10 @@ function appendToGroup(groups, testObject) {
819
866
  }
820
867
  groups[groupName] = groups[groupName] || {};
821
868
  groups[groupName][testObject.fieldName] = appendTestObject(groups[groupName], testObject);
869
+ groups[groupName][testObject.fieldName].valid =
870
+ groups[groupName][testObject.fieldName].valid === false
871
+ ? false
872
+ : shouldAddValidPropertyInGroup(groupName, testObject.fieldName);
822
873
  }
823
874
  /**
824
875
  * Counts the failed tests and adds global counters
@@ -867,6 +918,10 @@ function baseTestStats() {
867
918
  });
868
919
  }
869
920
 
921
+ function isPositive(value) {
922
+ return greaterThan(value, 0);
923
+ }
924
+
870
925
  // calls collectAll or getByFieldName depending on whether fieldName is provided
871
926
  function gatherFailures(testGroup, severityKey, fieldName) {
872
927
  return fieldName
@@ -879,10 +934,13 @@ function getByFieldName(testGroup, severityKey, fieldName) {
879
934
  }
880
935
  function collectAll(testGroup, severityKey) {
881
936
  var output = {};
937
+ var countKey = countKeyBySeverity(severityKey);
882
938
  for (var field in testGroup) {
883
- // We will probably never get to the fallback array
884
- // leaving it just in case the implementation changes
885
- output[field] = testGroup[field][severityKey] || [];
939
+ if (isPositive(testGroup[field][countKey])) {
940
+ // We will probably never get to the fallback array
941
+ // leaving it just in case the implementation changes
942
+ output[field] = testGroup[field][severityKey] || [];
943
+ }
886
944
  }
887
945
  return output;
888
946
  }
@@ -912,10 +970,6 @@ function getFailuresByGroup(groupName, severityKey, fieldName) {
912
970
  return gatherFailures(summary.groups[groupName], severityKey, fieldName);
913
971
  }
914
972
 
915
- function isPositive(value) {
916
- return greaterThan(value, 0);
917
- }
918
-
919
973
  function hasErrors(fieldName) {
920
974
  return hasFailures(SeverityCount.ERROR_COUNT, fieldName);
921
975
  }
@@ -958,9 +1012,30 @@ function hasFailuresByGroup(severityKey, groupName, fieldName) {
958
1012
  }
959
1013
 
960
1014
  function isValid(fieldName) {
961
- var _a;
962
1015
  var summary = useSummary();
963
- return fieldName ? Boolean((_a = summary.tests[fieldName]) === null || _a === void 0 ? void 0 : _a.valid) : summary.valid;
1016
+ return fieldName
1017
+ ? Boolean(isFieldValid(summary.tests, fieldName))
1018
+ : summary.valid;
1019
+ }
1020
+ function isValidByGroup(groupName, fieldName) {
1021
+ var summary = useSummary();
1022
+ var group = summary.groups[groupName];
1023
+ if (!group) {
1024
+ return false;
1025
+ }
1026
+ if (fieldName) {
1027
+ return isFieldValid(group, fieldName);
1028
+ }
1029
+ for (var fieldName_1 in group) {
1030
+ if (!isFieldValid(group, fieldName_1)) {
1031
+ return false;
1032
+ }
1033
+ }
1034
+ return true;
1035
+ }
1036
+ function isFieldValid(testContainer, fieldName) {
1037
+ var _a;
1038
+ return !!((_a = testContainer[fieldName]) === null || _a === void 0 ? void 0 : _a.valid);
964
1039
  }
965
1040
 
966
1041
  var cache$1 = createCache(1);
@@ -981,6 +1056,7 @@ function produceSuiteResult() {
981
1056
  hasWarnings: context.bind(ref, hasWarnings),
982
1057
  hasWarningsByGroup: context.bind(ref, hasWarningsByGroup),
983
1058
  isValid: context.bind(ref, isValid),
1059
+ isValidByGroup: context.bind(ref, isValidByGroup),
984
1060
  suiteName: suiteName
985
1061
  });
986
1062
  }));
@@ -1578,7 +1654,7 @@ function optional(optionals) {
1578
1654
  }
1579
1655
  }
1580
1656
 
1581
- /*! *****************************************************************************
1657
+ /******************************************************************************
1582
1658
  Copyright (c) Microsoft Corporation.
1583
1659
 
1584
1660
  Permission to use, copy, modify, and/or distribute this software for any
@@ -1723,8 +1799,8 @@ function useTestAtCursor(newTestObject) {
1723
1799
  function removeAllNextTestsInIsolate() {
1724
1800
  var _a = useTestObjects(), testObjects = _a[0], setTestObjects = _a[1];
1725
1801
  var prevTests = testObjects.prev;
1726
- var current = getCurrent(prevTests, usePath());
1727
- var cursorAt = useCursorAt();
1802
+ var current = getCurrent(prevTests, useCurrentPath());
1803
+ var cursorAt = useCursor().current();
1728
1804
  current.splice(cursorAt);
1729
1805
  // We actually don't mind mutating the state directly (as can be seen above). There is no harm in it
1730
1806
  // since we're only touching the "prev" state. The reason we still use the setter function is
@@ -1738,13 +1814,13 @@ function removeAllNextTestsInIsolate() {
1738
1814
  });
1739
1815
  }
1740
1816
  function useSetTestAtCursor(testObject) {
1741
- var cursorPath = usePath();
1817
+ var cursorPath = useCurrentPath();
1742
1818
  useSetTests(function (tests) {
1743
1819
  return setValueAtPath(tests, cursorPath, testObject);
1744
1820
  });
1745
1821
  }
1746
1822
  function useGetTestAtCursor(tests) {
1747
- var cursorPath = usePath();
1823
+ var cursorPath = useCurrentPath();
1748
1824
  return valueAtPath(tests, cursorPath);
1749
1825
  }
1750
1826
  function testReorderDetected(prevTest, newTest) {
@@ -1768,16 +1844,17 @@ function handleKeyTest(key, newTestObject) {
1768
1844
 
1769
1845
  // eslint-disable-next-line max-statements
1770
1846
  function registerPrevRunTest(testObject) {
1847
+ var cursor = useCursor();
1771
1848
  if (shouldSkipBasedOnMode(testObject)) {
1772
1849
  testObject.skip();
1773
1850
  useTestAtCursor(testObject);
1774
- moveForward();
1851
+ cursor.next();
1775
1852
  return testObject;
1776
1853
  }
1777
1854
  var prevRunTest = useTestAtCursor(testObject);
1778
1855
  if (isOmitted()) {
1779
1856
  prevRunTest.omit();
1780
- moveForward();
1857
+ cursor.next();
1781
1858
  return prevRunTest;
1782
1859
  }
1783
1860
  if (isExcluded(testObject)) {
@@ -1786,13 +1863,13 @@ function registerPrevRunTest(testObject) {
1786
1863
  // This mostly means that we're probably giving
1787
1864
  // up on this async test intentionally.
1788
1865
  prevRunTest.skip(isExcludedIndividually());
1789
- moveForward();
1866
+ cursor.next();
1790
1867
  return prevRunTest;
1791
1868
  }
1792
1869
  cancelOverriddenPendingTest(prevRunTest, testObject);
1793
1870
  useSetTestAtCursor(testObject);
1794
- moveForward();
1795
1871
  registerTestObjectByTier(testObject);
1872
+ cursor.next();
1796
1873
  return testObject;
1797
1874
  }
1798
1875
  function registerTestObjectByTier(testObject) {
@@ -1815,7 +1892,7 @@ function bindTestMemo(test) {
1815
1892
  for (var _i = 1; _i < arguments.length; _i++) {
1816
1893
  args[_i - 1] = arguments[_i];
1817
1894
  }
1818
- var cursorAt = useCursorAt();
1895
+ var cursorAt = useCursor().current();
1819
1896
  var _a = args.reverse(), deps = _a[0], testFn = _a[1], msg = _a[2];
1820
1897
  // Implicit dependency for more specificity
1821
1898
  var dependencies = [useSuiteId(), fieldName, cursorAt].concat(deps);
@@ -1877,7 +1954,7 @@ function warn() {
1877
1954
  ctx.currentTest.warn();
1878
1955
  }
1879
1956
 
1880
- var VERSION = "4.3.3";
1957
+ var VERSION = "4.4.0";
1881
1958
 
1882
1959
  Object.defineProperty(exports, 'enforce', {
1883
1960
  enumerable: true,