jasmine-core 5.6.0 → 5.7.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
@@ -1,4 +1,4 @@
1
- <a name="README">[<img src="https://rawgithub.com/jasmine/jasmine/main/images/jasmine-horizontal.svg" width="400px" />](http://jasmine.github.io)</a>
1
+ <a name="README"><img src="https://raw.githubusercontent.com/jasmine/jasmine/main/images/jasmine-horizontal.svg" width="400px" alt="Jasmine"></a>
2
2
 
3
3
  # A JavaScript Testing Framework
4
4
 
@@ -21,6 +21,7 @@ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
21
  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
22
  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
23
  */
24
+
24
25
  /**
25
26
  This file starts the process of "booting" Jasmine. It initializes Jasmine,
26
27
  makes its globals available, and creates the env. This file should be loaded
@@ -21,6 +21,7 @@ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
21
  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
22
  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
23
  */
24
+
24
25
  /**
25
26
  This file finishes 'booting' Jasmine, performing all of the necessary
26
27
  initialization before executing the loaded environment and all of a project's
@@ -21,6 +21,7 @@ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
21
  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
22
  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
23
  */
24
+
24
25
  // eslint-disable-next-line no-var
25
26
  var jasmineRequire = window.jasmineRequire || require('./jasmine.js');
26
27
 
@@ -155,8 +156,10 @@ jasmineRequire.HtmlReporter = function(j$) {
155
156
  if (noExpectations(result)) {
156
157
  const noSpecMsg = "Spec '" + result.fullName + "' has no expectations.";
157
158
  if (result.status === 'failed') {
159
+ // eslint-disable-next-line no-console
158
160
  console.error(noSpecMsg);
159
161
  } else {
162
+ // eslint-disable-next-line no-console
160
163
  console.warn(noSpecMsg);
161
164
  }
162
165
  }
@@ -21,6 +21,7 @@ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
21
  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
22
  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
23
  */
24
+
24
25
  // eslint-disable-next-line no-unused-vars,no-var
25
26
  var getJasmineRequireObj = (function(jasmineGlobal) {
26
27
  let jasmineRequire;
@@ -791,11 +792,11 @@ getJasmineRequireObj().Spec = function(j$) {
791
792
  this.onStart = attrs.onStart || function() {};
792
793
  this.autoCleanClosures =
793
794
  attrs.autoCleanClosures === undefined ? true : !!attrs.autoCleanClosures;
794
- this.getSpecName =
795
- attrs.getSpecName ||
796
- function() {
797
- return '';
798
- };
795
+
796
+ this.getPath = function() {
797
+ return attrs.getPath ? attrs.getPath(this) : [];
798
+ };
799
+
799
800
  this.onLateError = attrs.onLateError || function() {};
800
801
  this.catchingExceptions =
801
802
  attrs.catchingExceptions ||
@@ -918,6 +919,9 @@ getJasmineRequireObj().Spec = function(j$) {
918
919
  * @property {String} fullName - The full description including all ancestors of this spec.
919
920
  * @property {String|null} parentSuiteId - The ID of the suite containing this spec, or null if this spec is not in a describe().
920
921
  * @property {String} filename - The name of the file the spec was defined in.
922
+ * Note: The value may be incorrect if zone.js is installed or
923
+ * `it`/`fit`/`xit` have been replaced with versions that don't maintain the
924
+ * same call stack height as the originals.
921
925
  * @property {ExpectationResult[]} failedExpectations - The list of expectations that failed during execution of this spec.
922
926
  * @property {ExpectationResult[]} passedExpectations - The list of expectations that passed during execution of this spec.
923
927
  * @property {ExpectationResult[]} deprecationWarnings - The list of deprecation warnings that occurred during execution this spec.
@@ -1021,7 +1025,7 @@ getJasmineRequireObj().Spec = function(j$) {
1021
1025
  };
1022
1026
 
1023
1027
  Spec.prototype.getFullName = function() {
1024
- return this.getSpecName(this);
1028
+ return this.getPath().join(' ');
1025
1029
  };
1026
1030
 
1027
1031
  Spec.prototype.addDeprecationWarning = function(deprecation) {
@@ -1075,6 +1079,10 @@ getJasmineRequireObj().Spec = function(j$) {
1075
1079
  * @since 2.0.0
1076
1080
  */
1077
1081
  Object.defineProperty(Spec.prototype, 'metadata', {
1082
+ // NOTE: Although most of jasmine-core only exposes these metadata objects,
1083
+ // actual Spec instances are still passed to Configuration#specFilter. Until
1084
+ // that is fixed, it's important to make sure that all metadata properties
1085
+ // also exist in compatible form on the underlying Spec.
1078
1086
  get: function() {
1079
1087
  if (!this.metadata_) {
1080
1088
  this.metadata_ = {
@@ -1103,7 +1111,16 @@ getJasmineRequireObj().Spec = function(j$) {
1103
1111
  * @returns {string}
1104
1112
  * @since 2.0.0
1105
1113
  */
1106
- getFullName: this.getFullName.bind(this)
1114
+ getFullName: this.getFullName.bind(this),
1115
+
1116
+ /**
1117
+ * The full path of the spec, as an array of names.
1118
+ * @name Spec#getPath
1119
+ * @function
1120
+ * @returns {Array.<string>}
1121
+ * @since 5.7.0
1122
+ */
1123
+ getPath: this.getPath.bind(this)
1107
1124
  };
1108
1125
  }
1109
1126
 
@@ -1545,7 +1562,9 @@ getJasmineRequireObj().Env = function(j$) {
1545
1562
 
1546
1563
  // If we get here, all results have been reported and there's nothing we
1547
1564
  // can do except log the result and hope the user sees it.
1565
+ // eslint-disable-next-line no-console
1548
1566
  console.error('Jasmine received a result after the suite finished:');
1567
+ // eslint-disable-next-line no-console
1549
1568
  console.error(expectationResult);
1550
1569
  }
1551
1570
 
@@ -2693,7 +2712,8 @@ getJasmineRequireObj().buildExpectationResult = function(j$) {
2693
2712
  * in a future release. In many Jasmine configurations they are passed
2694
2713
  * through JSON serialization and deserialization, which is inherently
2695
2714
  * lossy. In such cases, the expected and actual values may be placeholders
2696
- * or approximations of the original objects.
2715
+ * or approximations of the original objects. jasmine-browser-runner 3.0 and
2716
+ * later omits them entirely.
2697
2717
  *
2698
2718
  * @typedef ExpectationResult
2699
2719
  * @property {String} matcherName - The name of the matcher that was executed for this expectation.
@@ -3065,6 +3085,15 @@ getJasmineRequireObj().Clock = function() {
3065
3085
  let installed = false;
3066
3086
  let delayedFunctionScheduler;
3067
3087
  let timer;
3088
+ // Tracks how the clock ticking behaves.
3089
+ // By default, the clock only ticks when the user manually calls a tick method.
3090
+ // There is also an 'auto' mode which will advance the clock automatically to
3091
+ // to the next task. Once enabled, there is currently no mechanism for users
3092
+ // to disable the auto ticking.
3093
+ let tickMode = {
3094
+ mode: 'manual',
3095
+ counter: 0
3096
+ };
3068
3097
 
3069
3098
  this.FakeTimeout = FakeTimeout;
3070
3099
 
@@ -3174,8 +3203,98 @@ getJasmineRequireObj().Clock = function() {
3174
3203
  }
3175
3204
  };
3176
3205
 
3206
+ /**
3207
+ * Updates the clock to automatically advance time.
3208
+ *
3209
+ * With this mode, the clock advances to the first scheduled timer and fires it, in a loop.
3210
+ * Between each timer, it will also break the event loop, allowing any scheduled promise
3211
+ callbacks to execute _before_ running the next one.
3212
+ *
3213
+ * This mode allows tests to be authored in a way that does not need to be aware of the
3214
+ * mock clock. Consequently, tests which have been authored without a mock clock installed
3215
+ * can one with auto tick enabled without any other updates to the test logic.
3216
+ *
3217
+ * In many cases, this can greatly improve test execution speed because asynchronous tasks
3218
+ * will execute as quickly as possible rather than waiting real time to complete.
3219
+ *
3220
+ * Furthermore, tests can be authored in a consistent manner. They can always be written in an asynchronous style
3221
+ * rather than having `tick` sprinkled throughout the tests with mock time in order to manually
3222
+ * advance the clock.
3223
+ *
3224
+ * When auto tick is enabled, `tick` can still be used to synchronously advance the clock if necessary.
3225
+ * @name Clock#autoTick
3226
+ * @function
3227
+ * @since 5.7.0
3228
+ */
3229
+ this.autoTick = function() {
3230
+ if (tickMode.mode === 'auto') {
3231
+ return;
3232
+ }
3233
+
3234
+ tickMode = { mode: 'auto', counter: tickMode.counter + 1 };
3235
+ advanceUntilModeChanges();
3236
+ };
3237
+
3177
3238
  return this;
3178
3239
 
3240
+ // Advances the Clock's time until the mode changes.
3241
+ //
3242
+ // The time is advanced asynchronously, giving microtasks and events a chance
3243
+ // to run before each timer runs.
3244
+ //
3245
+ // @function
3246
+ // @return {!Promise<undefined>}
3247
+ async function advanceUntilModeChanges() {
3248
+ if (!installed) {
3249
+ throw new Error(
3250
+ 'Mock clock is not installed, use jasmine.clock().install()'
3251
+ );
3252
+ }
3253
+ const { counter } = tickMode;
3254
+
3255
+ while (true) {
3256
+ await newMacrotask();
3257
+
3258
+ if (
3259
+ tickMode.counter !== counter ||
3260
+ !installed ||
3261
+ delayedFunctionScheduler === null
3262
+ ) {
3263
+ return;
3264
+ }
3265
+
3266
+ if (!delayedFunctionScheduler.isEmpty()) {
3267
+ delayedFunctionScheduler.runNextQueuedFunction(function(millis) {
3268
+ mockDate.tick(millis);
3269
+ });
3270
+ }
3271
+ }
3272
+ }
3273
+
3274
+ // Waits until a new macro task.
3275
+ //
3276
+ // Used with autoTick(), which is meant to act when the test is waiting, we need
3277
+ // to insert ourselves in the macro task queue.
3278
+ //
3279
+ // @return {!Promise<undefined>}
3280
+ async function newMacrotask() {
3281
+ // MessageChannel ensures that setTimeout is not throttled to 4ms.
3282
+ // https://developer.mozilla.org/en-US/docs/Web/API/setTimeout#reasons_for_delays_longer_than_specified
3283
+ // https://stackblitz.com/edit/stackblitz-starters-qtlpcc
3284
+ // Note: This trick does not work in Safari, which will still throttle the setTimeout
3285
+ const channel = new MessageChannel();
3286
+ await new Promise(resolve => {
3287
+ channel.port1.onmessage = resolve;
3288
+ channel.port2.postMessage(undefined);
3289
+ });
3290
+ channel.port1.close();
3291
+ channel.port2.close();
3292
+ // setTimeout ensures that we interleave with other setTimeouts.
3293
+ await new Promise(resolve => {
3294
+ realTimingFunctions.setTimeout.call(global, resolve);
3295
+ });
3296
+ }
3297
+
3179
3298
  function originalTimingFunctionsIntact() {
3180
3299
  return (
3181
3300
  global.setTimeout === realTimingFunctions.setTimeout &&
@@ -3406,6 +3525,37 @@ getJasmineRequireObj().DelayedFunctionScheduler = function(j$) {
3406
3525
  }
3407
3526
  };
3408
3527
 
3528
+ // Returns whether there are any scheduled functions.
3529
+ // Returns true if there are any scheduled functions, otherwise false.
3530
+ this.isEmpty = function() {
3531
+ return this.scheduledFunctions_.length === 0;
3532
+ };
3533
+
3534
+ // Runs the next timeout in the queue, advancing the clock.
3535
+ this.runNextQueuedFunction = function(tickDate) {
3536
+ if (this.scheduledLookup_.length === 0) {
3537
+ return;
3538
+ }
3539
+
3540
+ const newCurrentTime = this.scheduledLookup_[0];
3541
+ if (newCurrentTime >= this.currentTime_) {
3542
+ tickDate(newCurrentTime - this.currentTime_);
3543
+ this.currentTime_ = newCurrentTime;
3544
+ }
3545
+
3546
+ const funcsAtTime = this.scheduledFunctions_[this.currentTime_];
3547
+ const fn = funcsAtTime.shift();
3548
+ if (funcsAtTime.length === 0) {
3549
+ delete this.scheduledFunctions_[this.currentTime_];
3550
+ this.scheduledLookup_.splice(0, 1);
3551
+ }
3552
+
3553
+ if (fn.recurring) {
3554
+ this.reschedule_(fn);
3555
+ }
3556
+ fn.funcToCall.apply(null, fn.params || []);
3557
+ };
3558
+
3409
3559
  return this;
3410
3560
  }
3411
3561
 
@@ -3542,6 +3692,7 @@ getJasmineRequireObj().Deprecator = function(j$) {
3542
3692
 
3543
3693
  Deprecator.prototype.log_ = function(runnable, deprecation, options) {
3544
3694
  if (j$.isError_(deprecation)) {
3695
+ // eslint-disable-next-line no-console
3545
3696
  console.error(deprecation);
3546
3697
  return;
3547
3698
  }
@@ -3564,6 +3715,7 @@ getJasmineRequireObj().Deprecator = function(j$) {
3564
3715
  context += '\n' + verboseNote;
3565
3716
  }
3566
3717
 
3718
+ // eslint-disable-next-line no-console
3567
3719
  console.error('DEPRECATION: ' + deprecation + context);
3568
3720
  };
3569
3721
 
@@ -5861,6 +6013,7 @@ getJasmineRequireObj().toBeInstanceOf = function(j$) {
5861
6013
  try {
5862
6014
  expectedMatcher = new j$.Any(expected);
5863
6015
  pass = expectedMatcher.asymmetricMatch(actual);
6016
+ // eslint-disable-next-line no-unused-vars
5864
6017
  } catch (error) {
5865
6018
  throw new Error(
5866
6019
  usageError('Expected value is not a constructor function')
@@ -7618,6 +7771,7 @@ getJasmineRequireObj().makePrettyPrinter = function(j$) {
7618
7771
  ) {
7619
7772
  try {
7620
7773
  this.emitScalar(value.toString());
7774
+ // eslint-disable-next-line no-unused-vars
7621
7775
  } catch (e) {
7622
7776
  this.emitScalar('has-invalid-toString-method');
7623
7777
  }
@@ -7864,6 +8018,7 @@ getJasmineRequireObj().makePrettyPrinter = function(j$) {
7864
8018
  value.toString !== Object.prototype.toString &&
7865
8019
  value.toString() !== Object.prototype.toString.call(value)
7866
8020
  );
8021
+ // eslint-disable-next-line no-unused-vars
7867
8022
  } catch (e) {
7868
8023
  // The custom toString() threw.
7869
8024
  return true;
@@ -7942,6 +8097,7 @@ getJasmineRequireObj().QueueRunner = function(j$) {
7942
8097
  }
7943
8098
 
7944
8099
  function fallbackOnMultipleDone() {
8100
+ // eslint-disable-next-line no-console
7945
8101
  console.error(
7946
8102
  new Error(
7947
8103
  "An asynchronous function called its 'done' " +
@@ -8055,6 +8211,7 @@ getJasmineRequireObj().QueueRunner = function(j$) {
8055
8211
  // Any error we catch here is probably due to a bug in Jasmine,
8056
8212
  // and it's not likely to end up anywhere useful if we let it
8057
8213
  // propagate. Log it so it can at least show up when debugging.
8214
+ // eslint-disable-next-line no-console
8058
8215
  console.error(error);
8059
8216
  }
8060
8217
  }
@@ -9894,6 +10051,7 @@ getJasmineRequireObj().SpyRegistry = function(j$) {
9894
10051
  let value;
9895
10052
  try {
9896
10053
  value = obj[prop];
10054
+ // eslint-disable-next-line no-unused-vars
9897
10055
  } catch (e) {
9898
10056
  return false;
9899
10057
  }
@@ -10326,6 +10484,9 @@ getJasmineRequireObj().Suite = function(j$) {
10326
10484
  * @property {String} fullName - The full description including all ancestors of this suite.
10327
10485
  * @property {String|null} parentSuiteId - The ID of the suite containing this suite, or null if this is not in another describe().
10328
10486
  * @property {String} filename - The name of the file the suite was defined in.
10487
+ * Note: The value may be incorrect if zone.js is installed or
10488
+ * `describe`/`fdescribe`/`xdescribe` have been replaced with versions that
10489
+ * don't maintain the same call stack height as the originals.
10329
10490
  * @property {ExpectationResult[]} failedExpectations - The list of expectations that failed in an {@link afterAll} for this suite.
10330
10491
  * @property {ExpectationResult[]} deprecationWarnings - The list of deprecation warnings that occurred on this suite.
10331
10492
  * @property {String} status - Once the suite has completed, this string represents the pass/fail status of this suite.
@@ -10808,9 +10969,7 @@ getJasmineRequireObj().SuiteBuilder = function(j$) {
10808
10969
  resultCallback: (result, next) => {
10809
10970
  this.specResultCallback_(spec, result, next);
10810
10971
  },
10811
- getSpecName: function(spec) {
10812
- return getSpecName(spec, suite);
10813
- },
10972
+ getPath: spec => this.getSpecPath_(spec, suite),
10814
10973
  onStart: (spec, next) => this.specStarted_(spec, suite, next),
10815
10974
  description: description,
10816
10975
  userContext: function() {
@@ -10827,6 +10986,17 @@ getJasmineRequireObj().SuiteBuilder = function(j$) {
10827
10986
  return spec;
10828
10987
  }
10829
10988
 
10989
+ getSpecPath_(spec, suite) {
10990
+ const path = [spec.description];
10991
+
10992
+ while (suite && suite !== this.topSuite) {
10993
+ path.unshift(suite.description);
10994
+ suite = suite.parentSuite;
10995
+ }
10996
+
10997
+ return path;
10998
+ }
10999
+
10830
11000
  unfocusAncestor_() {
10831
11001
  const focusedAncestor = findFocusedAncestor(
10832
11002
  this.currentDeclarationSuite_
@@ -10890,16 +11060,6 @@ getJasmineRequireObj().SuiteBuilder = function(j$) {
10890
11060
  };
10891
11061
  }
10892
11062
 
10893
- function getSpecName(spec, suite) {
10894
- const fullName = [spec.description],
10895
- suiteFullName = suite.getFullName();
10896
-
10897
- if (suiteFullName !== '') {
10898
- fullName.unshift(suiteFullName);
10899
- }
10900
- return fullName.join(' ');
10901
- }
10902
-
10903
11063
  return SuiteBuilder;
10904
11064
  };
10905
11065
 
@@ -11231,5 +11391,5 @@ getJasmineRequireObj().UserContext = function(j$) {
11231
11391
  };
11232
11392
 
11233
11393
  getJasmineRequireObj().version = function() {
11234
- return '5.6.0';
11394
+ return '5.7.0';
11235
11395
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "jasmine-core",
3
3
  "license": "MIT",
4
- "version": "5.6.0",
4
+ "version": "5.7.0",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "https://github.com/jasmine/jasmine.git"
@@ -15,9 +15,11 @@
15
15
  ],
16
16
  "scripts": {
17
17
  "posttest": "eslint \"src/**/*.js\" \"spec/**/*.js\" && prettier --check \"src/**/*.js\" \"spec/**/*.js\"",
18
- "test": "grunt --stack execSpecsInNode",
18
+ "test": "node scripts/runSpecsInNode.js",
19
+ "test:parallel": "node scripts/runSpecsInParallel.js",
19
20
  "cleanup": "prettier --write \"src/**/*.js\" \"spec/**/*.js\"",
20
- "build": "grunt buildDistribution",
21
+ "build": "node scripts/buildDistribution.js",
22
+ "buildStandaloneDist": "node scripts/buildStandaloneDist.js",
21
23
  "serve": "node spec/support/localJasmineBrowser.js",
22
24
  "serve:performance": "node spec/support/localJasmineBrowser.js jasmine-browser-performance.json",
23
25
  "ci": "node spec/support/ci.js",
@@ -34,23 +36,22 @@
34
36
  "package.json"
35
37
  ],
36
38
  "devDependencies": {
37
- "eslint": "^8.36.0",
38
- "eslint-plugin-compat": "^4.0.0",
39
+ "@eslint/eslintrc": "^3.3.1",
40
+ "@eslint/js": "^9.24.0",
41
+ "archiver": "^7.0.1",
42
+ "css-url-embed": "^0.1.0",
43
+ "ejs": "^3.1.10",
44
+ "eslint": "^9.24.0",
45
+ "eslint-plugin-compat": "^6.0.2",
39
46
  "glob": "^10.2.3",
40
- "grunt": "^1.0.4",
41
- "grunt-cli": "^1.3.2",
42
- "grunt-contrib-compress": "^2.0.0",
43
- "grunt-contrib-concat": "^2.0.0",
44
- "grunt-css-url-embed": "^1.11.1",
45
- "grunt-sass": "^3.0.2",
47
+ "globals": "^16.0.0",
46
48
  "jasmine": "^5.0.0",
47
49
  "jasmine-browser-runner": "github:jasmine/jasmine-browser-runner",
48
- "jsdom": "^22.0.0",
49
- "load-grunt-tasks": "^5.1.0",
50
+ "jsdom": "^26.0.0",
50
51
  "prettier": "1.17.1",
52
+ "rimraf": "^5.0.10",
51
53
  "sass": "^1.58.3",
52
- "shelljs": "^0.8.3",
53
- "temp": "^0.9.0"
54
+ "shelljs": "^0.9.2"
54
55
  },
55
56
  "browserslist": [
56
57
  "Safari >= 15",