jasmine-core 3.10.1 → 3.99.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.
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright (c) 2008-2021 Pivotal Labs
2
+ Copyright (c) 2008-2022 Pivotal Labs
3
3
 
4
4
  Permission is hereby granted, free of charge, to any person obtaining
5
5
  a copy of this software and associated documentation files (the
@@ -60,11 +60,15 @@ var getJasmineRequireObj = (function(jasmineGlobal) {
60
60
  j$.Any = jRequire.Any(j$);
61
61
  j$.Anything = jRequire.Anything(j$);
62
62
  j$.CallTracker = jRequire.CallTracker(j$);
63
- j$.MockDate = jRequire.MockDate();
63
+ j$.MockDate = jRequire.MockDate(j$);
64
64
  j$.getClearStack = jRequire.clearStack(j$);
65
65
  j$.Clock = jRequire.Clock();
66
66
  j$.DelayedFunctionScheduler = jRequire.DelayedFunctionScheduler(j$);
67
+ j$.Deprecator = jRequire.Deprecator(j$);
67
68
  j$.Env = jRequire.Env(j$);
69
+ j$.deprecatingThisProxy = jRequire.deprecatingThisProxy(j$);
70
+ j$.deprecatingSuiteProxy = jRequire.deprecatingSuiteProxy(j$);
71
+ j$.deprecatingSpecProxy = jRequire.deprecatingSpecProxy(j$);
68
72
  j$.StackTrace = jRequire.StackTrace(j$);
69
73
  j$.ExceptionFormatter = jRequire.ExceptionFormatter(j$);
70
74
  j$.ExpectationFilterChain = jRequire.ExpectationFilterChain();
@@ -76,11 +80,34 @@ var getJasmineRequireObj = (function(jasmineGlobal) {
76
80
  j$
77
81
  );
78
82
  j$.makePrettyPrinter = jRequire.makePrettyPrinter(j$);
79
- j$.pp = j$.makePrettyPrinter();
83
+ j$.basicPrettyPrinter_ = j$.makePrettyPrinter();
84
+ Object.defineProperty(j$, 'pp', {
85
+ get: function() {
86
+ j$.getEnv().deprecated(
87
+ 'jasmine.pp is deprecated and will be removed in a future release. ' +
88
+ 'Use the pp method of the matchersUtil passed to the matcher factory ' +
89
+ "or the asymmetric equality tester's `asymmetricMatch` method " +
90
+ 'instead. See ' +
91
+ '<https://jasmine.github.io/tutorials/upgrading_to_Jasmine_4.0#static-utils> for details.'
92
+ );
93
+ return j$.basicPrettyPrinter_;
94
+ }
95
+ });
80
96
  j$.MatchersUtil = jRequire.MatchersUtil(j$);
81
- j$.matchersUtil = new j$.MatchersUtil({
97
+ var staticMatchersUtil = new j$.MatchersUtil({
82
98
  customTesters: [],
83
- pp: j$.pp
99
+ pp: j$.basicPrettyPrinter_
100
+ });
101
+ Object.defineProperty(j$, 'matchersUtil', {
102
+ get: function() {
103
+ j$.getEnv().deprecated(
104
+ 'jasmine.matchersUtil is deprecated and will be removed ' +
105
+ 'in a future release. Use the instance passed to the matcher factory or ' +
106
+ "the asymmetric equality tester's `asymmetricMatch` method instead. " +
107
+ 'See <https://jasmine.github.io/tutorials/upgrading_to_Jasmine_4.0#static-utils> for details.'
108
+ );
109
+ return staticMatchersUtil;
110
+ }
84
111
  });
85
112
 
86
113
  j$.ObjectContaining = jRequire.ObjectContaining(j$);
@@ -800,6 +827,7 @@ getJasmineRequireObj().Spec = function(j$) {
800
827
  };
801
828
  this.expectationResultFactory =
802
829
  attrs.expectationResultFactory || function() {};
830
+ this.deprecated = attrs.deprecated || function() {};
803
831
  this.queueRunnerFactory = attrs.queueRunnerFactory || function() {};
804
832
  this.catchingExceptions =
805
833
  attrs.catchingExceptions ||
@@ -897,13 +925,32 @@ x */
897
925
  onException: function() {
898
926
  self.onException.apply(self, arguments);
899
927
  },
900
- onComplete: function() {
901
- onComplete(
902
- self.result.status === 'failed' &&
903
- new j$.StopExecutionError('spec failed')
928
+ onMultipleDone: function() {
929
+ // Issue a deprecation. Include the context ourselves and pass
930
+ // ignoreRunnable: true, since getting here always means that we've already
931
+ // moved on and the current runnable isn't the one that caused the problem.
932
+ self.deprecated(
933
+ "An asynchronous function called its 'done' " +
934
+ 'callback more than once. This is a bug in the spec, beforeAll, ' +
935
+ 'beforeEach, afterAll, or afterEach function in question. This will ' +
936
+ 'be treated as an error in a future version. See' +
937
+ '<https://jasmine.github.io/tutorials/upgrading_to_Jasmine_4.0#deprecations-due-to-calling-done-multiple-times> ' +
938
+ 'for more information.\n' +
939
+ '(in spec: ' +
940
+ self.getFullName() +
941
+ ')',
942
+ { ignoreRunnable: true }
904
943
  );
905
944
  },
906
- userContext: this.userContext()
945
+ onComplete: function() {
946
+ if (self.result.status === 'failed') {
947
+ onComplete(new j$.StopExecutionError('spec failed'));
948
+ } else {
949
+ onComplete();
950
+ }
951
+ },
952
+ userContext: this.userContext(),
953
+ runnableName: this.getFullName.bind(this)
907
954
  };
908
955
 
909
956
  if (this.markedPending || excluded === true) {
@@ -1253,6 +1300,8 @@ getJasmineRequireObj().Env = function(j$) {
1253
1300
  * @since 3.5.0
1254
1301
  * @type function
1255
1302
  * @default undefined
1303
+ * @deprecated In a future version, Jasmine will ignore the Promise config
1304
+ * property and always create native promises instead.
1256
1305
  */
1257
1306
  Promise: undefined,
1258
1307
  /**
@@ -1263,7 +1312,19 @@ getJasmineRequireObj().Env = function(j$) {
1263
1312
  * @type boolean
1264
1313
  * @default true
1265
1314
  */
1266
- autoCleanClosures: true
1315
+ autoCleanClosures: true,
1316
+ /**
1317
+ * Whether or not to issue warnings for certain deprecated functionality
1318
+ * every time it's used. If not set or set to false, deprecation warnings
1319
+ * for methods that tend to be called frequently will be issued only once
1320
+ * or otherwise throttled to to prevent the suite output from being flooded
1321
+ * with warnings.
1322
+ * @name Configuration#verboseDeprecations
1323
+ * @since 3.6.0
1324
+ * @type Boolean
1325
+ * @default false
1326
+ */
1327
+ verboseDeprecations: false
1267
1328
  };
1268
1329
 
1269
1330
  var currentSuite = function() {
@@ -1327,6 +1388,18 @@ getJasmineRequireObj().Env = function(j$) {
1327
1388
  });
1328
1389
 
1329
1390
  if (typeof configuration.failFast !== 'undefined') {
1391
+ // We can't unconditionally issue a warning here because then users who
1392
+ // get the configuration from Jasmine, modify it, and pass it back would
1393
+ // see the warning.
1394
+ if (configuration.failFast !== config.failFast) {
1395
+ this.deprecated(
1396
+ 'The `failFast` config property is deprecated and will be removed ' +
1397
+ 'in a future version of Jasmine. Please use `stopOnSpecFailure` ' +
1398
+ 'instead.',
1399
+ { ignoreRunnable: true }
1400
+ );
1401
+ }
1402
+
1330
1403
  if (typeof configuration.stopOnSpecFailure !== 'undefined') {
1331
1404
  if (configuration.stopOnSpecFailure !== configuration.failFast) {
1332
1405
  throw new Error(
@@ -1344,6 +1417,18 @@ getJasmineRequireObj().Env = function(j$) {
1344
1417
  }
1345
1418
 
1346
1419
  if (typeof configuration.oneFailurePerSpec !== 'undefined') {
1420
+ // We can't unconditionally issue a warning here because then users who
1421
+ // get the configuration from Jasmine, modify it, and pass it back would
1422
+ // see the warning.
1423
+ if (configuration.oneFailurePerSpec !== config.oneFailurePerSpec) {
1424
+ this.deprecated(
1425
+ 'The `oneFailurePerSpec` config property is deprecated and will be ' +
1426
+ 'removed in a future version of Jasmine. Please use ' +
1427
+ '`stopSpecOnExpectationFailure` instead.',
1428
+ { ignoreRunnable: true }
1429
+ );
1430
+ }
1431
+
1347
1432
  if (typeof configuration.stopSpecOnExpectationFailure !== 'undefined') {
1348
1433
  if (
1349
1434
  configuration.stopSpecOnExpectationFailure !==
@@ -1383,12 +1468,22 @@ getJasmineRequireObj().Env = function(j$) {
1383
1468
  typeof configuration.Promise.reject === 'function'
1384
1469
  ) {
1385
1470
  customPromise = configuration.Promise;
1471
+ self.deprecated(
1472
+ 'The `Promise` config property is deprecated. Future versions ' +
1473
+ 'of Jasmine will create native promises even if the `Promise` ' +
1474
+ 'config property is set. Please remove it.'
1475
+ );
1386
1476
  } else {
1387
1477
  throw new Error(
1388
1478
  'Custom promise library missing `resolve`/`reject` functions'
1389
1479
  );
1390
1480
  }
1391
1481
  }
1482
+
1483
+ if (configuration.hasOwnProperty('verboseDeprecations')) {
1484
+ config.verboseDeprecations = configuration.verboseDeprecations;
1485
+ deprecator.verboseDeprecations(config.verboseDeprecations);
1486
+ }
1392
1487
  };
1393
1488
 
1394
1489
  /**
@@ -1409,13 +1504,19 @@ getJasmineRequireObj().Env = function(j$) {
1409
1504
  Object.defineProperty(this, 'specFilter', {
1410
1505
  get: function() {
1411
1506
  self.deprecated(
1412
- 'Getting specFilter directly from Env is deprecated and will be removed in a future version of Jasmine, please check the specFilter option from `configuration`'
1507
+ 'Getting specFilter directly from Env is deprecated and will be ' +
1508
+ 'removed in a future version of Jasmine. Please check the ' +
1509
+ 'specFilter option from `configuration` instead.',
1510
+ { ignoreRunnable: true }
1413
1511
  );
1414
1512
  return config.specFilter;
1415
1513
  },
1416
1514
  set: function(val) {
1417
1515
  self.deprecated(
1418
- 'Setting specFilter directly on Env is deprecated and will be removed in a future version of Jasmine, please use the specFilter option in `configure`'
1516
+ 'Setting specFilter directly on Env is deprecated and will be ' +
1517
+ 'removed in a future version of Jasmine. Please use the ' +
1518
+ 'specFilter option in `configure` instead.',
1519
+ { ignoreRunnable: true }
1419
1520
  );
1420
1521
  config.specFilter = val;
1421
1522
  }
@@ -1462,6 +1563,17 @@ getJasmineRequireObj().Env = function(j$) {
1462
1563
  runnableResources[currentRunnable().id].customMatchers;
1463
1564
 
1464
1565
  for (var matcherName in matchersToAdd) {
1566
+ if (matchersToAdd[matcherName].length > 1) {
1567
+ self.deprecated(
1568
+ 'The matcher factory for "' +
1569
+ matcherName +
1570
+ '" ' +
1571
+ 'accepts custom equality testers, but this parameter will no longer be ' +
1572
+ 'passed in a future release. ' +
1573
+ 'See <https://jasmine.github.io/tutorials/upgrading_to_Jasmine_4.0#matchers-cet> for details.'
1574
+ );
1575
+ }
1576
+
1465
1577
  customMatchers[matcherName] = matchersToAdd[matcherName];
1466
1578
  }
1467
1579
  };
@@ -1476,6 +1588,17 @@ getJasmineRequireObj().Env = function(j$) {
1476
1588
  runnableResources[currentRunnable().id].customAsyncMatchers;
1477
1589
 
1478
1590
  for (var matcherName in matchersToAdd) {
1591
+ if (matchersToAdd[matcherName].length > 1) {
1592
+ self.deprecated(
1593
+ 'The matcher factory for "' +
1594
+ matcherName +
1595
+ '" ' +
1596
+ 'accepts custom equality testers, but this parameter will no longer be ' +
1597
+ 'passed in a future release. ' +
1598
+ 'See <https://jasmine.github.io/tutorials/upgrading_to_Jasmine_4.0#matchers-cet> for details.'
1599
+ );
1600
+ }
1601
+
1479
1602
  customAsyncMatchers[matcherName] = matchersToAdd[matcherName];
1480
1603
  }
1481
1604
  };
@@ -1678,7 +1801,8 @@ getJasmineRequireObj().Env = function(j$) {
1678
1801
  this.deprecated(
1679
1802
  'Setting throwOnExpectationFailure directly on Env is deprecated and ' +
1680
1803
  'will be removed in a future version of Jasmine. Please use the ' +
1681
- 'stopSpecOnExpectationFailure option in `configure`.'
1804
+ 'stopSpecOnExpectationFailure option in `configure`.',
1805
+ { ignoreRunnable: true }
1682
1806
  );
1683
1807
  this.configure({ oneFailurePerSpec: !!value });
1684
1808
  };
@@ -1687,7 +1811,8 @@ getJasmineRequireObj().Env = function(j$) {
1687
1811
  this.deprecated(
1688
1812
  'Getting throwingExpectationFailures directly from Env is deprecated ' +
1689
1813
  'and will be removed in a future version of Jasmine. Please check ' +
1690
- 'the stopSpecOnExpectationFailure option from `configuration`.'
1814
+ 'the stopSpecOnExpectationFailure option from `configuration`.',
1815
+ { ignoreRunnable: true }
1691
1816
  );
1692
1817
  return config.oneFailurePerSpec;
1693
1818
  };
@@ -1704,7 +1829,8 @@ getJasmineRequireObj().Env = function(j$) {
1704
1829
  this.deprecated(
1705
1830
  'Setting stopOnSpecFailure directly is deprecated and will be ' +
1706
1831
  'removed in a future version of Jasmine. Please use the ' +
1707
- 'stopOnSpecFailure option in `configure`.'
1832
+ 'stopOnSpecFailure option in `configure`.',
1833
+ { ignoreRunnable: true }
1708
1834
  );
1709
1835
  this.configure({ stopOnSpecFailure: !!value });
1710
1836
  };
@@ -1713,7 +1839,8 @@ getJasmineRequireObj().Env = function(j$) {
1713
1839
  this.deprecated(
1714
1840
  'Getting stoppingOnSpecFailure directly from Env is deprecated and ' +
1715
1841
  'will be removed in a future version of Jasmine. Please check the ' +
1716
- 'stopOnSpecFailure option from `configuration`.'
1842
+ 'stopOnSpecFailure option from `configuration`.',
1843
+ { ignoreRunnable: true }
1717
1844
  );
1718
1845
  return config.failFast;
1719
1846
  };
@@ -1728,14 +1855,20 @@ getJasmineRequireObj().Env = function(j$) {
1728
1855
  */
1729
1856
  this.randomizeTests = function(value) {
1730
1857
  this.deprecated(
1731
- 'Setting randomizeTests directly is deprecated and will be removed in a future version of Jasmine, please use the random option in `configure`'
1858
+ 'Setting randomizeTests directly is deprecated and will be removed ' +
1859
+ 'in a future version of Jasmine. Please use the random option in ' +
1860
+ '`configure` instead.',
1861
+ { ignoreRunnable: true }
1732
1862
  );
1733
1863
  config.random = !!value;
1734
1864
  };
1735
1865
 
1736
1866
  this.randomTests = function() {
1737
1867
  this.deprecated(
1738
- 'Getting randomTests directly from Env is deprecated and will be removed in a future version of Jasmine, please check the random option from `configuration`'
1868
+ 'Getting randomTests directly from Env is deprecated and will be ' +
1869
+ 'removed in a future version of Jasmine. Please check the random ' +
1870
+ 'option from `configuration` instead.',
1871
+ { ignoreRunnable: true }
1739
1872
  );
1740
1873
  return config.random;
1741
1874
  };
@@ -1750,7 +1883,10 @@ getJasmineRequireObj().Env = function(j$) {
1750
1883
  */
1751
1884
  this.seed = function(value) {
1752
1885
  this.deprecated(
1753
- 'Setting seed directly is deprecated and will be removed in a future version of Jasmine, please use the seed option in `configure`'
1886
+ 'Setting seed directly is deprecated and will be removed in a ' +
1887
+ 'future version of Jasmine. Please use the seed option in ' +
1888
+ '`configure` instead.',
1889
+ { ignoreRunnable: true }
1754
1890
  );
1755
1891
  if (value) {
1756
1892
  config.seed = value;
@@ -1760,7 +1896,10 @@ getJasmineRequireObj().Env = function(j$) {
1760
1896
 
1761
1897
  this.hidingDisabled = function(value) {
1762
1898
  this.deprecated(
1763
- 'Getting hidingDisabled directly from Env is deprecated and will be removed in a future version of Jasmine, please check the hideDisabled option from `configuration`'
1899
+ 'Getting hidingDisabled directly from Env is deprecated and will ' +
1900
+ 'be removed in a future version of Jasmine. Please check the ' +
1901
+ 'hideDisabled option from `configuration` instead.',
1902
+ { ignoreRunnable: true }
1764
1903
  );
1765
1904
  return config.hideDisabled;
1766
1905
  };
@@ -1773,30 +1912,39 @@ getJasmineRequireObj().Env = function(j$) {
1773
1912
  */
1774
1913
  this.hideDisabled = function(value) {
1775
1914
  this.deprecated(
1776
- 'Setting hideDisabled directly is deprecated and will be removed in a future version of Jasmine, please use the hideDisabled option in `configure`'
1915
+ 'Setting hideDisabled directly is deprecated and will be removed ' +
1916
+ 'in a future version of Jasmine. Please use the hideDisabled option ' +
1917
+ 'in `configure` instead.',
1918
+ { ignoreRunnable: true }
1777
1919
  );
1778
1920
  config.hideDisabled = !!value;
1779
1921
  };
1780
1922
 
1781
- this.deprecated = function(deprecation) {
1923
+ /**
1924
+ * Causes a deprecation warning to be logged to the console and reported to
1925
+ * reporters.
1926
+ *
1927
+ * The optional second parameter is an object that can have either of the
1928
+ * following properties:
1929
+ *
1930
+ * omitStackTrace: Whether to omit the stack trace. Optional. Defaults to
1931
+ * false. This option is ignored if the deprecation is an Error. Set this
1932
+ * when the stack trace will not contain anything that helps the user find
1933
+ * the source of the deprecation.
1934
+ *
1935
+ * ignoreRunnable: Whether to log the deprecation on the root suite, ignoring
1936
+ * the spec or suite that's running when it happens. Optional. Defaults to
1937
+ * false.
1938
+ *
1939
+ * @name Env#deprecated
1940
+ * @since 2.99
1941
+ * @function
1942
+ * @param {String|Error} deprecation The deprecation message
1943
+ * @param {Object} [options] Optional extra options, as described above
1944
+ */
1945
+ this.deprecated = function(deprecation, options) {
1782
1946
  var runnable = currentRunnable() || topSuite;
1783
- var context;
1784
-
1785
- if (runnable === topSuite) {
1786
- context = '';
1787
- } else if (runnable === currentSuite()) {
1788
- context = ' (in suite: ' + runnable.getFullName() + ')';
1789
- } else {
1790
- context = ' (in spec: ' + runnable.getFullName() + ')';
1791
- }
1792
-
1793
- runnable.addDeprecationWarning(deprecation);
1794
- if (
1795
- typeof console !== 'undefined' &&
1796
- typeof console.error === 'function'
1797
- ) {
1798
- console.error('DEPRECATION: ' + deprecation + context);
1799
- }
1947
+ deprecator.addDeprecationWarning(runnable, deprecation, options);
1800
1948
  };
1801
1949
 
1802
1950
  var queueRunnerFactory = function(options, args) {
@@ -1833,6 +1981,7 @@ getJasmineRequireObj().Env = function(j$) {
1833
1981
  expectationResultFactory: expectationResultFactory,
1834
1982
  autoCleanClosures: config.autoCleanClosures
1835
1983
  });
1984
+ var deprecator = new j$.Deprecator(topSuite);
1836
1985
  currentDeclarationSuite = topSuite;
1837
1986
 
1838
1987
  /**
@@ -1844,7 +1993,7 @@ getJasmineRequireObj().Env = function(j$) {
1844
1993
  * @since 2.0.0
1845
1994
  */
1846
1995
  this.topSuite = function() {
1847
- return topSuite;
1996
+ return j$.deprecatingSuiteProxy(topSuite, null, this);
1848
1997
  };
1849
1998
 
1850
1999
  /**
@@ -1919,7 +2068,8 @@ getJasmineRequireObj().Env = function(j$) {
1919
2068
  */
1920
2069
  'specDone'
1921
2070
  ],
1922
- queueRunnerFactory
2071
+ queueRunnerFactory,
2072
+ self.deprecated
1923
2073
  );
1924
2074
 
1925
2075
  /**
@@ -2259,7 +2409,14 @@ getJasmineRequireObj().Env = function(j$) {
2259
2409
  suite.exclude();
2260
2410
  }
2261
2411
  addSpecsToSuite(suite, specDefinitions);
2262
- return suite;
2412
+ if (suite.parentSuite && !suite.children.length) {
2413
+ this.deprecated(
2414
+ 'describe with no children (describe() or it()) is ' +
2415
+ 'deprecated and will be removed in a future version of Jasmine. ' +
2416
+ 'Please either remove the describe or add children to it.'
2417
+ );
2418
+ }
2419
+ return j$.deprecatingSuiteProxy(suite, suite.parentSuite, this);
2263
2420
  };
2264
2421
 
2265
2422
  this.xdescribe = function(description, specDefinitions) {
@@ -2268,7 +2425,7 @@ getJasmineRequireObj().Env = function(j$) {
2268
2425
  var suite = suiteFactory(description);
2269
2426
  suite.exclude();
2270
2427
  addSpecsToSuite(suite, specDefinitions);
2271
- return suite;
2428
+ return j$.deprecatingSuiteProxy(suite, suite.parentSuite, this);
2272
2429
  };
2273
2430
 
2274
2431
  var focusedRunnables = [];
@@ -2283,7 +2440,7 @@ getJasmineRequireObj().Env = function(j$) {
2283
2440
  unfocusAncestor();
2284
2441
  addSpecsToSuite(suite, specDefinitions);
2285
2442
 
2286
- return suite;
2443
+ return j$.deprecatingSuiteProxy(suite, suite.parentSuite, this);
2287
2444
  };
2288
2445
 
2289
2446
  function addSpecsToSuite(suite, specDefinitions) {
@@ -2293,7 +2450,7 @@ getJasmineRequireObj().Env = function(j$) {
2293
2450
 
2294
2451
  var declarationError = null;
2295
2452
  try {
2296
- specDefinitions.call(suite);
2453
+ specDefinitions.call(j$.deprecatingThisProxy(suite, self));
2297
2454
  } catch (e) {
2298
2455
  declarationError = e;
2299
2456
  }
@@ -2335,6 +2492,7 @@ getJasmineRequireObj().Env = function(j$) {
2335
2492
  beforeAndAfterFns: beforeAndAfterFns(suite),
2336
2493
  expectationFactory: expectationFactory,
2337
2494
  asyncExpectationFactory: specAsyncExpectationFactory,
2495
+ deprecated: self.deprecated,
2338
2496
  resultCallback: specResultCallback,
2339
2497
  getSpecName: function(spec) {
2340
2498
  return getSpecName(spec, suite);
@@ -2374,7 +2532,7 @@ getJasmineRequireObj().Env = function(j$) {
2374
2532
  }
2375
2533
  };
2376
2534
 
2377
- this.it = function(description, fn, timeout) {
2535
+ this.it_ = function(description, fn, timeout) {
2378
2536
  ensureIsNotNested('it');
2379
2537
  // it() sometimes doesn't have a fn argument, so only check the type if
2380
2538
  // it's given.
@@ -2391,9 +2549,15 @@ getJasmineRequireObj().Env = function(j$) {
2391
2549
  spec.exclude();
2392
2550
  }
2393
2551
  currentDeclarationSuite.addChild(spec);
2552
+
2394
2553
  return spec;
2395
2554
  };
2396
2555
 
2556
+ this.it = function(description, fn, timeout) {
2557
+ var spec = this.it_(description, fn, timeout);
2558
+ return j$.deprecatingSpecProxy(spec, this);
2559
+ };
2560
+
2397
2561
  this.xit = function(description, fn, timeout) {
2398
2562
  ensureIsNotNested('xit');
2399
2563
  // xit(), like it(), doesn't always have a fn argument, so only check the
@@ -2401,9 +2565,9 @@ getJasmineRequireObj().Env = function(j$) {
2401
2565
  if (arguments.length > 1 && typeof fn !== 'undefined') {
2402
2566
  ensureIsFunctionOrAsync(fn, 'xit');
2403
2567
  }
2404
- var spec = this.it.apply(this, arguments);
2568
+ var spec = this.it_.apply(this, arguments);
2405
2569
  spec.exclude('Temporarily disabled with xit');
2406
- return spec;
2570
+ return j$.deprecatingSpecProxy(spec, this);
2407
2571
  };
2408
2572
 
2409
2573
  this.fit = function(description, fn, timeout) {
@@ -2417,7 +2581,7 @@ getJasmineRequireObj().Env = function(j$) {
2417
2581
  currentDeclarationSuite.addChild(spec);
2418
2582
  focusedRunnables.push(spec.id);
2419
2583
  unfocusAncestor();
2420
- return spec;
2584
+ return j$.deprecatingSpecProxy(spec, this);
2421
2585
  };
2422
2586
 
2423
2587
  /**
@@ -2785,7 +2949,7 @@ getJasmineRequireObj().ArrayContaining = function(j$) {
2785
2949
  if (!j$.isArray_(this.sample)) {
2786
2950
  throw new Error(
2787
2951
  'You must provide an array to arrayContaining, not ' +
2788
- j$.pp(this.sample) +
2952
+ j$.basicPrettyPrinter_(this.sample) +
2789
2953
  '.'
2790
2954
  );
2791
2955
  }
@@ -2826,7 +2990,7 @@ getJasmineRequireObj().ArrayWithExactContents = function(j$) {
2826
2990
  if (!j$.isArray_(this.sample)) {
2827
2991
  throw new Error(
2828
2992
  'You must provide an array to arrayWithExactContents, not ' +
2829
- j$.pp(this.sample) +
2993
+ j$.basicPrettyPrinter_(this.sample) +
2830
2994
  '.'
2831
2995
  );
2832
2996
  }
@@ -2895,7 +3059,8 @@ getJasmineRequireObj().MapContaining = function(j$) {
2895
3059
  function MapContaining(sample) {
2896
3060
  if (!j$.isMap(sample)) {
2897
3061
  throw new Error(
2898
- 'You must provide a map to `mapContaining`, not ' + j$.pp(sample)
3062
+ 'You must provide a map to `mapContaining`, not ' +
3063
+ j$.basicPrettyPrinter_(sample)
2899
3064
  );
2900
3065
  }
2901
3066
 
@@ -3046,7 +3211,8 @@ getJasmineRequireObj().SetContaining = function(j$) {
3046
3211
  function SetContaining(sample) {
3047
3212
  if (!j$.isSet(sample)) {
3048
3213
  throw new Error(
3049
- 'You must provide a set to `setContaining`, not ' + j$.pp(sample)
3214
+ 'You must provide a set to `setContaining`, not ' +
3215
+ j$.basicPrettyPrinter_(sample)
3050
3216
  );
3051
3217
  }
3052
3218
 
@@ -3196,34 +3362,49 @@ getJasmineRequireObj().asymmetricEqualityTesterArgCompatShim = function(j$) {
3196
3362
  matchersUtil,
3197
3363
  customEqualityTesters
3198
3364
  ) {
3199
- var self = Object.create(matchersUtil),
3200
- props,
3201
- i,
3202
- k;
3365
+ var self = Object.create(matchersUtil);
3203
3366
 
3204
- copy(self, customEqualityTesters, 'length');
3367
+ copyAndDeprecate(self, customEqualityTesters, 'length');
3205
3368
 
3206
3369
  for (i = 0; i < customEqualityTesters.length; i++) {
3207
- copy(self, customEqualityTesters, i);
3370
+ copyAndDeprecate(self, customEqualityTesters, i);
3371
+ }
3372
+
3373
+ // Avoid copying array props if we've previously done so,
3374
+ // to avoid triggering our own deprecation warnings.
3375
+ if (!self.isAsymmetricEqualityTesterArgCompatShim_) {
3376
+ copyAndDeprecateArrayMethods(self);
3208
3377
  }
3209
3378
 
3210
- var props = arrayProps();
3379
+ self.isAsymmetricEqualityTesterArgCompatShim_ = true;
3380
+ return self;
3381
+ }
3382
+
3383
+ function copyAndDeprecateArrayMethods(dest) {
3384
+ var props = arrayProps(),
3385
+ i,
3386
+ k;
3211
3387
 
3212
3388
  for (i = 0; i < props.length; i++) {
3213
3389
  k = props[i];
3390
+
3214
3391
  // Skip length (dealt with above), and anything that collides with
3215
3392
  // MatchesUtil e.g. an Array.prototype.contains method added by user code
3216
- if (k !== 'length' && !self[k]) {
3217
- copy(self, Array.prototype, k);
3393
+ if (k !== 'length' && !dest[k]) {
3394
+ copyAndDeprecate(dest, Array.prototype, k);
3218
3395
  }
3219
3396
  }
3220
-
3221
- return self;
3222
3397
  }
3223
3398
 
3224
- function copy(dest, src, propName) {
3399
+ function copyAndDeprecate(dest, src, propName) {
3225
3400
  Object.defineProperty(dest, propName, {
3226
3401
  get: function() {
3402
+ j$.getEnv().deprecated(
3403
+ 'The second argument to asymmetricMatch is now a ' +
3404
+ 'MatchersUtil. Using it as an array of custom equality testers is ' +
3405
+ 'deprecated and will stop working in a future release. ' +
3406
+ 'See <https://jasmine.github.io/tutorials/upgrading_to_Jasmine_4.0#asymmetricMatch-cet> for details.'
3407
+ );
3227
3408
  return src[propName];
3228
3409
  }
3229
3410
  });
@@ -3698,13 +3879,31 @@ getJasmineRequireObj().DelayedFunctionScheduler = function(j$) {
3698
3879
  var currentTime = 0;
3699
3880
  var delayedFnCount = 0;
3700
3881
  var deletedKeys = [];
3882
+ var ticking = false;
3701
3883
 
3702
3884
  self.tick = function(millis, tickDate) {
3703
- millis = millis || 0;
3704
- var endTime = currentTime + millis;
3885
+ if (ticking) {
3886
+ j$.getEnv().deprecated(
3887
+ 'The behavior of reentrant calls to jasmine.clock().tick() will ' +
3888
+ 'change in a future version. Either modify the affected spec to ' +
3889
+ 'not call tick() from within a setTimeout or setInterval handler, ' +
3890
+ 'or be aware that it may behave differently in the future. See ' +
3891
+ '<https://jasmine.github.io/tutorials/upgrading_to_Jasmine_4.0#deprecations-due-to-reentrant-calls-to-jasmine-clock-tick> ' +
3892
+ 'for details.'
3893
+ );
3894
+ }
3895
+
3896
+ ticking = true;
3705
3897
 
3706
- runScheduledFunctions(endTime, tickDate);
3707
- currentTime = endTime;
3898
+ try {
3899
+ millis = millis || 0;
3900
+ var endTime = currentTime + millis;
3901
+
3902
+ runScheduledFunctions(endTime, tickDate);
3903
+ currentTime = endTime;
3904
+ } finally {
3905
+ ticking = false;
3906
+ }
3708
3907
  };
3709
3908
 
3710
3909
  self.scheduleFunction = function(
@@ -3869,6 +4068,302 @@ getJasmineRequireObj().DelayedFunctionScheduler = function(j$) {
3869
4068
  return DelayedFunctionScheduler;
3870
4069
  };
3871
4070
 
4071
+ /* eslint-disable compat/compat */
4072
+ // TODO: Remove this in the next major release.
4073
+ getJasmineRequireObj().deprecatingSpecProxy = function(j$) {
4074
+ function isMember(target, prop) {
4075
+ return (
4076
+ Object.keys(target).indexOf(prop) !== -1 ||
4077
+ Object.keys(j$.Spec.prototype).indexOf(prop) !== -1
4078
+ );
4079
+ }
4080
+
4081
+ function isAllowedMember(prop) {
4082
+ return prop === 'id' || prop === 'description' || prop === 'getFullName';
4083
+ }
4084
+
4085
+ function msg(member) {
4086
+ var memberName = member.toString().replace(/^Symbol\((.+)\)$/, '$1');
4087
+ return (
4088
+ 'Access to private Spec members (in this case `' +
4089
+ memberName +
4090
+ '`) is not supported and will break in ' +
4091
+ 'a future release. See <https://jasmine.github.io/api/edge/Spec.html> ' +
4092
+ 'for correct usage.'
4093
+ );
4094
+ }
4095
+
4096
+ try {
4097
+ new Proxy({}, {});
4098
+ } catch (e) {
4099
+ // Environment does not support Poxy.
4100
+ return function(spec) {
4101
+ return spec;
4102
+ };
4103
+ }
4104
+
4105
+ function DeprecatingSpecProxyHandler(env) {
4106
+ this._env = env;
4107
+ }
4108
+
4109
+ DeprecatingSpecProxyHandler.prototype.get = function(target, prop, receiver) {
4110
+ this._maybeDeprecate(target, prop);
4111
+
4112
+ if (prop === 'getFullName') {
4113
+ // getFullName calls a private method. Re-bind 'this' to avoid a bogus
4114
+ // deprecation warning.
4115
+ return target.getFullName.bind(target);
4116
+ } else {
4117
+ return target[prop];
4118
+ }
4119
+ };
4120
+
4121
+ DeprecatingSpecProxyHandler.prototype.set = function(target, prop, value) {
4122
+ this._maybeDeprecate(target, prop);
4123
+ return (target[prop] = value);
4124
+ };
4125
+
4126
+ DeprecatingSpecProxyHandler.prototype._maybeDeprecate = function(
4127
+ target,
4128
+ prop
4129
+ ) {
4130
+ if (isMember(target, prop) && !isAllowedMember(prop)) {
4131
+ this._env.deprecated(msg(prop));
4132
+ }
4133
+ };
4134
+
4135
+ function deprecatingSpecProxy(spec, env) {
4136
+ return new Proxy(spec, new DeprecatingSpecProxyHandler(env));
4137
+ }
4138
+
4139
+ return deprecatingSpecProxy;
4140
+ };
4141
+
4142
+ /* eslint-disable compat/compat */
4143
+ // TODO: Remove this in the next major release.
4144
+ getJasmineRequireObj().deprecatingSuiteProxy = function(j$) {
4145
+ var allowedMembers = [
4146
+ 'id',
4147
+ 'children',
4148
+ 'description',
4149
+ 'parentSuite',
4150
+ 'getFullName'
4151
+ ];
4152
+
4153
+ function isMember(target, prop) {
4154
+ return (
4155
+ Object.keys(target).indexOf(prop) !== -1 ||
4156
+ Object.keys(j$.Suite.prototype).indexOf(prop) !== -1
4157
+ );
4158
+ }
4159
+
4160
+ function isAllowedMember(prop) {
4161
+ return allowedMembers.indexOf(prop) !== -1;
4162
+ }
4163
+
4164
+ function msg(member) {
4165
+ var memberName = member.toString().replace(/^Symbol\((.+)\)$/, '$1');
4166
+ return (
4167
+ 'Access to private Suite members (in this case `' +
4168
+ memberName +
4169
+ '`) is not supported and will break in ' +
4170
+ 'a future release. See <https://jasmine.github.io/api/edge/Suite.html> ' +
4171
+ 'for correct usage.'
4172
+ );
4173
+ }
4174
+ try {
4175
+ new Proxy({}, {});
4176
+ } catch (e) {
4177
+ // Environment does not support Poxy.
4178
+ return function(suite) {
4179
+ return suite;
4180
+ };
4181
+ }
4182
+
4183
+ function DeprecatingSuiteProxyHandler(parentSuite, env) {
4184
+ this._parentSuite = parentSuite;
4185
+ this._env = env;
4186
+ }
4187
+
4188
+ DeprecatingSuiteProxyHandler.prototype.get = function(
4189
+ target,
4190
+ prop,
4191
+ receiver
4192
+ ) {
4193
+ if (prop === 'children') {
4194
+ if (!this._children) {
4195
+ this._children = target.children.map(
4196
+ this._proxyForChild.bind(this, receiver)
4197
+ );
4198
+ }
4199
+
4200
+ return this._children;
4201
+ } else if (prop === 'parentSuite') {
4202
+ return this._parentSuite;
4203
+ } else {
4204
+ this._maybeDeprecate(target, prop);
4205
+ return target[prop];
4206
+ }
4207
+ };
4208
+
4209
+ DeprecatingSuiteProxyHandler.prototype.set = function(target, prop, value) {
4210
+ this._maybeDeprecate(target, prop);
4211
+ return (target[prop] = value);
4212
+ };
4213
+
4214
+ DeprecatingSuiteProxyHandler.prototype._maybeDeprecate = function(
4215
+ target,
4216
+ prop
4217
+ ) {
4218
+ if (isMember(target, prop) && !isAllowedMember(prop)) {
4219
+ this._env.deprecated(msg(prop));
4220
+ }
4221
+ };
4222
+
4223
+ DeprecatingSuiteProxyHandler.prototype._proxyForChild = function(
4224
+ ownProxy,
4225
+ child
4226
+ ) {
4227
+ if (child.children) {
4228
+ return deprecatingSuiteProxy(child, ownProxy, this._env);
4229
+ } else {
4230
+ return j$.deprecatingSpecProxy(child, this._env);
4231
+ }
4232
+ };
4233
+
4234
+ function deprecatingSuiteProxy(suite, parentSuite, env) {
4235
+ return new Proxy(suite, new DeprecatingSuiteProxyHandler(parentSuite, env));
4236
+ }
4237
+
4238
+ return deprecatingSuiteProxy;
4239
+ };
4240
+
4241
+ /* eslint-disable compat/compat */
4242
+ // TODO: Remove this in the next major release.
4243
+ getJasmineRequireObj().deprecatingThisProxy = function(j$) {
4244
+ var msg =
4245
+ "Access to 'this' in describe functions (and in arrow functions " +
4246
+ 'inside describe functions) is deprecated.';
4247
+
4248
+ try {
4249
+ new Proxy({}, {});
4250
+ } catch (e) {
4251
+ // Environment does not support Poxy.
4252
+ return function(suite) {
4253
+ return suite;
4254
+ };
4255
+ }
4256
+
4257
+ function DeprecatingThisProxyHandler(env) {
4258
+ this._env = env;
4259
+ }
4260
+
4261
+ DeprecatingThisProxyHandler.prototype.get = function(target, prop, receiver) {
4262
+ this._env.deprecated(msg);
4263
+ return target[prop];
4264
+ };
4265
+
4266
+ DeprecatingThisProxyHandler.prototype.set = function(target, prop, value) {
4267
+ this._env.deprecated(msg);
4268
+ return (target[prop] = value);
4269
+ };
4270
+
4271
+ return function(suite, env) {
4272
+ return new Proxy(suite, new DeprecatingThisProxyHandler(env));
4273
+ };
4274
+ };
4275
+
4276
+ getJasmineRequireObj().Deprecator = function(j$) {
4277
+ function Deprecator(topSuite) {
4278
+ this.topSuite_ = topSuite;
4279
+ this.verbose_ = false;
4280
+ this.toSuppress_ = [];
4281
+ }
4282
+
4283
+ var verboseNote =
4284
+ 'Note: This message will be shown only once. Set the verboseDeprecations ' +
4285
+ 'config property to true to see every occurrence.';
4286
+
4287
+ Deprecator.prototype.verboseDeprecations = function(enabled) {
4288
+ this.verbose_ = enabled;
4289
+ };
4290
+
4291
+ // runnable is a spec or a suite.
4292
+ // deprecation is a string or an Error.
4293
+ // See Env#deprecated for a description of the options argument.
4294
+ Deprecator.prototype.addDeprecationWarning = function(
4295
+ runnable,
4296
+ deprecation,
4297
+ options
4298
+ ) {
4299
+ options = options || {};
4300
+
4301
+ if (!this.verbose_ && !j$.isError_(deprecation)) {
4302
+ if (this.toSuppress_.indexOf(deprecation) !== -1) {
4303
+ return;
4304
+ }
4305
+ this.toSuppress_.push(deprecation);
4306
+ }
4307
+
4308
+ this.log_(runnable, deprecation, options);
4309
+ this.report_(runnable, deprecation, options);
4310
+ };
4311
+
4312
+ Deprecator.prototype.log_ = function(runnable, deprecation, options) {
4313
+ var context;
4314
+
4315
+ if (j$.isError_(deprecation)) {
4316
+ console.error(deprecation);
4317
+ return;
4318
+ }
4319
+
4320
+ if (runnable === this.topSuite_ || options.ignoreRunnable) {
4321
+ context = '';
4322
+ } else if (runnable.children) {
4323
+ context = ' (in suite: ' + runnable.getFullName() + ')';
4324
+ } else {
4325
+ context = ' (in spec: ' + runnable.getFullName() + ')';
4326
+ }
4327
+
4328
+ if (!options.omitStackTrace) {
4329
+ context += '\n' + this.stackTrace_();
4330
+ }
4331
+
4332
+ if (!this.verbose_) {
4333
+ context += '\n' + verboseNote;
4334
+ }
4335
+
4336
+ console.error('DEPRECATION: ' + deprecation + context);
4337
+ };
4338
+
4339
+ Deprecator.prototype.stackTrace_ = function() {
4340
+ var formatter = new j$.ExceptionFormatter();
4341
+ return formatter.stack(j$.util.errorWithStack()).replace(/^Error\n/m, '');
4342
+ };
4343
+
4344
+ Deprecator.prototype.report_ = function(runnable, deprecation, options) {
4345
+ if (options.ignoreRunnable) {
4346
+ runnable = this.topSuite_;
4347
+ }
4348
+
4349
+ if (j$.isError_(deprecation)) {
4350
+ runnable.addDeprecationWarning(deprecation);
4351
+ return;
4352
+ }
4353
+
4354
+ if (!this.verbose_) {
4355
+ deprecation += '\n' + verboseNote;
4356
+ }
4357
+
4358
+ runnable.addDeprecationWarning({
4359
+ message: deprecation,
4360
+ omitStackTrace: options.omitStackTrace || false
4361
+ });
4362
+ };
4363
+
4364
+ return Deprecator;
4365
+ };
4366
+
3872
4367
  getJasmineRequireObj().errors = function() {
3873
4368
  function ExpectationFailed() {}
3874
4369
 
@@ -3972,7 +4467,7 @@ getJasmineRequireObj().ExceptionFormatter = function(j$) {
3972
4467
  }
3973
4468
 
3974
4469
  if (!empty) {
3975
- return 'error properties: ' + j$.pp(result) + '\n';
4470
+ return 'error properties: ' + j$.basicPrettyPrinter_(result) + '\n';
3976
4471
  }
3977
4472
 
3978
4473
  return '';
@@ -4326,7 +4821,7 @@ getJasmineRequireObj().buildExpectationResult = function(j$) {
4326
4821
  var result = {
4327
4822
  matcherName: options.matcherName,
4328
4823
  message: message(),
4329
- stack: stack(),
4824
+ stack: options.omitStackTrace ? '' : stack(),
4330
4825
  passed: options.passed
4331
4826
  };
4332
4827
 
@@ -4412,7 +4907,15 @@ getJasmineRequireObj().Expector = function(j$) {
4412
4907
 
4413
4908
  this.args.unshift(this.actual);
4414
4909
 
4415
- var matcher = matcherFactory(this.matchersUtil, this.customEqualityTesters);
4910
+ // TODO: Remove support for passing customEqualityTesters in the next major release.
4911
+ var matcher;
4912
+
4913
+ if (matcherFactory.length >= 2) {
4914
+ matcher = matcherFactory(this.matchersUtil, this.customEqualityTesters);
4915
+ } else {
4916
+ matcher = matcherFactory(this.matchersUtil);
4917
+ }
4918
+
4416
4919
  var comparisonFunc = this.filters.selectComparisonFunc(matcher);
4417
4920
  return comparisonFunc || matcher.compare;
4418
4921
  };
@@ -5097,8 +5600,6 @@ getJasmineRequireObj().DiffBuilder = function(j$) {
5097
5600
  };
5098
5601
 
5099
5602
  getJasmineRequireObj().MatchersUtil = function(j$) {
5100
- // TODO: convert all uses of j$.pp to use the injected pp
5101
-
5102
5603
  /**
5103
5604
  * @class MatchersUtil
5104
5605
  * @classdesc Utilities for use in implementing matchers.<br>
@@ -5129,10 +5630,19 @@ getJasmineRequireObj().MatchersUtil = function(j$) {
5129
5630
  * @since 2.0.0
5130
5631
  * @param {*} haystack The collection to search
5131
5632
  * @param {*} needle The value to search for
5132
- * @param [customTesters] An array of custom equality testers
5633
+ * @param [customTesters] An array of custom equality testers. Deprecated.
5634
+ * As of 3.6 this parameter no longer needs to be passed. It will be removed in 4.0.
5133
5635
  * @returns {boolean} True if `needle` was found in `haystack`
5134
5636
  */
5135
5637
  MatchersUtil.prototype.contains = function(haystack, needle, customTesters) {
5638
+ if (customTesters) {
5639
+ j$.getEnv().deprecated(
5640
+ 'Passing custom equality testers ' +
5641
+ 'to MatchersUtil#contains is deprecated. ' +
5642
+ 'See <https://jasmine.github.io/tutorials/upgrading_to_Jasmine_4.0#matchers-cet> for details.'
5643
+ );
5644
+ }
5645
+
5136
5646
  if (j$.isSet(haystack)) {
5137
5647
  return haystack.has(needle);
5138
5648
  }
@@ -5142,8 +5652,13 @@ getJasmineRequireObj().MatchersUtil = function(j$) {
5142
5652
  (!!haystack && !haystack.indexOf)
5143
5653
  ) {
5144
5654
  for (var i = 0; i < haystack.length; i++) {
5145
- if (this.equals(haystack[i], needle, customTesters)) {
5146
- return true;
5655
+ try {
5656
+ this.suppressDeprecation_ = true;
5657
+ if (this.equals(haystack[i], needle, customTesters)) {
5658
+ return true;
5659
+ }
5660
+ } finally {
5661
+ this.suppressDeprecation_ = false;
5147
5662
  }
5148
5663
  }
5149
5664
  return false;
@@ -5247,7 +5762,8 @@ getJasmineRequireObj().MatchersUtil = function(j$) {
5247
5762
  * @since 2.0.0
5248
5763
  * @param {*} a The first value to compare
5249
5764
  * @param {*} b The second value to compare
5250
- * @param [customTesters] An array of custom equality testers
5765
+ * @param [customTesters] An array of custom equality testers. Deprecated.
5766
+ * As of 3.6 this parameter no longer needs to be passed. It will be removed in 4.0.
5251
5767
  * @returns {boolean} True if the values are equal
5252
5768
  */
5253
5769
  MatchersUtil.prototype.equals = function(
@@ -5261,6 +5777,22 @@ getJasmineRequireObj().MatchersUtil = function(j$) {
5261
5777
  if (isDiffBuilder(customTestersOrDiffBuilder)) {
5262
5778
  diffBuilder = customTestersOrDiffBuilder;
5263
5779
  } else {
5780
+ if (customTestersOrDiffBuilder && !this.suppressDeprecation_) {
5781
+ j$.getEnv().deprecated(
5782
+ 'Passing custom equality testers ' +
5783
+ 'to MatchersUtil#equals is deprecated. ' +
5784
+ 'See <https://jasmine.github.io/tutorials/upgrading_to_Jasmine_4.0#matchers-cet> for details.'
5785
+ );
5786
+ }
5787
+
5788
+ if (diffBuilderOrNothing) {
5789
+ j$.getEnv().deprecated(
5790
+ 'Diff builder should be passed ' +
5791
+ 'as the third argument to MatchersUtil#equals, not the fourth. ' +
5792
+ 'See <https://jasmine.github.io/tutorials/upgrading_to_Jasmine_4.0#matchers-cet> for details.'
5793
+ );
5794
+ }
5795
+
5264
5796
  customTesters = customTestersOrDiffBuilder;
5265
5797
  diffBuilder = diffBuilderOrNothing;
5266
5798
  }
@@ -7406,7 +7938,7 @@ getJasmineRequireObj().toThrowMatching = function(j$) {
7406
7938
  return toThrowMatching;
7407
7939
  };
7408
7940
 
7409
- getJasmineRequireObj().MockDate = function() {
7941
+ getJasmineRequireObj().MockDate = function(j$) {
7410
7942
  function MockDate(global) {
7411
7943
  var self = this;
7412
7944
  var currentTime = 0;
@@ -7424,6 +7956,14 @@ getJasmineRequireObj().MockDate = function() {
7424
7956
  if (mockDate instanceof GlobalDate) {
7425
7957
  currentTime = mockDate.getTime();
7426
7958
  } else {
7959
+ if (!j$.util.isUndefined(mockDate)) {
7960
+ j$.getEnv().deprecated(
7961
+ 'The argument to jasmine.clock().mockDate(), if specified, ' +
7962
+ 'should be a Date instance. Passing anything other than a Date ' +
7963
+ 'will be treated as an error in a future release.'
7964
+ );
7965
+ }
7966
+
7427
7967
  currentTime = new GlobalDate().getTime();
7428
7968
  }
7429
7969
 
@@ -7925,10 +8465,14 @@ getJasmineRequireObj().QueueRunner = function(j$) {
7925
8465
  StopExecutionError.prototype = new Error();
7926
8466
  j$.StopExecutionError = StopExecutionError;
7927
8467
 
7928
- function once(fn) {
8468
+ function once(fn, onTwice) {
7929
8469
  var called = false;
7930
8470
  return function(arg) {
7931
- if (!called) {
8471
+ if (called) {
8472
+ if (onTwice) {
8473
+ onTwice();
8474
+ }
8475
+ } else {
7932
8476
  called = true;
7933
8477
  // Direct call using single parameter, because cleanup/next does not need more
7934
8478
  fn(arg);
@@ -7937,6 +8481,16 @@ getJasmineRequireObj().QueueRunner = function(j$) {
7937
8481
  };
7938
8482
  }
7939
8483
 
8484
+ function fallbackOnMultipleDone() {
8485
+ console.error(
8486
+ new Error(
8487
+ "An asynchronous function called its 'done' " +
8488
+ 'callback more than once, in a QueueRunner without a onMultipleDone ' +
8489
+ 'handler.'
8490
+ )
8491
+ );
8492
+ }
8493
+
7940
8494
  function emptyFn() {}
7941
8495
 
7942
8496
  function QueueRunner(attrs) {
@@ -7951,6 +8505,7 @@ getJasmineRequireObj().QueueRunner = function(j$) {
7951
8505
  fn();
7952
8506
  };
7953
8507
  this.onException = attrs.onException || emptyFn;
8508
+ this.onMultipleDone = attrs.onMultipleDone || fallbackOnMultipleDone;
7954
8509
  this.userContext = attrs.userContext || new j$.UserContext();
7955
8510
  this.timeout = attrs.timeout || {
7956
8511
  setTimeout: setTimeout,
@@ -8008,6 +8563,8 @@ getJasmineRequireObj().QueueRunner = function(j$) {
8008
8563
  var self = this,
8009
8564
  completedSynchronously = true,
8010
8565
  handleError = function handleError(error) {
8566
+ // TODO probably shouldn't next() right away here.
8567
+ // That makes debugging async failures much more confusing.
8011
8568
  onException(error);
8012
8569
  },
8013
8570
  cleanup = once(function cleanup() {
@@ -8016,31 +8573,52 @@ getJasmineRequireObj().QueueRunner = function(j$) {
8016
8573
  }
8017
8574
  self.globalErrors.popListener(handleError);
8018
8575
  }),
8019
- next = once(function next(err) {
8020
- cleanup();
8576
+ next = once(
8577
+ function next(err) {
8578
+ cleanup();
8021
8579
 
8022
- if (j$.isError_(err)) {
8023
- if (!(err instanceof StopExecutionError) && !err.jasmineMessage) {
8024
- self.fail(err);
8580
+ if (j$.isError_(err)) {
8581
+ if (!(err instanceof StopExecutionError) && !err.jasmineMessage) {
8582
+ self.fail(err);
8583
+ }
8584
+ self.errored = errored = true;
8585
+ } else if (typeof err !== 'undefined' && !self.errored) {
8586
+ self.deprecated(
8587
+ 'Any argument passed to a done callback will be treated as an ' +
8588
+ 'error in a future release. Call the done callback without ' +
8589
+ "arguments if you don't want to trigger a spec failure."
8590
+ );
8025
8591
  }
8026
- self.errored = errored = true;
8027
- }
8028
8592
 
8029
- function runNext() {
8030
- if (self.completeOnFirstError && errored) {
8031
- self.skipToCleanup(iterativeIndex);
8032
- } else {
8033
- self.run(iterativeIndex + 1);
8593
+ function runNext() {
8594
+ if (self.completeOnFirstError && errored) {
8595
+ self.skipToCleanup(iterativeIndex);
8596
+ } else {
8597
+ self.run(iterativeIndex + 1);
8598
+ }
8034
8599
  }
8035
- }
8036
8600
 
8037
- if (completedSynchronously) {
8038
- self.setTimeout(runNext);
8039
- } else {
8040
- runNext();
8601
+ if (completedSynchronously) {
8602
+ self.setTimeout(runNext);
8603
+ } else {
8604
+ runNext();
8605
+ }
8606
+ },
8607
+ function() {
8608
+ try {
8609
+ if (!timedOut) {
8610
+ self.onMultipleDone();
8611
+ }
8612
+ } catch (error) {
8613
+ // Any error we catch here is probably due to a bug in Jasmine,
8614
+ // and it's not likely to end up anywhere useful if we let it
8615
+ // propagate. Log it so it can at least show up when debugging.
8616
+ console.error(error);
8617
+ }
8041
8618
  }
8042
- }),
8619
+ ),
8043
8620
  errored = false,
8621
+ timedOut = false,
8044
8622
  queueableFn = self.queueableFns[iterativeIndex],
8045
8623
  timeoutId,
8046
8624
  maybeThenable;
@@ -8056,6 +8634,7 @@ getJasmineRequireObj().QueueRunner = function(j$) {
8056
8634
  if (queueableFn.timeout !== undefined) {
8057
8635
  var timeoutInterval = queueableFn.timeout || j$.DEFAULT_TIMEOUT_INTERVAL;
8058
8636
  timeoutId = self.setTimeout(function() {
8637
+ timedOut = true;
8059
8638
  var error = new Error(
8060
8639
  'Timeout - Async function did not complete within ' +
8061
8640
  timeoutInterval +
@@ -8064,6 +8643,9 @@ getJasmineRequireObj().QueueRunner = function(j$) {
8064
8643
  ? '(custom timeout)'
8065
8644
  : '(set by jasmine.DEFAULT_TIMEOUT_INTERVAL)')
8066
8645
  );
8646
+ // TODO Need to decide what to do about a successful completion after a
8647
+ // timeout. That should probably not be a deprecation, and maybe not
8648
+ // an error in 4.0. (But a diagnostic of some sort might be helpful.)
8067
8649
  onException(error);
8068
8650
  next();
8069
8651
  }, timeoutInterval);
@@ -8129,30 +8711,39 @@ getJasmineRequireObj().QueueRunner = function(j$) {
8129
8711
 
8130
8712
  this.clearStack(function() {
8131
8713
  self.globalErrors.popListener(self.handleFinalError);
8132
- self.onComplete(self.errored && new StopExecutionError());
8714
+
8715
+ if (self.errored) {
8716
+ self.onComplete(new StopExecutionError());
8717
+ } else {
8718
+ self.onComplete();
8719
+ }
8133
8720
  });
8134
8721
  };
8135
8722
 
8136
8723
  QueueRunner.prototype.diagnoseConflictingAsync_ = function(fn, retval) {
8724
+ var msg;
8725
+
8137
8726
  if (retval && j$.isFunction_(retval.then)) {
8138
- // Issue a warning that matches the user's code
8727
+ // Issue a warning that matches the user's code.
8728
+ // Omit the stack trace because there's almost certainly no user code
8729
+ // on the stack at this point.
8139
8730
  if (j$.isAsyncFunction_(fn)) {
8140
- this.deprecated(
8731
+ msg =
8141
8732
  'An asynchronous before/it/after ' +
8142
- 'function was defined with the async keyword but also took a ' +
8143
- 'done callback. This is not supported and will stop working in' +
8144
- ' the future. Either remove the done callback (recommended) or ' +
8145
- 'remove the async keyword.'
8146
- );
8733
+ 'function was defined with the async keyword but also took a ' +
8734
+ 'done callback. This is not supported and will stop working in' +
8735
+ ' the future. Either remove the done callback (recommended) or ' +
8736
+ 'remove the async keyword.';
8147
8737
  } else {
8148
- this.deprecated(
8738
+ msg =
8149
8739
  'An asynchronous before/it/after ' +
8150
- 'function took a done callback but also returned a promise. ' +
8151
- 'This is not supported and will stop working in the future. ' +
8152
- 'Either remove the done callback (recommended) or change the ' +
8153
- 'function to not return a promise.'
8154
- );
8740
+ 'function took a done callback but also returned a promise. ' +
8741
+ 'This is not supported and will stop working in the future. ' +
8742
+ 'Either remove the done callback (recommended) or change the ' +
8743
+ 'function to not return a promise.';
8155
8744
  }
8745
+
8746
+ this.deprecated(msg, { omitStackTrace: true });
8156
8747
  }
8157
8748
  };
8158
8749
 
@@ -8160,7 +8751,7 @@ getJasmineRequireObj().QueueRunner = function(j$) {
8160
8751
  };
8161
8752
 
8162
8753
  getJasmineRequireObj().ReportDispatcher = function(j$) {
8163
- function ReportDispatcher(methods, queueRunnerFactory) {
8754
+ function ReportDispatcher(methods, queueRunnerFactory, deprecated) {
8164
8755
  var dispatchedMethods = methods || [];
8165
8756
 
8166
8757
  for (var i = 0; i < dispatchedMethods.length; i++) {
@@ -8204,7 +8795,18 @@ getJasmineRequireObj().ReportDispatcher = function(j$) {
8204
8795
  queueRunnerFactory({
8205
8796
  queueableFns: fns,
8206
8797
  onComplete: onComplete,
8207
- isReporter: true
8798
+ isReporter: true,
8799
+ onMultipleDone: function() {
8800
+ deprecated(
8801
+ "An asynchronous reporter callback called its 'done' callback " +
8802
+ 'more than once. This is a bug in the reporter callback in ' +
8803
+ 'question. This will be treated as an error in a future ' +
8804
+ 'version. See' +
8805
+ '<https://jasmine.github.io/tutorials/upgrading_to_Jasmine_4.0#deprecations-due-to-calling-done-multiple-times> ' +
8806
+ 'for more information.',
8807
+ { ignoreRunnable: true }
8808
+ );
8809
+ }
8208
8810
  });
8209
8811
  }
8210
8812
 
@@ -8834,7 +9436,7 @@ getJasmineRequireObj().Spy = function(j$) {
8834
9436
  "Spy '" +
8835
9437
  strategyArgs.name +
8836
9438
  "' received a call with arguments " +
8837
- j$.pp(Array.prototype.slice.call(args)) +
9439
+ j$.basicPrettyPrinter_(Array.prototype.slice.call(args)) +
8838
9440
  ' but all configured strategies specify other arguments.'
8839
9441
  );
8840
9442
  } else {
@@ -9780,6 +10382,36 @@ getJasmineRequireObj().Suite = function(j$) {
9780
10382
  this.result.failedExpectations.push(failedExpectation);
9781
10383
  };
9782
10384
 
10385
+ Suite.prototype.onMultipleDone = function() {
10386
+ var msg;
10387
+
10388
+ // Issue a deprecation. Include the context ourselves and pass
10389
+ // ignoreRunnable: true, since getting here always means that we've already
10390
+ // moved on and the current runnable isn't the one that caused the problem.
10391
+ if (this.parentSuite) {
10392
+ msg =
10393
+ "An asynchronous function called its 'done' callback more than " +
10394
+ 'once. This is a bug in the spec, beforeAll, beforeEach, afterAll, ' +
10395
+ 'or afterEach function in question. This will be treated as an error ' +
10396
+ 'in a future version. See' +
10397
+ '<https://jasmine.github.io/tutorials/upgrading_to_Jasmine_4.0#deprecations-due-to-calling-done-multiple-times> ' +
10398
+ 'for more information.\n' +
10399
+ '(in suite: ' +
10400
+ this.getFullName() +
10401
+ ')';
10402
+ } else {
10403
+ msg =
10404
+ 'A top-level beforeAll or afterAll function called its ' +
10405
+ "'done' callback more than once. This is a bug in the beforeAll " +
10406
+ 'or afterAll function in question. This will be treated as an ' +
10407
+ 'error in a future version. See' +
10408
+ '<https://jasmine.github.io/tutorials/upgrading_to_Jasmine_4.0#deprecations-due-to-calling-done-multiple-times> ' +
10409
+ 'for more information.';
10410
+ }
10411
+
10412
+ this.env.deprecated(msg, { ignoreRunnable: true });
10413
+ };
10414
+
9783
10415
  Suite.prototype.addExpectationResult = function() {
9784
10416
  if (isFailure(arguments)) {
9785
10417
  var data = arguments[1];
@@ -9882,7 +10514,10 @@ getJasmineRequireObj().TreeProcessor = function() {
9882
10514
  onException: function() {
9883
10515
  tree.onException.apply(tree, arguments);
9884
10516
  },
9885
- onComplete: done
10517
+ onComplete: done,
10518
+ onMultipleDone: tree.onMultipleDone
10519
+ ? tree.onMultipleDone.bind(tree)
10520
+ : null
9886
10521
  });
9887
10522
  };
9888
10523
 
@@ -10054,7 +10689,10 @@ getJasmineRequireObj().TreeProcessor = function() {
10054
10689
  userContext: node.sharedUserContext(),
10055
10690
  onException: function() {
10056
10691
  node.onException.apply(node, arguments);
10057
- }
10692
+ },
10693
+ onMultipleDone: node.onMultipleDone
10694
+ ? node.onMultipleDone.bind(node)
10695
+ : null
10058
10696
  });
10059
10697
  }
10060
10698
  };
@@ -10111,5 +10749,5 @@ getJasmineRequireObj().UserContext = function(j$) {
10111
10749
  };
10112
10750
 
10113
10751
  getJasmineRequireObj().version = function() {
10114
- return '3.10.1';
10752
+ return '3.99.0';
10115
10753
  };