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.
- checksums.yaml +4 -4
- data/lib/jasmine-core/boot/boot.js +4 -2
- data/lib/jasmine-core/boot/boot1.js +2 -2
- data/lib/jasmine-core/boot.js +5 -3
- data/lib/jasmine-core/boot0.js +1 -1
- data/lib/jasmine-core/boot1.js +3 -3
- data/lib/jasmine-core/core.py +4 -4
- data/lib/jasmine-core/jasmine-html.js +66 -16
- data/lib/jasmine-core/jasmine.css +19 -0
- data/lib/jasmine-core/jasmine.js +758 -120
- data/lib/jasmine-core/node_boot.js +1 -1
- data/lib/jasmine-core/version.rb +1 -1
- data/lib/jasmine-core.rb +1 -1
- metadata +3 -3
data/lib/jasmine-core/jasmine.js
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
/*
|
2
|
-
Copyright (c) 2008-
|
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$.
|
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
|
-
|
97
|
+
var staticMatchersUtil = new j$.MatchersUtil({
|
82
98
|
customTesters: [],
|
83
|
-
pp: j$.
|
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
|
-
|
901
|
-
|
902
|
-
|
903
|
-
|
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
|
-
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
-
|
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
|
-
|
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
|
-
|
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.
|
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.
|
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$.
|
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$.
|
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 ' +
|
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 ' +
|
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
|
-
|
3367
|
+
copyAndDeprecate(self, customEqualityTesters, 'length');
|
3205
3368
|
|
3206
3369
|
for (i = 0; i < customEqualityTesters.length; i++) {
|
3207
|
-
|
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
|
-
|
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' && !
|
3217
|
-
|
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
|
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
|
-
|
3704
|
-
|
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
|
-
|
3707
|
-
|
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$.
|
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
|
-
|
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
|
-
|
5146
|
-
|
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 (
|
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(
|
8020
|
-
|
8576
|
+
next = once(
|
8577
|
+
function next(err) {
|
8578
|
+
cleanup();
|
8021
8579
|
|
8022
|
-
|
8023
|
-
|
8024
|
-
|
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
|
-
|
8030
|
-
|
8031
|
-
|
8032
|
-
|
8033
|
-
|
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
|
-
|
8038
|
-
|
8039
|
-
|
8040
|
-
|
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
|
-
|
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
|
-
|
8731
|
+
msg =
|
8141
8732
|
'An asynchronous before/it/after ' +
|
8142
|
-
|
8143
|
-
|
8144
|
-
|
8145
|
-
|
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
|
-
|
8738
|
+
msg =
|
8149
8739
|
'An asynchronous before/it/after ' +
|
8150
|
-
|
8151
|
-
|
8152
|
-
|
8153
|
-
|
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$.
|
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.
|
10752
|
+
return '3.99.0';
|
10115
10753
|
};
|