jasmine-core 3.10.1 → 3.99.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
  };