jasmine-core 4.5.0 → 5.0.0-alpha.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.
package/README.md CHANGED
@@ -32,10 +32,10 @@ Microsoft Edge) as well as Node.
32
32
 
33
33
  | Environment | Supported versions |
34
34
  |-------------------|--------------------|
35
- | Node | 12.17+, 14, 16, 18 |
36
- | Safari | 14-16 |
35
+ | Node | 16.14-16.19, 18 |
36
+ | Safari | 15-16 |
37
37
  | Chrome | Evergreen |
38
- | Firefox | Evergreen, 91 |
38
+ | Firefox | Evergreen, 102 |
39
39
  | Edge | Evergreen |
40
40
 
41
41
  For evergreen browsers, each version of Jasmine is tested against the version of the browser that is available to us
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright (c) 2008-2022 Pivotal Labs
2
+ Copyright (c) 2008-2023 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
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright (c) 2008-2022 Pivotal Labs
2
+ Copyright (c) 2008-2023 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
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright (c) 2008-2022 Pivotal Labs
2
+ Copyright (c) 2008-2023 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
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright (c) 2008-2022 Pivotal Labs
2
+ Copyright (c) 2008-2023 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
@@ -741,6 +741,8 @@ getJasmineRequireObj().Spec = function(j$) {
741
741
  this.asyncExpectationFactory = attrs.asyncExpectationFactory;
742
742
  this.resultCallback = attrs.resultCallback || function() {};
743
743
  this.id = attrs.id;
744
+ this.filename = attrs.filename;
745
+ this.parentSuiteId = attrs.parentSuiteId;
744
746
  this.description = attrs.description || '';
745
747
  this.queueableFn = attrs.queueableFn;
746
748
  this.beforeAndAfterFns =
@@ -774,35 +776,7 @@ getJasmineRequireObj().Spec = function(j$) {
774
776
  this.exclude();
775
777
  }
776
778
 
777
- /**
778
- * @typedef SpecResult
779
- * @property {String} id - The unique id of this spec.
780
- * @property {String} description - The description passed to the {@link it} that created this spec.
781
- * @property {String} fullName - The full description including all ancestors of this spec.
782
- * @property {Expectation[]} failedExpectations - The list of expectations that failed during execution of this spec.
783
- * @property {Expectation[]} passedExpectations - The list of expectations that passed during execution of this spec.
784
- * @property {Expectation[]} deprecationWarnings - The list of deprecation warnings that occurred during execution this spec.
785
- * @property {String} pendingReason - If the spec is {@link pending}, this will be the reason.
786
- * @property {String} status - Once the spec has completed, this string represents the pass/fail status of this spec.
787
- * @property {number} duration - The time in ms used by the spec execution, including any before/afterEach.
788
- * @property {Object} properties - User-supplied properties, if any, that were set using {@link Env#setSpecProperty}
789
- * @property {DebugLogEntry[]|null} debugLogs - Messages, if any, that were logged using {@link jasmine.debugLog} during a failing spec.
790
- * @since 2.0.0
791
- */
792
- this.result = {
793
- id: this.id,
794
- description: this.description,
795
- fullName: this.getFullName(),
796
- failedExpectations: [],
797
- passedExpectations: [],
798
- deprecationWarnings: [],
799
- pendingReason: '',
800
- duration: null,
801
- properties: null,
802
- debugLogs: null
803
- };
804
-
805
- this.reportedDone = false;
779
+ this.reset();
806
780
  }
807
781
 
808
782
  Spec.prototype.addExpectationResult = function(passed, data, isError) {
@@ -912,14 +886,33 @@ getJasmineRequireObj().Spec = function(j$) {
912
886
  };
913
887
 
914
888
  Spec.prototype.reset = function() {
889
+ /**
890
+ * @typedef SpecResult
891
+ * @property {String} id - The unique id of this spec.
892
+ * @property {String} description - The description passed to the {@link it} that created this spec.
893
+ * @property {String} fullName - The full description including all ancestors of this spec.
894
+ * @property {String|null} parentSuiteId - The ID of the suite containing this spec, or null if this spec is not in a describe().
895
+ * @property {String} filename - The name of the file the spec was defined in.
896
+ * @property {Expectation[]} failedExpectations - The list of expectations that failed during execution of this spec.
897
+ * @property {Expectation[]} passedExpectations - The list of expectations that passed during execution of this spec.
898
+ * @property {Expectation[]} deprecationWarnings - The list of deprecation warnings that occurred during execution this spec.
899
+ * @property {String} pendingReason - If the spec is {@link pending}, this will be the reason.
900
+ * @property {String} status - Once the spec has completed, this string represents the pass/fail status of this spec.
901
+ * @property {number} duration - The time in ms used by the spec execution, including any before/afterEach.
902
+ * @property {Object} properties - User-supplied properties, if any, that were set using {@link Env#setSpecProperty}
903
+ * @property {DebugLogEntry[]|null} debugLogs - Messages, if any, that were logged using {@link jasmine.debugLog} during a failing spec.
904
+ * @since 2.0.0
905
+ */
915
906
  this.result = {
916
907
  id: this.id,
917
908
  description: this.description,
918
909
  fullName: this.getFullName(),
910
+ parentSuiteId: this.parentSuiteId,
911
+ filename: this.filename,
919
912
  failedExpectations: [],
920
913
  passedExpectations: [],
921
914
  deprecationWarnings: [],
922
- pendingReason: this.excludeMessage,
915
+ pendingReason: this.excludeMessage || '',
923
916
  duration: null,
924
917
  properties: null,
925
918
  debugLogs: null
@@ -1188,6 +1181,7 @@ getJasmineRequireObj().Env = function(j$) {
1188
1181
  let reporter;
1189
1182
  let topSuite;
1190
1183
  let runner;
1184
+ let parallelLoadingState = null; // 'specs', 'helpers', or null for non-parallel
1191
1185
 
1192
1186
  /**
1193
1187
  * This represents the available options to configure Jasmine.
@@ -1216,6 +1210,10 @@ getJasmineRequireObj().Env = function(j$) {
1216
1210
  seed: null,
1217
1211
  /**
1218
1212
  * Whether to stop execution of the suite after the first spec failure
1213
+ *
1214
+ * <p>In parallel mode, `stopOnSpecFailure` works on a "best effort"
1215
+ * basis. Jasmine will stop execution as soon as practical after a failure
1216
+ * but it might not be immediate.</p>
1219
1217
  * @name Configuration#stopOnSpecFailure
1220
1218
  * @since 3.9.0
1221
1219
  * @type Boolean
@@ -1291,20 +1289,14 @@ getJasmineRequireObj().Env = function(j$) {
1291
1289
 
1292
1290
  if (!options.suppressLoadErrors) {
1293
1291
  installGlobalErrors();
1294
- globalErrors.pushListener(function loadtimeErrorHandler(
1295
- message,
1296
- filename,
1297
- lineno,
1298
- colNo,
1299
- err
1300
- ) {
1292
+ globalErrors.pushListener(function loadtimeErrorHandler(error, event) {
1301
1293
  topSuite.result.failedExpectations.push({
1302
1294
  passed: false,
1303
1295
  globalErrorType: 'load',
1304
- message: message,
1305
- stack: err && err.stack,
1306
- filename: filename,
1307
- lineno: lineno
1296
+ message: error ? error.message : event.message,
1297
+ stack: error && error.stack,
1298
+ filename: event && event.filename,
1299
+ lineno: event && event.lineno
1308
1300
  });
1309
1301
  });
1310
1302
  }
@@ -1522,7 +1514,6 @@ getJasmineRequireObj().Env = function(j$) {
1522
1514
  function(e) {
1523
1515
  (runner.currentRunable() || topSuite).handleException(e);
1524
1516
  };
1525
- options.deprecated = self.deprecated;
1526
1517
 
1527
1518
  new j$.QueueRunner(options).execute();
1528
1519
  }
@@ -1548,6 +1539,7 @@ getJasmineRequireObj().Env = function(j$) {
1548
1539
  * @since 2.0.0
1549
1540
  */
1550
1541
  this.topSuite = function() {
1542
+ ensureNonParallel('topSuite');
1551
1543
  return topSuite.metadata;
1552
1544
  };
1553
1545
 
@@ -1641,21 +1633,25 @@ getJasmineRequireObj().Env = function(j$) {
1641
1633
  reportSpecDone
1642
1634
  });
1643
1635
 
1636
+ this.setParallelLoadingState = function(state) {
1637
+ parallelLoadingState = state;
1638
+ };
1639
+
1640
+ this.parallelReset = function() {
1641
+ // TODO: ensure that autoCleanClosures was false
1642
+ suiteBuilder.parallelReset();
1643
+ runner.parallelReset();
1644
+ };
1645
+
1644
1646
  /**
1645
1647
  * Executes the specs.
1646
1648
  *
1647
- * If called with no parameters or with a falsy value as the first parameter,
1649
+ * If called with no parameter or with a falsy parameter,
1648
1650
  * all specs will be executed except those that are excluded by a
1649
1651
  * [spec filter]{@link Configuration#specFilter} or other mechanism. If the
1650
- * first parameter is a list of spec/suite IDs, only those specs/suites will
1652
+ * parameter is a list of spec/suite IDs, only those specs/suites will
1651
1653
  * be run.
1652
1654
  *
1653
- * Both parameters are optional, but a completion callback is only valid as
1654
- * the second parameter. To specify a completion callback but not a list of
1655
- * specs/suites to run, pass null or undefined as the first parameter. The
1656
- * completion callback is supported for backward compatibility. In most
1657
- * cases it will be more convenient to use the returned promise instead.
1658
- *
1659
1655
  * execute should not be called more than once unless the env has been
1660
1656
  * configured with `{autoCleanClosures: false}`.
1661
1657
  *
@@ -1663,25 +1659,26 @@ getJasmineRequireObj().Env = function(j$) {
1663
1659
  * {@link JasmineDoneInfo|overall result} that's passed to a reporter's
1664
1660
  * `jasmineDone` method, even if the suite did not pass. To determine
1665
1661
  * whether the suite passed, check the value that the promise resolves to
1666
- * or use a {@link Reporter}.
1662
+ * or use a {@link Reporter}. The promise will be rejected in the case of
1663
+ * certain serious errors that prevent execution from starting.
1667
1664
  *
1668
1665
  * @name Env#execute
1669
1666
  * @since 2.0.0
1670
1667
  * @function
1668
+ * @async
1671
1669
  * @param {(string[])=} runablesToRun IDs of suites and/or specs to run
1672
- * @param {Function=} onComplete Function that will be called after all specs have run
1673
1670
  * @return {Promise<JasmineDoneInfo>}
1674
1671
  */
1675
- this.execute = function(runablesToRun, onComplete) {
1672
+ this.execute = async function(runablesToRun) {
1676
1673
  installGlobalErrors();
1677
1674
 
1678
- return runner.execute(runablesToRun).then(function(jasmineDoneInfo) {
1679
- if (onComplete) {
1680
- onComplete();
1681
- }
1675
+ if (parallelLoadingState) {
1676
+ validateConfigForParallel();
1677
+ }
1682
1678
 
1683
- return jasmineDoneInfo;
1684
- });
1679
+ const result = await runner.execute(runablesToRun);
1680
+ this.cleanup_();
1681
+ return result;
1685
1682
  };
1686
1683
 
1687
1684
  /**
@@ -1693,6 +1690,10 @@ getJasmineRequireObj().Env = function(j$) {
1693
1690
  * @see custom_reporter
1694
1691
  */
1695
1692
  this.addReporter = function(reporterToAdd) {
1693
+ if (parallelLoadingState) {
1694
+ throw new Error('Reporters cannot be added via Env in parallel mode');
1695
+ }
1696
+
1696
1697
  reporter.addReporter(reporterToAdd);
1697
1698
  };
1698
1699
 
@@ -1715,6 +1716,10 @@ getJasmineRequireObj().Env = function(j$) {
1715
1716
  * @function
1716
1717
  */
1717
1718
  this.clearReporters = function() {
1719
+ if (parallelLoadingState) {
1720
+ throw new Error('Reporters cannot be removed via Env in parallel mode');
1721
+ }
1722
+
1718
1723
  reporter.clearReporters();
1719
1724
  };
1720
1725
 
@@ -1814,19 +1819,58 @@ getJasmineRequireObj().Env = function(j$) {
1814
1819
  }
1815
1820
  }
1816
1821
 
1822
+ function ensureNonParallel(method) {
1823
+ if (parallelLoadingState) {
1824
+ throw new Error(`'${method}' is not available in parallel mode`);
1825
+ }
1826
+ }
1827
+
1828
+ function ensureNonParallelOrInDescribe(msg) {
1829
+ if (parallelLoadingState && !suiteBuilder.inDescribe()) {
1830
+ throw new Error(msg);
1831
+ }
1832
+ }
1833
+
1834
+ function ensureNonParallelOrInHelperOrInDescribe(method) {
1835
+ if (parallelLoadingState === 'specs' && !suiteBuilder.inDescribe()) {
1836
+ throw new Error(
1837
+ 'In parallel mode, ' +
1838
+ method +
1839
+ ' must be in a describe block or in a helper file'
1840
+ );
1841
+ }
1842
+ }
1843
+
1844
+ function validateConfigForParallel() {
1845
+ if (!config.random) {
1846
+ throw new Error('Randomization cannot be disabled in parallel mode');
1847
+ }
1848
+
1849
+ if (config.seed !== null && config.seed !== undefined) {
1850
+ throw new Error('Random seed cannot be set in parallel mode');
1851
+ }
1852
+ }
1853
+
1817
1854
  this.describe = function(description, definitionFn) {
1818
1855
  ensureIsNotNested('describe');
1819
- return suiteBuilder.describe(description, definitionFn).metadata;
1856
+ const filename = callerCallerFilename();
1857
+ return suiteBuilder.describe(description, definitionFn, filename)
1858
+ .metadata;
1820
1859
  };
1821
1860
 
1822
1861
  this.xdescribe = function(description, definitionFn) {
1823
1862
  ensureIsNotNested('xdescribe');
1824
- return suiteBuilder.xdescribe(description, definitionFn).metadata;
1863
+ const filename = callerCallerFilename();
1864
+ return suiteBuilder.xdescribe(description, definitionFn, filename)
1865
+ .metadata;
1825
1866
  };
1826
1867
 
1827
1868
  this.fdescribe = function(description, definitionFn) {
1828
1869
  ensureIsNotNested('fdescribe');
1829
- return suiteBuilder.fdescribe(description, definitionFn).metadata;
1870
+ ensureNonParallel('fdescribe');
1871
+ const filename = callerCallerFilename();
1872
+ return suiteBuilder.fdescribe(description, definitionFn, filename)
1873
+ .metadata;
1830
1874
  };
1831
1875
 
1832
1876
  function specResultCallback(spec, result, next) {
@@ -1853,17 +1897,21 @@ getJasmineRequireObj().Env = function(j$) {
1853
1897
 
1854
1898
  this.it = function(description, fn, timeout) {
1855
1899
  ensureIsNotNested('it');
1856
- return suiteBuilder.it(description, fn, timeout).metadata;
1900
+ const filename = callerCallerFilename();
1901
+ return suiteBuilder.it(description, fn, timeout, filename).metadata;
1857
1902
  };
1858
1903
 
1859
1904
  this.xit = function(description, fn, timeout) {
1860
1905
  ensureIsNotNested('xit');
1861
- return suiteBuilder.xit(description, fn, timeout).metadata;
1906
+ const filename = callerCallerFilename();
1907
+ return suiteBuilder.xit(description, fn, timeout, filename).metadata;
1862
1908
  };
1863
1909
 
1864
1910
  this.fit = function(description, fn, timeout) {
1865
1911
  ensureIsNotNested('fit');
1866
- return suiteBuilder.fit(description, fn, timeout).metadata;
1912
+ ensureNonParallel('fit');
1913
+ const filename = callerCallerFilename();
1914
+ return suiteBuilder.fit(description, fn, timeout, filename).metadata;
1867
1915
  };
1868
1916
 
1869
1917
  /**
@@ -1935,21 +1983,37 @@ getJasmineRequireObj().Env = function(j$) {
1935
1983
 
1936
1984
  this.beforeEach = function(beforeEachFunction, timeout) {
1937
1985
  ensureIsNotNested('beforeEach');
1986
+ ensureNonParallelOrInHelperOrInDescribe('beforeEach');
1938
1987
  suiteBuilder.beforeEach(beforeEachFunction, timeout);
1939
1988
  };
1940
1989
 
1941
1990
  this.beforeAll = function(beforeAllFunction, timeout) {
1942
1991
  ensureIsNotNested('beforeAll');
1992
+ // This message is -npm-specific, but currently parallel operation is
1993
+ // only supported via -npm.
1994
+ ensureNonParallelOrInDescribe(
1995
+ "In parallel mode, 'beforeAll' " +
1996
+ 'must be in a describe block. Use the globalSetup config ' +
1997
+ 'property for exactly-once setup in parallel mode.'
1998
+ );
1943
1999
  suiteBuilder.beforeAll(beforeAllFunction, timeout);
1944
2000
  };
1945
2001
 
1946
2002
  this.afterEach = function(afterEachFunction, timeout) {
1947
2003
  ensureIsNotNested('afterEach');
2004
+ ensureNonParallelOrInHelperOrInDescribe('afterEach');
1948
2005
  suiteBuilder.afterEach(afterEachFunction, timeout);
1949
2006
  };
1950
2007
 
1951
2008
  this.afterAll = function(afterAllFunction, timeout) {
1952
2009
  ensureIsNotNested('afterAll');
2010
+ // This message is -npm-specific, but currently parallel operation is
2011
+ // only supported via -npm.
2012
+ ensureNonParallelOrInDescribe(
2013
+ "In parallel mode, 'afterAll' " +
2014
+ 'must be in a describe block. Use the globalTeardown config ' +
2015
+ 'property for exactly-once teardown in parallel mode.'
2016
+ );
1953
2017
  suiteBuilder.afterAll(afterAllFunction, timeout);
1954
2018
  };
1955
2019
 
@@ -2003,6 +2067,13 @@ getJasmineRequireObj().Env = function(j$) {
2003
2067
  };
2004
2068
  }
2005
2069
 
2070
+ function callerCallerFilename() {
2071
+ const frames = new j$.StackTrace(new Error()).frames;
2072
+ // frames[3] should always exist except in Jasmine's own tests, which bypass
2073
+ // the global it/describe layer, but don't crash if it doesn't.
2074
+ return frames[3] && frames[3].file;
2075
+ }
2076
+
2006
2077
  return Env;
2007
2078
  };
2008
2079
 
@@ -3999,18 +4070,22 @@ getJasmineRequireObj().GlobalErrors = function(j$) {
3999
4070
  let overrideHandler = null,
4000
4071
  onRemoveOverrideHandler = null;
4001
4072
 
4002
- function onerror(message, source, lineno, colno, error) {
4073
+ function onBrowserError(event) {
4074
+ dispatchBrowserError(event.error, event);
4075
+ }
4076
+
4077
+ function dispatchBrowserError(error, event) {
4003
4078
  if (overrideHandler) {
4004
- overrideHandler(error || message);
4079
+ overrideHandler(error);
4005
4080
  return;
4006
4081
  }
4007
4082
 
4008
4083
  const handler = handlers[handlers.length - 1];
4009
4084
 
4010
4085
  if (handler) {
4011
- handler.apply(null, Array.prototype.slice.call(arguments, 0));
4086
+ handler(error, event);
4012
4087
  } else {
4013
- throw arguments[0];
4088
+ throw error;
4014
4089
  }
4015
4090
  }
4016
4091
 
@@ -4087,8 +4162,7 @@ getJasmineRequireObj().GlobalErrors = function(j$) {
4087
4162
  this.installOne_('uncaughtException', 'Uncaught exception');
4088
4163
  this.installOne_('unhandledRejection', 'Unhandled promise rejection');
4089
4164
  } else {
4090
- const originalHandler = global.onerror;
4091
- global.onerror = onerror;
4165
+ global.addEventListener('error', onBrowserError);
4092
4166
 
4093
4167
  const browserRejectionHandler = function browserRejectionHandler(
4094
4168
  event
@@ -4096,16 +4170,19 @@ getJasmineRequireObj().GlobalErrors = function(j$) {
4096
4170
  if (j$.isError_(event.reason)) {
4097
4171
  event.reason.jasmineMessage =
4098
4172
  'Unhandled promise rejection: ' + event.reason;
4099
- global.onerror(event.reason);
4173
+ dispatchBrowserError(event.reason, event);
4100
4174
  } else {
4101
- global.onerror('Unhandled promise rejection: ' + event.reason);
4175
+ dispatchBrowserError(
4176
+ 'Unhandled promise rejection: ' + event.reason,
4177
+ event
4178
+ );
4102
4179
  }
4103
4180
  };
4104
4181
 
4105
4182
  global.addEventListener('unhandledrejection', browserRejectionHandler);
4106
4183
 
4107
4184
  this.uninstall = function uninstall() {
4108
- global.onerror = originalHandler;
4185
+ global.removeEventListener('error', onBrowserError);
4109
4186
  global.removeEventListener(
4110
4187
  'unhandledrejection',
4111
4188
  browserRejectionHandler
@@ -4114,6 +4191,13 @@ getJasmineRequireObj().GlobalErrors = function(j$) {
4114
4191
  }
4115
4192
  };
4116
4193
 
4194
+ // The listener at the top of the stack will be called with two arguments:
4195
+ // the error and the event. Either of them may be falsy.
4196
+ // The error will normally be provided, but will be falsy in the case of
4197
+ // some browser load-time errors. The event will normally be provided in
4198
+ // browsers but will be falsy in Node.
4199
+ // Listeners that are pushed after spec files have been loaded should be
4200
+ // able to just use the error parameter.
4117
4201
  this.pushListener = function pushListener(listener) {
4118
4202
  handlers.push(listener);
4119
4203
  };
@@ -7444,6 +7528,15 @@ getJasmineRequireObj().makePrettyPrinter = function(j$) {
7444
7528
  };
7445
7529
 
7446
7530
  getJasmineRequireObj().QueueRunner = function(j$) {
7531
+ /*
7532
+ QueueRunner isn't part of the public interface, but it is used by
7533
+ jasmine-npm. -core and -npm version in lockstep at the major and minor
7534
+ levels but version independently at the patch level. Any changes that
7535
+ would break -npm should be done in a major or minor release, never a
7536
+ patch release, and accompanied by a change to -npm that's released in
7537
+ the same version.
7538
+ */
7539
+
7447
7540
  let nextid = 1;
7448
7541
 
7449
7542
  function StopExecutionError() {}
@@ -7507,15 +7600,11 @@ getJasmineRequireObj().QueueRunner = function(j$) {
7507
7600
  if (typeof this.onComplete !== 'function') {
7508
7601
  throw new Error('invalid onComplete ' + JSON.stringify(this.onComplete));
7509
7602
  }
7510
- this.deprecated = attrs.deprecated;
7511
7603
  }
7512
7604
 
7513
7605
  QueueRunner.prototype.execute = function() {
7514
- this.handleFinalError = (message, source, lineno, colno, error) => {
7515
- // Older browsers would send the error as the first parameter. HTML5
7516
- // specifies the the five parameters above. The error instance should
7517
- // be preffered, otherwise the call stack would get lost.
7518
- this.onException(error || message);
7606
+ this.handleFinalError = error => {
7607
+ this.onException(error);
7519
7608
  };
7520
7609
  this.globalErrors.pushListener(this.handleFinalError);
7521
7610
  this.run(0);
@@ -7734,6 +7823,15 @@ getJasmineRequireObj().QueueRunner = function(j$) {
7734
7823
  };
7735
7824
 
7736
7825
  getJasmineRequireObj().ReportDispatcher = function(j$) {
7826
+ /*
7827
+ ReportDispatcher isn't part of the public interface, but it is used by
7828
+ jasmine-npm. -core and -npm version in lockstep at the major and minor
7829
+ levels but version independently at the patch level. Any changes that
7830
+ would break -npm should be done in a major or minor release, never a
7831
+ patch release, and accompanied by a change to -npm that's released in
7832
+ the same version.
7833
+ */
7834
+
7737
7835
  function ReportDispatcher(methods, queueRunnerFactory, onLateError) {
7738
7836
  const dispatchedMethods = methods || [];
7739
7837
 
@@ -8405,6 +8503,7 @@ getJasmineRequireObj().Runner = function(j$) {
8405
8503
  class Runner {
8406
8504
  constructor(options) {
8407
8505
  this.topSuite_ = options.topSuite;
8506
+ // TODO use names that read like getters
8408
8507
  this.totalSpecsDefined_ = options.totalSpecsDefined;
8409
8508
  this.focusedRunables_ = options.focusedRunables;
8410
8509
  this.runableResources_ = options.runableResources;
@@ -8429,11 +8528,11 @@ getJasmineRequireObj().Runner = function(j$) {
8429
8528
  ];
8430
8529
  }
8431
8530
 
8432
- // Although execute returns a promise, it isn't async for backwards
8433
- // compatibility: The "Invalid order" exception needs to be propagated
8434
- // synchronously from Env#execute.
8435
- // TODO: make this and Env#execute async in the next major release
8436
- execute(runablesToRun) {
8531
+ parallelReset() {
8532
+ this.executedBefore_ = false;
8533
+ }
8534
+
8535
+ async execute(runablesToRun) {
8437
8536
  if (this.executedBefore_) {
8438
8537
  this.topSuite_.reset();
8439
8538
  }
@@ -8529,13 +8628,17 @@ getJasmineRequireObj().Runner = function(j$) {
8529
8628
  /**
8530
8629
  * Information passed to the {@link Reporter#jasmineStarted} event.
8531
8630
  * @typedef JasmineStartedInfo
8532
- * @property {Int} totalSpecsDefined - The total number of specs defined in this suite.
8533
- * @property {Order} order - Information about the ordering (random or not) of this execution of the suite.
8631
+ * @property {Int} totalSpecsDefined - The total number of specs defined in this suite. Note that this property is not present when Jasmine is run in parallel mode.
8632
+ * @property {Order} order - Information about the ordering (random or not) of this execution of the suite. Note that this property is not present when Jasmine is run in parallel mode.
8633
+ * @property {Boolean} parallel - Whether Jasmine is being run in parallel mode.
8534
8634
  * @since 2.0.0
8535
8635
  */
8536
8636
  await this.reporter_.jasmineStarted({
8637
+ // In parallel mode, the jasmineStarted event is separately dispatched
8638
+ // by jasmine-npm. This event only reaches reporters in non-parallel.
8537
8639
  totalSpecsDefined,
8538
- order: order
8640
+ order: order,
8641
+ parallel: false
8539
8642
  });
8540
8643
 
8541
8644
  this.currentlyExecutingSuites_.push(this.topSuite_);
@@ -8547,7 +8650,7 @@ getJasmineRequireObj().Runner = function(j$) {
8547
8650
 
8548
8651
  this.runableResources_.clearForRunable(this.topSuite_.id);
8549
8652
  this.currentlyExecutingSuites_.pop();
8550
- let overallStatus, incompleteReason;
8653
+ let overallStatus, incompleteReason, incompleteCode;
8551
8654
 
8552
8655
  if (
8553
8656
  this.hasFailures ||
@@ -8557,9 +8660,11 @@ getJasmineRequireObj().Runner = function(j$) {
8557
8660
  } else if (this.focusedRunables_().length > 0) {
8558
8661
  overallStatus = 'incomplete';
8559
8662
  incompleteReason = 'fit() or fdescribe() was found';
8663
+ incompleteCode = 'focused';
8560
8664
  } else if (totalSpecsDefined === 0) {
8561
8665
  overallStatus = 'incomplete';
8562
8666
  incompleteReason = 'No specs found';
8667
+ incompleteCode = 'noSpecsFound';
8563
8668
  } else {
8564
8669
  overallStatus = 'passed';
8565
8670
  }
@@ -8569,8 +8674,10 @@ getJasmineRequireObj().Runner = function(j$) {
8569
8674
  * @typedef JasmineDoneInfo
8570
8675
  * @property {OverallStatus} overallStatus - The overall result of the suite: 'passed', 'failed', or 'incomplete'.
8571
8676
  * @property {Int} totalTime - The total time (in ms) that it took to execute the suite
8572
- * @property {IncompleteReason} incompleteReason - Explanation of why the suite was incomplete.
8573
- * @property {Order} order - Information about the ordering (random or not) of this execution of the suite.
8677
+ * @property {String} incompleteReason - Human-readable explanation of why the suite was incomplete.
8678
+ * @property {String} incompleteCode - Machine-readable explanation of why the suite was incomplete: 'focused', 'noSpecsFound', or undefined.
8679
+ * @property {Order} order - Information about the ordering (random or not) of this execution of the suite. Note that this property is not present when Jasmine is run in parallel mode.
8680
+ * @property {Int} numWorkers - Number of parallel workers. Note that this property is only present when Jasmine is run in parallel mode.
8574
8681
  * @property {Expectation[]} failedExpectations - List of expectations that failed in an {@link afterAll} at the global level.
8575
8682
  * @property {Expectation[]} deprecationWarnings - List of deprecation warnings that occurred at the global level.
8576
8683
  * @since 2.4.0
@@ -8579,6 +8686,7 @@ getJasmineRequireObj().Runner = function(j$) {
8579
8686
  overallStatus: overallStatus,
8580
8687
  totalTime: jasmineTimer.elapsed(),
8581
8688
  incompleteReason: incompleteReason,
8689
+ incompleteCode: incompleteCode,
8582
8690
  order: order,
8583
8691
  failedExpectations: this.topSuite_.result.failedExpectations,
8584
8692
  deprecationWarnings: this.topSuite_.result.deprecationWarnings
@@ -9530,6 +9638,8 @@ getJasmineRequireObj().Suite = function(j$) {
9530
9638
  this.id = attrs.id;
9531
9639
  this.parentSuite = attrs.parentSuite;
9532
9640
  this.description = attrs.description;
9641
+ this.reportedParentSuiteId = attrs.reportedParentSuiteId;
9642
+ this.filename = attrs.filename;
9533
9643
  this.expectationFactory = attrs.expectationFactory;
9534
9644
  this.asyncExpectationFactory = attrs.asyncExpectationFactory;
9535
9645
  this.throwOnExpectationFailure = !!attrs.throwOnExpectationFailure;
@@ -9635,6 +9745,8 @@ getJasmineRequireObj().Suite = function(j$) {
9635
9745
  * @property {String} id - The unique id of this suite.
9636
9746
  * @property {String} description - The description text passed to the {@link describe} that made this suite.
9637
9747
  * @property {String} fullName - The full description including all ancestors of this suite.
9748
+ * @property {String|null} parentSuiteId - The ID of the suite containing this suite, or null if this is not in another describe().
9749
+ * @property {String} filename - The name of the file the suite was defined in.
9638
9750
  * @property {Expectation[]} failedExpectations - The list of expectations that failed in an {@link afterAll} for this suite.
9639
9751
  * @property {Expectation[]} deprecationWarnings - The list of deprecation warnings that occurred on this suite.
9640
9752
  * @property {String} status - Once the suite has completed, this string represents the pass/fail status of this suite.
@@ -9646,6 +9758,8 @@ getJasmineRequireObj().Suite = function(j$) {
9646
9758
  id: this.id,
9647
9759
  description: this.description,
9648
9760
  fullName: this.getFullName(),
9761
+ parentSuiteId: this.reportedParentSuiteId,
9762
+ filename: this.filename,
9649
9763
  failedExpectations: [],
9650
9764
  deprecationWarnings: [],
9651
9765
  duration: null,
@@ -9658,6 +9772,10 @@ getJasmineRequireObj().Suite = function(j$) {
9658
9772
  this.reportedDone = false;
9659
9773
  };
9660
9774
 
9775
+ Suite.prototype.removeChildren = function() {
9776
+ this.children = [];
9777
+ };
9778
+
9661
9779
  Suite.prototype.addChild = function(child) {
9662
9780
  this.children.push(child);
9663
9781
  };
@@ -9873,9 +9991,20 @@ getJasmineRequireObj().SuiteBuilder = function(j$) {
9873
9991
  this.focusedRunables = [];
9874
9992
  }
9875
9993
 
9876
- describe(description, definitionFn) {
9994
+ inDescribe() {
9995
+ return this.currentDeclarationSuite_ !== this.topSuite;
9996
+ }
9997
+
9998
+ parallelReset() {
9999
+ this.topSuite.removeChildren();
10000
+ this.topSuite.reset();
10001
+ this.totalSpecsDefined = 0;
10002
+ this.focusedRunables = [];
10003
+ }
10004
+
10005
+ describe(description, definitionFn, filename) {
9877
10006
  ensureIsFunction(definitionFn, 'describe');
9878
- const suite = this.suiteFactory_(description);
10007
+ const suite = this.suiteFactory_(description, filename);
9879
10008
  if (definitionFn.length > 0) {
9880
10009
  throw new Error('describe does not expect any arguments');
9881
10010
  }
@@ -9886,9 +10015,9 @@ getJasmineRequireObj().SuiteBuilder = function(j$) {
9886
10015
  return suite;
9887
10016
  }
9888
10017
 
9889
- fdescribe(description, definitionFn) {
10018
+ fdescribe(description, definitionFn, filename) {
9890
10019
  ensureIsFunction(definitionFn, 'fdescribe');
9891
- const suite = this.suiteFactory_(description);
10020
+ const suite = this.suiteFactory_(description, filename);
9892
10021
  suite.isFocused = true;
9893
10022
 
9894
10023
  this.focusedRunables.push(suite.id);
@@ -9898,37 +10027,37 @@ getJasmineRequireObj().SuiteBuilder = function(j$) {
9898
10027
  return suite;
9899
10028
  }
9900
10029
 
9901
- xdescribe(description, definitionFn) {
10030
+ xdescribe(description, definitionFn, filename) {
9902
10031
  ensureIsFunction(definitionFn, 'xdescribe');
9903
- const suite = this.suiteFactory_(description);
10032
+ const suite = this.suiteFactory_(description, filename);
9904
10033
  suite.exclude();
9905
10034
  this.addSpecsToSuite_(suite, definitionFn);
9906
10035
 
9907
10036
  return suite;
9908
10037
  }
9909
10038
 
9910
- it(description, fn, timeout) {
10039
+ it(description, fn, timeout, filename) {
9911
10040
  // it() sometimes doesn't have a fn argument, so only check the type if
9912
10041
  // it's given.
9913
10042
  if (arguments.length > 1 && typeof fn !== 'undefined') {
9914
10043
  ensureIsFunctionOrAsync(fn, 'it');
9915
10044
  }
9916
10045
 
9917
- return this.it_(description, fn, timeout);
10046
+ return this.it_(description, fn, timeout, filename);
9918
10047
  }
9919
10048
 
9920
- xit(description, fn, timeout) {
10049
+ xit(description, fn, timeout, filename) {
9921
10050
  // xit(), like it(), doesn't always have a fn argument, so only check the
9922
10051
  // type when needed.
9923
10052
  if (arguments.length > 1 && typeof fn !== 'undefined') {
9924
10053
  ensureIsFunctionOrAsync(fn, 'xit');
9925
10054
  }
9926
- const spec = this.it_(description, fn, timeout);
10055
+ const spec = this.it_(description, fn, timeout, filename);
9927
10056
  spec.exclude('Temporarily disabled with xit');
9928
10057
  return spec;
9929
10058
  }
9930
10059
 
9931
- fit(description, fn, timeout) {
10060
+ fit(description, fn, timeout, filename) {
9932
10061
  // Unlike it and xit, the function is required because it doesn't make
9933
10062
  // sense to focus on nothing.
9934
10063
  ensureIsFunctionOrAsync(fn, 'fit');
@@ -9936,7 +10065,7 @@ getJasmineRequireObj().SuiteBuilder = function(j$) {
9936
10065
  if (timeout) {
9937
10066
  j$.util.validateTimeout(timeout);
9938
10067
  }
9939
- const spec = this.specFactory_(description, fn, timeout);
10068
+ const spec = this.specFactory_(description, fn, timeout, filename);
9940
10069
  this.currentDeclarationSuite_.addChild(spec);
9941
10070
  this.focusedRunables.push(spec.id);
9942
10071
  this.unfocusAncestor_();
@@ -9996,12 +10125,12 @@ getJasmineRequireObj().SuiteBuilder = function(j$) {
9996
10125
  });
9997
10126
  }
9998
10127
 
9999
- it_(description, fn, timeout) {
10128
+ it_(description, fn, timeout, filename) {
10000
10129
  if (timeout) {
10001
10130
  j$.util.validateTimeout(timeout);
10002
10131
  }
10003
10132
 
10004
- const spec = this.specFactory_(description, fn, timeout);
10133
+ const spec = this.specFactory_(description, fn, timeout, filename);
10005
10134
  if (this.currentDeclarationSuite_.markedExcluding) {
10006
10135
  spec.exclude();
10007
10136
  }
@@ -10010,12 +10139,17 @@ getJasmineRequireObj().SuiteBuilder = function(j$) {
10010
10139
  return spec;
10011
10140
  }
10012
10141
 
10013
- suiteFactory_(description) {
10142
+ suiteFactory_(description, filename) {
10014
10143
  const config = this.env_.configuration();
10144
+ const parentSuite = this.currentDeclarationSuite_;
10145
+ const reportedParentSuiteId =
10146
+ parentSuite === this.topSuite ? null : parentSuite.id;
10015
10147
  return new j$.Suite({
10016
10148
  id: 'suite' + this.nextSuiteId_++,
10017
10149
  description,
10018
- parentSuite: this.currentDeclarationSuite_,
10150
+ filename,
10151
+ parentSuite,
10152
+ reportedParentSuiteId,
10019
10153
  timer: new j$.Timer(),
10020
10154
  expectationFactory: this.expectationFactory_,
10021
10155
  asyncExpectationFactory: this.suiteAsyncExpectationFactory_,
@@ -10047,12 +10181,15 @@ getJasmineRequireObj().SuiteBuilder = function(j$) {
10047
10181
  this.currentDeclarationSuite_ = parentSuite;
10048
10182
  }
10049
10183
 
10050
- specFactory_(description, fn, timeout) {
10184
+ specFactory_(description, fn, timeout, filename) {
10051
10185
  this.totalSpecsDefined++;
10052
10186
  const config = this.env_.configuration();
10053
10187
  const suite = this.currentDeclarationSuite_;
10188
+ const parentSuiteId = suite === this.topSuite ? null : suite.id;
10054
10189
  const spec = new j$.Spec({
10055
10190
  id: 'spec' + this.nextSpecId_++,
10191
+ filename,
10192
+ parentSuiteId,
10056
10193
  beforeAndAfterFns: beforeAndAfterFns(suite),
10057
10194
  expectationFactory: this.expectationFactory_,
10058
10195
  asyncExpectationFactory: this.specAsyncExpectationFactory_,
@@ -10156,6 +10293,15 @@ getJasmineRequireObj().SuiteBuilder = function(j$) {
10156
10293
  };
10157
10294
 
10158
10295
  getJasmineRequireObj().Timer = function() {
10296
+ /*
10297
+ Timer isn't part of the public interface, but it is used by
10298
+ jasmine-npm. -core and -npm version in lockstep at the major and minor
10299
+ levels but version independently at the patch level. Any changes that
10300
+ would break -npm should be done in a major or minor release, never a
10301
+ patch release, and accompanied by a change to -npm that's released in
10302
+ the same version.
10303
+ */
10304
+
10159
10305
  const defaultNow = (function(Date) {
10160
10306
  return function() {
10161
10307
  return new Date().getTime();
@@ -10464,5 +10610,5 @@ getJasmineRequireObj().UserContext = function(j$) {
10464
10610
  };
10465
10611
 
10466
10612
  getJasmineRequireObj().version = function() {
10467
- return '4.5.0';
10613
+ return '5.0.0-alpha.0';
10468
10614
  };
@@ -6,36 +6,48 @@
6
6
  const jasmineRequire = require('./jasmine-core/jasmine.js');
7
7
  module.exports = jasmineRequire;
8
8
 
9
+ const bootOnce = (function() {
10
+ let jasmine, jasmineInterface;
11
+
12
+ return function bootWithoutGlobals() {
13
+ if (!jasmineInterface) {
14
+ jasmine = jasmineRequire.core(jasmineRequire);
15
+ const env = jasmine.getEnv({ suppressLoadErrors: true });
16
+ jasmineInterface = jasmineRequire.interface(jasmine, env);
17
+ }
18
+
19
+ return {jasmine, jasmineInterface};
20
+ };
21
+ }());
22
+
9
23
  /**
10
24
  * Boots a copy of Jasmine and returns an object as described in {@link jasmine}.
25
+ * If boot is called multiple times, the same object is returned every time.
11
26
  * @type {function}
12
27
  * @return {jasmine}
13
28
  */
14
- module.exports.boot = require('./jasmine-core/node_boot.js');
29
+ module.exports.boot = function() {
30
+ const {jasmine, jasmineInterface} = bootOnce();
31
+
32
+ for (const k in jasmineInterface) {
33
+ global[k] = jasmineInterface[k];
34
+ }
35
+
36
+ return jasmine;
37
+ };
15
38
 
16
39
  /**
17
40
  * Boots a copy of Jasmine and returns an object containing the properties
18
41
  * that would normally be added to the global object. If noGlobals is called
19
42
  * multiple times, the same object is returned every time.
20
43
  *
21
- * Do not call boot() if you also call noGlobals().
22
- *
23
44
  * @example
24
45
  * const {describe, beforeEach, it, expect, jasmine} = require('jasmine-core').noGlobals();
25
46
  */
26
- module.exports.noGlobals = (function() {
27
- let jasmineInterface;
28
-
29
- return function bootWithoutGlobals() {
30
- if (!jasmineInterface) {
31
- const jasmine = jasmineRequire.core(jasmineRequire);
32
- const env = jasmine.getEnv({ suppressLoadErrors: true });
33
- jasmineInterface = jasmineRequire.interface(jasmine, env);
34
- }
35
-
36
- return jasmineInterface;
37
- };
38
- }());
47
+ module.exports.noGlobals = function() {
48
+ const {jasmineInterface} = bootOnce();
49
+ return jasmineInterface;
50
+ };
39
51
 
40
52
  const path = require('path'),
41
53
  fs = require('fs');
@@ -43,10 +55,9 @@ const path = require('path'),
43
55
  const rootPath = path.join(__dirname, 'jasmine-core'),
44
56
  bootFiles = ['boot0.js', 'boot1.js'],
45
57
  legacyBootFiles = ['boot.js'],
46
- nodeBootFiles = ['node_boot.js'],
47
58
  cssFiles = [],
48
59
  jsFiles = [],
49
- jsFilesToSkip = ['jasmine.js'].concat(bootFiles, legacyBootFiles, nodeBootFiles);
60
+ jsFilesToSkip = ['jasmine.js'].concat(bootFiles, legacyBootFiles);
50
61
 
51
62
  fs.readdirSync(rootPath).forEach(function(file) {
52
63
  if(fs.statSync(path.join(rootPath, file)).isFile()) {
@@ -56,18 +67,18 @@ fs.readdirSync(rootPath).forEach(function(file) {
56
67
  break;
57
68
  case '.js':
58
69
  if (jsFilesToSkip.indexOf(file) < 0) {
59
- jsFiles.push(file);
60
- }
70
+ jsFiles.push(file);
71
+ }
61
72
  break;
62
73
  }
63
74
  }
64
75
  });
65
76
 
66
77
  module.exports.files = {
78
+ self: __filename,
67
79
  path: rootPath,
68
80
  bootDir: rootPath,
69
81
  bootFiles: bootFiles,
70
- nodeBootFiles: nodeBootFiles,
71
82
  cssFiles: cssFiles,
72
83
  jsFiles: ['jasmine.js'].concat(jsFiles),
73
84
  imagesDir: path.join(__dirname, '../images')
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "jasmine-core",
3
3
  "license": "MIT",
4
- "version": "4.5.0",
4
+ "version": "5.0.0-alpha.0",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "https://github.com/jasmine/jasmine.git"
@@ -35,20 +35,20 @@
35
35
  ],
36
36
  "devDependencies": {
37
37
  "eslint": "^7.32.0",
38
- "eslint-plugin-compat": "^4.0.0",
38
+ "eslint-plugin-compat": ">=4.0.0 <4.1.0",
39
39
  "glob": "^7.2.0",
40
- "grunt": "^1.0.4",
40
+ "grunt": ">=1.0.4 <1.6.0",
41
41
  "grunt-cli": "^1.3.2",
42
42
  "grunt-contrib-compress": "^2.0.0",
43
43
  "grunt-contrib-concat": "^2.0.0",
44
44
  "grunt-css-url-embed": "^1.11.1",
45
45
  "grunt-sass": "^3.0.2",
46
- "jasmine": "^4.1.0",
46
+ "jasmine": "github:jasmine/jasmine-npm#5.0",
47
47
  "jasmine-browser-runner": "^1.0.0",
48
48
  "jsdom": "^19.0.0",
49
49
  "load-grunt-tasks": "^5.1.0",
50
50
  "prettier": "1.17.1",
51
- "sass": "^1.45.1",
51
+ "sass": "1.58.3",
52
52
  "shelljs": "^0.8.3",
53
53
  "temp": "^0.9.0"
54
54
  },
@@ -101,10 +101,9 @@
101
101
  }
102
102
  },
103
103
  "browserslist": [
104
- "Safari >= 14",
104
+ "Safari >= 15",
105
+ "Firefox >= 102",
105
106
  "last 2 Chrome versions",
106
- "last 2 Firefox versions",
107
- "Firefox >= 91",
108
107
  "last 2 Edge versions"
109
108
  ]
110
109
  }
@@ -1,38 +0,0 @@
1
- /*
2
- Copyright (c) 2008-2022 Pivotal Labs
3
-
4
- Permission is hereby granted, free of charge, to any person obtaining
5
- a copy of this software and associated documentation files (the
6
- "Software"), to deal in the Software without restriction, including
7
- without limitation the rights to use, copy, modify, merge, publish,
8
- distribute, sublicense, and/or sell copies of the Software, and to
9
- permit persons to whom the Software is furnished to do so, subject to
10
- the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be
13
- included in all copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
- */
23
- module.exports = function(jasmineRequire) {
24
- const jasmine = jasmineRequire.core(jasmineRequire);
25
-
26
- const env = jasmine.getEnv({ suppressLoadErrors: true });
27
-
28
- const jasmineInterface = jasmineRequire.interface(jasmine, env);
29
-
30
- extend(global, jasmineInterface);
31
-
32
- function extend(destination, source) {
33
- for (const property in source) destination[property] = source[property];
34
- return destination;
35
- }
36
-
37
- return jasmine;
38
- };