jasmine-core 3.7.0 → 3.10.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.
@@ -96,6 +96,7 @@ var getJasmineRequireObj = (function(jasmineGlobal) {
96
96
  j$.SpyRegistry = jRequire.SpyRegistry(j$);
97
97
  j$.SpyStrategy = jRequire.SpyStrategy(j$);
98
98
  j$.StringMatching = jRequire.StringMatching(j$);
99
+ j$.StringContaining = jRequire.StringContaining(j$);
99
100
  j$.UserContext = jRequire.UserContext(j$);
100
101
  j$.Suite = jRequire.Suite(j$);
101
102
  j$.Timer = jRequire.Timer();
@@ -175,6 +176,7 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
175
176
  * Maximum object depth the pretty printer will print to.
176
177
  * Set this to a lower value to speed up pretty printing if you have large objects.
177
178
  * @name jasmine.MAX_PRETTY_PRINT_DEPTH
179
+ * @default 8
178
180
  * @since 1.3.0
179
181
  */
180
182
  j$.MAX_PRETTY_PRINT_DEPTH = 8;
@@ -183,6 +185,7 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
183
185
  * This will also limit the number of keys and values displayed for an object.
184
186
  * Elements past this number will be ellipised.
185
187
  * @name jasmine.MAX_PRETTY_PRINT_ARRAY_LENGTH
188
+ * @default 50
186
189
  * @since 2.7.0
187
190
  */
188
191
  j$.MAX_PRETTY_PRINT_ARRAY_LENGTH = 50;
@@ -190,15 +193,35 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
190
193
  * Maximum number of characters to display when pretty printing objects.
191
194
  * Characters past this number will be ellipised.
192
195
  * @name jasmine.MAX_PRETTY_PRINT_CHARS
196
+ * @default 100
193
197
  * @since 2.9.0
194
198
  */
195
199
  j$.MAX_PRETTY_PRINT_CHARS = 1000;
196
200
  /**
197
- * Default number of milliseconds Jasmine will wait for an asynchronous spec to complete.
201
+ * Default number of milliseconds Jasmine will wait for an asynchronous spec,
202
+ * before, or after function to complete. This can be overridden on a case by
203
+ * case basis by passing a time limit as the third argument to {@link it},
204
+ * {@link beforeEach}, {@link afterEach}, {@link beforeAll}, or
205
+ * {@link afterAll}. The value must be no greater than the largest number of
206
+ * milliseconds supported by setTimeout, which is usually 2147483647.
207
+ *
208
+ * While debugging tests, you may want to set this to a large number (or pass
209
+ * a large number to one of the functions mentioned above) so that Jasmine
210
+ * does not move on to after functions or the next spec while you're debugging.
198
211
  * @name jasmine.DEFAULT_TIMEOUT_INTERVAL
212
+ * @default 5000
199
213
  * @since 1.3.0
200
214
  */
201
- j$.DEFAULT_TIMEOUT_INTERVAL = 5000;
215
+ var DEFAULT_TIMEOUT_INTERVAL = 5000;
216
+ Object.defineProperty(j$, 'DEFAULT_TIMEOUT_INTERVAL', {
217
+ get: function() {
218
+ return DEFAULT_TIMEOUT_INTERVAL;
219
+ },
220
+ set: function(newValue) {
221
+ j$.util.validateTimeout(newValue, 'jasmine.DEFAULT_TIMEOUT_INTERVAL');
222
+ DEFAULT_TIMEOUT_INTERVAL = newValue;
223
+ }
224
+ });
202
225
 
203
226
  j$.getGlobal = function() {
204
227
  return jasmineGlobal;
@@ -267,9 +290,21 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
267
290
  };
268
291
 
269
292
  j$.isError_ = function(value) {
293
+ if (!value) {
294
+ return false;
295
+ }
296
+
270
297
  if (value instanceof Error) {
271
298
  return true;
272
299
  }
300
+ if (
301
+ typeof window !== 'undefined' &&
302
+ typeof window.trustedTypes !== 'undefined'
303
+ ) {
304
+ return (
305
+ typeof value.stack === 'string' && typeof value.message === 'string'
306
+ );
307
+ }
273
308
  if (value && value.constructor && value.constructor.constructor) {
274
309
  var valueGlobal = value.constructor.constructor('return this');
275
310
  if (j$.isFunction_(valueGlobal)) {
@@ -371,8 +406,21 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
371
406
  return matches ? matches[1] : '<anonymous>';
372
407
  };
373
408
 
409
+ j$.isPending_ = function(promise) {
410
+ var sentinel = {};
411
+ // eslint-disable-next-line compat/compat
412
+ return Promise.race([promise, Promise.resolve(sentinel)]).then(
413
+ function(result) {
414
+ return result === sentinel;
415
+ },
416
+ function() {
417
+ return false;
418
+ }
419
+ );
420
+ };
421
+
374
422
  /**
375
- * Get a matcher, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),
423
+ * Get an {@link AsymmetricEqualityTester}, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),
376
424
  * that will succeed if the actual value being compared is an instance of the specified class/constructor.
377
425
  * @name jasmine.any
378
426
  * @since 1.3.0
@@ -384,7 +432,7 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
384
432
  };
385
433
 
386
434
  /**
387
- * Get a matcher, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),
435
+ * Get an {@link AsymmetricEqualityTester}, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),
388
436
  * that will succeed if the actual value being compared is not `null` and not `undefined`.
389
437
  * @name jasmine.anything
390
438
  * @since 2.2.0
@@ -395,7 +443,7 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
395
443
  };
396
444
 
397
445
  /**
398
- * Get a matcher, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),
446
+ * Get an {@link AsymmetricEqualityTester}, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),
399
447
  * that will succeed if the actual value being compared is `true` or anything truthy.
400
448
  * @name jasmine.truthy
401
449
  * @since 3.1.0
@@ -406,7 +454,7 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
406
454
  };
407
455
 
408
456
  /**
409
- * Get a matcher, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),
457
+ * Get an {@link AsymmetricEqualityTester}, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),
410
458
  * that will succeed if the actual value being compared is `null`, `undefined`, `0`, `false` or anything falsey.
411
459
  * @name jasmine.falsy
412
460
  * @since 3.1.0
@@ -417,7 +465,7 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
417
465
  };
418
466
 
419
467
  /**
420
- * Get a matcher, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),
468
+ * Get an {@link AsymmetricEqualityTester}, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),
421
469
  * that will succeed if the actual value being compared is empty.
422
470
  * @name jasmine.empty
423
471
  * @since 3.1.0
@@ -428,7 +476,7 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
428
476
  };
429
477
 
430
478
  /**
431
- * Get a matcher, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),
479
+ * Get an {@link AsymmetricEqualityTester}, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),
432
480
  * that will succeed if the actual value being compared is not empty.
433
481
  * @name jasmine.notEmpty
434
482
  * @since 3.1.0
@@ -439,7 +487,7 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
439
487
  };
440
488
 
441
489
  /**
442
- * Get a matcher, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),
490
+ * Get an {@link AsymmetricEqualityTester}, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),
443
491
  * that will succeed if the actual value being compared contains at least the keys and values.
444
492
  * @name jasmine.objectContaining
445
493
  * @since 1.3.0
@@ -451,7 +499,7 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
451
499
  };
452
500
 
453
501
  /**
454
- * Get a matcher, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),
502
+ * Get an {@link AsymmetricEqualityTester}, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),
455
503
  * that will succeed if the actual value is a `String` that matches the `RegExp` or `String`.
456
504
  * @name jasmine.stringMatching
457
505
  * @since 2.2.0
@@ -463,7 +511,19 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
463
511
  };
464
512
 
465
513
  /**
466
- * Get a matcher, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),
514
+ * Get an {@link AsymmetricEqualityTester}, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),
515
+ * that will succeed if the actual value is a `String` that contains the specified `String`.
516
+ * @name jasmine.stringContaining
517
+ * @since 3.10.0
518
+ * @function
519
+ * @param {String} expected
520
+ */
521
+ j$.stringContaining = function(expected) {
522
+ return new j$.StringContaining(expected);
523
+ };
524
+
525
+ /**
526
+ * Get an {@link AsymmetricEqualityTester}, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),
467
527
  * that will succeed if the actual value is an `Array` that contains at least the elements in the sample.
468
528
  * @name jasmine.arrayContaining
469
529
  * @since 2.2.0
@@ -475,7 +535,7 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
475
535
  };
476
536
 
477
537
  /**
478
- * Get a matcher, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),
538
+ * Get an {@link AsymmetricEqualityTester}, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),
479
539
  * that will succeed if the actual value is an `Array` that contains all of the elements in the sample in any order.
480
540
  * @name jasmine.arrayWithExactContents
481
541
  * @since 2.8.0
@@ -487,7 +547,7 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
487
547
  };
488
548
 
489
549
  /**
490
- * Get a matcher, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),
550
+ * Get an {@link AsymmetricEqualityTester}, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),
491
551
  * that will succeed if every key/value pair in the sample passes the deep equality comparison
492
552
  * with at least one key/value pair in the actual value being compared
493
553
  * @name jasmine.mapContaining
@@ -500,7 +560,7 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
500
560
  };
501
561
 
502
562
  /**
503
- * Get a matcher, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),
563
+ * Get an {@link AsymmetricEqualityTester}, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),
504
564
  * that will succeed if every item in the sample passes the deep equality comparison
505
565
  * with at least one item in the actual value being compared
506
566
  * @name jasmine.setContaining
@@ -675,15 +735,49 @@ getJasmineRequireObj().util = function(j$) {
675
735
  }
676
736
  };
677
737
 
738
+ util.validateTimeout = function(timeout, msgPrefix) {
739
+ // Timeouts are implemented with setTimeout, which only supports a limited
740
+ // range of values. The limit is unspecified, as is the behavior when it's
741
+ // exceeded. But on all currently supported JS runtimes, setTimeout calls
742
+ // the callback immediately when the timeout is greater than 2147483647
743
+ // (the maximum value of a signed 32 bit integer).
744
+ var max = 2147483647;
745
+
746
+ if (timeout > max) {
747
+ throw new Error(
748
+ (msgPrefix || 'Timeout value') + ' cannot be greater than ' + max
749
+ );
750
+ }
751
+ };
752
+
678
753
  return util;
679
754
  };
680
755
 
681
756
  getJasmineRequireObj().Spec = function(j$) {
757
+ /**
758
+ * @interface Spec
759
+ * @see Configuration#specFilter
760
+ * @since 2.0.0
761
+ */
682
762
  function Spec(attrs) {
683
763
  this.expectationFactory = attrs.expectationFactory;
684
764
  this.asyncExpectationFactory = attrs.asyncExpectationFactory;
685
765
  this.resultCallback = attrs.resultCallback || function() {};
766
+ /**
767
+ * The unique ID of this spec.
768
+ * @name Spec#id
769
+ * @readonly
770
+ * @type {string}
771
+ * @since 2.0.0
772
+ */
686
773
  this.id = attrs.id;
774
+ /**
775
+ * The description passed to the {@link it} that created this spec.
776
+ * @name Spec#description
777
+ * @readonly
778
+ * @type {string}
779
+ * @since 2.0.0
780
+ */
687
781
  this.description = attrs.description || '';
688
782
  this.queueableFn = attrs.queueableFn;
689
783
  this.beforeAndAfterFns =
@@ -697,6 +791,8 @@ getJasmineRequireObj().Spec = function(j$) {
697
791
  return {};
698
792
  };
699
793
  this.onStart = attrs.onStart || function() {};
794
+ this.autoCleanClosures =
795
+ attrs.autoCleanClosures === undefined ? true : !!attrs.autoCleanClosures;
700
796
  this.getSpecName =
701
797
  attrs.getSpecName ||
702
798
  function() {
@@ -714,7 +810,7 @@ getJasmineRequireObj().Spec = function(j$) {
714
810
  this.timer = attrs.timer || new j$.Timer();
715
811
 
716
812
  if (!this.queueableFn.fn) {
717
- this.pend();
813
+ this.exclude();
718
814
  }
719
815
 
720
816
  /**
@@ -729,7 +825,8 @@ getJasmineRequireObj().Spec = function(j$) {
729
825
  * @property {String} status - Once the spec has completed, this string represents the pass/fail status of this spec.
730
826
  * @property {number} duration - The time in ms used by the spec execution, including any before/afterEach.
731
827
  * @property {Object} properties - User-supplied properties, if any, that were set using {@link Env#setSpecProperty}
732
- */
828
+ * @since 2.0.0
829
+ x */
733
830
  this.result = {
734
831
  id: this.id,
735
832
  description: this.description,
@@ -781,7 +878,9 @@ getJasmineRequireObj().Spec = function(j$) {
781
878
 
782
879
  var complete = {
783
880
  fn: function(done) {
784
- self.queueableFn.fn = null;
881
+ if (self.autoCleanClosures) {
882
+ self.queueableFn.fn = null;
883
+ }
785
884
  self.result.status = self.status(excluded, failSpecWithNoExp);
786
885
  self.result.duration = self.timer.elapsed();
787
886
  self.resultCallback(self.result, done);
@@ -818,6 +917,36 @@ getJasmineRequireObj().Spec = function(j$) {
818
917
  this.queueRunnerFactory(runnerConfig);
819
918
  };
820
919
 
920
+ Spec.prototype.reset = function() {
921
+ /**
922
+ * @typedef SpecResult
923
+ * @property {Int} id - The unique id of this spec.
924
+ * @property {String} description - The description passed to the {@link it} that created this spec.
925
+ * @property {String} fullName - The full description including all ancestors of this spec.
926
+ * @property {Expectation[]} failedExpectations - The list of expectations that failed during execution of this spec.
927
+ * @property {Expectation[]} passedExpectations - The list of expectations that passed during execution of this spec.
928
+ * @property {Expectation[]} deprecationWarnings - The list of deprecation warnings that occurred during execution this spec.
929
+ * @property {String} pendingReason - If the spec is {@link pending}, this will be the reason.
930
+ * @property {String} status - Once the spec has completed, this string represents the pass/fail status of this spec.
931
+ * @property {number} duration - The time in ms used by the spec execution, including any before/afterEach.
932
+ * @property {Object} properties - User-supplied properties, if any, that were set using {@link Env#setSpecProperty}
933
+ * @since 2.0.0
934
+ */
935
+ this.result = {
936
+ id: this.id,
937
+ description: this.description,
938
+ fullName: this.getFullName(),
939
+ failedExpectations: [],
940
+ passedExpectations: [],
941
+ deprecationWarnings: [],
942
+ pendingReason: this.excludeMessage,
943
+ duration: null,
944
+ properties: null,
945
+ trace: null
946
+ };
947
+ this.markedPending = this.markedExcluding;
948
+ };
949
+
821
950
  Spec.prototype.onException = function onException(e) {
822
951
  if (Spec.isPendingSpecException(e)) {
823
952
  this.pend(extractCustomPendingMessage(e));
@@ -841,6 +970,10 @@ getJasmineRequireObj().Spec = function(j$) {
841
970
  );
842
971
  };
843
972
 
973
+ /*
974
+ * Marks state as pending
975
+ * @param {string} [message] An optional reason message
976
+ */
844
977
  Spec.prototype.pend = function(message) {
845
978
  this.markedPending = true;
846
979
  if (message) {
@@ -848,6 +981,19 @@ getJasmineRequireObj().Spec = function(j$) {
848
981
  }
849
982
  };
850
983
 
984
+ /*
985
+ * Like {@link Spec#pend}, but pending state will survive {@link Spec#reset}
986
+ * Useful for fit, xit, where pending state remains.
987
+ * @param {string} [message] An optional reason message
988
+ */
989
+ Spec.prototype.exclude = function(message) {
990
+ this.markedExcluding = true;
991
+ if (this.message) {
992
+ this.excludeMessage = message;
993
+ }
994
+ this.pend();
995
+ };
996
+
851
997
  Spec.prototype.getResult = function() {
852
998
  this.result.status = this.status();
853
999
  return this.result;
@@ -875,6 +1021,13 @@ getJasmineRequireObj().Spec = function(j$) {
875
1021
  return 'passed';
876
1022
  };
877
1023
 
1024
+ /**
1025
+ * The full description including all ancestors of this spec.
1026
+ * @name Spec#getFullName
1027
+ * @function
1028
+ * @returns {string}
1029
+ * @since 2.0.0
1030
+ */
878
1031
  Spec.prototype.getFullName = function() {
879
1032
  return this.getSpecName(this);
880
1033
  };
@@ -963,11 +1116,12 @@ getJasmineRequireObj().Order = function() {
963
1116
 
964
1117
  getJasmineRequireObj().Env = function(j$) {
965
1118
  /**
966
- * _Note:_ Do not construct this directly, Jasmine will make one during booting.
967
- * @name Env
1119
+ * @class Env
968
1120
  * @since 2.0.0
969
- * @classdesc The Jasmine environment
970
- * @constructor
1121
+ * @classdesc The Jasmine environment.<br>
1122
+ * _Note:_ Do not construct this directly. You can obtain the Env instance by
1123
+ * calling {@link jasmine.getEnv}.
1124
+ * @hideconstructor
971
1125
  */
972
1126
  function Env(options) {
973
1127
  options = options || {};
@@ -998,7 +1152,8 @@ getJasmineRequireObj().Env = function(j$) {
998
1152
 
999
1153
  /**
1000
1154
  * This represents the available options to configure Jasmine.
1001
- * Options that are not provided will use their default values
1155
+ * Options that are not provided will use their default values.
1156
+ * @see Env#configure
1002
1157
  * @interface Configuration
1003
1158
  * @since 3.3.0
1004
1159
  */
@@ -1016,7 +1171,7 @@ getJasmineRequireObj().Env = function(j$) {
1016
1171
  * Null causes the seed to be determined randomly at the start of execution.
1017
1172
  * @name Configuration#seed
1018
1173
  * @since 3.3.0
1019
- * @type function
1174
+ * @type (number|string)
1020
1175
  * @default null
1021
1176
  */
1022
1177
  seed: null,
@@ -1026,8 +1181,17 @@ getJasmineRequireObj().Env = function(j$) {
1026
1181
  * @since 3.3.0
1027
1182
  * @type Boolean
1028
1183
  * @default false
1184
+ * @deprecated Use the `stopOnSpecFailure` config property instead.
1029
1185
  */
1030
1186
  failFast: false,
1187
+ /**
1188
+ * Whether to stop execution of the suite after the first spec failure
1189
+ * @name Configuration#stopOnSpecFailure
1190
+ * @since 3.9.0
1191
+ * @type Boolean
1192
+ * @default false
1193
+ */
1194
+ stopOnSpecFailure: false,
1031
1195
  /**
1032
1196
  * Whether to fail the spec if it ran no expectations. By default
1033
1197
  * a spec that ran no expectations is reported as passed. Setting this
@@ -1044,14 +1208,30 @@ getJasmineRequireObj().Env = function(j$) {
1044
1208
  * @since 3.3.0
1045
1209
  * @type Boolean
1046
1210
  * @default false
1211
+ * @deprecated Use the `stopSpecOnExpectationFailure` config property instead.
1047
1212
  */
1048
1213
  oneFailurePerSpec: false,
1214
+ /**
1215
+ * Whether to cause specs to only have one expectation failure.
1216
+ * @name Configuration#stopSpecOnExpectationFailure
1217
+ * @since 3.3.0
1218
+ * @type Boolean
1219
+ * @default false
1220
+ */
1221
+ stopSpecOnExpectationFailure: false,
1222
+ /**
1223
+ * A function that takes a spec and returns true if it should be executed
1224
+ * or false if it should be skipped.
1225
+ * @callback SpecFilter
1226
+ * @param {Spec} spec - The spec that the filter is being applied to.
1227
+ * @return boolean
1228
+ */
1049
1229
  /**
1050
1230
  * Function to use to filter specs
1051
1231
  * @name Configuration#specFilter
1052
1232
  * @since 3.3.0
1053
- * @type function
1054
- * @default true
1233
+ * @type SpecFilter
1234
+ * @default A function that always returns true.
1055
1235
  */
1056
1236
  specFilter: function() {
1057
1237
  return true;
@@ -1074,7 +1254,16 @@ getJasmineRequireObj().Env = function(j$) {
1074
1254
  * @type function
1075
1255
  * @default undefined
1076
1256
  */
1077
- Promise: undefined
1257
+ Promise: undefined,
1258
+ /**
1259
+ * Clean closures when a suite is done running (done by clearing the stored function reference).
1260
+ * This prevents memory leaks, but you won't be able to run jasmine multiple times.
1261
+ * @name Configuration#autoCleanClosures
1262
+ * @since 3.10.0
1263
+ * @type boolean
1264
+ * @default true
1265
+ */
1266
+ autoCleanClosures: true
1078
1267
  };
1079
1268
 
1080
1269
  var currentSuite = function() {
@@ -1124,33 +1313,65 @@ getJasmineRequireObj().Env = function(j$) {
1124
1313
  * @function
1125
1314
  */
1126
1315
  this.configure = function(configuration) {
1127
- if (configuration.specFilter) {
1128
- config.specFilter = configuration.specFilter;
1129
- }
1130
-
1131
- if (configuration.hasOwnProperty('random')) {
1132
- config.random = !!configuration.random;
1133
- }
1316
+ var booleanProps = [
1317
+ 'random',
1318
+ 'failSpecWithNoExpectations',
1319
+ 'hideDisabled',
1320
+ 'autoCleanClosures'
1321
+ ];
1322
+
1323
+ booleanProps.forEach(function(prop) {
1324
+ if (typeof configuration[prop] !== 'undefined') {
1325
+ config[prop] = !!configuration[prop];
1326
+ }
1327
+ });
1134
1328
 
1135
- if (configuration.hasOwnProperty('seed')) {
1136
- config.seed = configuration.seed;
1137
- }
1329
+ if (typeof configuration.failFast !== 'undefined') {
1330
+ if (typeof configuration.stopOnSpecFailure !== 'undefined') {
1331
+ if (configuration.stopOnSpecFailure !== configuration.failFast) {
1332
+ throw new Error(
1333
+ 'stopOnSpecFailure and failFast are aliases for ' +
1334
+ "each other. Don't set failFast if you also set stopOnSpecFailure."
1335
+ );
1336
+ }
1337
+ }
1138
1338
 
1139
- if (configuration.hasOwnProperty('failFast')) {
1140
1339
  config.failFast = configuration.failFast;
1340
+ config.stopOnSpecFailure = configuration.failFast;
1341
+ } else if (typeof configuration.stopOnSpecFailure !== 'undefined') {
1342
+ config.failFast = configuration.stopOnSpecFailure;
1343
+ config.stopOnSpecFailure = configuration.stopOnSpecFailure;
1141
1344
  }
1142
1345
 
1143
- if (configuration.hasOwnProperty('failSpecWithNoExpectations')) {
1144
- config.failSpecWithNoExpectations =
1145
- configuration.failSpecWithNoExpectations;
1146
- }
1346
+ if (typeof configuration.oneFailurePerSpec !== 'undefined') {
1347
+ if (typeof configuration.stopSpecOnExpectationFailure !== 'undefined') {
1348
+ if (
1349
+ configuration.stopSpecOnExpectationFailure !==
1350
+ configuration.oneFailurePerSpec
1351
+ ) {
1352
+ throw new Error(
1353
+ 'stopSpecOnExpectationFailure and oneFailurePerSpec are aliases for ' +
1354
+ "each other. Don't set oneFailurePerSpec if you also set stopSpecOnExpectationFailure."
1355
+ );
1356
+ }
1357
+ }
1147
1358
 
1148
- if (configuration.hasOwnProperty('oneFailurePerSpec')) {
1149
1359
  config.oneFailurePerSpec = configuration.oneFailurePerSpec;
1360
+ config.stopSpecOnExpectationFailure = configuration.oneFailurePerSpec;
1361
+ } else if (
1362
+ typeof configuration.stopSpecOnExpectationFailure !== 'undefined'
1363
+ ) {
1364
+ config.oneFailurePerSpec = configuration.stopSpecOnExpectationFailure;
1365
+ config.stopSpecOnExpectationFailure =
1366
+ configuration.stopSpecOnExpectationFailure;
1150
1367
  }
1151
1368
 
1152
- if (configuration.hasOwnProperty('hideDisabled')) {
1153
- config.hideDisabled = configuration.hideDisabled;
1369
+ if (configuration.specFilter) {
1370
+ config.specFilter = configuration.specFilter;
1371
+ }
1372
+
1373
+ if (typeof configuration.seed !== 'undefined') {
1374
+ config.seed = configuration.seed;
1154
1375
  }
1155
1376
 
1156
1377
  // Don't use hasOwnProperty to check for Promise existence because Promise
@@ -1337,7 +1558,9 @@ getJasmineRequireObj().Env = function(j$) {
1337
1558
  }
1338
1559
 
1339
1560
  delayedExpectationResult.message +=
1340
- 'Did you forget to return or await the result of expectAsync?';
1561
+ '1. Did you forget to return or await the result of expectAsync?\n' +
1562
+ '2. Was done() invoked before an async operation completed?\n' +
1563
+ '3. Did an expectation follow a call to done()?';
1341
1564
 
1342
1565
  topSuite.result.failedExpectations.push(delayedExpectationResult);
1343
1566
  }
@@ -1402,10 +1625,11 @@ getJasmineRequireObj().Env = function(j$) {
1402
1625
  delete runnableResources[id];
1403
1626
  };
1404
1627
 
1405
- var beforeAndAfterFns = function(suite) {
1628
+ var beforeAndAfterFns = function(targetSuite) {
1406
1629
  return function() {
1407
1630
  var befores = [],
1408
- afters = [];
1631
+ afters = [],
1632
+ suite = targetSuite;
1409
1633
 
1410
1634
  while (suite) {
1411
1635
  befores = befores.concat(suite.beforeFns);
@@ -1448,18 +1672,22 @@ getJasmineRequireObj().Env = function(j$) {
1448
1672
  * @since 2.3.0
1449
1673
  * @function
1450
1674
  * @param {Boolean} value Whether to throw when a expectation fails
1451
- * @deprecated Use the `oneFailurePerSpec` option with {@link Env#configure}
1675
+ * @deprecated Use the `stopSpecOnExpectationFailure` option with {@link Env#configure}
1452
1676
  */
1453
1677
  this.throwOnExpectationFailure = function(value) {
1454
1678
  this.deprecated(
1455
- 'Setting throwOnExpectationFailure directly on Env is deprecated and will be removed in a future version of Jasmine, please use the oneFailurePerSpec option in `configure`'
1679
+ 'Setting throwOnExpectationFailure directly on Env is deprecated and ' +
1680
+ 'will be removed in a future version of Jasmine. Please use the ' +
1681
+ 'stopSpecOnExpectationFailure option in `configure`.'
1456
1682
  );
1457
1683
  this.configure({ oneFailurePerSpec: !!value });
1458
1684
  };
1459
1685
 
1460
1686
  this.throwingExpectationFailures = function() {
1461
1687
  this.deprecated(
1462
- 'Getting throwingExpectationFailures directly from Env is deprecated and will be removed in a future version of Jasmine, please check the oneFailurePerSpec option from `configuration`'
1688
+ 'Getting throwingExpectationFailures directly from Env is deprecated ' +
1689
+ 'and will be removed in a future version of Jasmine. Please check ' +
1690
+ 'the stopSpecOnExpectationFailure option from `configuration`.'
1463
1691
  );
1464
1692
  return config.oneFailurePerSpec;
1465
1693
  };
@@ -1470,18 +1698,22 @@ getJasmineRequireObj().Env = function(j$) {
1470
1698
  * @since 2.7.0
1471
1699
  * @function
1472
1700
  * @param {Boolean} value Whether to stop suite execution when a spec fails
1473
- * @deprecated Use the `failFast` option with {@link Env#configure}
1701
+ * @deprecated Use the `stopOnSpecFailure` option with {@link Env#configure}
1474
1702
  */
1475
1703
  this.stopOnSpecFailure = function(value) {
1476
1704
  this.deprecated(
1477
- 'Setting stopOnSpecFailure directly is deprecated and will be removed in a future version of Jasmine, please use the failFast option in `configure`'
1705
+ 'Setting stopOnSpecFailure directly is deprecated and will be ' +
1706
+ 'removed in a future version of Jasmine. Please use the ' +
1707
+ 'stopOnSpecFailure option in `configure`.'
1478
1708
  );
1479
- this.configure({ failFast: !!value });
1709
+ this.configure({ stopOnSpecFailure: !!value });
1480
1710
  };
1481
1711
 
1482
1712
  this.stoppingOnSpecFailure = function() {
1483
1713
  this.deprecated(
1484
- 'Getting stoppingOnSpecFailure directly from Env is deprecated and will be removed in a future version of Jasmine, please check the failFast option from `configuration`'
1714
+ 'Getting stoppingOnSpecFailure directly from Env is deprecated and ' +
1715
+ 'will be removed in a future version of Jasmine. Please check the ' +
1716
+ 'stopOnSpecFailure option from `configuration`.'
1485
1717
  );
1486
1718
  return config.failFast;
1487
1719
  };
@@ -1537,6 +1769,7 @@ getJasmineRequireObj().Env = function(j$) {
1537
1769
  * @name Env#hideDisabled
1538
1770
  * @since 3.2.0
1539
1771
  * @function
1772
+ * @deprecated Use the `hideDisabled` option with {@link Env#configure}
1540
1773
  */
1541
1774
  this.hideDisabled = function(value) {
1542
1775
  this.deprecated(
@@ -1569,9 +1802,9 @@ getJasmineRequireObj().Env = function(j$) {
1569
1802
  var queueRunnerFactory = function(options, args) {
1570
1803
  var failFast = false;
1571
1804
  if (options.isLeaf) {
1572
- failFast = config.oneFailurePerSpec;
1805
+ failFast = config.stopSpecOnExpectationFailure;
1573
1806
  } else if (!options.isReporter) {
1574
- failFast = config.failFast;
1807
+ failFast = config.stopOnSpecFailure;
1575
1808
  }
1576
1809
  options.clearStack = options.clearStack || clearStack;
1577
1810
  options.timeout = {
@@ -1597,11 +1830,19 @@ getJasmineRequireObj().Env = function(j$) {
1597
1830
  description: 'Jasmine__TopLevel__Suite',
1598
1831
  expectationFactory: expectationFactory,
1599
1832
  asyncExpectationFactory: suiteAsyncExpectationFactory,
1600
- expectationResultFactory: expectationResultFactory
1833
+ expectationResultFactory: expectationResultFactory,
1834
+ autoCleanClosures: config.autoCleanClosures
1601
1835
  });
1602
- defaultResourcesForRunnable(topSuite.id);
1603
1836
  currentDeclarationSuite = topSuite;
1604
1837
 
1838
+ /**
1839
+ * Provides the root suite, through which all suites and specs can be
1840
+ * accessed.
1841
+ * @function
1842
+ * @name Env#topSuite
1843
+ * @return {Suite} the root suite
1844
+ * @since 2.0.0
1845
+ */
1605
1846
  this.topSuite = function() {
1606
1847
  return topSuite;
1607
1848
  };
@@ -1681,8 +1922,39 @@ getJasmineRequireObj().Env = function(j$) {
1681
1922
  queueRunnerFactory
1682
1923
  );
1683
1924
 
1684
- // Both params are optional.
1925
+ /**
1926
+ * Executes the specs.
1927
+ *
1928
+ * If called with no parameters or with a falsy value as the first parameter,
1929
+ * all specs will be executed except those that are excluded by a
1930
+ * [spec filter]{@link Configuration#specFilter} or other mechanism. If the
1931
+ * first parameter is a list of spec/suite IDs, only those specs/suites will
1932
+ * be run.
1933
+ *
1934
+ * Both parameters are optional, but a completion callback is only valid as
1935
+ * the second parameter. To specify a completion callback but not a list of
1936
+ * specs/suites to run, pass null or undefined as the first parameter.
1937
+ *
1938
+ * execute should not be called more than once.
1939
+ *
1940
+ * If the environment supports promises, execute will return a promise that
1941
+ * is resolved after the suite finishes executing. The promise will be
1942
+ * resolved (not rejected) as long as the suite runs to completion. Use a
1943
+ * {@link Reporter} to determine whether or not the suite passed.
1944
+ *
1945
+ * @name Env#execute
1946
+ * @since 2.0.0
1947
+ * @function
1948
+ * @param {(string[])=} runnablesToRun IDs of suites and/or specs to run
1949
+ * @param {Function=} onComplete Function that will be called after all specs have run
1950
+ * @return {Promise<undefined>}
1951
+ */
1685
1952
  this.execute = function(runnablesToRun, onComplete) {
1953
+ if (this._executedBefore) {
1954
+ topSuite.reset();
1955
+ }
1956
+ this._executedBefore = true;
1957
+ defaultResourcesForRunnable(topSuite.id);
1686
1958
  installGlobalErrors();
1687
1959
 
1688
1960
  if (!runnablesToRun) {
@@ -1740,65 +2012,88 @@ getJasmineRequireObj().Env = function(j$) {
1740
2012
  var jasmineTimer = new j$.Timer();
1741
2013
  jasmineTimer.start();
1742
2014
 
1743
- /**
1744
- * Information passed to the {@link Reporter#jasmineStarted} event.
1745
- * @typedef JasmineStartedInfo
1746
- * @property {Int} totalSpecsDefined - The total number of specs defined in this suite.
1747
- * @property {Order} order - Information about the ordering (random or not) of this execution of the suite.
1748
- */
1749
- reporter.jasmineStarted(
1750
- {
1751
- totalSpecsDefined: totalSpecsDefined,
1752
- order: order
1753
- },
1754
- function() {
1755
- currentlyExecutingSuites.push(topSuite);
1756
-
1757
- processor.execute(function() {
1758
- clearResourcesForRunnable(topSuite.id);
1759
- currentlyExecutingSuites.pop();
1760
- var overallStatus, incompleteReason;
1761
-
1762
- if (hasFailures || topSuite.result.failedExpectations.length > 0) {
1763
- overallStatus = 'failed';
1764
- } else if (focusedRunnables.length > 0) {
1765
- overallStatus = 'incomplete';
1766
- incompleteReason = 'fit() or fdescribe() was found';
1767
- } else if (totalSpecsDefined === 0) {
1768
- overallStatus = 'incomplete';
1769
- incompleteReason = 'No specs found';
1770
- } else {
1771
- overallStatus = 'passed';
2015
+ var Promise = customPromise || global.Promise;
2016
+
2017
+ if (Promise) {
2018
+ return new Promise(function(resolve) {
2019
+ runAll(function() {
2020
+ if (onComplete) {
2021
+ onComplete();
1772
2022
  }
1773
2023
 
1774
- /**
1775
- * Information passed to the {@link Reporter#jasmineDone} event.
1776
- * @typedef JasmineDoneInfo
1777
- * @property {OverallStatus} overallStatus - The overall result of the suite: 'passed', 'failed', or 'incomplete'.
1778
- * @property {Int} totalTime - The total time (in ms) that it took to execute the suite
1779
- * @property {IncompleteReason} incompleteReason - Explanation of why the suite was incomplete.
1780
- * @property {Order} order - Information about the ordering (random or not) of this execution of the suite.
1781
- * @property {Expectation[]} failedExpectations - List of expectations that failed in an {@link afterAll} at the global level.
1782
- * @property {Expectation[]} deprecationWarnings - List of deprecation warnings that occurred at the global level.
1783
- */
1784
- reporter.jasmineDone(
1785
- {
1786
- overallStatus: overallStatus,
1787
- totalTime: jasmineTimer.elapsed(),
1788
- incompleteReason: incompleteReason,
1789
- order: order,
1790
- failedExpectations: topSuite.result.failedExpectations,
1791
- deprecationWarnings: topSuite.result.deprecationWarnings
1792
- },
1793
- function() {
1794
- if (onComplete) {
1795
- onComplete();
1796
- }
1797
- }
1798
- );
2024
+ resolve();
1799
2025
  });
1800
- }
1801
- );
2026
+ });
2027
+ } else {
2028
+ runAll(function() {
2029
+ if (onComplete) {
2030
+ onComplete();
2031
+ }
2032
+ });
2033
+ }
2034
+
2035
+ function runAll(done) {
2036
+ /**
2037
+ * Information passed to the {@link Reporter#jasmineStarted} event.
2038
+ * @typedef JasmineStartedInfo
2039
+ * @property {Int} totalSpecsDefined - The total number of specs defined in this suite.
2040
+ * @property {Order} order - Information about the ordering (random or not) of this execution of the suite.
2041
+ * @since 2.0.0
2042
+ */
2043
+ reporter.jasmineStarted(
2044
+ {
2045
+ totalSpecsDefined: totalSpecsDefined,
2046
+ order: order
2047
+ },
2048
+ function() {
2049
+ currentlyExecutingSuites.push(topSuite);
2050
+
2051
+ processor.execute(function() {
2052
+ clearResourcesForRunnable(topSuite.id);
2053
+ currentlyExecutingSuites.pop();
2054
+ var overallStatus, incompleteReason;
2055
+
2056
+ if (
2057
+ hasFailures ||
2058
+ topSuite.result.failedExpectations.length > 0
2059
+ ) {
2060
+ overallStatus = 'failed';
2061
+ } else if (focusedRunnables.length > 0) {
2062
+ overallStatus = 'incomplete';
2063
+ incompleteReason = 'fit() or fdescribe() was found';
2064
+ } else if (totalSpecsDefined === 0) {
2065
+ overallStatus = 'incomplete';
2066
+ incompleteReason = 'No specs found';
2067
+ } else {
2068
+ overallStatus = 'passed';
2069
+ }
2070
+
2071
+ /**
2072
+ * Information passed to the {@link Reporter#jasmineDone} event.
2073
+ * @typedef JasmineDoneInfo
2074
+ * @property {OverallStatus} overallStatus - The overall result of the suite: 'passed', 'failed', or 'incomplete'.
2075
+ * @property {Int} totalTime - The total time (in ms) that it took to execute the suite
2076
+ * @property {IncompleteReason} incompleteReason - Explanation of why the suite was incomplete.
2077
+ * @property {Order} order - Information about the ordering (random or not) of this execution of the suite.
2078
+ * @property {Expectation[]} failedExpectations - List of expectations that failed in an {@link afterAll} at the global level.
2079
+ * @property {Expectation[]} deprecationWarnings - List of deprecation warnings that occurred at the global level.
2080
+ * @since 2.4.0
2081
+ */
2082
+ reporter.jasmineDone(
2083
+ {
2084
+ overallStatus: overallStatus,
2085
+ totalTime: jasmineTimer.elapsed(),
2086
+ incompleteReason: incompleteReason,
2087
+ order: order,
2088
+ failedExpectations: topSuite.result.failedExpectations,
2089
+ deprecationWarnings: topSuite.result.deprecationWarnings
2090
+ },
2091
+ done
2092
+ );
2093
+ });
2094
+ }
2095
+ );
2096
+ }
1802
2097
  };
1803
2098
 
1804
2099
  /**
@@ -1873,6 +2168,15 @@ getJasmineRequireObj().Env = function(j$) {
1873
2168
  }
1874
2169
  });
1875
2170
 
2171
+ /**
2172
+ * Configures whether Jasmine should allow the same function to be spied on
2173
+ * more than once during the execution of a spec. By default, spying on
2174
+ * a function that is already a spy will cause an error.
2175
+ * @name Env#allowRespy
2176
+ * @function
2177
+ * @since 2.5.0
2178
+ * @param {boolean} allow Whether to allow respying
2179
+ */
1876
2180
  this.allowRespy = function(allow) {
1877
2181
  spyRegistry.allowRespy(allow);
1878
2182
  };
@@ -1937,7 +2241,8 @@ getJasmineRequireObj().Env = function(j$) {
1937
2241
  expectationFactory: expectationFactory,
1938
2242
  asyncExpectationFactory: suiteAsyncExpectationFactory,
1939
2243
  expectationResultFactory: expectationResultFactory,
1940
- throwOnExpectationFailure: config.oneFailurePerSpec
2244
+ throwOnExpectationFailure: config.oneFailurePerSpec,
2245
+ autoCleanClosures: config.autoCleanClosures
1941
2246
  });
1942
2247
 
1943
2248
  return suite;
@@ -1950,8 +2255,8 @@ getJasmineRequireObj().Env = function(j$) {
1950
2255
  if (specDefinitions.length > 0) {
1951
2256
  throw new Error('describe does not expect any arguments');
1952
2257
  }
1953
- if (currentDeclarationSuite.markedPending) {
1954
- suite.pend();
2258
+ if (currentDeclarationSuite.markedExcluding) {
2259
+ suite.exclude();
1955
2260
  }
1956
2261
  addSpecsToSuite(suite, specDefinitions);
1957
2262
  return suite;
@@ -1961,7 +2266,7 @@ getJasmineRequireObj().Env = function(j$) {
1961
2266
  ensureIsNotNested('xdescribe');
1962
2267
  ensureIsFunction(specDefinitions, 'xdescribe');
1963
2268
  var suite = suiteFactory(description);
1964
- suite.pend();
2269
+ suite.exclude();
1965
2270
  addSpecsToSuite(suite, specDefinitions);
1966
2271
  return suite;
1967
2272
  };
@@ -2046,6 +2351,7 @@ getJasmineRequireObj().Env = function(j$) {
2046
2351
  timeout: timeout || 0
2047
2352
  },
2048
2353
  throwOnExpectationFailure: config.oneFailurePerSpec,
2354
+ autoCleanClosures: config.autoCleanClosures,
2049
2355
  timer: new j$.Timer()
2050
2356
  });
2051
2357
  return spec;
@@ -2075,9 +2381,14 @@ getJasmineRequireObj().Env = function(j$) {
2075
2381
  if (arguments.length > 1 && typeof fn !== 'undefined') {
2076
2382
  ensureIsFunctionOrAsync(fn, 'it');
2077
2383
  }
2384
+
2385
+ if (timeout) {
2386
+ j$.util.validateTimeout(timeout);
2387
+ }
2388
+
2078
2389
  var spec = specFactory(description, fn, currentDeclarationSuite, timeout);
2079
- if (currentDeclarationSuite.markedPending) {
2080
- spec.pend();
2390
+ if (currentDeclarationSuite.markedExcluding) {
2391
+ spec.exclude();
2081
2392
  }
2082
2393
  currentDeclarationSuite.addChild(spec);
2083
2394
  return spec;
@@ -2091,13 +2402,17 @@ getJasmineRequireObj().Env = function(j$) {
2091
2402
  ensureIsFunctionOrAsync(fn, 'xit');
2092
2403
  }
2093
2404
  var spec = this.it.apply(this, arguments);
2094
- spec.pend('Temporarily disabled with xit');
2405
+ spec.exclude('Temporarily disabled with xit');
2095
2406
  return spec;
2096
2407
  };
2097
2408
 
2098
2409
  this.fit = function(description, fn, timeout) {
2099
2410
  ensureIsNotNested('fit');
2100
2411
  ensureIsFunctionOrAsync(fn, 'fit');
2412
+
2413
+ if (timeout) {
2414
+ j$.util.validateTimeout(timeout);
2415
+ }
2101
2416
  var spec = specFactory(description, fn, currentDeclarationSuite, timeout);
2102
2417
  currentDeclarationSuite.addChild(spec);
2103
2418
  focusedRunnables.push(spec.id);
@@ -2162,6 +2477,11 @@ getJasmineRequireObj().Env = function(j$) {
2162
2477
  this.beforeEach = function(beforeEachFunction, timeout) {
2163
2478
  ensureIsNotNested('beforeEach');
2164
2479
  ensureIsFunctionOrAsync(beforeEachFunction, 'beforeEach');
2480
+
2481
+ if (timeout) {
2482
+ j$.util.validateTimeout(timeout);
2483
+ }
2484
+
2165
2485
  currentDeclarationSuite.beforeEach({
2166
2486
  fn: beforeEachFunction,
2167
2487
  timeout: timeout || 0
@@ -2171,6 +2491,11 @@ getJasmineRequireObj().Env = function(j$) {
2171
2491
  this.beforeAll = function(beforeAllFunction, timeout) {
2172
2492
  ensureIsNotNested('beforeAll');
2173
2493
  ensureIsFunctionOrAsync(beforeAllFunction, 'beforeAll');
2494
+
2495
+ if (timeout) {
2496
+ j$.util.validateTimeout(timeout);
2497
+ }
2498
+
2174
2499
  currentDeclarationSuite.beforeAll({
2175
2500
  fn: beforeAllFunction,
2176
2501
  timeout: timeout || 0
@@ -2180,6 +2505,11 @@ getJasmineRequireObj().Env = function(j$) {
2180
2505
  this.afterEach = function(afterEachFunction, timeout) {
2181
2506
  ensureIsNotNested('afterEach');
2182
2507
  ensureIsFunctionOrAsync(afterEachFunction, 'afterEach');
2508
+
2509
+ if (timeout) {
2510
+ j$.util.validateTimeout(timeout);
2511
+ }
2512
+
2183
2513
  afterEachFunction.isCleanup = true;
2184
2514
  currentDeclarationSuite.afterEach({
2185
2515
  fn: afterEachFunction,
@@ -2190,6 +2520,11 @@ getJasmineRequireObj().Env = function(j$) {
2190
2520
  this.afterAll = function(afterAllFunction, timeout) {
2191
2521
  ensureIsNotNested('afterAll');
2192
2522
  ensureIsFunctionOrAsync(afterAllFunction, 'afterAll');
2523
+
2524
+ if (timeout) {
2525
+ j$.util.validateTimeout(timeout);
2526
+ }
2527
+
2193
2528
  currentDeclarationSuite.afterAll({
2194
2529
  fn: afterAllFunction,
2195
2530
  timeout: timeout || 0
@@ -2749,6 +3084,31 @@ getJasmineRequireObj().SetContaining = function(j$) {
2749
3084
  return SetContaining;
2750
3085
  };
2751
3086
 
3087
+ getJasmineRequireObj().StringContaining = function(j$) {
3088
+ function StringContaining(expected) {
3089
+ if (!j$.isString_(expected)) {
3090
+ throw new Error('Expected is not a String');
3091
+ }
3092
+
3093
+ this.expected = expected;
3094
+ }
3095
+
3096
+ StringContaining.prototype.asymmetricMatch = function(other) {
3097
+ if (!j$.isString_(other)) {
3098
+ // Arrays, etc. don't match no matter what their indexOf returns.
3099
+ return false;
3100
+ }
3101
+
3102
+ return other.indexOf(this.expected) !== -1;
3103
+ };
3104
+
3105
+ StringContaining.prototype.jasmineToString = function() {
3106
+ return '<jasmine.stringContaining("' + this.expected + '")>';
3107
+ };
3108
+
3109
+ return StringContaining;
3110
+ };
3111
+
2752
3112
  getJasmineRequireObj().StringMatching = function(j$) {
2753
3113
  function StringMatching(expected) {
2754
3114
  if (!j$.isString_(expected) && !j$.isA_('RegExp', expected)) {
@@ -2942,6 +3302,19 @@ getJasmineRequireObj().CallTracker = function(j$) {
2942
3302
  return call ? call.args : [];
2943
3303
  };
2944
3304
 
3305
+ /**
3306
+ * Get the "this" object that was passed to a specific invocation of this spy.
3307
+ * @name Spy#calls#thisFor
3308
+ * @since 3.8.0
3309
+ * @function
3310
+ * @param {Integer} index The 0-based invocation index.
3311
+ * @return {Object?}
3312
+ */
3313
+ this.thisFor = function(index) {
3314
+ var call = calls[index];
3315
+ return call ? call.object : undefined;
3316
+ };
3317
+
2945
3318
  /**
2946
3319
  * Get the raw calls array for this spy.
2947
3320
  * @name Spy#calls#all
@@ -3093,9 +3466,12 @@ getJasmineRequireObj().Clock = function() {
3093
3466
  typeof process.versions.node === 'string';
3094
3467
 
3095
3468
  /**
3096
- * _Note:_ Do not construct this directly, Jasmine will make one during booting. You can get the current clock with {@link jasmine.clock}.
3097
3469
  * @class Clock
3098
- * @classdesc Jasmine's mock clock is used when testing time dependent code.
3470
+ * @since 1.3.0
3471
+ * @classdesc Jasmine's mock clock is used when testing time dependent code.<br>
3472
+ * _Note:_ Do not construct this directly. You can get the current clock with
3473
+ * {@link jasmine.clock}.
3474
+ * @hideconstructor
3099
3475
  */
3100
3476
  function Clock(global, delayedFunctionSchedulerFactory, mockDate) {
3101
3477
  var self = this,
@@ -3651,7 +4027,35 @@ getJasmineRequireObj().Expectation = function(j$) {
3651
4027
  });
3652
4028
 
3653
4029
  /**
3654
- * Asynchronous matchers.
4030
+ * Asynchronous matchers that operate on an actual value which is a promise,
4031
+ * and return a promise.
4032
+ *
4033
+ * Most async matchers will wait indefinitely for the promise to be resolved
4034
+ * or rejected, resulting in a spec timeout if that never happens. If you
4035
+ * expect that the promise will already be resolved or rejected at the time
4036
+ * the matcher is called, you can use the {@link async-matchers#already}
4037
+ * modifier to get a faster failure with a more helpful message.
4038
+ *
4039
+ * Note: Specs must await the result of each async matcher, return the
4040
+ * promise returned by the matcher, or return a promise that's derived from
4041
+ * the one returned by the matcher. Otherwise the matcher will not be
4042
+ * evaluated before the spec completes.
4043
+ *
4044
+ * @example
4045
+ * // Good
4046
+ * await expectAsync(aPromise).toBeResolved();
4047
+ * @example
4048
+ * // Good
4049
+ * return expectAsync(aPromise).toBeResolved();
4050
+ * @example
4051
+ * // Good
4052
+ * return expectAsync(aPromise).toBeResolved()
4053
+ * .then(function() {
4054
+ * // more spec code
4055
+ * });
4056
+ * @example
4057
+ * // Bad
4058
+ * expectAsync(aPromise).toBeResolved();
3655
4059
  * @namespace async-matchers
3656
4060
  */
3657
4061
  function AsyncExpectation(options) {
@@ -3701,6 +4105,24 @@ getJasmineRequireObj().Expectation = function(j$) {
3701
4105
  }
3702
4106
  });
3703
4107
 
4108
+ /**
4109
+ * Fail as soon as possible if the actual is pending.
4110
+ * Otherwise evaluate the matcher.
4111
+ * @member
4112
+ * @name async-matchers#already
4113
+ * @since 3.8.0
4114
+ * @type {async-matchers}
4115
+ * @example
4116
+ * await expectAsync(myPromise).already.toBeResolved();
4117
+ * @example
4118
+ * return expectAsync(myPromise).already.toBeResolved();
4119
+ */
4120
+ Object.defineProperty(AsyncExpectation.prototype, 'already', {
4121
+ get: function() {
4122
+ return addFilter(this, expectSettledPromiseFilter);
4123
+ }
4124
+ });
4125
+
3704
4126
  function wrapSyncCompare(name, matcherFactory) {
3705
4127
  return function() {
3706
4128
  var result = this.expector.compare(name, matcherFactory, arguments);
@@ -3779,6 +4201,27 @@ getJasmineRequireObj().Expectation = function(j$) {
3779
4201
  buildFailureMessage: negatedFailureMessage
3780
4202
  };
3781
4203
 
4204
+ var expectSettledPromiseFilter = {
4205
+ selectComparisonFunc: function(matcher) {
4206
+ return function(actual) {
4207
+ var matcherArgs = arguments;
4208
+
4209
+ return j$.isPending_(actual).then(function(isPending) {
4210
+ if (isPending) {
4211
+ return {
4212
+ pass: false,
4213
+ message:
4214
+ 'Expected a promise to be settled (via ' +
4215
+ 'expectAsync(...).already) but it was pending.'
4216
+ };
4217
+ } else {
4218
+ return matcher.compare.apply(null, matcherArgs);
4219
+ }
4220
+ });
4221
+ };
4222
+ }
4223
+ };
4224
+
3782
4225
  function ContextAddingFilter(message) {
3783
4226
  this.message = message;
3784
4227
  }
@@ -4074,7 +4517,28 @@ getJasmineRequireObj().GlobalErrors = function(j$) {
4074
4517
  this.jasmineHandlers = {};
4075
4518
  this.installOne_ = function installOne_(errorType, jasmineMessage) {
4076
4519
  function taggedOnError(error) {
4077
- error.jasmineMessage = jasmineMessage + ': ' + error;
4520
+ var substituteMsg;
4521
+
4522
+ if (j$.isError_(error)) {
4523
+ error.jasmineMessage = jasmineMessage + ': ' + error;
4524
+ } else {
4525
+ if (error) {
4526
+ substituteMsg = jasmineMessage + ': ' + error;
4527
+ } else {
4528
+ substituteMsg = jasmineMessage + ' with no error or message';
4529
+ }
4530
+
4531
+ if (errorType === 'unhandledRejection') {
4532
+ substituteMsg +=
4533
+ '\n' +
4534
+ '(Tip: to get a useful stack trace, use ' +
4535
+ 'Promise.reject(new Error(...)) instead of Promise.reject(' +
4536
+ (error ? '...' : '') +
4537
+ ').)';
4538
+ }
4539
+
4540
+ error = new Error(substituteMsg);
4541
+ }
4078
4542
 
4079
4543
  var handler = handlers[handlers.length - 1];
4080
4544
 
@@ -4423,7 +4887,7 @@ getJasmineRequireObj().toBeResolved = function(j$) {
4423
4887
  * @example
4424
4888
  * return expectAsync(aPromise).toBeResolved();
4425
4889
  */
4426
- return function toBeResolved() {
4890
+ return function toBeResolved(matchersUtil) {
4427
4891
  return {
4428
4892
  compare: function(actual) {
4429
4893
  if (!j$.isPromiseLike(actual)) {
@@ -4434,8 +4898,15 @@ getJasmineRequireObj().toBeResolved = function(j$) {
4434
4898
  function() {
4435
4899
  return { pass: true };
4436
4900
  },
4437
- function() {
4438
- return { pass: false };
4901
+ function(e) {
4902
+ return {
4903
+ pass: false,
4904
+ message:
4905
+ 'Expected a promise to be resolved but it was ' +
4906
+ 'rejected with ' +
4907
+ matchersUtil.pp(e) +
4908
+ '.'
4909
+ };
4439
4910
  }
4440
4911
  );
4441
4912
  }
@@ -4490,10 +4961,14 @@ getJasmineRequireObj().toBeResolvedTo = function(j$) {
4490
4961
  };
4491
4962
  }
4492
4963
  },
4493
- function() {
4964
+ function(e) {
4494
4965
  return {
4495
4966
  pass: false,
4496
- message: prefix(false) + ' but it was rejected.'
4967
+ message:
4968
+ prefix(false) +
4969
+ ' but it was rejected with ' +
4970
+ matchersUtil.pp(e) +
4971
+ '.'
4497
4972
  };
4498
4973
  }
4499
4974
  );
@@ -4625,11 +5100,11 @@ getJasmineRequireObj().MatchersUtil = function(j$) {
4625
5100
  // TODO: convert all uses of j$.pp to use the injected pp
4626
5101
 
4627
5102
  /**
5103
+ * @class MatchersUtil
5104
+ * @classdesc Utilities for use in implementing matchers.<br>
4628
5105
  * _Note:_ Do not construct this directly. Jasmine will construct one and
4629
5106
  * pass it to matchers and asymmetric equality testers.
4630
- * @name MatchersUtil
4631
- * @classdesc Utilities for use in implementing matchers
4632
- * @constructor
5107
+ * @hideconstructor
4633
5108
  */
4634
5109
  function MatchersUtil(options) {
4635
5110
  options = options || {};
@@ -4892,6 +5367,17 @@ getJasmineRequireObj().MatchersUtil = function(j$) {
4892
5367
  diffBuilder.recordMismatch();
4893
5368
  }
4894
5369
  return result;
5370
+ case '[object ArrayBuffer]':
5371
+ // If we have an instance of ArrayBuffer the Uint8Array ctor
5372
+ // will be defined as well
5373
+ return self.eq_(
5374
+ new Uint8Array(a), // eslint-disable-line compat/compat
5375
+ new Uint8Array(b), // eslint-disable-line compat/compat
5376
+ aStack,
5377
+ bStack,
5378
+ customTesters,
5379
+ diffBuilder
5380
+ );
4895
5381
  // RegExps are compared by their source patterns and flags.
4896
5382
  case '[object RegExp]':
4897
5383
  return (
@@ -5268,6 +5754,55 @@ getJasmineRequireObj().MatchersUtil = function(j$) {
5268
5754
  return MatchersUtil;
5269
5755
  };
5270
5756
 
5757
+ /**
5758
+ * @interface AsymmetricEqualityTester
5759
+ * @classdesc An asymmetric equality tester is an object that can match multiple
5760
+ * objects. Examples include jasmine.any() and jasmine.stringMatching(). Jasmine
5761
+ * includes a number of built-in asymmetric equality testers, such as
5762
+ * {@link jasmine.objectContaining}. User-defined asymmetric equality testers are
5763
+ * also supported.
5764
+ *
5765
+ * Asymmetric equality testers work with any matcher, including user-defined
5766
+ * custom matchers, that uses {@link MatchersUtil#equals} or
5767
+ * {@link MatchersUtil#contains}.
5768
+ *
5769
+ * @example
5770
+ * function numberDivisibleBy(divisor) {
5771
+ * return {
5772
+ * asymmetricMatch: function(n) {
5773
+ * return typeof n === 'number' && n % divisor === 0;
5774
+ * },
5775
+ * jasmineToString: function() {
5776
+ * return `<a number divisible by ${divisor}>`;
5777
+ * }
5778
+ * };
5779
+ * }
5780
+ *
5781
+ * var actual = {
5782
+ * n: 2,
5783
+ * otherFields: "don't care"
5784
+ * };
5785
+ *
5786
+ * expect(actual).toEqual(jasmine.objectContaining({n: numberDivisibleBy(2)}));
5787
+ * @see custom_asymmetric_equality_testers
5788
+ * @since 2.0.0
5789
+ */
5790
+ /**
5791
+ * Determines whether a value matches this tester
5792
+ * @function
5793
+ * @name AsymmetricEqualityTester#asymmetricMatch
5794
+ * @param value {any} The value to test
5795
+ * @param matchersUtil {MatchersUtil} utilities for testing equality, etc
5796
+ * @return {Boolean}
5797
+ */
5798
+ /**
5799
+ * Returns a string representation of this tester to use in matcher failure messages
5800
+ * @function
5801
+ * @name AsymmetricEqualityTester#jasmineToString
5802
+ * @param pp {function} Function that takes a value and returns a pretty-printed representation
5803
+ * @return {String}
5804
+ */
5805
+
5271
5806
  getJasmineRequireObj().MismatchTree = function(j$) {
5272
5807
  /*
5273
5808
  To be able to apply custom object formatters at all possible levels of an
@@ -7474,7 +8009,6 @@ getJasmineRequireObj().QueueRunner = function(j$) {
7474
8009
  completedSynchronously = true,
7475
8010
  handleError = function handleError(error) {
7476
8011
  onException(error);
7477
- next(error);
7478
8012
  },
7479
8013
  cleanup = once(function cleanup() {
7480
8014
  if (timeoutId !== void 0) {
@@ -7987,10 +8521,11 @@ getJasmineRequireObj().interface = function(jasmine, env) {
7987
8521
  * @function
7988
8522
  * @global
7989
8523
  * @param {Object} obj - The object upon which to install the {@link Spy}s
8524
+ * @param {boolean} includeNonEnumerable - Whether or not to add spies to non-enumerable properties
7990
8525
  * @returns {Object} the spied object
7991
8526
  */
7992
- spyOnAllFunctions: function(obj) {
7993
- return env.spyOnAllFunctions(obj);
8527
+ spyOnAllFunctions: function(obj, includeNonEnumerable) {
8528
+ return env.spyOnAllFunctions(obj, includeNonEnumerable);
7994
8529
  },
7995
8530
 
7996
8531
  jsApiReporter: new jasmine.JsApiReporter({
@@ -8145,9 +8680,11 @@ getJasmineRequireObj().Spy = function(j$) {
8145
8680
  });
8146
8681
 
8147
8682
  /**
8148
- * _Note:_ Do not construct this directly, use {@link spyOn}, {@link spyOnProperty}, {@link jasmine.createSpy}, or {@link jasmine.createSpyObj}
8149
- * @constructor
8150
- * @name Spy
8683
+ * @classdesc _Note:_ Do not construct this directly. Use {@link spyOn},
8684
+ * {@link spyOnProperty}, {@link jasmine.createSpy}, or
8685
+ * {@link jasmine.createSpyObj} instead.
8686
+ * @class Spy
8687
+ * @hideconstructor
8151
8688
  */
8152
8689
  function Spy(
8153
8690
  name,
@@ -8176,6 +8713,7 @@ getJasmineRequireObj().Spy = function(j$) {
8176
8713
  * @property {object} object - `this` context for the invocation.
8177
8714
  * @property {number} invocationOrder - Order of the invocation.
8178
8715
  * @property {Array} args - The arguments passed for this invocation.
8716
+ * @property returnValue - The value that was returned from this invocation.
8179
8717
  */
8180
8718
  var callData = {
8181
8719
  object: context,
@@ -8591,7 +9129,7 @@ getJasmineRequireObj().SpyRegistry = function(j$) {
8591
9129
  return spy;
8592
9130
  };
8593
9131
 
8594
- this.spyOnAllFunctions = function(obj) {
9132
+ this.spyOnAllFunctions = function(obj, includeNonEnumerable) {
8595
9133
  if (j$.util.isUndefined(obj)) {
8596
9134
  throw new Error(
8597
9135
  'spyOnAllFunctions could not find an object to spy upon'
@@ -8599,30 +9137,27 @@ getJasmineRequireObj().SpyRegistry = function(j$) {
8599
9137
  }
8600
9138
 
8601
9139
  var pointer = obj,
8602
- props = [],
8603
- prop,
8604
- descriptor;
9140
+ propsToSpyOn = [],
9141
+ properties,
9142
+ propertiesToSkip = [];
8605
9143
 
8606
- while (pointer) {
8607
- for (prop in pointer) {
8608
- if (
8609
- Object.prototype.hasOwnProperty.call(pointer, prop) &&
8610
- pointer[prop] instanceof Function
8611
- ) {
8612
- descriptor = Object.getOwnPropertyDescriptor(pointer, prop);
8613
- if (
8614
- (descriptor.writable || descriptor.set) &&
8615
- descriptor.configurable
8616
- ) {
8617
- props.push(prop);
8618
- }
8619
- }
8620
- }
9144
+ while (
9145
+ pointer &&
9146
+ (!includeNonEnumerable || pointer !== Object.prototype)
9147
+ ) {
9148
+ properties = getProps(pointer, includeNonEnumerable);
9149
+ properties = properties.filter(function(prop) {
9150
+ return propertiesToSkip.indexOf(prop) === -1;
9151
+ });
9152
+ propertiesToSkip = propertiesToSkip.concat(properties);
9153
+ propsToSpyOn = propsToSpyOn.concat(
9154
+ getSpyableFunctionProps(pointer, properties)
9155
+ );
8621
9156
  pointer = Object.getPrototypeOf(pointer);
8622
9157
  }
8623
9158
 
8624
- for (var i = 0; i < props.length; i++) {
8625
- this.spyOn(obj, props[i]);
9159
+ for (var i = 0; i < propsToSpyOn.length; i++) {
9160
+ this.spyOn(obj, propsToSpyOn[i]);
8626
9161
  }
8627
9162
 
8628
9163
  return obj;
@@ -8637,6 +9172,50 @@ getJasmineRequireObj().SpyRegistry = function(j$) {
8637
9172
  };
8638
9173
  }
8639
9174
 
9175
+ function getProps(obj, includeNonEnumerable) {
9176
+ var enumerableProperties = Object.keys(obj);
9177
+
9178
+ if (!includeNonEnumerable) {
9179
+ return enumerableProperties;
9180
+ }
9181
+
9182
+ return Object.getOwnPropertyNames(obj).filter(function(prop) {
9183
+ return (
9184
+ prop !== 'constructor' ||
9185
+ enumerableProperties.indexOf('constructor') > -1
9186
+ );
9187
+ });
9188
+ }
9189
+
9190
+ function getSpyableFunctionProps(obj, propertiesToCheck) {
9191
+ var props = [],
9192
+ prop;
9193
+ for (var i = 0; i < propertiesToCheck.length; i++) {
9194
+ prop = propertiesToCheck[i];
9195
+ if (
9196
+ Object.prototype.hasOwnProperty.call(obj, prop) &&
9197
+ isSpyableProp(obj, prop)
9198
+ ) {
9199
+ props.push(prop);
9200
+ }
9201
+ }
9202
+ return props;
9203
+ }
9204
+
9205
+ function isSpyableProp(obj, prop) {
9206
+ var value, descriptor;
9207
+ try {
9208
+ value = obj[prop];
9209
+ } catch (e) {
9210
+ return false;
9211
+ }
9212
+ if (value instanceof Function) {
9213
+ descriptor = Object.getOwnPropertyDescriptor(obj, prop);
9214
+ return (descriptor.writable || descriptor.set) && descriptor.configurable;
9215
+ }
9216
+ return false;
9217
+ }
9218
+
8640
9219
  return SpyRegistry;
8641
9220
  };
8642
9221
 
@@ -8969,15 +9548,42 @@ getJasmineRequireObj().StackTrace = function(j$) {
8969
9548
  };
8970
9549
 
8971
9550
  getJasmineRequireObj().Suite = function(j$) {
9551
+ /**
9552
+ * @interface Suite
9553
+ * @see Env#topSuite
9554
+ * @since 2.0.0
9555
+ */
8972
9556
  function Suite(attrs) {
8973
9557
  this.env = attrs.env;
9558
+ /**
9559
+ * The unique ID of this suite.
9560
+ * @name Suite#id
9561
+ * @readonly
9562
+ * @type {string}
9563
+ * @since 2.0.0
9564
+ */
8974
9565
  this.id = attrs.id;
9566
+ /**
9567
+ * The parent of this suite, or null if this is the top suite.
9568
+ * @name Suite#parentSuite
9569
+ * @readonly
9570
+ * @type {Suite}
9571
+ */
8975
9572
  this.parentSuite = attrs.parentSuite;
9573
+ /**
9574
+ * The description passed to the {@link describe} that created this suite.
9575
+ * @name Suite#description
9576
+ * @readonly
9577
+ * @type {string}
9578
+ * @since 2.0.0
9579
+ */
8976
9580
  this.description = attrs.description;
8977
9581
  this.expectationFactory = attrs.expectationFactory;
8978
9582
  this.asyncExpectationFactory = attrs.asyncExpectationFactory;
8979
9583
  this.expectationResultFactory = attrs.expectationResultFactory;
8980
9584
  this.throwOnExpectationFailure = !!attrs.throwOnExpectationFailure;
9585
+ this.autoCleanClosures =
9586
+ attrs.autoCleanClosures === undefined ? true : !!attrs.autoCleanClosures;
8981
9587
 
8982
9588
  this.beforeFns = [];
8983
9589
  this.afterFns = [];
@@ -8986,28 +9592,15 @@ getJasmineRequireObj().Suite = function(j$) {
8986
9592
 
8987
9593
  this.timer = attrs.timer || new j$.Timer();
8988
9594
 
8989
- this.children = [];
8990
-
8991
9595
  /**
8992
- * @typedef SuiteResult
8993
- * @property {Int} id - The unique id of this suite.
8994
- * @property {String} description - The description text passed to the {@link describe} that made this suite.
8995
- * @property {String} fullName - The full description including all ancestors of this suite.
8996
- * @property {Expectation[]} failedExpectations - The list of expectations that failed in an {@link afterAll} for this suite.
8997
- * @property {Expectation[]} deprecationWarnings - The list of deprecation warnings that occurred on this suite.
8998
- * @property {String} status - Once the suite has completed, this string represents the pass/fail status of this suite.
8999
- * @property {number} duration - The time in ms for Suite execution, including any before/afterAll, before/afterEach.
9000
- * @property {Object} properties - User-supplied properties, if any, that were set using {@link Env#setSuiteProperty}
9596
+ * The suite's children.
9597
+ * @name Suite#children
9598
+ * @type {Array.<(Spec|Suite)>}
9599
+ * @since 2.0.0
9001
9600
  */
9002
- this.result = {
9003
- id: this.id,
9004
- description: this.description,
9005
- fullName: this.getFullName(),
9006
- failedExpectations: [],
9007
- deprecationWarnings: [],
9008
- duration: null,
9009
- properties: null
9010
- };
9601
+ this.children = [];
9602
+
9603
+ this.reset();
9011
9604
  }
9012
9605
 
9013
9606
  Suite.prototype.setSuiteProperty = function(key, value) {
@@ -9023,6 +9616,13 @@ getJasmineRequireObj().Suite = function(j$) {
9023
9616
  return this.asyncExpectationFactory(actual, this);
9024
9617
  };
9025
9618
 
9619
+ /**
9620
+ * The full description including all ancestors of this suite.
9621
+ * @name Suite#getFullName
9622
+ * @function
9623
+ * @returns {string}
9624
+ * @since 2.0.0
9625
+ */
9026
9626
  Suite.prototype.getFullName = function() {
9027
9627
  var fullName = [];
9028
9628
  for (
@@ -9037,10 +9637,22 @@ getJasmineRequireObj().Suite = function(j$) {
9037
9637
  return fullName.join(' ');
9038
9638
  };
9039
9639
 
9640
+ /*
9641
+ * Mark the suite with "pending" status
9642
+ */
9040
9643
  Suite.prototype.pend = function() {
9041
9644
  this.markedPending = true;
9042
9645
  };
9043
9646
 
9647
+ /*
9648
+ * Like {@link Suite#pend}, but pending state will survive {@link Spec#reset}
9649
+ * Useful for fdescribe, xdescribe, where pending state should remain.
9650
+ */
9651
+ Suite.prototype.exclude = function() {
9652
+ this.pend();
9653
+ this.markedExcluding = true;
9654
+ };
9655
+
9044
9656
  Suite.prototype.beforeEach = function(fn) {
9045
9657
  this.beforeFns.unshift(fn);
9046
9658
  };
@@ -9072,10 +9684,40 @@ getJasmineRequireObj().Suite = function(j$) {
9072
9684
  }
9073
9685
 
9074
9686
  Suite.prototype.cleanupBeforeAfter = function() {
9075
- removeFns(this.beforeAllFns);
9076
- removeFns(this.afterAllFns);
9077
- removeFns(this.beforeFns);
9078
- removeFns(this.afterFns);
9687
+ if (this.autoCleanClosures) {
9688
+ removeFns(this.beforeAllFns);
9689
+ removeFns(this.afterAllFns);
9690
+ removeFns(this.beforeFns);
9691
+ removeFns(this.afterFns);
9692
+ }
9693
+ };
9694
+
9695
+ Suite.prototype.reset = function() {
9696
+ /**
9697
+ * @typedef SuiteResult
9698
+ * @property {Int} id - The unique id of this suite.
9699
+ * @property {String} description - The description text passed to the {@link describe} that made this suite.
9700
+ * @property {String} fullName - The full description including all ancestors of this suite.
9701
+ * @property {Expectation[]} failedExpectations - The list of expectations that failed in an {@link afterAll} for this suite.
9702
+ * @property {Expectation[]} deprecationWarnings - The list of deprecation warnings that occurred on this suite.
9703
+ * @property {String} status - Once the suite has completed, this string represents the pass/fail status of this suite.
9704
+ * @property {number} duration - The time in ms for Suite execution, including any before/afterAll, before/afterEach.
9705
+ * @property {Object} properties - User-supplied properties, if any, that were set using {@link Env#setSuiteProperty}
9706
+ * @since 2.0.0
9707
+ */
9708
+ this.result = {
9709
+ id: this.id,
9710
+ description: this.description,
9711
+ fullName: this.getFullName(),
9712
+ failedExpectations: [],
9713
+ deprecationWarnings: [],
9714
+ duration: null,
9715
+ properties: null
9716
+ };
9717
+ this.markedPending = this.markedExcluding;
9718
+ this.children.forEach(function(child) {
9719
+ child.reset();
9720
+ });
9079
9721
  };
9080
9722
 
9081
9723
  Suite.prototype.addChild = function(child) {
@@ -9469,5 +10111,5 @@ getJasmineRequireObj().UserContext = function(j$) {
9469
10111
  };
9470
10112
 
9471
10113
  getJasmineRequireObj().version = function() {
9472
- return '3.6.0';
10114
+ return '3.10.0';
9473
10115
  };