vest 3.3.0-dev-92c1af → 4.0.0-dev-f53683

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 CHANGED
@@ -4,48 +4,61 @@ All notable changes to this project will be documented in this file.
4
4
 
5
5
  The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
6
6
 
7
- ## 3.3.0 - 2021-09-15
7
+ ## 4.0.0 - 2021-10-07
8
+ ### Changed or removed
9
+ - 0e3af10 major(context): used named export in context (ealush)
10
+ - 1897164 major(vest, enforce): setup next major version (ealush)
11
+ - bf9265e breaking(vest, enforce): prepare next major (ealush)
12
+
8
13
  ### Added
9
- - fe6af86 feat(vest): Add a parser export (ealush)
10
- - 7501303 feat(vest): isValid with field name (ealush)
11
- - 160071e feat(vest): handle execution order state refill with memoized tests (ealush)
12
- - 4122ceb feat(vest): Make the state rely on execution order. Add skipWhen. (undefined)
13
- - f38d86d added(n4s): partial rule modifier (undefined)
14
- - 362410c feat(n4s): context propagation within enforce (undefined)
14
+ - b0cbb32 feat(vest): Add a parser export (ealush)
15
+ - fc75f1d feat(vest): isValid with field name (ealush)
16
+ - c427e4e feat(vest): handle execution order state refill with memoized tests (ealush)
17
+ - 443c275 feat(vest): Make the state rely on execution order. Add skipWhen. (undefined)
18
+ - 2988655 added(n4s): partial rule modifier (undefined)
19
+ - f41a444 feat(n4s): context propagation within enforce (undefined)
15
20
 
16
21
  ### Fixed and improved
17
- - .github/workflows/integration.yml
22
+ - f536834 fix(vest): prevent changing test status once it was finalized (ealush)
23
+ - df64c2e patch(vest): add cache invalidation for canceled tests (ealush)
24
+ - fd1e31e types(vest): add safeguard around shouldUseErrorAsMessage (ealush)
25
+ - 8321a36 patch(vest): some cleanups (ealush)
26
+ - 8320956 patch(vest): remove duplicate code handling perv test registration (ealush)
27
+ - 7e3fffb vx: use context directly from published package (ealush)
28
+ - ac45a64 patch: run done callbacks via event (ealush)
29
+ - e0f05d6 patch(vest): removed state subscription (ealush)
30
+ - package.json
31
+ - packages/anyone/package.json
32
+ - packages/anyone/package.json
18
33
  - packages/vast/types/vast.d.ts
19
- - 59779fc patch(vest): remove pending and lagging state (ealush)
20
- - 1d024b2 patch(vest): convert boolean flags to a single status key (ealush)
21
- - ba3990c patch: simplify fieldname comparison (ealush)
22
- - e37d7f2 patch(vest): add useAllIncomplete hook (ealush)
23
- - 14ae130 patch(vest): invalid accounts for warning tests as well (ealush)
24
- - 8054ee9 patch(vest): isValid counts all required tests per field (ealush)
25
- - 5b25f55 chore: cleanups (ealush)
34
+ - 2515275 patch(vest): remove pending and lagging state (ealush)
35
+ - 4c38835 patch(vest): convert boolean flags to a single status key (ealush)
36
+ - e24f0bd patch: simplify fieldname comparison (ealush)
37
+ - b927b5c patch(vest): add useAllIncomplete hook (ealush)
38
+ - a88dd38 patch(vest): invalid accounts for warning tests as well (ealush)
39
+ - eaf9bef patch(vest): isValid counts all required tests per field (ealush)
40
+ - 7a4ba03 chore: cleanups (ealush)
26
41
  - .eslintrc.js
27
- - 85fa7e8 add(n4s): enforce.condition (ealush)
42
+ - 1878ffc add(n4s): enforce.condition (ealush)
28
43
  - package.json
29
44
  - packages/anyone/package.json
30
- - d792787 chore: cleanup residue (undefined)
31
- - 7c3eaf3 chore: remove duplicate types (undefined)
45
+ - a89af46 chore: cleanup residue (undefined)
46
+ - be86496 chore: remove duplicate types (undefined)
32
47
  - packages/anyone/package.json
33
- - bad36ae patch: add nodejs exports (undefined)
34
- - bfbe922 patch: remove unused exports (undefined)
48
+ - 44de93f patch: add nodejs exports (undefined)
49
+ - abb0efe patch: remove unused exports (undefined)
35
50
  - packages/anyone/package.json
36
- - 32ce807 chore: reduce complexity, remove all lint errors (undefined)
51
+ - a8540de chore: reduce complexity, remove all lint errors (undefined)
37
52
  - packages/anyone/.npmignore
38
53
  - .github/PULL_REQUEST_TEMPLATE.md
39
- - 8171561 chore: cleanup unused code (ealush)
40
- - 681021b lint: handling lint of all packages (ealush)
54
+ - f58327f chore: cleanup unused code (ealush)
55
+ - 853cee6 lint: handling lint of all packages (ealush)
41
56
  - .gitignore
42
- - 527e3e1 patch(n4s): add ruleReturn default values (ealush)
43
- - 6c89f6c fix(n4s): make enforce compound runners fall back to correct response (ealush)
44
- - 9f2caca fix(n4s): make enforce chaining work (ealush)
45
- - 0ff7a9b chore: some lint fixes (ealush)
46
- - dbd7d13 add cli options support (ealush)
47
- - 3d0393c Vest 4 Infra Setup (ealush)
48
- - 6ee296e Vest 4 Infra Setup (ealush)
57
+ - d148f6d patch(n4s): add ruleReturn default values (ealush)
58
+ - c722fbd fix(n4s): make enforce compound runners fall back to correct response (ealush)
59
+ - fa65911 fix(n4s): make enforce chaining work (ealush)
60
+ - a2437a3 chore: some lint fixes (ealush)
61
+ - aabb5f4 add cli options support (ealush)
49
62
 
50
63
  ## 3.2.7 - 2021-07-17
51
64
 
@@ -198,7 +198,7 @@ function compounds() {
198
198
  return { allOf: allOf, anyOf: anyOf, noneOf: noneOf, oneOf: oneOf, optional: optional$1 };
199
199
  }
200
200
 
201
- function isStringValue (v) {
201
+ function isStringValue(v) {
202
202
  return String(v) === v;
203
203
  }
204
204
 
@@ -609,7 +609,7 @@ function transformResult(result, ruleName, value) {
609
609
  return ruleReturn(result);
610
610
  }
611
611
  else {
612
- return ruleReturn(result.pass, optionalFunctionValue.apply(void 0, __spreadArray([result.message, ruleName, value], args)));
612
+ return ruleReturn(result.pass, optionalFunctionValue.apply(void 0, __spreadArray([result.message, ruleName, value], args, false)));
613
613
  }
614
614
  }
615
615
  function validateResult(result) {
@@ -643,9 +643,9 @@ function enforceEager(value) {
643
643
  for (var _i = 0; _i < arguments.length; _i++) {
644
644
  args[_i] = arguments[_i];
645
645
  }
646
- var transformedResult = transformResult.apply(void 0, __spreadArray([ctx$1.run({ value: value }, function () { return rule.apply(void 0, __spreadArray([value], args)); }),
646
+ var transformedResult = transformResult.apply(void 0, __spreadArray([ctx$1.run({ value: value }, function () { return rule.apply(void 0, __spreadArray([value], args, false)); }),
647
647
  ruleName,
648
- value], args));
648
+ value], args, false));
649
649
  if (!transformedResult.pass) {
650
650
  if (isEmpty(transformedResult.message)) {
651
651
  throwError("enforce/" + ruleName + " failed with " + JSON.stringify(value));
@@ -675,7 +675,7 @@ function genEnforceLazy(key) {
675
675
  }
676
676
  var rule = getRule(ruleName);
677
677
  registeredRules.push(function (value) {
678
- return transformResult.apply(void 0, __spreadArray([rule.apply(void 0, __spreadArray([value], args)), ruleName, value], args));
678
+ return transformResult.apply(void 0, __spreadArray([rule.apply(void 0, __spreadArray([value], args, false)), ruleName, value], args, false));
679
679
  });
680
680
  var proxy = {
681
681
  run: function (value) {
@@ -895,10 +895,6 @@ function matchingFieldName(testObject, fieldName) {
895
895
  function createCache(maxSize) {
896
896
  if (maxSize === void 0) { maxSize = 10; }
897
897
  var cacheStorage = [];
898
- /**
899
- * @param {any[]} deps dependency array.
900
- * @param {Function} cache action function.
901
- */
902
898
  var cache = function (deps, cacheAction) {
903
899
  var cacheHit = cache.get(deps);
904
900
  // cache hit is not null
@@ -906,15 +902,21 @@ function createCache(maxSize) {
906
902
  return cacheHit[1];
907
903
  var result = cacheAction();
908
904
  cacheStorage.unshift([deps.concat(), result]);
909
- if (cacheStorage.length > maxSize) {
905
+ if (cacheStorage.length > maxSize)
910
906
  cacheStorage.length = maxSize;
911
- }
912
907
  return result;
913
908
  };
914
- /**
915
- * Retrieves an item from the cache.
916
- * @param {deps} deps Dependency array
917
- */
909
+ // invalidate an item in the cache by its dependencies
910
+ cache.invalidate = function (deps) {
911
+ var index = cacheStorage.findIndex(function (_a) {
912
+ var cachedDeps = _a[0];
913
+ return lengthEquals(deps, cachedDeps.length) &&
914
+ deps.every(function (dep, i) { return dep === cachedDeps[i]; });
915
+ });
916
+ if (index > -1)
917
+ cacheStorage.splice(index, 1);
918
+ };
919
+ // Retrieves an item from the cache.
918
920
  cache.get = function (deps) {
919
921
  return cacheStorage[cacheStorage.findIndex(function (_a) {
920
922
  var cachedDeps = _a[0];
@@ -1107,6 +1109,13 @@ function noMatch(testObject, severity, group, fieldName) {
1107
1109
  return false;
1108
1110
  }
1109
1111
 
1112
+ function getFailuresArrayOrObject(group, fieldName) {
1113
+ if (fieldName) {
1114
+ return group[fieldName];
1115
+ }
1116
+ return group;
1117
+ }
1118
+
1110
1119
  function getErrors(fieldName) {
1111
1120
  return getFailures('errors', fieldName);
1112
1121
  }
@@ -1121,25 +1130,16 @@ function getFailures(severityKey, fieldName) {
1121
1130
  var failureMessages = collectFailureMessages(severityKey, testObjects, {
1122
1131
  fieldName: fieldName
1123
1132
  });
1124
- if (fieldName) {
1125
- return failureMessages[fieldName];
1126
- }
1127
- return failureMessages;
1133
+ return getFailuresArrayOrObject(failureMessages, fieldName);
1128
1134
  }
1129
1135
 
1130
1136
  function getErrorsByGroup(groupName, fieldName) {
1131
1137
  var errors = getByGroup('errors', groupName, fieldName);
1132
- if (fieldName) {
1133
- return errors[fieldName];
1134
- }
1135
- return errors;
1138
+ return getFailuresArrayOrObject(errors, fieldName);
1136
1139
  }
1137
1140
  function getWarningsByGroup(groupName, fieldName) {
1138
- var errors = getByGroup('warnings', groupName, fieldName);
1139
- if (fieldName) {
1140
- return errors[fieldName];
1141
- }
1142
- return errors;
1141
+ var warnings = getByGroup('warnings', groupName, fieldName);
1142
+ return getFailuresArrayOrObject(warnings, fieldName);
1143
1143
  }
1144
1144
  /**
1145
1145
  * Gets failure messages by group.
@@ -1321,22 +1321,90 @@ function deferDoneCallback(doneCallback, fieldName) {
1321
1321
  });
1322
1322
  }
1323
1323
 
1324
+ function createBus() {
1325
+ var listeners = {};
1326
+ return {
1327
+ emit: function (event, data) {
1328
+ if (!listeners[event]) {
1329
+ return;
1330
+ }
1331
+ listeners[event].forEach(function (listener) {
1332
+ listener(data);
1333
+ });
1334
+ },
1335
+ on: function (event, handler) {
1336
+ if (!listeners[event]) {
1337
+ listeners[event] = [];
1338
+ }
1339
+ listeners[event].push(handler);
1340
+ return {
1341
+ off: function () {
1342
+ listeners[event] = listeners[event].filter(function (h) { return h !== handler; });
1343
+ }
1344
+ };
1345
+ }
1346
+ };
1347
+ }
1348
+
1349
+ function callEach(arr) {
1350
+ return arr.forEach(function (fn) { return fn(); });
1351
+ }
1352
+
1353
+ /**
1354
+ * Runs done callback per field when async tests are finished running.
1355
+ */
1356
+ function runFieldCallbacks(fieldName) {
1357
+ var fieldCallbacks = useTestCallbacks()[0].fieldCallbacks;
1358
+ if (fieldName) {
1359
+ if (!hasRemainingTests(fieldName) &&
1360
+ Array.isArray(fieldCallbacks[fieldName])) {
1361
+ callEach(fieldCallbacks[fieldName]);
1362
+ }
1363
+ }
1364
+ }
1365
+ /**
1366
+ * Runs unlabelled done callback when async tests are finished running.
1367
+ */
1368
+ function runDoneCallbacks() {
1369
+ var doneCallbacks = useTestCallbacks()[0].doneCallbacks;
1370
+ if (!hasRemainingTests()) {
1371
+ callEach(doneCallbacks);
1372
+ }
1373
+ }
1374
+
1375
+ function initBus() {
1376
+ var bus = createBus();
1377
+ bus.on(Events.TEST_COMPLETED, function (testObject) {
1378
+ if (testObject.isCanceled()) {
1379
+ return;
1380
+ }
1381
+ testObject.done();
1382
+ runFieldCallbacks(testObject.fieldName);
1383
+ runDoneCallbacks();
1384
+ });
1385
+ return bus;
1386
+ }
1387
+ function useBus() {
1388
+ var context = ctx.useX();
1389
+ if (!context.bus) {
1390
+ throwError();
1391
+ }
1392
+ return context.bus;
1393
+ }
1394
+ var Events;
1395
+ (function (Events) {
1396
+ Events["TEST_COMPLETED"] = "test_completed";
1397
+ })(Events || (Events = {}));
1398
+
1324
1399
  // eslint-disable-next-line max-lines-per-function
1325
1400
  function create(suiteCallback) {
1326
1401
  if (!isFunction(suiteCallback)) {
1327
1402
  throwError('Suite initialization error. Expected `tests` to be a function.');
1328
1403
  }
1329
- var handlers = [];
1330
- var state = createState(function () {
1331
- handlers.forEach(function (fn) {
1332
- return fn({
1333
- suiteState: stateRef,
1334
- type: 'suiteStateUpdate'
1335
- });
1336
- });
1337
- });
1404
+ var bus = initBus();
1405
+ var state = createState();
1338
1406
  var stateRef = createStateRef(state, { suiteId: genId() });
1339
- var suite = assign(ctx.bind({ stateRef: stateRef }, function () {
1407
+ var suite = assign(ctx.bind({ stateRef: stateRef, bus: bus }, function () {
1340
1408
  var args = [];
1341
1409
  for (var _i = 0; _i < arguments.length; _i++) {
1342
1410
  args[_i] = arguments[_i];
@@ -1360,16 +1428,7 @@ function create(suiteCallback) {
1360
1428
  }
1361
1429
  });
1362
1430
  }),
1363
- reset: state.reset,
1364
- subscribe: function (handler) {
1365
- if (!isFunction(handler))
1366
- return;
1367
- handlers.push(handler);
1368
- handler({
1369
- type: 'suiteSubscribeInit',
1370
- suiteState: stateRef
1371
- });
1372
- }
1431
+ reset: state.reset
1373
1432
  });
1374
1433
  return suite;
1375
1434
  }
@@ -1501,16 +1560,16 @@ function skipWhen(conditional, callback) {
1501
1560
  */
1502
1561
  function group(groupName, tests) {
1503
1562
  if (!isStringValue(groupName)) {
1504
- throwGroupError(groupName);
1563
+ throwGroupError('name must be a string');
1505
1564
  }
1506
1565
  if (!isFunction(tests)) {
1507
- throwGroupError(tests);
1566
+ throwGroupError('callback must be a function');
1508
1567
  }
1509
1568
  // Running with the context applied
1510
- ctx.bind({ groupName: groupName }, tests)();
1569
+ ctx.run({ groupName: groupName }, tests);
1511
1570
  }
1512
- function throwGroupError(value) {
1513
- throwError("group initialization error. Expected \"" + value + "\" to be a string.");
1571
+ function throwGroupError(error) {
1572
+ throwError("Wrong arguments passed to group. Group " + error + ".");
1514
1573
  }
1515
1574
 
1516
1575
  function optional(optionals) {
@@ -1547,6 +1606,7 @@ function removeTestFromState (testObject) {
1547
1606
  }
1548
1607
 
1549
1608
  function shouldUseErrorAsMessage(message, error) {
1609
+ // kind of cheating with this safe guard, but it does the job
1550
1610
  return isUndefined(message) && isStringValue(error);
1551
1611
  }
1552
1612
 
@@ -1582,7 +1642,7 @@ var VestTest = /** @class */ (function () {
1582
1642
  return result;
1583
1643
  };
1584
1644
  VestTest.prototype.setStatus = function (status) {
1585
- if (this.isCanceled()) {
1645
+ if (this.isFinalStatus()) {
1586
1646
  return;
1587
1647
  }
1588
1648
  this.status = status;
@@ -1594,7 +1654,7 @@ var VestTest = /** @class */ (function () {
1594
1654
  this.setStatus(this.warns ? STATUS_WARNING : STATUS_FAILED);
1595
1655
  };
1596
1656
  VestTest.prototype.done = function () {
1597
- if (this.isWarning() || this.isCanceled() || this.isFailing()) {
1657
+ if (this.isFinalStatus()) {
1598
1658
  return;
1599
1659
  }
1600
1660
  this.setStatus(STATUS_PASSING);
@@ -1602,6 +1662,9 @@ var VestTest = /** @class */ (function () {
1602
1662
  VestTest.prototype.warn = function () {
1603
1663
  this.warns = true;
1604
1664
  };
1665
+ VestTest.prototype.isFinalStatus = function () {
1666
+ return this.hasFailures() || this.isCanceled() || this.isPassing();
1667
+ };
1605
1668
  VestTest.prototype.skip = function () {
1606
1669
  this.setStatus(STATUS_SKIPPED);
1607
1670
  };
@@ -1621,6 +1684,9 @@ var VestTest = /** @class */ (function () {
1621
1684
  VestTest.prototype.isTested = function () {
1622
1685
  return this.hasFailures() || this.isPassing();
1623
1686
  };
1687
+ VestTest.prototype.isUntested = function () {
1688
+ return this.status === STATUS_UNTESTED;
1689
+ };
1624
1690
  VestTest.prototype.isFailing = function () {
1625
1691
  return this.status === STATUS_FAILED;
1626
1692
  };
@@ -1646,27 +1712,23 @@ var STATUS_PASSING = 'PASSING';
1646
1712
  var STATUS_PENDING = 'PENDING';
1647
1713
  var STATUS_CANCELED = 'CANCELED';
1648
1714
 
1715
+ function isPromise(value) {
1716
+ return value && isFunction(value.then);
1717
+ }
1718
+
1649
1719
  function isSameProfileTest(testObject1, testObject2) {
1650
1720
  return (testObject1.fieldName === testObject2.fieldName &&
1651
1721
  testObject1.groupName === testObject2.groupName);
1652
1722
  }
1653
1723
 
1654
1724
  function cancelOverriddenPendingTest(prevRunTestObject, currentRunTestObject) {
1655
- if (isSameProfileTest(prevRunTestObject, currentRunTestObject) &&
1656
- prevRunTestObject.isPending() &&
1657
- currentRunTestObject !== prevRunTestObject) {
1725
+ if (currentRunTestObject !== prevRunTestObject &&
1726
+ isSameProfileTest(prevRunTestObject, currentRunTestObject) &&
1727
+ prevRunTestObject.isPending()) {
1658
1728
  prevRunTestObject.cancel();
1659
1729
  }
1660
1730
  }
1661
1731
 
1662
- function isPromise(value) {
1663
- return value && isFunction(value.then);
1664
- }
1665
-
1666
- function callEach(arr) {
1667
- return arr.forEach(function (fn) { return fn(); });
1668
- }
1669
-
1670
1732
  /**
1671
1733
  * Runs async test.
1672
1734
  */
@@ -1674,16 +1736,10 @@ function runAsyncTest(testObject) {
1674
1736
  var asyncTest = testObject.asyncTest, message = testObject.message;
1675
1737
  if (!isPromise(asyncTest))
1676
1738
  return;
1739
+ var emit = useBus().emit;
1677
1740
  var stateRef = useStateRef();
1678
1741
  var done = ctx.bind({ stateRef: stateRef }, function () {
1679
- testObject.done();
1680
- // This is for cases in which the suite state was already reset
1681
- if (testObject.isCanceled()) {
1682
- return;
1683
- }
1684
- // Perform required done callback calls and cleanups after the test is finished
1685
- runFieldCallbacks(testObject.fieldName);
1686
- runDoneCallbacks();
1742
+ emit(Events.TEST_COMPLETED, testObject);
1687
1743
  });
1688
1744
  var fail = ctx.bind({ stateRef: stateRef }, function (rejectionMessage) {
1689
1745
  if (testObject.isCanceled()) {
@@ -1704,27 +1760,6 @@ function runAsyncTest(testObject) {
1704
1760
  fail();
1705
1761
  }
1706
1762
  }
1707
- /**
1708
- * Runs done callback per field when async tests are finished running.
1709
- */
1710
- function runFieldCallbacks(fieldName) {
1711
- var fieldCallbacks = useTestCallbacks()[0].fieldCallbacks;
1712
- if (fieldName) {
1713
- if (!hasRemainingTests(fieldName) &&
1714
- Array.isArray(fieldCallbacks[fieldName])) {
1715
- callEach(fieldCallbacks[fieldName]);
1716
- }
1717
- }
1718
- }
1719
- /**
1720
- * Runs unlabelled done callback when async tests are finished running.
1721
- */
1722
- function runDoneCallbacks() {
1723
- var doneCallbacks = useTestCallbacks()[0].doneCallbacks;
1724
- if (!hasRemainingTests()) {
1725
- callEach(doneCallbacks);
1726
- }
1727
- }
1728
1763
 
1729
1764
  /**
1730
1765
  * Runs sync tests - or extracts promise.
@@ -1752,6 +1787,7 @@ function runSyncTest(testObject) {
1752
1787
  * Registers test, if async - adds to pending array
1753
1788
  */
1754
1789
  function registerTest(testObject) {
1790
+ var emit = useBus().emit;
1755
1791
  // Run test callback.
1756
1792
  // If a promise is returned, set as async and
1757
1793
  // Move to pending list.
@@ -1765,7 +1801,7 @@ function registerTest(testObject) {
1765
1801
  runAsyncTest(testObject);
1766
1802
  }
1767
1803
  else {
1768
- testObject.done();
1804
+ emit(Events.TEST_COMPLETED, testObject);
1769
1805
  }
1770
1806
  }
1771
1807
  catch (_a) {
@@ -1773,6 +1809,29 @@ function registerTest(testObject) {
1773
1809
  }
1774
1810
  }
1775
1811
 
1812
+ function registerPrevRunTest(testObject) {
1813
+ var prevRunTest = useTestAtCursor(testObject);
1814
+ if (isExcluded(testObject)) {
1815
+ testObject.skip();
1816
+ useSetNextCursorAt();
1817
+ return prevRunTest;
1818
+ }
1819
+ cancelOverriddenPendingTest(prevRunTest, testObject);
1820
+ useSetTestAtCursor(testObject);
1821
+ useSetNextCursorAt();
1822
+ registerTestObjectByTier(testObject);
1823
+ return testObject;
1824
+ }
1825
+ function registerTestObjectByTier(testObject) {
1826
+ if (testObject.isUntested()) {
1827
+ registerTest(testObject);
1828
+ }
1829
+ else if (isPromise(testObject.asyncTest)) {
1830
+ testObject.setPending();
1831
+ runAsyncTest(testObject);
1832
+ }
1833
+ }
1834
+
1776
1835
  function bindTestEach(test) {
1777
1836
  /**
1778
1837
  * Run multiple tests using a parameter table
@@ -1789,7 +1848,7 @@ function bindTestEach(test) {
1789
1848
  var _a = args.reverse(), testFn = _a[0], message = _a[1];
1790
1849
  return table.map(function (item) {
1791
1850
  item = asArray(item);
1792
- return test(optionalFunctionValue.apply(void 0, __spreadArray([fieldName], item)), optionalFunctionValue.apply(void 0, __spreadArray([message], item)), function () { return testFn.apply(void 0, item); });
1851
+ return test(optionalFunctionValue.apply(void 0, __spreadArray([fieldName], item, false)), optionalFunctionValue.apply(void 0, __spreadArray([message], item, false)), function () { return testFn.apply(void 0, item); });
1793
1852
  });
1794
1853
  }
1795
1854
  return eachReturn;
@@ -1812,32 +1871,20 @@ function bindTestMemo(test) {
1812
1871
  // Implicit dependency for more specificity
1813
1872
  var dependencies = [suiteId, fieldName, cursorAt].concat(deps);
1814
1873
  var cached = cache.get(dependencies);
1815
- // Cache miss. Start fresh
1816
1874
  if (isNull(cached)) {
1875
+ // cache miss
1817
1876
  return cache(dependencies, function () { return test(fieldName, msg, testFn); });
1818
1877
  }
1819
- var testObject = cached[1];
1820
- var prevRunTest = useTestAtCursor(testObject);
1821
- if (isExcluded(testObject)) {
1822
- useSetNextCursorAt();
1823
- return prevRunTest;
1878
+ if (cached[1].isCanceled()) {
1879
+ // cache hit, but test is canceled
1880
+ cache.invalidate(dependencies);
1881
+ return cache(dependencies, function () { return test(fieldName, msg, testFn); });
1824
1882
  }
1825
- cancelOverriddenPendingTest(prevRunTest, testObject);
1826
- useSetTestAtCursor(testObject);
1827
- useSetNextCursorAt();
1828
- handleAsyncTest(testObject);
1829
- return testObject;
1883
+ return registerPrevRunTest(cached[1]);
1830
1884
  }
1831
1885
  return memo;
1832
1886
  }
1833
- function handleAsyncTest(testObject) {
1834
- if (testObject && isPromise(testObject.asyncTest)) {
1835
- testObject.setPending();
1836
- runAsyncTest(testObject);
1837
- }
1838
- }
1839
1887
 
1840
- // eslint-disable-next-line max-statements
1841
1888
  function testBase(fieldName) {
1842
1889
  var args = [];
1843
1890
  for (var _i = 1; _i < arguments.length; _i++) {
@@ -1849,26 +1896,14 @@ function testBase(fieldName) {
1849
1896
  message: message,
1850
1897
  groupName: context === null || context === void 0 ? void 0 : context.groupName
1851
1898
  });
1852
- var prevRunTest = useTestAtCursor(testObject);
1853
- if (isExcluded(testObject)) {
1854
- testObject.skip();
1855
- useSetNextCursorAt();
1856
- return prevRunTest;
1857
- }
1858
- cancelOverriddenPendingTest(prevRunTest, testObject);
1859
- useSetTestAtCursor(testObject);
1860
- useSetNextCursorAt(); // maybe somehow do this only in one place?
1861
- if (!isFunction(testFn))
1862
- return testObject;
1863
- registerTest(testObject);
1864
- return testObject;
1899
+ return registerPrevRunTest(testObject);
1865
1900
  }
1866
1901
  var test = assign(testBase, {
1867
1902
  each: bindTestEach(testBase),
1868
1903
  memo: bindTestMemo(testBase)
1869
1904
  });
1870
1905
 
1871
- var VERSION = "3.3.0-dev-92c1af";
1906
+ var VERSION = "4.0.0-dev-f53683";
1872
1907
 
1873
1908
  exports.VERSION = VERSION;
1874
1909
  exports.create = create;