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.
@@ -176,40 +176,6 @@ function getCurrent(array, path) {
176
176
  return current;
177
177
  }
178
178
 
179
- function createCursor() {
180
- var storage = {
181
- cursor: []
182
- };
183
- function addLevel() {
184
- storage.cursor.push(0);
185
- }
186
- function removeLevel() {
187
- storage.cursor.pop();
188
- }
189
- function cursorAt() {
190
- return last(storage.cursor);
191
- }
192
- function getCursor() {
193
- return asArray(storage.cursor);
194
- }
195
- function next() {
196
- storage.cursor[storage.cursor.length - 1]++;
197
- return last(storage.cursor);
198
- }
199
- function reset() {
200
- storage.cursor = [0];
201
- }
202
- reset();
203
- return {
204
- addLevel: addLevel,
205
- cursorAt: cursorAt,
206
- getCursor: getCursor,
207
- next: next,
208
- removeLevel: removeLevel,
209
- reset: reset
210
- };
211
- }
212
-
213
179
  var IsolateTypes;
214
180
  (function (IsolateTypes) {
215
181
  IsolateTypes[IsolateTypes["DEFAULT"] = 0] = "DEFAULT";
@@ -226,6 +192,133 @@ var Modes;
226
192
  Modes[Modes["EAGER"] = 1] = "EAGER";
227
193
  })(Modes || (Modes = {}));
228
194
 
195
+ function invariant(condition,
196
+ // eslint-disable-next-line @typescript-eslint/ban-types
197
+ message) {
198
+ if (condition) {
199
+ return;
200
+ }
201
+ // If message is a string object (rather than string literal)
202
+ // Throw the value directly as a string
203
+ // Alternatively, throw an error with the message
204
+ throw message instanceof String
205
+ ? message.valueOf()
206
+ : new Error(message ? optionalFunctionValue(message) : message);
207
+ }
208
+
209
+ function createIsolateCursor() {
210
+ var cursor = {
211
+ value: 0
212
+ };
213
+ return {
214
+ current: current,
215
+ next: next
216
+ };
217
+ /**
218
+ * @returns {number} The current value of the cursor
219
+ */
220
+ function current() {
221
+ return cursor.value;
222
+ }
223
+ /**
224
+ * Moves the isolate cursor forward by 1
225
+ */
226
+ function next() {
227
+ cursor.value++;
228
+ }
229
+ }
230
+
231
+ function isNullish(value) {
232
+ return isNull(value) || isUndefined(value);
233
+ }
234
+
235
+ function deferThrow(message) {
236
+ setTimeout(function () {
237
+ throw new Error(message);
238
+ }, 0);
239
+ }
240
+
241
+ function usePrevKeys() {
242
+ var prev = useTestObjects()[0].prev;
243
+ return asArray(getCurrent(prev, useCurrentPath())).reduce(function (prevKeys, testObject) {
244
+ if (!(testObject instanceof VestTest)) {
245
+ return prevKeys;
246
+ }
247
+ if (isNullish(testObject.key)) {
248
+ return prevKeys;
249
+ }
250
+ prevKeys[testObject.key] = testObject;
251
+ return prevKeys;
252
+ }, {});
253
+ }
254
+ function usePrevTestByKey(key) {
255
+ var prev = context.useX().isolate.keys.prev;
256
+ return prev[key];
257
+ }
258
+ function useRetainTestKey(key, testObject) {
259
+ var context$1 = context.useX();
260
+ var current = context$1.isolate.keys.current;
261
+ if (isNullish(current[key])) {
262
+ current[key] = testObject;
263
+ }
264
+ else {
265
+ 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."));
266
+ }
267
+ }
268
+
269
+ function isolate(_a, callback) {
270
+ var _b = _a.type, type = _b === void 0 ? IsolateTypes.DEFAULT : _b;
271
+ invariant(isFunction(callback));
272
+ // Generate a new Isolate layer, with its own cursor
273
+ var isolate = generateIsolate(type, useCurrentPath());
274
+ var output = context.run({ isolate: isolate }, function () {
275
+ isolate.keys.prev = usePrevKeys();
276
+ useSetTests(function (tests) { return setValueAtPath(tests, isolate.path, []); });
277
+ var res = callback();
278
+ return res;
279
+ });
280
+ // Move the parent cursor forward once we're done
281
+ useCursor().next();
282
+ return output;
283
+ }
284
+ /**
285
+ * @returns {Isolate} The current isolate layer
286
+ */
287
+ function useIsolate() {
288
+ return context.useX().isolate;
289
+ }
290
+ /**
291
+ * @returns {boolean} Whether or not the current isolate allows tests to be reordered
292
+ */
293
+ function shouldAllowReorder() {
294
+ return context.useX().isolate.type === IsolateTypes.EACH;
295
+ }
296
+ /**
297
+ * @returns {number[]} The current cursor path of the isolate tree
298
+ */
299
+ function useCurrentPath() {
300
+ var isolate = useIsolate();
301
+ return isolate.path.concat(isolate.cursor.current());
302
+ }
303
+ /**
304
+ * @returns {IsolateCursor} The cursor object for the current isolate
305
+ */
306
+ function useCursor() {
307
+ return useIsolate().cursor;
308
+ }
309
+ function generateIsolate(type, path) {
310
+ if (path === void 0) { path = []; }
311
+ return {
312
+ cursor: createIsolateCursor(),
313
+ keys: {
314
+ current: {},
315
+ prev: {}
316
+ },
317
+ path: path,
318
+ type: type
319
+ };
320
+ }
321
+
229
322
  var context = createContext(function (ctxRef, parentContext) {
230
323
  return parentContext
231
324
  ? null
@@ -235,15 +328,8 @@ var context = createContext(function (ctxRef, parentContext) {
235
328
  groups: {}
236
329
  },
237
330
  inclusion: {},
238
- isolate: {
239
- type: IsolateTypes.DEFAULT,
240
- keys: {
241
- current: {},
242
- prev: {}
243
- }
244
- },
245
- mode: [Modes.ALL],
246
- testCursor: createCursor()
331
+ isolate: generateIsolate(IsolateTypes.DEFAULT),
332
+ mode: [Modes.ALL]
247
333
  }, ctxRef);
248
334
  });
249
335
 
@@ -462,20 +548,6 @@ var STATUS_PENDING = 'PENDING';
462
548
  var STATUS_CANCELED = 'CANCELED';
463
549
  var STATUS_OMITTED = 'OMITTED';
464
550
 
465
- function invariant(condition,
466
- // eslint-disable-next-line @typescript-eslint/ban-types
467
- message) {
468
- if (condition) {
469
- return;
470
- }
471
- // If message is a string object (rather than string literal)
472
- // Throw the value directly as a string
473
- // Alternatively, throw an error with the message
474
- throw message instanceof String
475
- ? message.valueOf()
476
- : new Error(message ? optionalFunctionValue(message) : message);
477
- }
478
-
479
551
  // eslint-disable-next-line max-lines-per-function
480
552
  function createState(onStateChange) {
481
553
  var state = {
@@ -559,87 +631,6 @@ function createStateRef(state, _a) {
559
631
  };
560
632
  }
561
633
 
562
- function isNullish(value) {
563
- return isNull(value) || isUndefined(value);
564
- }
565
-
566
- function deferThrow(message) {
567
- setTimeout(function () {
568
- throw new Error(message);
569
- }, 0);
570
- }
571
-
572
- function usePath() {
573
- var context$1 = context.useX();
574
- return context$1.testCursor.getCursor();
575
- }
576
- function useCursorAt() {
577
- var context$1 = context.useX();
578
- return context$1.testCursor.cursorAt();
579
- }
580
- function moveForward() {
581
- var context$1 = context.useX();
582
- return context$1.testCursor.next();
583
- }
584
- function addLevel() {
585
- var context$1 = context.useX();
586
- context$1.testCursor.addLevel();
587
- }
588
- function removeLevel() {
589
- var context$1 = context.useX();
590
- context$1.testCursor.removeLevel();
591
- }
592
-
593
- function usePrevKeys() {
594
- var prev = useTestObjects()[0].prev;
595
- return asArray(getCurrent(prev, usePath())).reduce(function (prevKeys, testObject) {
596
- if (!(testObject instanceof VestTest)) {
597
- return prevKeys;
598
- }
599
- if (isNullish(testObject.key)) {
600
- return prevKeys;
601
- }
602
- prevKeys[testObject.key] = testObject;
603
- return prevKeys;
604
- }, {});
605
- }
606
- function usePrevTestByKey(key) {
607
- var prev = context.useX().isolate.keys.prev;
608
- return prev[key];
609
- }
610
- function useRetainTestKey(key, testObject) {
611
- var context$1 = context.useX();
612
- var current = context$1.isolate.keys.current;
613
- if (isNullish(current[key])) {
614
- current[key] = testObject;
615
- }
616
- else {
617
- 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."));
618
- }
619
- }
620
-
621
- function isolate(_a, callback) {
622
- var _b = _a.type, type = _b === void 0 ? IsolateTypes.DEFAULT : _b;
623
- invariant(isFunction(callback));
624
- var keys = {
625
- current: {},
626
- prev: {}
627
- };
628
- var path = usePath();
629
- return context.run({ isolate: { type: type, keys: keys } }, function () {
630
- addLevel();
631
- keys.prev = usePrevKeys();
632
- useSetTests(function (tests) { return setValueAtPath(tests, path, []); });
633
- var res = callback();
634
- removeLevel();
635
- moveForward();
636
- return res;
637
- });
638
- }
639
- function shouldAllowReorder() {
640
- return context.useX().isolate.type === IsolateTypes.EACH;
641
- }
642
-
643
634
  var Severity;
644
635
  (function (Severity) {
645
636
  Severity["WARNINGS"] = "warnings";
@@ -691,6 +682,11 @@ function matchingFieldName(testObject, fieldName) {
691
682
  return !!(fieldName && testObject.fieldName === fieldName);
692
683
  }
693
684
 
685
+ var nonMatchingGroupName = bindNot(matchingGroupName);
686
+ function matchingGroupName(testObject, groupName) {
687
+ return testObject.groupName === groupName;
688
+ }
689
+
694
690
  function either(a, b) {
695
691
  return !!a !== !!b;
696
692
  }
@@ -715,6 +711,15 @@ function hasFailuresByTestObjects(severityKey, fieldName) {
715
711
  return hasFailuresByTestObject(testObject, severityKey, fieldName);
716
712
  });
717
713
  }
714
+ function hasGroupFailuresByTestObjects(severityKey, groupName, fieldName) {
715
+ var testObjects = useTestsFlat();
716
+ return testObjects.some(function (testObject) {
717
+ if (nonMatchingGroupName(testObject, groupName)) {
718
+ return false;
719
+ }
720
+ return hasFailuresByTestObject(testObject, severityKey, fieldName);
721
+ });
722
+ }
718
723
  /**
719
724
  * Determines whether a certain test profile has failures.
720
725
  */
@@ -732,7 +737,7 @@ function hasFailuresByTestObject(testObject, severityKey, fieldName) {
732
737
  }
733
738
 
734
739
  // eslint-disable-next-line max-statements, complexity
735
- function shouldAddValidProp(fieldName) {
740
+ function shouldAddValidProperty(fieldName) {
736
741
  if (fieldIsOmitted(fieldName)) {
737
742
  return true;
738
743
  }
@@ -743,36 +748,78 @@ function shouldAddValidProp(fieldName) {
743
748
  if (isEmpty(testObjects)) {
744
749
  return false;
745
750
  }
751
+ // Does the given field have any pending tests that are not optional?
746
752
  if (hasNonOptionalIncomplete(fieldName)) {
747
753
  return false;
748
754
  }
749
755
  return noMissingTests(fieldName);
750
756
  }
757
+ function shouldAddValidPropertyInGroup(groupName, fieldName) {
758
+ if (fieldIsOmitted(fieldName)) {
759
+ return true;
760
+ }
761
+ if (hasGroupFailuresByTestObjects(Severity.ERRORS, groupName, fieldName)) {
762
+ return false;
763
+ }
764
+ // Do the given group/field have any pending tests that are not optional?
765
+ if (hasNonOptionalIncompleteByGroup(groupName, fieldName)) {
766
+ return false;
767
+ }
768
+ return noMissingTestsByGroup(groupName, fieldName);
769
+ }
751
770
  function fieldIsOmitted(fieldName) {
752
771
  if (!fieldName) {
753
772
  return false;
754
773
  }
755
774
  return useOptionalFieldApplied(fieldName) === true;
756
775
  }
776
+ // Does the given field have any pending tests that are not optional?
757
777
  function hasNonOptionalIncomplete(fieldName) {
758
778
  return isNotEmpty(useAllIncomplete().filter(function (testObject) {
759
- if (nonMatchingFieldName(testObject, fieldName)) {
779
+ return isOptionalFieldIncomplete(testObject, fieldName);
780
+ }));
781
+ }
782
+ // Do the given group/field have any pending tests that are not optional?
783
+ function hasNonOptionalIncompleteByGroup(groupName, fieldName) {
784
+ return isNotEmpty(useAllIncomplete().filter(function (testObject) {
785
+ if (nonMatchingGroupName(testObject, groupName)) {
760
786
  return false;
761
787
  }
762
- return useOptionalFieldConfig(testObject.fieldName) !== true;
788
+ return isOptionalFieldIncomplete(testObject, fieldName);
763
789
  }));
764
790
  }
791
+ function isOptionalFieldIncomplete(testObject, fieldName) {
792
+ if (nonMatchingFieldName(testObject, fieldName)) {
793
+ return false;
794
+ }
795
+ return useOptionalFieldConfig(testObject.fieldName) !== true;
796
+ }
765
797
  function noMissingTests(fieldName) {
766
798
  var testObjects = useTestsFlat();
767
799
  return testObjects.every(function (testObject) {
768
800
  if (nonMatchingFieldName(testObject, fieldName)) {
769
801
  return true;
770
802
  }
771
- return (useOptionalFieldConfig(testObject.fieldName) === true ||
772
- testObject.isTested() ||
773
- testObject.isOmitted());
803
+ return missingTestsLogic(testObject, fieldName);
804
+ });
805
+ }
806
+ function noMissingTestsByGroup(groupName, fieldName) {
807
+ var testObjects = useTestsFlat();
808
+ return testObjects.every(function (testObject) {
809
+ if (nonMatchingGroupName(testObject, groupName)) {
810
+ return true;
811
+ }
812
+ return missingTestsLogic(testObject, fieldName);
774
813
  });
775
814
  }
815
+ function missingTestsLogic(testObject, fieldName) {
816
+ if (nonMatchingFieldName(testObject, fieldName)) {
817
+ return true;
818
+ }
819
+ return (useOptionalFieldConfig(testObject.fieldName) === true ||
820
+ testObject.isTested() ||
821
+ testObject.isOmitted());
822
+ }
776
823
 
777
824
  function useSummary() {
778
825
  var summary = context.useX().summary;
@@ -794,7 +841,7 @@ function genTestsSummary() {
794
841
  appendToGroup(summary.groups, testObject);
795
842
  return summary;
796
843
  }, summary);
797
- summary.valid = shouldAddValidProp();
844
+ summary.valid = shouldAddValidProperty();
798
845
  return countFailures(summary);
799
846
  }
800
847
  function appendToTest(tests, testObject) {
@@ -803,7 +850,7 @@ function appendToTest(tests, testObject) {
803
850
  tests[testObject.fieldName].valid =
804
851
  tests[testObject.fieldName].valid === false
805
852
  ? false
806
- : shouldAddValidProp(testObject.fieldName);
853
+ : shouldAddValidProperty(testObject.fieldName);
807
854
  }
808
855
  /**
809
856
  * Appends to a group object if within a group
@@ -815,6 +862,10 @@ function appendToGroup(groups, testObject) {
815
862
  }
816
863
  groups[groupName] = groups[groupName] || {};
817
864
  groups[groupName][testObject.fieldName] = appendTestObject(groups[groupName], testObject);
865
+ groups[groupName][testObject.fieldName].valid =
866
+ groups[groupName][testObject.fieldName].valid === false
867
+ ? false
868
+ : shouldAddValidPropertyInGroup(groupName, testObject.fieldName);
818
869
  }
819
870
  /**
820
871
  * Counts the failed tests and adds global counters
@@ -863,6 +914,10 @@ function baseTestStats() {
863
914
  });
864
915
  }
865
916
 
917
+ function isPositive(value) {
918
+ return greaterThan(value, 0);
919
+ }
920
+
866
921
  // calls collectAll or getByFieldName depending on whether fieldName is provided
867
922
  function gatherFailures(testGroup, severityKey, fieldName) {
868
923
  return fieldName
@@ -875,10 +930,13 @@ function getByFieldName(testGroup, severityKey, fieldName) {
875
930
  }
876
931
  function collectAll(testGroup, severityKey) {
877
932
  var output = {};
933
+ var countKey = countKeyBySeverity(severityKey);
878
934
  for (var field in testGroup) {
879
- // We will probably never get to the fallback array
880
- // leaving it just in case the implementation changes
881
- output[field] = testGroup[field][severityKey] || [];
935
+ if (isPositive(testGroup[field][countKey])) {
936
+ // We will probably never get to the fallback array
937
+ // leaving it just in case the implementation changes
938
+ output[field] = testGroup[field][severityKey] || [];
939
+ }
882
940
  }
883
941
  return output;
884
942
  }
@@ -908,10 +966,6 @@ function getFailuresByGroup(groupName, severityKey, fieldName) {
908
966
  return gatherFailures(summary.groups[groupName], severityKey, fieldName);
909
967
  }
910
968
 
911
- function isPositive(value) {
912
- return greaterThan(value, 0);
913
- }
914
-
915
969
  function hasErrors(fieldName) {
916
970
  return hasFailures(SeverityCount.ERROR_COUNT, fieldName);
917
971
  }
@@ -954,9 +1008,30 @@ function hasFailuresByGroup(severityKey, groupName, fieldName) {
954
1008
  }
955
1009
 
956
1010
  function isValid(fieldName) {
957
- var _a;
958
1011
  var summary = useSummary();
959
- return fieldName ? Boolean((_a = summary.tests[fieldName]) === null || _a === void 0 ? void 0 : _a.valid) : summary.valid;
1012
+ return fieldName
1013
+ ? Boolean(isFieldValid(summary.tests, fieldName))
1014
+ : summary.valid;
1015
+ }
1016
+ function isValidByGroup(groupName, fieldName) {
1017
+ var summary = useSummary();
1018
+ var group = summary.groups[groupName];
1019
+ if (!group) {
1020
+ return false;
1021
+ }
1022
+ if (fieldName) {
1023
+ return isFieldValid(group, fieldName);
1024
+ }
1025
+ for (var fieldName_1 in group) {
1026
+ if (!isFieldValid(group, fieldName_1)) {
1027
+ return false;
1028
+ }
1029
+ }
1030
+ return true;
1031
+ }
1032
+ function isFieldValid(testContainer, fieldName) {
1033
+ var _a;
1034
+ return !!((_a = testContainer[fieldName]) === null || _a === void 0 ? void 0 : _a.valid);
960
1035
  }
961
1036
 
962
1037
  var cache$1 = createCache(1);
@@ -977,6 +1052,7 @@ function produceSuiteResult() {
977
1052
  hasWarnings: context.bind(ref, hasWarnings),
978
1053
  hasWarningsByGroup: context.bind(ref, hasWarningsByGroup),
979
1054
  isValid: context.bind(ref, isValid),
1055
+ isValidByGroup: context.bind(ref, isValidByGroup),
980
1056
  suiteName: suiteName
981
1057
  });
982
1058
  }));
@@ -1574,7 +1650,7 @@ function optional(optionals) {
1574
1650
  }
1575
1651
  }
1576
1652
 
1577
- /*! *****************************************************************************
1653
+ /******************************************************************************
1578
1654
  Copyright (c) Microsoft Corporation.
1579
1655
 
1580
1656
  Permission to use, copy, modify, and/or distribute this software for any
@@ -1719,8 +1795,8 @@ function useTestAtCursor(newTestObject) {
1719
1795
  function removeAllNextTestsInIsolate() {
1720
1796
  var _a = useTestObjects(), testObjects = _a[0], setTestObjects = _a[1];
1721
1797
  var prevTests = testObjects.prev;
1722
- var current = getCurrent(prevTests, usePath());
1723
- var cursorAt = useCursorAt();
1798
+ var current = getCurrent(prevTests, useCurrentPath());
1799
+ var cursorAt = useCursor().current();
1724
1800
  current.splice(cursorAt);
1725
1801
  // We actually don't mind mutating the state directly (as can be seen above). There is no harm in it
1726
1802
  // since we're only touching the "prev" state. The reason we still use the setter function is
@@ -1734,13 +1810,13 @@ function removeAllNextTestsInIsolate() {
1734
1810
  });
1735
1811
  }
1736
1812
  function useSetTestAtCursor(testObject) {
1737
- var cursorPath = usePath();
1813
+ var cursorPath = useCurrentPath();
1738
1814
  useSetTests(function (tests) {
1739
1815
  return setValueAtPath(tests, cursorPath, testObject);
1740
1816
  });
1741
1817
  }
1742
1818
  function useGetTestAtCursor(tests) {
1743
- var cursorPath = usePath();
1819
+ var cursorPath = useCurrentPath();
1744
1820
  return valueAtPath(tests, cursorPath);
1745
1821
  }
1746
1822
  function testReorderDetected(prevTest, newTest) {
@@ -1764,16 +1840,17 @@ function handleKeyTest(key, newTestObject) {
1764
1840
 
1765
1841
  // eslint-disable-next-line max-statements
1766
1842
  function registerPrevRunTest(testObject) {
1843
+ var cursor = useCursor();
1767
1844
  if (shouldSkipBasedOnMode(testObject)) {
1768
1845
  testObject.skip();
1769
1846
  useTestAtCursor(testObject);
1770
- moveForward();
1847
+ cursor.next();
1771
1848
  return testObject;
1772
1849
  }
1773
1850
  var prevRunTest = useTestAtCursor(testObject);
1774
1851
  if (isOmitted()) {
1775
1852
  prevRunTest.omit();
1776
- moveForward();
1853
+ cursor.next();
1777
1854
  return prevRunTest;
1778
1855
  }
1779
1856
  if (isExcluded(testObject)) {
@@ -1782,13 +1859,13 @@ function registerPrevRunTest(testObject) {
1782
1859
  // This mostly means that we're probably giving
1783
1860
  // up on this async test intentionally.
1784
1861
  prevRunTest.skip(isExcludedIndividually());
1785
- moveForward();
1862
+ cursor.next();
1786
1863
  return prevRunTest;
1787
1864
  }
1788
1865
  cancelOverriddenPendingTest(prevRunTest, testObject);
1789
1866
  useSetTestAtCursor(testObject);
1790
- moveForward();
1791
1867
  registerTestObjectByTier(testObject);
1868
+ cursor.next();
1792
1869
  return testObject;
1793
1870
  }
1794
1871
  function registerTestObjectByTier(testObject) {
@@ -1811,7 +1888,7 @@ function bindTestMemo(test) {
1811
1888
  for (var _i = 1; _i < arguments.length; _i++) {
1812
1889
  args[_i - 1] = arguments[_i];
1813
1890
  }
1814
- var cursorAt = useCursorAt();
1891
+ var cursorAt = useCursor().current();
1815
1892
  var _a = args.reverse(), deps = _a[0], testFn = _a[1], msg = _a[2];
1816
1893
  // Implicit dependency for more specificity
1817
1894
  var dependencies = [useSuiteId(), fieldName, cursorAt].concat(deps);
@@ -1873,6 +1950,6 @@ function warn() {
1873
1950
  ctx.currentTest.warn();
1874
1951
  }
1875
1952
 
1876
- var VERSION = "4.3.3";
1953
+ var VERSION = "4.4.0";
1877
1954
 
1878
1955
  export { VERSION, context, create, each, eager, group, include, omitWhen, only, optional, skip, skipWhen, test, warn };