jasmine-core 3.7.0 → 3.10.0

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