jasmine-core 2.3.4 → 2.4.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.
@@ -24,7 +24,11 @@ var getJasmineRequireObj = (function (jasmineGlobal) {
24
24
  var jasmineRequire;
25
25
 
26
26
  if (typeof module !== 'undefined' && module.exports) {
27
- jasmineGlobal = global;
27
+ if (typeof global !== 'undefined') {
28
+ jasmineGlobal = global;
29
+ } else {
30
+ jasmineGlobal = {};
31
+ }
28
32
  jasmineRequire = exports;
29
33
  } else {
30
34
  if (typeof window !== 'undefined' && typeof window.toString === 'function' && window.toString() === '[object GjsGlobal]') {
@@ -68,6 +72,7 @@ var getJasmineRequireObj = (function (jasmineGlobal) {
68
72
  j$.Timer = jRequire.Timer();
69
73
  j$.TreeProcessor = jRequire.TreeProcessor();
70
74
  j$.version = jRequire.version();
75
+ j$.Order = jRequire.Order();
71
76
 
72
77
  j$.matchers = jRequire.requireMatchers(jRequire, j$);
73
78
 
@@ -93,6 +98,7 @@ getJasmineRequireObj().requireMatchers = function(jRequire, j$) {
93
98
  'toEqual',
94
99
  'toHaveBeenCalled',
95
100
  'toHaveBeenCalledWith',
101
+ 'toHaveBeenCalledTimes',
96
102
  'toMatch',
97
103
  'toThrow',
98
104
  'toThrowError'
@@ -447,6 +453,53 @@ if (typeof window == void 0 && typeof exports == 'object') {
447
453
  exports.Spec = jasmineRequire.Spec;
448
454
  }
449
455
 
456
+ /*jshint bitwise: false*/
457
+
458
+ getJasmineRequireObj().Order = function() {
459
+ function Order(options) {
460
+ this.random = 'random' in options ? options.random : true;
461
+ var seed = this.seed = options.seed || generateSeed();
462
+ this.sort = this.random ? randomOrder : naturalOrder;
463
+
464
+ function naturalOrder(items) {
465
+ return items;
466
+ }
467
+
468
+ function randomOrder(items) {
469
+ var copy = items.slice();
470
+ copy.sort(function(a, b) {
471
+ return jenkinsHash(seed + a.id) - jenkinsHash(seed + b.id);
472
+ });
473
+ return copy;
474
+ }
475
+
476
+ function generateSeed() {
477
+ return String(Math.random()).slice(-5);
478
+ }
479
+
480
+ // Bob Jenkins One-at-a-Time Hash algorithm is a non-cryptographic hash function
481
+ // used to get a different output when the key changes slighly.
482
+ // We use your return to sort the children randomly in a consistent way when
483
+ // used in conjunction with a seed
484
+
485
+ function jenkinsHash(key) {
486
+ var hash, i;
487
+ for(hash = i = 0; i < key.length; ++i) {
488
+ hash += key.charCodeAt(i);
489
+ hash += (hash << 10);
490
+ hash ^= (hash >> 6);
491
+ }
492
+ hash += (hash << 3);
493
+ hash ^= (hash >> 11);
494
+ hash += (hash << 15);
495
+ return hash;
496
+ }
497
+
498
+ }
499
+
500
+ return Order;
501
+ };
502
+
450
503
  getJasmineRequireObj().Env = function(j$) {
451
504
  function Env(options) {
452
505
  options = options || {};
@@ -469,6 +522,8 @@ getJasmineRequireObj().Env = function(j$) {
469
522
  var currentlyExecutingSuites = [];
470
523
  var currentDeclarationSuite = null;
471
524
  var throwOnExpectationFailure = false;
525
+ var random = false;
526
+ var seed = null;
472
527
 
473
528
  var currentSuite = function() {
474
529
  return currentlyExecutingSuites[currentlyExecutingSuites.length - 1];
@@ -557,7 +612,7 @@ getJasmineRequireObj().Env = function(j$) {
557
612
 
558
613
  while(suite) {
559
614
  befores = befores.concat(suite.beforeFns);
560
- afters = afters.concat(suite.afterFns);
615
+ afters = afters.concat(suite.afterFns.reverse());
561
616
 
562
617
  suite = suite.parentSuite;
563
618
  }
@@ -618,6 +673,21 @@ getJasmineRequireObj().Env = function(j$) {
618
673
  return throwOnExpectationFailure;
619
674
  };
620
675
 
676
+ this.randomizeTests = function(value) {
677
+ random = !!value;
678
+ };
679
+
680
+ this.randomTests = function() {
681
+ return random;
682
+ };
683
+
684
+ this.seed = function(value) {
685
+ if (value) {
686
+ seed = value;
687
+ }
688
+ return seed;
689
+ };
690
+
621
691
  var queueRunnerFactory = function(options) {
622
692
  options.catchException = catchException;
623
693
  options.clearStack = options.clearStack || clearStack;
@@ -649,6 +719,12 @@ getJasmineRequireObj().Env = function(j$) {
649
719
  runnablesToRun = [topSuite.id];
650
720
  }
651
721
  }
722
+
723
+ var order = new j$.Order({
724
+ random: random,
725
+ seed: seed
726
+ });
727
+
652
728
  var processor = new j$.TreeProcessor({
653
729
  tree: topSuite,
654
730
  runnableIds: runnablesToRun,
@@ -664,6 +740,9 @@ getJasmineRequireObj().Env = function(j$) {
664
740
  }
665
741
  currentlyExecutingSuites.pop();
666
742
  reporter.suiteDone(result);
743
+ },
744
+ orderChildren: function(node) {
745
+ return order.sort(node.children);
667
746
  }
668
747
  });
669
748
 
@@ -675,7 +754,11 @@ getJasmineRequireObj().Env = function(j$) {
675
754
  totalSpecsDefined: totalSpecsDefined
676
755
  });
677
756
 
678
- processor.execute(reporter.jasmineDone);
757
+ processor.execute(function() {
758
+ reporter.jasmineDone({
759
+ order: order
760
+ });
761
+ });
679
762
  };
680
763
 
681
764
  this.addReporter = function(reporterToAdd) {
@@ -710,13 +793,20 @@ getJasmineRequireObj().Env = function(j$) {
710
793
 
711
794
  this.describe = function(description, specDefinitions) {
712
795
  var suite = suiteFactory(description);
796
+ if (specDefinitions.length > 0) {
797
+ throw new Error('describe does not expect a done parameter');
798
+ }
799
+ if (currentDeclarationSuite.markedPending) {
800
+ suite.pend();
801
+ }
713
802
  addSpecsToSuite(suite, specDefinitions);
714
803
  return suite;
715
804
  };
716
805
 
717
806
  this.xdescribe = function(description, specDefinitions) {
718
- var suite = this.describe(description, specDefinitions);
719
- suite.disable();
807
+ var suite = suiteFactory(description);
808
+ suite.pend();
809
+ addSpecsToSuite(suite, specDefinitions);
720
810
  return suite;
721
811
  };
722
812
 
@@ -822,19 +912,22 @@ getJasmineRequireObj().Env = function(j$) {
822
912
 
823
913
  this.it = function(description, fn, timeout) {
824
914
  var spec = specFactory(description, fn, currentDeclarationSuite, timeout);
915
+ if (currentDeclarationSuite.markedPending) {
916
+ spec.pend();
917
+ }
825
918
  currentDeclarationSuite.addChild(spec);
826
919
  return spec;
827
920
  };
828
921
 
829
922
  this.xit = function() {
830
923
  var spec = this.it.apply(this, arguments);
831
- spec.pend();
924
+ spec.pend('Temporarily disabled with xit');
832
925
  return spec;
833
926
  };
834
927
 
835
- this.fit = function(){
836
- var spec = this.it.apply(this, arguments);
837
-
928
+ this.fit = function(description, fn, timeout){
929
+ var spec = specFactory(description, fn, currentDeclarationSuite, timeout);
930
+ currentDeclarationSuite.addChild(spec);
838
931
  focusedRunnables.push(spec.id);
839
932
  unfocusAncestor();
840
933
  return spec;
@@ -918,6 +1011,7 @@ getJasmineRequireObj().JsApiReporter = function() {
918
1011
 
919
1012
  this.started = false;
920
1013
  this.finished = false;
1014
+ this.runDetails = {};
921
1015
 
922
1016
  this.jasmineStarted = function() {
923
1017
  this.started = true;
@@ -927,8 +1021,9 @@ getJasmineRequireObj().JsApiReporter = function() {
927
1021
 
928
1022
  var executionTime;
929
1023
 
930
- this.jasmineDone = function() {
1024
+ this.jasmineDone = function(runDetails) {
931
1025
  this.finished = true;
1026
+ this.runDetails = runDetails;
932
1027
  executionTime = timer.elapsed();
933
1028
  status = 'done';
934
1029
  };
@@ -1606,6 +1701,8 @@ getJasmineRequireObj().pp = function(j$) {
1606
1701
  this.emitScalar('HTMLNode');
1607
1702
  } else if (value instanceof Date) {
1608
1703
  this.emitScalar('Date(' + value + ')');
1704
+ } else if (value.toString && typeof value === 'object' && !(value instanceof Array) && value.toString !== Object.prototype.toString) {
1705
+ this.emitScalar(value.toString());
1609
1706
  } else if (j$.util.arrayContains(this.seen, value)) {
1610
1707
  this.emitScalar('<circular reference: ' + (j$.isArray_(value) ? 'Array' : 'Object') + '>');
1611
1708
  } else if (j$.isArray_(value) || j$.isA_('Object', value)) {
@@ -1810,7 +1907,7 @@ getJasmineRequireObj().QueueRunner = function(j$) {
1810
1907
  if (queueableFn.timeout) {
1811
1908
  timeoutId = Function.prototype.apply.apply(self.timeout.setTimeout, [j$.getGlobal(), [function() {
1812
1909
  var error = new Error('Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.');
1813
- onException(error, queueableFn);
1910
+ onException(error);
1814
1911
  next();
1815
1912
  }, queueableFn.timeout()]]);
1816
1913
  }
@@ -1823,12 +1920,12 @@ getJasmineRequireObj().QueueRunner = function(j$) {
1823
1920
  }
1824
1921
  }
1825
1922
 
1826
- function onException(e, queueableFn) {
1923
+ function onException(e) {
1827
1924
  self.onException(e);
1828
1925
  }
1829
1926
 
1830
1927
  function handleException(e, queueableFn) {
1831
- onException(e, queueableFn);
1928
+ onException(e);
1832
1929
  if (!self.catchException(e)) {
1833
1930
  //TODO: set a var when we catch an exception and
1834
1931
  //use a finally block to close the loop in a nice way..
@@ -1900,6 +1997,17 @@ getJasmineRequireObj().SpyRegistry = function(j$) {
1900
1997
  throw new Error(methodName + ' has already been spied upon');
1901
1998
  }
1902
1999
 
2000
+ var descriptor;
2001
+ try {
2002
+ descriptor = Object.getOwnPropertyDescriptor(obj, methodName);
2003
+ } catch(e) {
2004
+ // IE 8 doesn't support `definePropery` on non-DOM nodes
2005
+ }
2006
+
2007
+ if (descriptor && !(descriptor.writable || descriptor.set)) {
2008
+ throw new Error(methodName + ' is not declared writable or has no setter');
2009
+ }
2010
+
1903
2011
  var spy = j$.createSpy(methodName, obj[methodName]);
1904
2012
 
1905
2013
  currentSpies().push({
@@ -2030,6 +2138,10 @@ getJasmineRequireObj().Suite = function(j$) {
2030
2138
  this.disabled = true;
2031
2139
  };
2032
2140
 
2141
+ Suite.prototype.pend = function(message) {
2142
+ this.markedPending = true;
2143
+ };
2144
+
2033
2145
  Suite.prototype.beforeEach = function(fn) {
2034
2146
  this.beforeFns.unshift(fn);
2035
2147
  };
@@ -2055,6 +2167,10 @@ getJasmineRequireObj().Suite = function(j$) {
2055
2167
  return 'disabled';
2056
2168
  }
2057
2169
 
2170
+ if (this.markedPending) {
2171
+ return 'pending';
2172
+ }
2173
+
2058
2174
  if (this.result.failedExpectations.length > 0) {
2059
2175
  return 'failed';
2060
2176
  } else {
@@ -2184,6 +2300,7 @@ getJasmineRequireObj().TreeProcessor = function() {
2184
2300
  queueRunnerFactory = attrs.queueRunnerFactory,
2185
2301
  nodeStart = attrs.nodeStart || function() {},
2186
2302
  nodeComplete = attrs.nodeComplete || function() {},
2303
+ orderChildren = attrs.orderChildren || function(node) { return node.children; },
2187
2304
  stats = { valid: true },
2188
2305
  processed = false,
2189
2306
  defaultMin = Infinity,
@@ -2247,8 +2364,10 @@ getJasmineRequireObj().TreeProcessor = function() {
2247
2364
  } else {
2248
2365
  var hasExecutableChild = false;
2249
2366
 
2250
- for (var i = 0; i < node.children.length; i++) {
2251
- var child = node.children[i];
2367
+ var orderedChildren = orderChildren(node);
2368
+
2369
+ for (var i = 0; i < orderedChildren.length; i++) {
2370
+ var child = orderedChildren[i];
2252
2371
 
2253
2372
  processNode(child, parentEnabled);
2254
2373
 
@@ -2265,7 +2384,7 @@ getJasmineRequireObj().TreeProcessor = function() {
2265
2384
  executable: hasExecutableChild
2266
2385
  };
2267
2386
 
2268
- segmentChildren(node, stats[node.id], executableIndex);
2387
+ segmentChildren(node, orderedChildren, stats[node.id], executableIndex);
2269
2388
 
2270
2389
  if (!node.canBeReentered() && stats[node.id].segments.length > 1) {
2271
2390
  stats = { valid: false };
@@ -2281,11 +2400,11 @@ getJasmineRequireObj().TreeProcessor = function() {
2281
2400
  return executableIndex === undefined ? defaultMax : executableIndex;
2282
2401
  }
2283
2402
 
2284
- function segmentChildren(node, nodeStats, executableIndex) {
2403
+ function segmentChildren(node, orderedChildren, nodeStats, executableIndex) {
2285
2404
  var currentSegment = { index: 0, owner: node, nodes: [], min: startingMin(executableIndex), max: startingMax(executableIndex) },
2286
2405
  result = [currentSegment],
2287
2406
  lastMax = defaultMax,
2288
- orderedChildSegments = orderChildSegments(node.children);
2407
+ orderedChildSegments = orderChildSegments(orderedChildren);
2289
2408
 
2290
2409
  function isSegmentBoundary(minIndex) {
2291
2410
  return lastMax !== defaultMax && minIndex !== defaultMin && lastMax < minIndex - 1;
@@ -2384,6 +2503,12 @@ getJasmineRequireObj().TreeProcessor = function() {
2384
2503
  getJasmineRequireObj().Any = function(j$) {
2385
2504
 
2386
2505
  function Any(expectedObject) {
2506
+ if (typeof expectedObject === 'undefined') {
2507
+ throw new TypeError(
2508
+ 'jasmine.any() expects to be passed a constructor function. ' +
2509
+ 'Please pass one or use jasmine.anything() to match any object.'
2510
+ );
2511
+ }
2387
2512
  this.expectedObject = expectedObject;
2388
2513
  }
2389
2514
 
@@ -2976,6 +3101,37 @@ getJasmineRequireObj().toHaveBeenCalled = function(j$) {
2976
3101
  return toHaveBeenCalled;
2977
3102
  };
2978
3103
 
3104
+ getJasmineRequireObj().toHaveBeenCalledTimes = function(j$) {
3105
+
3106
+ function toHaveBeenCalledTimes() {
3107
+ return {
3108
+ compare: function(actual, expected) {
3109
+ if (!j$.isSpy(actual)) {
3110
+ throw new Error('Expected a spy, but got ' + j$.pp(actual) + '.');
3111
+ }
3112
+
3113
+ var args = Array.prototype.slice.call(arguments, 0),
3114
+ result = { pass: false };
3115
+
3116
+ if(!expected){
3117
+ throw new Error('Expected times failed is required as an argument.');
3118
+ }
3119
+
3120
+ actual = args[0];
3121
+ var calls = actual.calls.count();
3122
+ var timesMessage = expected === 1 ? 'once' : expected + ' times';
3123
+ result.pass = calls === expected;
3124
+ result.message = result.pass ?
3125
+ 'Expected spy ' + actual.and.identity() + ' not to have been called ' + timesMessage + '. It was called ' + calls + ' times.' :
3126
+ 'Expected spy ' + actual.and.identity() + ' to have been called ' + timesMessage + '. It was called ' + calls + ' times.';
3127
+ return result;
3128
+ }
3129
+ };
3130
+ }
3131
+
3132
+ return toHaveBeenCalledTimes;
3133
+ };
3134
+
2979
3135
  getJasmineRequireObj().toHaveBeenCalledWith = function(j$) {
2980
3136
 
2981
3137
  function toHaveBeenCalledWith(util, customEqualityTesters) {
@@ -3079,7 +3235,7 @@ getJasmineRequireObj().toThrow = function(j$) {
3079
3235
  };
3080
3236
 
3081
3237
  getJasmineRequireObj().toThrowError = function(j$) {
3082
- function toThrowError (util) {
3238
+ function toThrowError () {
3083
3239
  return {
3084
3240
  compare: function(actual) {
3085
3241
  var threw = false,
@@ -3294,5 +3450,5 @@ getJasmineRequireObj().interface = function(jasmine, env) {
3294
3450
  };
3295
3451
 
3296
3452
  getJasmineRequireObj().version = function() {
3297
- return '2.3.4';
3453
+ return '2.4.0';
3298
3454
  };
@@ -26,6 +26,15 @@ describe("Env", function() {
26
26
  });
27
27
  });
28
28
 
29
+ describe('#describe', function () {
30
+ var spec = function(done){};
31
+ it("throws the error", function() {
32
+ expect(function() {
33
+ env.describe('done method', spec);
34
+ }).toThrow(new Error('describe does not expect a done parameter'));
35
+ });
36
+ });
37
+
29
38
  it('can configure specs to throw errors on expectation failures', function() {
30
39
  env.throwOnExpectationFailure(true);
31
40
 
@@ -45,4 +54,15 @@ describe("Env", function() {
45
54
  throwOnExpectationFailure: true
46
55
  }));
47
56
  });
57
+
58
+ describe('#xit', function() {
59
+ it('calls spec.pend with "Temporarily disabled with xit"', function() {
60
+ var pendSpy = jasmine.createSpy();
61
+ spyOn(env, 'it').and.returnValue({
62
+ pend: pendSpy
63
+ });
64
+ env.xit();
65
+ expect(pendSpy).toHaveBeenCalledWith('Temporarily disabled with xit');
66
+ });
67
+ });
48
68
  });
@@ -248,4 +248,12 @@ describe("JsApiReporter", function() {
248
248
  });
249
249
  });
250
250
  });
251
+
252
+ describe('#runDetails', function() {
253
+ it('should have details about the run', function() {
254
+ var reporter = new j$.JsApiReporter({});
255
+ reporter.jasmineDone({some: {run: 'details'}});
256
+ expect(reporter.runDetails).toEqual({some: {run: 'details'}});
257
+ });
258
+ });
251
259
  });
@@ -181,6 +181,14 @@ describe("j$.pp", function () {
181
181
  expect(j$.pp(obj)).toEqual("strung");
182
182
  });
183
183
 
184
+ it("should stringify objects that implement custom toString", function () {
185
+ var obj = {
186
+ toString: function () { return "my toString"; }
187
+ };
188
+
189
+ expect(j$.pp(obj)).toEqual("my toString");
190
+ });
191
+
184
192
  it("should handle objects with null prototype", function() {
185
193
  if (jasmine.getEnv().ieVersion < 9) { return; }
186
194