~ubuntu-branches/debian/sid/wordpress/sid

« back to all changes in this revision

Viewing changes to debian/missing-sources/mediaelement/test/lib/jasmine-1.3.1/jasmine.js

  • Committer: Package Import Robot
  • Author(s): Craig Small
  • Date: 2014-04-16 22:48:26 UTC
  • mfrom: (1.2.34)
  • Revision ID: package-import@ubuntu.com-20140416224826-087tu71aw8bjhvmd
Tags: 3.8.3+dfsg-1
New upstream release - fixes Quick Draft tool that broke in 3.8.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
var isCommonJS = typeof window == "undefined" && typeof exports == "object";
 
2
 
 
3
/**
 
4
 * Top level namespace for Jasmine, a lightweight JavaScript BDD/spec/testing framework.
 
5
 *
 
6
 * @namespace
 
7
 */
 
8
var jasmine = {};
 
9
if (isCommonJS) exports.jasmine = jasmine;
 
10
/**
 
11
 * @private
 
12
 */
 
13
jasmine.unimplementedMethod_ = function() {
 
14
  throw new Error("unimplemented method");
 
15
};
 
16
 
 
17
/**
 
18
 * Use <code>jasmine.undefined</code> instead of <code>undefined</code>, since <code>undefined</code> is just
 
19
 * a plain old variable and may be redefined by somebody else.
 
20
 *
 
21
 * @private
 
22
 */
 
23
jasmine.undefined = jasmine.___undefined___;
 
24
 
 
25
/**
 
26
 * Show diagnostic messages in the console if set to true
 
27
 *
 
28
 */
 
29
jasmine.VERBOSE = false;
 
30
 
 
31
/**
 
32
 * Default interval in milliseconds for event loop yields (e.g. to allow network activity or to refresh the screen with the HTML-based runner). Small values here may result in slow test running. Zero means no updates until all tests have completed.
 
33
 *
 
34
 */
 
35
jasmine.DEFAULT_UPDATE_INTERVAL = 250;
 
36
 
 
37
/**
 
38
 * Maximum levels of nesting that will be included when an object is pretty-printed
 
39
 */
 
40
jasmine.MAX_PRETTY_PRINT_DEPTH = 40;
 
41
 
 
42
/**
 
43
 * Default timeout interval in milliseconds for waitsFor() blocks.
 
44
 */
 
45
jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000;
 
46
 
 
47
/**
 
48
 * By default exceptions thrown in the context of a test are caught by jasmine so that it can run the remaining tests in the suite.
 
49
 * Set to false to let the exception bubble up in the browser.
 
50
 *
 
51
 */
 
52
jasmine.CATCH_EXCEPTIONS = true;
 
53
 
 
54
jasmine.getGlobal = function() {
 
55
  function getGlobal() {
 
56
    return this;
 
57
  }
 
58
 
 
59
  return getGlobal();
 
60
};
 
61
 
 
62
/**
 
63
 * Allows for bound functions to be compared.  Internal use only.
 
64
 *
 
65
 * @ignore
 
66
 * @private
 
67
 * @param base {Object} bound 'this' for the function
 
68
 * @param name {Function} function to find
 
69
 */
 
70
jasmine.bindOriginal_ = function(base, name) {
 
71
  var original = base[name];
 
72
  if (original.apply) {
 
73
    return function() {
 
74
      return original.apply(base, arguments);
 
75
    };
 
76
  } else {
 
77
    // IE support
 
78
    return jasmine.getGlobal()[name];
 
79
  }
 
80
};
 
81
 
 
82
jasmine.setTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'setTimeout');
 
83
jasmine.clearTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearTimeout');
 
84
jasmine.setInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'setInterval');
 
85
jasmine.clearInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearInterval');
 
86
 
 
87
jasmine.MessageResult = function(values) {
 
88
  this.type = 'log';
 
89
  this.values = values;
 
90
  this.trace = new Error(); // todo: test better
 
91
};
 
92
 
 
93
jasmine.MessageResult.prototype.toString = function() {
 
94
  var text = "";
 
95
  for (var i = 0; i < this.values.length; i++) {
 
96
    if (i > 0) text += " ";
 
97
    if (jasmine.isString_(this.values[i])) {
 
98
      text += this.values[i];
 
99
    } else {
 
100
      text += jasmine.pp(this.values[i]);
 
101
    }
 
102
  }
 
103
  return text;
 
104
};
 
105
 
 
106
jasmine.ExpectationResult = function(params) {
 
107
  this.type = 'expect';
 
108
  this.matcherName = params.matcherName;
 
109
  this.passed_ = params.passed;
 
110
  this.expected = params.expected;
 
111
  this.actual = params.actual;
 
112
  this.message = this.passed_ ? 'Passed.' : params.message;
 
113
 
 
114
  var trace = (params.trace || new Error(this.message));
 
115
  this.trace = this.passed_ ? '' : trace;
 
116
};
 
117
 
 
118
jasmine.ExpectationResult.prototype.toString = function () {
 
119
  return this.message;
 
120
};
 
121
 
 
122
jasmine.ExpectationResult.prototype.passed = function () {
 
123
  return this.passed_;
 
124
};
 
125
 
 
126
/**
 
127
 * Getter for the Jasmine environment. Ensures one gets created
 
128
 */
 
129
jasmine.getEnv = function() {
 
130
  var env = jasmine.currentEnv_ = jasmine.currentEnv_ || new jasmine.Env();
 
131
  return env;
 
132
};
 
133
 
 
134
/**
 
135
 * @ignore
 
136
 * @private
 
137
 * @param value
 
138
 * @returns {Boolean}
 
139
 */
 
140
jasmine.isArray_ = function(value) {
 
141
  return jasmine.isA_("Array", value);
 
142
};
 
143
 
 
144
/**
 
145
 * @ignore
 
146
 * @private
 
147
 * @param value
 
148
 * @returns {Boolean}
 
149
 */
 
150
jasmine.isString_ = function(value) {
 
151
  return jasmine.isA_("String", value);
 
152
};
 
153
 
 
154
/**
 
155
 * @ignore
 
156
 * @private
 
157
 * @param value
 
158
 * @returns {Boolean}
 
159
 */
 
160
jasmine.isNumber_ = function(value) {
 
161
  return jasmine.isA_("Number", value);
 
162
};
 
163
 
 
164
/**
 
165
 * @ignore
 
166
 * @private
 
167
 * @param {String} typeName
 
168
 * @param value
 
169
 * @returns {Boolean}
 
170
 */
 
171
jasmine.isA_ = function(typeName, value) {
 
172
  return Object.prototype.toString.apply(value) === '[object ' + typeName + ']';
 
173
};
 
174
 
 
175
/**
 
176
 * Pretty printer for expecations.  Takes any object and turns it into a human-readable string.
 
177
 *
 
178
 * @param value {Object} an object to be outputted
 
179
 * @returns {String}
 
180
 */
 
181
jasmine.pp = function(value) {
 
182
  var stringPrettyPrinter = new jasmine.StringPrettyPrinter();
 
183
  stringPrettyPrinter.format(value);
 
184
  return stringPrettyPrinter.string;
 
185
};
 
186
 
 
187
/**
 
188
 * Returns true if the object is a DOM Node.
 
189
 *
 
190
 * @param {Object} obj object to check
 
191
 * @returns {Boolean}
 
192
 */
 
193
jasmine.isDomNode = function(obj) {
 
194
  return obj.nodeType > 0;
 
195
};
 
196
 
 
197
/**
 
198
 * Returns a matchable 'generic' object of the class type.  For use in expecations of type when values don't matter.
 
199
 *
 
200
 * @example
 
201
 * // don't care about which function is passed in, as long as it's a function
 
202
 * expect(mySpy).toHaveBeenCalledWith(jasmine.any(Function));
 
203
 *
 
204
 * @param {Class} clazz
 
205
 * @returns matchable object of the type clazz
 
206
 */
 
207
jasmine.any = function(clazz) {
 
208
  return new jasmine.Matchers.Any(clazz);
 
209
};
 
210
 
 
211
/**
 
212
 * Returns a matchable subset of a JSON object. For use in expectations when you don't care about all of the
 
213
 * attributes on the object.
 
214
 *
 
215
 * @example
 
216
 * // don't care about any other attributes than foo.
 
217
 * expect(mySpy).toHaveBeenCalledWith(jasmine.objectContaining({foo: "bar"});
 
218
 *
 
219
 * @param sample {Object} sample
 
220
 * @returns matchable object for the sample
 
221
 */
 
222
jasmine.objectContaining = function (sample) {
 
223
    return new jasmine.Matchers.ObjectContaining(sample);
 
224
};
 
225
 
 
226
/**
 
227
 * Jasmine Spies are test doubles that can act as stubs, spies, fakes or when used in an expecation, mocks.
 
228
 *
 
229
 * Spies should be created in test setup, before expectations.  They can then be checked, using the standard Jasmine
 
230
 * expectation syntax. Spies can be checked if they were called or not and what the calling params were.
 
231
 *
 
232
 * A Spy has the following fields: wasCalled, callCount, mostRecentCall, and argsForCall (see docs).
 
233
 *
 
234
 * Spies are torn down at the end of every spec.
 
235
 *
 
236
 * Note: Do <b>not</b> call new jasmine.Spy() directly - a spy must be created using spyOn, jasmine.createSpy or jasmine.createSpyObj.
 
237
 *
 
238
 * @example
 
239
 * // a stub
 
240
 * var myStub = jasmine.createSpy('myStub');  // can be used anywhere
 
241
 *
 
242
 * // spy example
 
243
 * var foo = {
 
244
 *   not: function(bool) { return !bool; }
 
245
 * }
 
246
 *
 
247
 * // actual foo.not will not be called, execution stops
 
248
 * spyOn(foo, 'not');
 
249
 
 
250
 // foo.not spied upon, execution will continue to implementation
 
251
 * spyOn(foo, 'not').andCallThrough();
 
252
 *
 
253
 * // fake example
 
254
 * var foo = {
 
255
 *   not: function(bool) { return !bool; }
 
256
 * }
 
257
 *
 
258
 * // foo.not(val) will return val
 
259
 * spyOn(foo, 'not').andCallFake(function(value) {return value;});
 
260
 *
 
261
 * // mock example
 
262
 * foo.not(7 == 7);
 
263
 * expect(foo.not).toHaveBeenCalled();
 
264
 * expect(foo.not).toHaveBeenCalledWith(true);
 
265
 *
 
266
 * @constructor
 
267
 * @see spyOn, jasmine.createSpy, jasmine.createSpyObj
 
268
 * @param {String} name
 
269
 */
 
270
jasmine.Spy = function(name) {
 
271
  /**
 
272
   * The name of the spy, if provided.
 
273
   */
 
274
  this.identity = name || 'unknown';
 
275
  /**
 
276
   *  Is this Object a spy?
 
277
   */
 
278
  this.isSpy = true;
 
279
  /**
 
280
   * The actual function this spy stubs.
 
281
   */
 
282
  this.plan = function() {
 
283
  };
 
284
  /**
 
285
   * Tracking of the most recent call to the spy.
 
286
   * @example
 
287
   * var mySpy = jasmine.createSpy('foo');
 
288
   * mySpy(1, 2);
 
289
   * mySpy.mostRecentCall.args = [1, 2];
 
290
   */
 
291
  this.mostRecentCall = {};
 
292
 
 
293
  /**
 
294
   * Holds arguments for each call to the spy, indexed by call count
 
295
   * @example
 
296
   * var mySpy = jasmine.createSpy('foo');
 
297
   * mySpy(1, 2);
 
298
   * mySpy(7, 8);
 
299
   * mySpy.mostRecentCall.args = [7, 8];
 
300
   * mySpy.argsForCall[0] = [1, 2];
 
301
   * mySpy.argsForCall[1] = [7, 8];
 
302
   */
 
303
  this.argsForCall = [];
 
304
  this.calls = [];
 
305
};
 
306
 
 
307
/**
 
308
 * Tells a spy to call through to the actual implemenatation.
 
309
 *
 
310
 * @example
 
311
 * var foo = {
 
312
 *   bar: function() { // do some stuff }
 
313
 * }
 
314
 *
 
315
 * // defining a spy on an existing property: foo.bar
 
316
 * spyOn(foo, 'bar').andCallThrough();
 
317
 */
 
318
jasmine.Spy.prototype.andCallThrough = function() {
 
319
  this.plan = this.originalValue;
 
320
  return this;
 
321
};
 
322
 
 
323
/**
 
324
 * For setting the return value of a spy.
 
325
 *
 
326
 * @example
 
327
 * // defining a spy from scratch: foo() returns 'baz'
 
328
 * var foo = jasmine.createSpy('spy on foo').andReturn('baz');
 
329
 *
 
330
 * // defining a spy on an existing property: foo.bar() returns 'baz'
 
331
 * spyOn(foo, 'bar').andReturn('baz');
 
332
 *
 
333
 * @param {Object} value
 
334
 */
 
335
jasmine.Spy.prototype.andReturn = function(value) {
 
336
  this.plan = function() {
 
337
    return value;
 
338
  };
 
339
  return this;
 
340
};
 
341
 
 
342
/**
 
343
 * For throwing an exception when a spy is called.
 
344
 *
 
345
 * @example
 
346
 * // defining a spy from scratch: foo() throws an exception w/ message 'ouch'
 
347
 * var foo = jasmine.createSpy('spy on foo').andThrow('baz');
 
348
 *
 
349
 * // defining a spy on an existing property: foo.bar() throws an exception w/ message 'ouch'
 
350
 * spyOn(foo, 'bar').andThrow('baz');
 
351
 *
 
352
 * @param {String} exceptionMsg
 
353
 */
 
354
jasmine.Spy.prototype.andThrow = function(exceptionMsg) {
 
355
  this.plan = function() {
 
356
    throw exceptionMsg;
 
357
  };
 
358
  return this;
 
359
};
 
360
 
 
361
/**
 
362
 * Calls an alternate implementation when a spy is called.
 
363
 *
 
364
 * @example
 
365
 * var baz = function() {
 
366
 *   // do some stuff, return something
 
367
 * }
 
368
 * // defining a spy from scratch: foo() calls the function baz
 
369
 * var foo = jasmine.createSpy('spy on foo').andCall(baz);
 
370
 *
 
371
 * // defining a spy on an existing property: foo.bar() calls an anonymnous function
 
372
 * spyOn(foo, 'bar').andCall(function() { return 'baz';} );
 
373
 *
 
374
 * @param {Function} fakeFunc
 
375
 */
 
376
jasmine.Spy.prototype.andCallFake = function(fakeFunc) {
 
377
  this.plan = fakeFunc;
 
378
  return this;
 
379
};
 
380
 
 
381
/**
 
382
 * Resets all of a spy's the tracking variables so that it can be used again.
 
383
 *
 
384
 * @example
 
385
 * spyOn(foo, 'bar');
 
386
 *
 
387
 * foo.bar();
 
388
 *
 
389
 * expect(foo.bar.callCount).toEqual(1);
 
390
 *
 
391
 * foo.bar.reset();
 
392
 *
 
393
 * expect(foo.bar.callCount).toEqual(0);
 
394
 */
 
395
jasmine.Spy.prototype.reset = function() {
 
396
  this.wasCalled = false;
 
397
  this.callCount = 0;
 
398
  this.argsForCall = [];
 
399
  this.calls = [];
 
400
  this.mostRecentCall = {};
 
401
};
 
402
 
 
403
jasmine.createSpy = function(name) {
 
404
 
 
405
  var spyObj = function() {
 
406
    spyObj.wasCalled = true;
 
407
    spyObj.callCount++;
 
408
    var args = jasmine.util.argsToArray(arguments);
 
409
    spyObj.mostRecentCall.object = this;
 
410
    spyObj.mostRecentCall.args = args;
 
411
    spyObj.argsForCall.push(args);
 
412
    spyObj.calls.push({object: this, args: args});
 
413
    return spyObj.plan.apply(this, arguments);
 
414
  };
 
415
 
 
416
  var spy = new jasmine.Spy(name);
 
417
 
 
418
  for (var prop in spy) {
 
419
    spyObj[prop] = spy[prop];
 
420
  }
 
421
 
 
422
  spyObj.reset();
 
423
 
 
424
  return spyObj;
 
425
};
 
426
 
 
427
/**
 
428
 * Determines whether an object is a spy.
 
429
 *
 
430
 * @param {jasmine.Spy|Object} putativeSpy
 
431
 * @returns {Boolean}
 
432
 */
 
433
jasmine.isSpy = function(putativeSpy) {
 
434
  return putativeSpy && putativeSpy.isSpy;
 
435
};
 
436
 
 
437
/**
 
438
 * Creates a more complicated spy: an Object that has every property a function that is a spy.  Used for stubbing something
 
439
 * large in one call.
 
440
 *
 
441
 * @param {String} baseName name of spy class
 
442
 * @param {Array} methodNames array of names of methods to make spies
 
443
 */
 
444
jasmine.createSpyObj = function(baseName, methodNames) {
 
445
  if (!jasmine.isArray_(methodNames) || methodNames.length === 0) {
 
446
    throw new Error('createSpyObj requires a non-empty array of method names to create spies for');
 
447
  }
 
448
  var obj = {};
 
449
  for (var i = 0; i < methodNames.length; i++) {
 
450
    obj[methodNames[i]] = jasmine.createSpy(baseName + '.' + methodNames[i]);
 
451
  }
 
452
  return obj;
 
453
};
 
454
 
 
455
/**
 
456
 * All parameters are pretty-printed and concatenated together, then written to the current spec's output.
 
457
 *
 
458
 * Be careful not to leave calls to <code>jasmine.log</code> in production code.
 
459
 */
 
460
jasmine.log = function() {
 
461
  var spec = jasmine.getEnv().currentSpec;
 
462
  spec.log.apply(spec, arguments);
 
463
};
 
464
 
 
465
/**
 
466
 * Function that installs a spy on an existing object's method name.  Used within a Spec to create a spy.
 
467
 *
 
468
 * @example
 
469
 * // spy example
 
470
 * var foo = {
 
471
 *   not: function(bool) { return !bool; }
 
472
 * }
 
473
 * spyOn(foo, 'not'); // actual foo.not will not be called, execution stops
 
474
 *
 
475
 * @see jasmine.createSpy
 
476
 * @param obj
 
477
 * @param methodName
 
478
 * @return {jasmine.Spy} a Jasmine spy that can be chained with all spy methods
 
479
 */
 
480
var spyOn = function(obj, methodName) {
 
481
  return jasmine.getEnv().currentSpec.spyOn(obj, methodName);
 
482
};
 
483
if (isCommonJS) exports.spyOn = spyOn;
 
484
 
 
485
/**
 
486
 * Creates a Jasmine spec that will be added to the current suite.
 
487
 *
 
488
 * // TODO: pending tests
 
489
 *
 
490
 * @example
 
491
 * it('should be true', function() {
 
492
 *   expect(true).toEqual(true);
 
493
 * });
 
494
 *
 
495
 * @param {String} desc description of this specification
 
496
 * @param {Function} func defines the preconditions and expectations of the spec
 
497
 */
 
498
var it = function(desc, func) {
 
499
  return jasmine.getEnv().it(desc, func);
 
500
};
 
501
if (isCommonJS) exports.it = it;
 
502
 
 
503
/**
 
504
 * Creates a <em>disabled</em> Jasmine spec.
 
505
 *
 
506
 * A convenience method that allows existing specs to be disabled temporarily during development.
 
507
 *
 
508
 * @param {String} desc description of this specification
 
509
 * @param {Function} func defines the preconditions and expectations of the spec
 
510
 */
 
511
var xit = function(desc, func) {
 
512
  return jasmine.getEnv().xit(desc, func);
 
513
};
 
514
if (isCommonJS) exports.xit = xit;
 
515
 
 
516
/**
 
517
 * Starts a chain for a Jasmine expectation.
 
518
 *
 
519
 * It is passed an Object that is the actual value and should chain to one of the many
 
520
 * jasmine.Matchers functions.
 
521
 *
 
522
 * @param {Object} actual Actual value to test against and expected value
 
523
 * @return {jasmine.Matchers}
 
524
 */
 
525
var expect = function(actual) {
 
526
  return jasmine.getEnv().currentSpec.expect(actual);
 
527
};
 
528
if (isCommonJS) exports.expect = expect;
 
529
 
 
530
/**
 
531
 * Defines part of a jasmine spec.  Used in cominbination with waits or waitsFor in asynchrnous specs.
 
532
 *
 
533
 * @param {Function} func Function that defines part of a jasmine spec.
 
534
 */
 
535
var runs = function(func) {
 
536
  jasmine.getEnv().currentSpec.runs(func);
 
537
};
 
538
if (isCommonJS) exports.runs = runs;
 
539
 
 
540
/**
 
541
 * Waits a fixed time period before moving to the next block.
 
542
 *
 
543
 * @deprecated Use waitsFor() instead
 
544
 * @param {Number} timeout milliseconds to wait
 
545
 */
 
546
var waits = function(timeout) {
 
547
  jasmine.getEnv().currentSpec.waits(timeout);
 
548
};
 
549
if (isCommonJS) exports.waits = waits;
 
550
 
 
551
/**
 
552
 * Waits for the latchFunction to return true before proceeding to the next block.
 
553
 *
 
554
 * @param {Function} latchFunction
 
555
 * @param {String} optional_timeoutMessage
 
556
 * @param {Number} optional_timeout
 
557
 */
 
558
var waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) {
 
559
  jasmine.getEnv().currentSpec.waitsFor.apply(jasmine.getEnv().currentSpec, arguments);
 
560
};
 
561
if (isCommonJS) exports.waitsFor = waitsFor;
 
562
 
 
563
/**
 
564
 * A function that is called before each spec in a suite.
 
565
 *
 
566
 * Used for spec setup, including validating assumptions.
 
567
 *
 
568
 * @param {Function} beforeEachFunction
 
569
 */
 
570
var beforeEach = function(beforeEachFunction) {
 
571
  jasmine.getEnv().beforeEach(beforeEachFunction);
 
572
};
 
573
if (isCommonJS) exports.beforeEach = beforeEach;
 
574
 
 
575
/**
 
576
 * A function that is called after each spec in a suite.
 
577
 *
 
578
 * Used for restoring any state that is hijacked during spec execution.
 
579
 *
 
580
 * @param {Function} afterEachFunction
 
581
 */
 
582
var afterEach = function(afterEachFunction) {
 
583
  jasmine.getEnv().afterEach(afterEachFunction);
 
584
};
 
585
if (isCommonJS) exports.afterEach = afterEach;
 
586
 
 
587
/**
 
588
 * Defines a suite of specifications.
 
589
 *
 
590
 * Stores the description and all defined specs in the Jasmine environment as one suite of specs. Variables declared
 
591
 * are accessible by calls to beforeEach, it, and afterEach. Describe blocks can be nested, allowing for specialization
 
592
 * of setup in some tests.
 
593
 *
 
594
 * @example
 
595
 * // TODO: a simple suite
 
596
 *
 
597
 * // TODO: a simple suite with a nested describe block
 
598
 *
 
599
 * @param {String} description A string, usually the class under test.
 
600
 * @param {Function} specDefinitions function that defines several specs.
 
601
 */
 
602
var describe = function(description, specDefinitions) {
 
603
  return jasmine.getEnv().describe(description, specDefinitions);
 
604
};
 
605
if (isCommonJS) exports.describe = describe;
 
606
 
 
607
/**
 
608
 * Disables a suite of specifications.  Used to disable some suites in a file, or files, temporarily during development.
 
609
 *
 
610
 * @param {String} description A string, usually the class under test.
 
611
 * @param {Function} specDefinitions function that defines several specs.
 
612
 */
 
613
var xdescribe = function(description, specDefinitions) {
 
614
  return jasmine.getEnv().xdescribe(description, specDefinitions);
 
615
};
 
616
if (isCommonJS) exports.xdescribe = xdescribe;
 
617
 
 
618
 
 
619
// Provide the XMLHttpRequest class for IE 5.x-6.x:
 
620
jasmine.XmlHttpRequest = (typeof XMLHttpRequest == "undefined") ? function() {
 
621
  function tryIt(f) {
 
622
    try {
 
623
      return f();
 
624
    } catch(e) {
 
625
    }
 
626
    return null;
 
627
  }
 
628
 
 
629
  var xhr = tryIt(function() {
 
630
    return new ActiveXObject("Msxml2.XMLHTTP.6.0");
 
631
  }) ||
 
632
    tryIt(function() {
 
633
      return new ActiveXObject("Msxml2.XMLHTTP.3.0");
 
634
    }) ||
 
635
    tryIt(function() {
 
636
      return new ActiveXObject("Msxml2.XMLHTTP");
 
637
    }) ||
 
638
    tryIt(function() {
 
639
      return new ActiveXObject("Microsoft.XMLHTTP");
 
640
    });
 
641
 
 
642
  if (!xhr) throw new Error("This browser does not support XMLHttpRequest.");
 
643
 
 
644
  return xhr;
 
645
} : XMLHttpRequest;
 
646
/**
 
647
 * @namespace
 
648
 */
 
649
jasmine.util = {};
 
650
 
 
651
/**
 
652
 * Declare that a child class inherit it's prototype from the parent class.
 
653
 *
 
654
 * @private
 
655
 * @param {Function} childClass
 
656
 * @param {Function} parentClass
 
657
 */
 
658
jasmine.util.inherit = function(childClass, parentClass) {
 
659
  /**
 
660
   * @private
 
661
   */
 
662
  var subclass = function() {
 
663
  };
 
664
  subclass.prototype = parentClass.prototype;
 
665
  childClass.prototype = new subclass();
 
666
};
 
667
 
 
668
jasmine.util.formatException = function(e) {
 
669
  var lineNumber;
 
670
  if (e.line) {
 
671
    lineNumber = e.line;
 
672
  }
 
673
  else if (e.lineNumber) {
 
674
    lineNumber = e.lineNumber;
 
675
  }
 
676
 
 
677
  var file;
 
678
 
 
679
  if (e.sourceURL) {
 
680
    file = e.sourceURL;
 
681
  }
 
682
  else if (e.fileName) {
 
683
    file = e.fileName;
 
684
  }
 
685
 
 
686
  var message = (e.name && e.message) ? (e.name + ': ' + e.message) : e.toString();
 
687
 
 
688
  if (file && lineNumber) {
 
689
    message += ' in ' + file + ' (line ' + lineNumber + ')';
 
690
  }
 
691
 
 
692
  return message;
 
693
};
 
694
 
 
695
jasmine.util.htmlEscape = function(str) {
 
696
  if (!str) return str;
 
697
  return str.replace(/&/g, '&amp;')
 
698
    .replace(/</g, '&lt;')
 
699
    .replace(/>/g, '&gt;');
 
700
};
 
701
 
 
702
jasmine.util.argsToArray = function(args) {
 
703
  var arrayOfArgs = [];
 
704
  for (var i = 0; i < args.length; i++) arrayOfArgs.push(args[i]);
 
705
  return arrayOfArgs;
 
706
};
 
707
 
 
708
jasmine.util.extend = function(destination, source) {
 
709
  for (var property in source) destination[property] = source[property];
 
710
  return destination;
 
711
};
 
712
 
 
713
/**
 
714
 * Environment for Jasmine
 
715
 *
 
716
 * @constructor
 
717
 */
 
718
jasmine.Env = function() {
 
719
  this.currentSpec = null;
 
720
  this.currentSuite = null;
 
721
  this.currentRunner_ = new jasmine.Runner(this);
 
722
 
 
723
  this.reporter = new jasmine.MultiReporter();
 
724
 
 
725
  this.updateInterval = jasmine.DEFAULT_UPDATE_INTERVAL;
 
726
  this.defaultTimeoutInterval = jasmine.DEFAULT_TIMEOUT_INTERVAL;
 
727
  this.lastUpdate = 0;
 
728
  this.specFilter = function() {
 
729
    return true;
 
730
  };
 
731
 
 
732
  this.nextSpecId_ = 0;
 
733
  this.nextSuiteId_ = 0;
 
734
  this.equalityTesters_ = [];
 
735
 
 
736
  // wrap matchers
 
737
  this.matchersClass = function() {
 
738
    jasmine.Matchers.apply(this, arguments);
 
739
  };
 
740
  jasmine.util.inherit(this.matchersClass, jasmine.Matchers);
 
741
 
 
742
  jasmine.Matchers.wrapInto_(jasmine.Matchers.prototype, this.matchersClass);
 
743
};
 
744
 
 
745
 
 
746
jasmine.Env.prototype.setTimeout = jasmine.setTimeout;
 
747
jasmine.Env.prototype.clearTimeout = jasmine.clearTimeout;
 
748
jasmine.Env.prototype.setInterval = jasmine.setInterval;
 
749
jasmine.Env.prototype.clearInterval = jasmine.clearInterval;
 
750
 
 
751
/**
 
752
 * @returns an object containing jasmine version build info, if set.
 
753
 */
 
754
jasmine.Env.prototype.version = function () {
 
755
  if (jasmine.version_) {
 
756
    return jasmine.version_;
 
757
  } else {
 
758
    throw new Error('Version not set');
 
759
  }
 
760
};
 
761
 
 
762
/**
 
763
 * @returns string containing jasmine version build info, if set.
 
764
 */
 
765
jasmine.Env.prototype.versionString = function() {
 
766
  if (!jasmine.version_) {
 
767
    return "version unknown";
 
768
  }
 
769
 
 
770
  var version = this.version();
 
771
  var versionString = version.major + "." + version.minor + "." + version.build;
 
772
  if (version.release_candidate) {
 
773
    versionString += ".rc" + version.release_candidate;
 
774
  }
 
775
  versionString += " revision " + version.revision;
 
776
  return versionString;
 
777
};
 
778
 
 
779
/**
 
780
 * @returns a sequential integer starting at 0
 
781
 */
 
782
jasmine.Env.prototype.nextSpecId = function () {
 
783
  return this.nextSpecId_++;
 
784
};
 
785
 
 
786
/**
 
787
 * @returns a sequential integer starting at 0
 
788
 */
 
789
jasmine.Env.prototype.nextSuiteId = function () {
 
790
  return this.nextSuiteId_++;
 
791
};
 
792
 
 
793
/**
 
794
 * Register a reporter to receive status updates from Jasmine.
 
795
 * @param {jasmine.Reporter} reporter An object which will receive status updates.
 
796
 */
 
797
jasmine.Env.prototype.addReporter = function(reporter) {
 
798
  this.reporter.addReporter(reporter);
 
799
};
 
800
 
 
801
jasmine.Env.prototype.execute = function() {
 
802
  this.currentRunner_.execute();
 
803
};
 
804
 
 
805
jasmine.Env.prototype.describe = function(description, specDefinitions) {
 
806
  var suite = new jasmine.Suite(this, description, specDefinitions, this.currentSuite);
 
807
 
 
808
  var parentSuite = this.currentSuite;
 
809
  if (parentSuite) {
 
810
    parentSuite.add(suite);
 
811
  } else {
 
812
    this.currentRunner_.add(suite);
 
813
  }
 
814
 
 
815
  this.currentSuite = suite;
 
816
 
 
817
  var declarationError = null;
 
818
  try {
 
819
    specDefinitions.call(suite);
 
820
  } catch(e) {
 
821
    declarationError = e;
 
822
  }
 
823
 
 
824
  if (declarationError) {
 
825
    this.it("encountered a declaration exception", function() {
 
826
      throw declarationError;
 
827
    });
 
828
  }
 
829
 
 
830
  this.currentSuite = parentSuite;
 
831
 
 
832
  return suite;
 
833
};
 
834
 
 
835
jasmine.Env.prototype.beforeEach = function(beforeEachFunction) {
 
836
  if (this.currentSuite) {
 
837
    this.currentSuite.beforeEach(beforeEachFunction);
 
838
  } else {
 
839
    this.currentRunner_.beforeEach(beforeEachFunction);
 
840
  }
 
841
};
 
842
 
 
843
jasmine.Env.prototype.currentRunner = function () {
 
844
  return this.currentRunner_;
 
845
};
 
846
 
 
847
jasmine.Env.prototype.afterEach = function(afterEachFunction) {
 
848
  if (this.currentSuite) {
 
849
    this.currentSuite.afterEach(afterEachFunction);
 
850
  } else {
 
851
    this.currentRunner_.afterEach(afterEachFunction);
 
852
  }
 
853
 
 
854
};
 
855
 
 
856
jasmine.Env.prototype.xdescribe = function(desc, specDefinitions) {
 
857
  return {
 
858
    execute: function() {
 
859
    }
 
860
  };
 
861
};
 
862
 
 
863
jasmine.Env.prototype.it = function(description, func) {
 
864
  var spec = new jasmine.Spec(this, this.currentSuite, description);
 
865
  this.currentSuite.add(spec);
 
866
  this.currentSpec = spec;
 
867
 
 
868
  if (func) {
 
869
    spec.runs(func);
 
870
  }
 
871
 
 
872
  return spec;
 
873
};
 
874
 
 
875
jasmine.Env.prototype.xit = function(desc, func) {
 
876
  return {
 
877
    id: this.nextSpecId(),
 
878
    runs: function() {
 
879
    }
 
880
  };
 
881
};
 
882
 
 
883
jasmine.Env.prototype.compareRegExps_ = function(a, b, mismatchKeys, mismatchValues) {
 
884
  if (a.source != b.source)
 
885
    mismatchValues.push("expected pattern /" + b.source + "/ is not equal to the pattern /" + a.source + "/");
 
886
 
 
887
  if (a.ignoreCase != b.ignoreCase)
 
888
    mismatchValues.push("expected modifier i was" + (b.ignoreCase ? " " : " not ") + "set and does not equal the origin modifier");
 
889
 
 
890
  if (a.global != b.global)
 
891
    mismatchValues.push("expected modifier g was" + (b.global ? " " : " not ") + "set and does not equal the origin modifier");
 
892
 
 
893
  if (a.multiline != b.multiline)
 
894
    mismatchValues.push("expected modifier m was" + (b.multiline ? " " : " not ") + "set and does not equal the origin modifier");
 
895
 
 
896
  if (a.sticky != b.sticky)
 
897
    mismatchValues.push("expected modifier y was" + (b.sticky ? " " : " not ") + "set and does not equal the origin modifier");
 
898
 
 
899
  return (mismatchValues.length === 0);
 
900
};
 
901
 
 
902
jasmine.Env.prototype.compareObjects_ = function(a, b, mismatchKeys, mismatchValues) {
 
903
  if (a.__Jasmine_been_here_before__ === b && b.__Jasmine_been_here_before__ === a) {
 
904
    return true;
 
905
  }
 
906
 
 
907
  a.__Jasmine_been_here_before__ = b;
 
908
  b.__Jasmine_been_here_before__ = a;
 
909
 
 
910
  var hasKey = function(obj, keyName) {
 
911
    return obj !== null && obj[keyName] !== jasmine.undefined;
 
912
  };
 
913
 
 
914
  for (var property in b) {
 
915
    if (!hasKey(a, property) && hasKey(b, property)) {
 
916
      mismatchKeys.push("expected has key '" + property + "', but missing from actual.");
 
917
    }
 
918
  }
 
919
  for (property in a) {
 
920
    if (!hasKey(b, property) && hasKey(a, property)) {
 
921
      mismatchKeys.push("expected missing key '" + property + "', but present in actual.");
 
922
    }
 
923
  }
 
924
  for (property in b) {
 
925
    if (property == '__Jasmine_been_here_before__') continue;
 
926
    if (!this.equals_(a[property], b[property], mismatchKeys, mismatchValues)) {
 
927
      mismatchValues.push("'" + property + "' was '" + (b[property] ? jasmine.util.htmlEscape(b[property].toString()) : b[property]) + "' in expected, but was '" + (a[property] ? jasmine.util.htmlEscape(a[property].toString()) : a[property]) + "' in actual.");
 
928
    }
 
929
  }
 
930
 
 
931
  if (jasmine.isArray_(a) && jasmine.isArray_(b) && a.length != b.length) {
 
932
    mismatchValues.push("arrays were not the same length");
 
933
  }
 
934
 
 
935
  delete a.__Jasmine_been_here_before__;
 
936
  delete b.__Jasmine_been_here_before__;
 
937
  return (mismatchKeys.length === 0 && mismatchValues.length === 0);
 
938
};
 
939
 
 
940
jasmine.Env.prototype.equals_ = function(a, b, mismatchKeys, mismatchValues) {
 
941
  mismatchKeys = mismatchKeys || [];
 
942
  mismatchValues = mismatchValues || [];
 
943
 
 
944
  for (var i = 0; i < this.equalityTesters_.length; i++) {
 
945
    var equalityTester = this.equalityTesters_[i];
 
946
    var result = equalityTester(a, b, this, mismatchKeys, mismatchValues);
 
947
    if (result !== jasmine.undefined) return result;
 
948
  }
 
949
 
 
950
  if (a === b) return true;
 
951
 
 
952
  if (a === jasmine.undefined || a === null || b === jasmine.undefined || b === null) {
 
953
    return (a == jasmine.undefined && b == jasmine.undefined);
 
954
  }
 
955
 
 
956
  if (jasmine.isDomNode(a) && jasmine.isDomNode(b)) {
 
957
    return a === b;
 
958
  }
 
959
 
 
960
  if (a instanceof Date && b instanceof Date) {
 
961
    return a.getTime() == b.getTime();
 
962
  }
 
963
 
 
964
  if (a.jasmineMatches) {
 
965
    return a.jasmineMatches(b);
 
966
  }
 
967
 
 
968
  if (b.jasmineMatches) {
 
969
    return b.jasmineMatches(a);
 
970
  }
 
971
 
 
972
  if (a instanceof jasmine.Matchers.ObjectContaining) {
 
973
    return a.matches(b);
 
974
  }
 
975
 
 
976
  if (b instanceof jasmine.Matchers.ObjectContaining) {
 
977
    return b.matches(a);
 
978
  }
 
979
 
 
980
  if (jasmine.isString_(a) && jasmine.isString_(b)) {
 
981
    return (a == b);
 
982
  }
 
983
 
 
984
  if (jasmine.isNumber_(a) && jasmine.isNumber_(b)) {
 
985
    return (a == b);
 
986
  }
 
987
 
 
988
  if (a instanceof RegExp && b instanceof RegExp) {
 
989
    return this.compareRegExps_(a, b, mismatchKeys, mismatchValues);
 
990
  }
 
991
 
 
992
  if (typeof a === "object" && typeof b === "object") {
 
993
    return this.compareObjects_(a, b, mismatchKeys, mismatchValues);
 
994
  }
 
995
 
 
996
  //Straight check
 
997
  return (a === b);
 
998
};
 
999
 
 
1000
jasmine.Env.prototype.contains_ = function(haystack, needle) {
 
1001
  if (jasmine.isArray_(haystack)) {
 
1002
    for (var i = 0; i < haystack.length; i++) {
 
1003
      if (this.equals_(haystack[i], needle)) return true;
 
1004
    }
 
1005
    return false;
 
1006
  }
 
1007
  return haystack.indexOf(needle) >= 0;
 
1008
};
 
1009
 
 
1010
jasmine.Env.prototype.addEqualityTester = function(equalityTester) {
 
1011
  this.equalityTesters_.push(equalityTester);
 
1012
};
 
1013
/** No-op base class for Jasmine reporters.
 
1014
 *
 
1015
 * @constructor
 
1016
 */
 
1017
jasmine.Reporter = function() {
 
1018
};
 
1019
 
 
1020
//noinspection JSUnusedLocalSymbols
 
1021
jasmine.Reporter.prototype.reportRunnerStarting = function(runner) {
 
1022
};
 
1023
 
 
1024
//noinspection JSUnusedLocalSymbols
 
1025
jasmine.Reporter.prototype.reportRunnerResults = function(runner) {
 
1026
};
 
1027
 
 
1028
//noinspection JSUnusedLocalSymbols
 
1029
jasmine.Reporter.prototype.reportSuiteResults = function(suite) {
 
1030
};
 
1031
 
 
1032
//noinspection JSUnusedLocalSymbols
 
1033
jasmine.Reporter.prototype.reportSpecStarting = function(spec) {
 
1034
};
 
1035
 
 
1036
//noinspection JSUnusedLocalSymbols
 
1037
jasmine.Reporter.prototype.reportSpecResults = function(spec) {
 
1038
};
 
1039
 
 
1040
//noinspection JSUnusedLocalSymbols
 
1041
jasmine.Reporter.prototype.log = function(str) {
 
1042
};
 
1043
 
 
1044
/**
 
1045
 * Blocks are functions with executable code that make up a spec.
 
1046
 *
 
1047
 * @constructor
 
1048
 * @param {jasmine.Env} env
 
1049
 * @param {Function} func
 
1050
 * @param {jasmine.Spec} spec
 
1051
 */
 
1052
jasmine.Block = function(env, func, spec) {
 
1053
  this.env = env;
 
1054
  this.func = func;
 
1055
  this.spec = spec;
 
1056
};
 
1057
 
 
1058
jasmine.Block.prototype.execute = function(onComplete) {
 
1059
  if (!jasmine.CATCH_EXCEPTIONS) {
 
1060
    this.func.apply(this.spec);
 
1061
  }
 
1062
  else {
 
1063
    try {
 
1064
      this.func.apply(this.spec);
 
1065
    } catch (e) {
 
1066
      this.spec.fail(e);
 
1067
    }
 
1068
  }
 
1069
  onComplete();
 
1070
};
 
1071
/** JavaScript API reporter.
 
1072
 *
 
1073
 * @constructor
 
1074
 */
 
1075
jasmine.JsApiReporter = function() {
 
1076
  this.started = false;
 
1077
  this.finished = false;
 
1078
  this.suites_ = [];
 
1079
  this.results_ = {};
 
1080
};
 
1081
 
 
1082
jasmine.JsApiReporter.prototype.reportRunnerStarting = function(runner) {
 
1083
  this.started = true;
 
1084
  var suites = runner.topLevelSuites();
 
1085
  for (var i = 0; i < suites.length; i++) {
 
1086
    var suite = suites[i];
 
1087
    this.suites_.push(this.summarize_(suite));
 
1088
  }
 
1089
};
 
1090
 
 
1091
jasmine.JsApiReporter.prototype.suites = function() {
 
1092
  return this.suites_;
 
1093
};
 
1094
 
 
1095
jasmine.JsApiReporter.prototype.summarize_ = function(suiteOrSpec) {
 
1096
  var isSuite = suiteOrSpec instanceof jasmine.Suite;
 
1097
  var summary = {
 
1098
    id: suiteOrSpec.id,
 
1099
    name: suiteOrSpec.description,
 
1100
    type: isSuite ? 'suite' : 'spec',
 
1101
    children: []
 
1102
  };
 
1103
  
 
1104
  if (isSuite) {
 
1105
    var children = suiteOrSpec.children();
 
1106
    for (var i = 0; i < children.length; i++) {
 
1107
      summary.children.push(this.summarize_(children[i]));
 
1108
    }
 
1109
  }
 
1110
  return summary;
 
1111
};
 
1112
 
 
1113
jasmine.JsApiReporter.prototype.results = function() {
 
1114
  return this.results_;
 
1115
};
 
1116
 
 
1117
jasmine.JsApiReporter.prototype.resultsForSpec = function(specId) {
 
1118
  return this.results_[specId];
 
1119
};
 
1120
 
 
1121
//noinspection JSUnusedLocalSymbols
 
1122
jasmine.JsApiReporter.prototype.reportRunnerResults = function(runner) {
 
1123
  this.finished = true;
 
1124
};
 
1125
 
 
1126
//noinspection JSUnusedLocalSymbols
 
1127
jasmine.JsApiReporter.prototype.reportSuiteResults = function(suite) {
 
1128
};
 
1129
 
 
1130
//noinspection JSUnusedLocalSymbols
 
1131
jasmine.JsApiReporter.prototype.reportSpecResults = function(spec) {
 
1132
  this.results_[spec.id] = {
 
1133
    messages: spec.results().getItems(),
 
1134
    result: spec.results().failedCount > 0 ? "failed" : "passed"
 
1135
  };
 
1136
};
 
1137
 
 
1138
//noinspection JSUnusedLocalSymbols
 
1139
jasmine.JsApiReporter.prototype.log = function(str) {
 
1140
};
 
1141
 
 
1142
jasmine.JsApiReporter.prototype.resultsForSpecs = function(specIds){
 
1143
  var results = {};
 
1144
  for (var i = 0; i < specIds.length; i++) {
 
1145
    var specId = specIds[i];
 
1146
    results[specId] = this.summarizeResult_(this.results_[specId]);
 
1147
  }
 
1148
  return results;
 
1149
};
 
1150
 
 
1151
jasmine.JsApiReporter.prototype.summarizeResult_ = function(result){
 
1152
  var summaryMessages = [];
 
1153
  var messagesLength = result.messages.length;
 
1154
  for (var messageIndex = 0; messageIndex < messagesLength; messageIndex++) {
 
1155
    var resultMessage = result.messages[messageIndex];
 
1156
    summaryMessages.push({
 
1157
      text: resultMessage.type == 'log' ? resultMessage.toString() : jasmine.undefined,
 
1158
      passed: resultMessage.passed ? resultMessage.passed() : true,
 
1159
      type: resultMessage.type,
 
1160
      message: resultMessage.message,
 
1161
      trace: {
 
1162
        stack: resultMessage.passed && !resultMessage.passed() ? resultMessage.trace.stack : jasmine.undefined
 
1163
      }
 
1164
    });
 
1165
  }
 
1166
 
 
1167
  return {
 
1168
    result : result.result,
 
1169
    messages : summaryMessages
 
1170
  };
 
1171
};
 
1172
 
 
1173
/**
 
1174
 * @constructor
 
1175
 * @param {jasmine.Env} env
 
1176
 * @param actual
 
1177
 * @param {jasmine.Spec} spec
 
1178
 */
 
1179
jasmine.Matchers = function(env, actual, spec, opt_isNot) {
 
1180
  this.env = env;
 
1181
  this.actual = actual;
 
1182
  this.spec = spec;
 
1183
  this.isNot = opt_isNot || false;
 
1184
  this.reportWasCalled_ = false;
 
1185
};
 
1186
 
 
1187
// todo: @deprecated as of Jasmine 0.11, remove soon [xw]
 
1188
jasmine.Matchers.pp = function(str) {
 
1189
  throw new Error("jasmine.Matchers.pp() is no longer supported, please use jasmine.pp() instead!");
 
1190
};
 
1191
 
 
1192
// todo: @deprecated Deprecated as of Jasmine 0.10. Rewrite your custom matchers to return true or false. [xw]
 
1193
jasmine.Matchers.prototype.report = function(result, failing_message, details) {
 
1194
  throw new Error("As of jasmine 0.11, custom matchers must be implemented differently -- please see jasmine docs");
 
1195
};
 
1196
 
 
1197
jasmine.Matchers.wrapInto_ = function(prototype, matchersClass) {
 
1198
  for (var methodName in prototype) {
 
1199
    if (methodName == 'report') continue;
 
1200
    var orig = prototype[methodName];
 
1201
    matchersClass.prototype[methodName] = jasmine.Matchers.matcherFn_(methodName, orig);
 
1202
  }
 
1203
};
 
1204
 
 
1205
jasmine.Matchers.matcherFn_ = function(matcherName, matcherFunction) {
 
1206
  return function() {
 
1207
    var matcherArgs = jasmine.util.argsToArray(arguments);
 
1208
    var result = matcherFunction.apply(this, arguments);
 
1209
 
 
1210
    if (this.isNot) {
 
1211
      result = !result;
 
1212
    }
 
1213
 
 
1214
    if (this.reportWasCalled_) return result;
 
1215
 
 
1216
    var message;
 
1217
    if (!result) {
 
1218
      if (this.message) {
 
1219
        message = this.message.apply(this, arguments);
 
1220
        if (jasmine.isArray_(message)) {
 
1221
          message = message[this.isNot ? 1 : 0];
 
1222
        }
 
1223
      } else {
 
1224
        var englishyPredicate = matcherName.replace(/[A-Z]/g, function(s) { return ' ' + s.toLowerCase(); });
 
1225
        message = "Expected " + jasmine.pp(this.actual) + (this.isNot ? " not " : " ") + englishyPredicate;
 
1226
        if (matcherArgs.length > 0) {
 
1227
          for (var i = 0; i < matcherArgs.length; i++) {
 
1228
            if (i > 0) message += ",";
 
1229
            message += " " + jasmine.pp(matcherArgs[i]);
 
1230
          }
 
1231
        }
 
1232
        message += ".";
 
1233
      }
 
1234
    }
 
1235
    var expectationResult = new jasmine.ExpectationResult({
 
1236
      matcherName: matcherName,
 
1237
      passed: result,
 
1238
      expected: matcherArgs.length > 1 ? matcherArgs : matcherArgs[0],
 
1239
      actual: this.actual,
 
1240
      message: message
 
1241
    });
 
1242
    this.spec.addMatcherResult(expectationResult);
 
1243
    return jasmine.undefined;
 
1244
  };
 
1245
};
 
1246
 
 
1247
 
 
1248
 
 
1249
 
 
1250
/**
 
1251
 * toBe: compares the actual to the expected using ===
 
1252
 * @param expected
 
1253
 */
 
1254
jasmine.Matchers.prototype.toBe = function(expected) {
 
1255
  return this.actual === expected;
 
1256
};
 
1257
 
 
1258
/**
 
1259
 * toNotBe: compares the actual to the expected using !==
 
1260
 * @param expected
 
1261
 * @deprecated as of 1.0. Use not.toBe() instead.
 
1262
 */
 
1263
jasmine.Matchers.prototype.toNotBe = function(expected) {
 
1264
  return this.actual !== expected;
 
1265
};
 
1266
 
 
1267
/**
 
1268
 * toEqual: compares the actual to the expected using common sense equality. Handles Objects, Arrays, etc.
 
1269
 *
 
1270
 * @param expected
 
1271
 */
 
1272
jasmine.Matchers.prototype.toEqual = function(expected) {
 
1273
  return this.env.equals_(this.actual, expected);
 
1274
};
 
1275
 
 
1276
/**
 
1277
 * toNotEqual: compares the actual to the expected using the ! of jasmine.Matchers.toEqual
 
1278
 * @param expected
 
1279
 * @deprecated as of 1.0. Use not.toEqual() instead.
 
1280
 */
 
1281
jasmine.Matchers.prototype.toNotEqual = function(expected) {
 
1282
  return !this.env.equals_(this.actual, expected);
 
1283
};
 
1284
 
 
1285
/**
 
1286
 * Matcher that compares the actual to the expected using a regular expression.  Constructs a RegExp, so takes
 
1287
 * a pattern or a String.
 
1288
 *
 
1289
 * @param expected
 
1290
 */
 
1291
jasmine.Matchers.prototype.toMatch = function(expected) {
 
1292
  return new RegExp(expected).test(this.actual);
 
1293
};
 
1294
 
 
1295
/**
 
1296
 * Matcher that compares the actual to the expected using the boolean inverse of jasmine.Matchers.toMatch
 
1297
 * @param expected
 
1298
 * @deprecated as of 1.0. Use not.toMatch() instead.
 
1299
 */
 
1300
jasmine.Matchers.prototype.toNotMatch = function(expected) {
 
1301
  return !(new RegExp(expected).test(this.actual));
 
1302
};
 
1303
 
 
1304
/**
 
1305
 * Matcher that compares the actual to jasmine.undefined.
 
1306
 */
 
1307
jasmine.Matchers.prototype.toBeDefined = function() {
 
1308
  return (this.actual !== jasmine.undefined);
 
1309
};
 
1310
 
 
1311
/**
 
1312
 * Matcher that compares the actual to jasmine.undefined.
 
1313
 */
 
1314
jasmine.Matchers.prototype.toBeUndefined = function() {
 
1315
  return (this.actual === jasmine.undefined);
 
1316
};
 
1317
 
 
1318
/**
 
1319
 * Matcher that compares the actual to null.
 
1320
 */
 
1321
jasmine.Matchers.prototype.toBeNull = function() {
 
1322
  return (this.actual === null);
 
1323
};
 
1324
 
 
1325
/**
 
1326
 * Matcher that compares the actual to NaN.
 
1327
 */
 
1328
jasmine.Matchers.prototype.toBeNaN = function() {
 
1329
        this.message = function() {
 
1330
                return [ "Expected " + jasmine.pp(this.actual) + " to be NaN." ];
 
1331
        };
 
1332
 
 
1333
        return (this.actual !== this.actual);
 
1334
};
 
1335
 
 
1336
/**
 
1337
 * Matcher that boolean not-nots the actual.
 
1338
 */
 
1339
jasmine.Matchers.prototype.toBeTruthy = function() {
 
1340
  return !!this.actual;
 
1341
};
 
1342
 
 
1343
 
 
1344
/**
 
1345
 * Matcher that boolean nots the actual.
 
1346
 */
 
1347
jasmine.Matchers.prototype.toBeFalsy = function() {
 
1348
  return !this.actual;
 
1349
};
 
1350
 
 
1351
 
 
1352
/**
 
1353
 * Matcher that checks to see if the actual, a Jasmine spy, was called.
 
1354
 */
 
1355
jasmine.Matchers.prototype.toHaveBeenCalled = function() {
 
1356
  if (arguments.length > 0) {
 
1357
    throw new Error('toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith');
 
1358
  }
 
1359
 
 
1360
  if (!jasmine.isSpy(this.actual)) {
 
1361
    throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');
 
1362
  }
 
1363
 
 
1364
  this.message = function() {
 
1365
    return [
 
1366
      "Expected spy " + this.actual.identity + " to have been called.",
 
1367
      "Expected spy " + this.actual.identity + " not to have been called."
 
1368
    ];
 
1369
  };
 
1370
 
 
1371
  return this.actual.wasCalled;
 
1372
};
 
1373
 
 
1374
/** @deprecated Use expect(xxx).toHaveBeenCalled() instead */
 
1375
jasmine.Matchers.prototype.wasCalled = jasmine.Matchers.prototype.toHaveBeenCalled;
 
1376
 
 
1377
/**
 
1378
 * Matcher that checks to see if the actual, a Jasmine spy, was not called.
 
1379
 *
 
1380
 * @deprecated Use expect(xxx).not.toHaveBeenCalled() instead
 
1381
 */
 
1382
jasmine.Matchers.prototype.wasNotCalled = function() {
 
1383
  if (arguments.length > 0) {
 
1384
    throw new Error('wasNotCalled does not take arguments');
 
1385
  }
 
1386
 
 
1387
  if (!jasmine.isSpy(this.actual)) {
 
1388
    throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');
 
1389
  }
 
1390
 
 
1391
  this.message = function() {
 
1392
    return [
 
1393
      "Expected spy " + this.actual.identity + " to not have been called.",
 
1394
      "Expected spy " + this.actual.identity + " to have been called."
 
1395
    ];
 
1396
  };
 
1397
 
 
1398
  return !this.actual.wasCalled;
 
1399
};
 
1400
 
 
1401
/**
 
1402
 * Matcher that checks to see if the actual, a Jasmine spy, was called with a set of parameters.
 
1403
 *
 
1404
 * @example
 
1405
 *
 
1406
 */
 
1407
jasmine.Matchers.prototype.toHaveBeenCalledWith = function() {
 
1408
  var expectedArgs = jasmine.util.argsToArray(arguments);
 
1409
  if (!jasmine.isSpy(this.actual)) {
 
1410
    throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');
 
1411
  }
 
1412
  this.message = function() {
 
1413
    var invertedMessage = "Expected spy " + this.actual.identity + " not to have been called with " + jasmine.pp(expectedArgs) + " but it was.";
 
1414
    var positiveMessage = "";
 
1415
    if (this.actual.callCount === 0) {
 
1416
      positiveMessage = "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but it was never called.";
 
1417
    } else {
 
1418
      positiveMessage = "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but actual calls were " + jasmine.pp(this.actual.argsForCall).replace(/^\[ | \]$/g, '')
 
1419
    }
 
1420
    return [positiveMessage, invertedMessage];
 
1421
  };
 
1422
 
 
1423
  return this.env.contains_(this.actual.argsForCall, expectedArgs);
 
1424
};
 
1425
 
 
1426
/** @deprecated Use expect(xxx).toHaveBeenCalledWith() instead */
 
1427
jasmine.Matchers.prototype.wasCalledWith = jasmine.Matchers.prototype.toHaveBeenCalledWith;
 
1428
 
 
1429
/** @deprecated Use expect(xxx).not.toHaveBeenCalledWith() instead */
 
1430
jasmine.Matchers.prototype.wasNotCalledWith = function() {
 
1431
  var expectedArgs = jasmine.util.argsToArray(arguments);
 
1432
  if (!jasmine.isSpy(this.actual)) {
 
1433
    throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');
 
1434
  }
 
1435
 
 
1436
  this.message = function() {
 
1437
    return [
 
1438
      "Expected spy not to have been called with " + jasmine.pp(expectedArgs) + " but it was",
 
1439
      "Expected spy to have been called with " + jasmine.pp(expectedArgs) + " but it was"
 
1440
    ];
 
1441
  };
 
1442
 
 
1443
  return !this.env.contains_(this.actual.argsForCall, expectedArgs);
 
1444
};
 
1445
 
 
1446
/**
 
1447
 * Matcher that checks that the expected item is an element in the actual Array.
 
1448
 *
 
1449
 * @param {Object} expected
 
1450
 */
 
1451
jasmine.Matchers.prototype.toContain = function(expected) {
 
1452
  return this.env.contains_(this.actual, expected);
 
1453
};
 
1454
 
 
1455
/**
 
1456
 * Matcher that checks that the expected item is NOT an element in the actual Array.
 
1457
 *
 
1458
 * @param {Object} expected
 
1459
 * @deprecated as of 1.0. Use not.toContain() instead.
 
1460
 */
 
1461
jasmine.Matchers.prototype.toNotContain = function(expected) {
 
1462
  return !this.env.contains_(this.actual, expected);
 
1463
};
 
1464
 
 
1465
jasmine.Matchers.prototype.toBeLessThan = function(expected) {
 
1466
  return this.actual < expected;
 
1467
};
 
1468
 
 
1469
jasmine.Matchers.prototype.toBeGreaterThan = function(expected) {
 
1470
  return this.actual > expected;
 
1471
};
 
1472
 
 
1473
/**
 
1474
 * Matcher that checks that the expected item is equal to the actual item
 
1475
 * up to a given level of decimal precision (default 2).
 
1476
 *
 
1477
 * @param {Number} expected
 
1478
 * @param {Number} precision, as number of decimal places
 
1479
 */
 
1480
jasmine.Matchers.prototype.toBeCloseTo = function(expected, precision) {
 
1481
  if (!(precision === 0)) {
 
1482
    precision = precision || 2;
 
1483
  }
 
1484
  return Math.abs(expected - this.actual) < (Math.pow(10, -precision) / 2);
 
1485
};
 
1486
 
 
1487
/**
 
1488
 * Matcher that checks that the expected exception was thrown by the actual.
 
1489
 *
 
1490
 * @param {String} [expected]
 
1491
 */
 
1492
jasmine.Matchers.prototype.toThrow = function(expected) {
 
1493
  var result = false;
 
1494
  var exception;
 
1495
  if (typeof this.actual != 'function') {
 
1496
    throw new Error('Actual is not a function');
 
1497
  }
 
1498
  try {
 
1499
    this.actual();
 
1500
  } catch (e) {
 
1501
    exception = e;
 
1502
  }
 
1503
  if (exception) {
 
1504
    result = (expected === jasmine.undefined || this.env.equals_(exception.message || exception, expected.message || expected));
 
1505
  }
 
1506
 
 
1507
  var not = this.isNot ? "not " : "";
 
1508
 
 
1509
  this.message = function() {
 
1510
    if (exception && (expected === jasmine.undefined || !this.env.equals_(exception.message || exception, expected.message || expected))) {
 
1511
      return ["Expected function " + not + "to throw", expected ? expected.message || expected : "an exception", ", but it threw", exception.message || exception].join(' ');
 
1512
    } else {
 
1513
      return "Expected function to throw an exception.";
 
1514
    }
 
1515
  };
 
1516
 
 
1517
  return result;
 
1518
};
 
1519
 
 
1520
jasmine.Matchers.Any = function(expectedClass) {
 
1521
  this.expectedClass = expectedClass;
 
1522
};
 
1523
 
 
1524
jasmine.Matchers.Any.prototype.jasmineMatches = function(other) {
 
1525
  if (this.expectedClass == String) {
 
1526
    return typeof other == 'string' || other instanceof String;
 
1527
  }
 
1528
 
 
1529
  if (this.expectedClass == Number) {
 
1530
    return typeof other == 'number' || other instanceof Number;
 
1531
  }
 
1532
 
 
1533
  if (this.expectedClass == Function) {
 
1534
    return typeof other == 'function' || other instanceof Function;
 
1535
  }
 
1536
 
 
1537
  if (this.expectedClass == Object) {
 
1538
    return typeof other == 'object';
 
1539
  }
 
1540
 
 
1541
  return other instanceof this.expectedClass;
 
1542
};
 
1543
 
 
1544
jasmine.Matchers.Any.prototype.jasmineToString = function() {
 
1545
  return '<jasmine.any(' + this.expectedClass + ')>';
 
1546
};
 
1547
 
 
1548
jasmine.Matchers.ObjectContaining = function (sample) {
 
1549
  this.sample = sample;
 
1550
};
 
1551
 
 
1552
jasmine.Matchers.ObjectContaining.prototype.jasmineMatches = function(other, mismatchKeys, mismatchValues) {
 
1553
  mismatchKeys = mismatchKeys || [];
 
1554
  mismatchValues = mismatchValues || [];
 
1555
 
 
1556
  var env = jasmine.getEnv();
 
1557
 
 
1558
  var hasKey = function(obj, keyName) {
 
1559
    return obj != null && obj[keyName] !== jasmine.undefined;
 
1560
  };
 
1561
 
 
1562
  for (var property in this.sample) {
 
1563
    if (!hasKey(other, property) && hasKey(this.sample, property)) {
 
1564
      mismatchKeys.push("expected has key '" + property + "', but missing from actual.");
 
1565
    }
 
1566
    else if (!env.equals_(this.sample[property], other[property], mismatchKeys, mismatchValues)) {
 
1567
      mismatchValues.push("'" + property + "' was '" + (other[property] ? jasmine.util.htmlEscape(other[property].toString()) : other[property]) + "' in expected, but was '" + (this.sample[property] ? jasmine.util.htmlEscape(this.sample[property].toString()) : this.sample[property]) + "' in actual.");
 
1568
    }
 
1569
  }
 
1570
 
 
1571
  return (mismatchKeys.length === 0 && mismatchValues.length === 0);
 
1572
};
 
1573
 
 
1574
jasmine.Matchers.ObjectContaining.prototype.jasmineToString = function () {
 
1575
  return "<jasmine.objectContaining(" + jasmine.pp(this.sample) + ")>";
 
1576
};
 
1577
// Mock setTimeout, clearTimeout
 
1578
// Contributed by Pivotal Computer Systems, www.pivotalsf.com
 
1579
 
 
1580
jasmine.FakeTimer = function() {
 
1581
  this.reset();
 
1582
 
 
1583
  var self = this;
 
1584
  self.setTimeout = function(funcToCall, millis) {
 
1585
    self.timeoutsMade++;
 
1586
    self.scheduleFunction(self.timeoutsMade, funcToCall, millis, false);
 
1587
    return self.timeoutsMade;
 
1588
  };
 
1589
 
 
1590
  self.setInterval = function(funcToCall, millis) {
 
1591
    self.timeoutsMade++;
 
1592
    self.scheduleFunction(self.timeoutsMade, funcToCall, millis, true);
 
1593
    return self.timeoutsMade;
 
1594
  };
 
1595
 
 
1596
  self.clearTimeout = function(timeoutKey) {
 
1597
    self.scheduledFunctions[timeoutKey] = jasmine.undefined;
 
1598
  };
 
1599
 
 
1600
  self.clearInterval = function(timeoutKey) {
 
1601
    self.scheduledFunctions[timeoutKey] = jasmine.undefined;
 
1602
  };
 
1603
 
 
1604
};
 
1605
 
 
1606
jasmine.FakeTimer.prototype.reset = function() {
 
1607
  this.timeoutsMade = 0;
 
1608
  this.scheduledFunctions = {};
 
1609
  this.nowMillis = 0;
 
1610
};
 
1611
 
 
1612
jasmine.FakeTimer.prototype.tick = function(millis) {
 
1613
  var oldMillis = this.nowMillis;
 
1614
  var newMillis = oldMillis + millis;
 
1615
  this.runFunctionsWithinRange(oldMillis, newMillis);
 
1616
  this.nowMillis = newMillis;
 
1617
};
 
1618
 
 
1619
jasmine.FakeTimer.prototype.runFunctionsWithinRange = function(oldMillis, nowMillis) {
 
1620
  var scheduledFunc;
 
1621
  var funcsToRun = [];
 
1622
  for (var timeoutKey in this.scheduledFunctions) {
 
1623
    scheduledFunc = this.scheduledFunctions[timeoutKey];
 
1624
    if (scheduledFunc != jasmine.undefined &&
 
1625
        scheduledFunc.runAtMillis >= oldMillis &&
 
1626
        scheduledFunc.runAtMillis <= nowMillis) {
 
1627
      funcsToRun.push(scheduledFunc);
 
1628
      this.scheduledFunctions[timeoutKey] = jasmine.undefined;
 
1629
    }
 
1630
  }
 
1631
 
 
1632
  if (funcsToRun.length > 0) {
 
1633
    funcsToRun.sort(function(a, b) {
 
1634
      return a.runAtMillis - b.runAtMillis;
 
1635
    });
 
1636
    for (var i = 0; i < funcsToRun.length; ++i) {
 
1637
      try {
 
1638
        var funcToRun = funcsToRun[i];
 
1639
        this.nowMillis = funcToRun.runAtMillis;
 
1640
        funcToRun.funcToCall();
 
1641
        if (funcToRun.recurring) {
 
1642
          this.scheduleFunction(funcToRun.timeoutKey,
 
1643
              funcToRun.funcToCall,
 
1644
              funcToRun.millis,
 
1645
              true);
 
1646
        }
 
1647
      } catch(e) {
 
1648
      }
 
1649
    }
 
1650
    this.runFunctionsWithinRange(oldMillis, nowMillis);
 
1651
  }
 
1652
};
 
1653
 
 
1654
jasmine.FakeTimer.prototype.scheduleFunction = function(timeoutKey, funcToCall, millis, recurring) {
 
1655
  this.scheduledFunctions[timeoutKey] = {
 
1656
    runAtMillis: this.nowMillis + millis,
 
1657
    funcToCall: funcToCall,
 
1658
    recurring: recurring,
 
1659
    timeoutKey: timeoutKey,
 
1660
    millis: millis
 
1661
  };
 
1662
};
 
1663
 
 
1664
/**
 
1665
 * @namespace
 
1666
 */
 
1667
jasmine.Clock = {
 
1668
  defaultFakeTimer: new jasmine.FakeTimer(),
 
1669
 
 
1670
  reset: function() {
 
1671
    jasmine.Clock.assertInstalled();
 
1672
    jasmine.Clock.defaultFakeTimer.reset();
 
1673
  },
 
1674
 
 
1675
  tick: function(millis) {
 
1676
    jasmine.Clock.assertInstalled();
 
1677
    jasmine.Clock.defaultFakeTimer.tick(millis);
 
1678
  },
 
1679
 
 
1680
  runFunctionsWithinRange: function(oldMillis, nowMillis) {
 
1681
    jasmine.Clock.defaultFakeTimer.runFunctionsWithinRange(oldMillis, nowMillis);
 
1682
  },
 
1683
 
 
1684
  scheduleFunction: function(timeoutKey, funcToCall, millis, recurring) {
 
1685
    jasmine.Clock.defaultFakeTimer.scheduleFunction(timeoutKey, funcToCall, millis, recurring);
 
1686
  },
 
1687
 
 
1688
  useMock: function() {
 
1689
    if (!jasmine.Clock.isInstalled()) {
 
1690
      var spec = jasmine.getEnv().currentSpec;
 
1691
      spec.after(jasmine.Clock.uninstallMock);
 
1692
 
 
1693
      jasmine.Clock.installMock();
 
1694
    }
 
1695
  },
 
1696
 
 
1697
  installMock: function() {
 
1698
    jasmine.Clock.installed = jasmine.Clock.defaultFakeTimer;
 
1699
  },
 
1700
 
 
1701
  uninstallMock: function() {
 
1702
    jasmine.Clock.assertInstalled();
 
1703
    jasmine.Clock.installed = jasmine.Clock.real;
 
1704
  },
 
1705
 
 
1706
  real: {
 
1707
    setTimeout: jasmine.getGlobal().setTimeout,
 
1708
    clearTimeout: jasmine.getGlobal().clearTimeout,
 
1709
    setInterval: jasmine.getGlobal().setInterval,
 
1710
    clearInterval: jasmine.getGlobal().clearInterval
 
1711
  },
 
1712
 
 
1713
  assertInstalled: function() {
 
1714
    if (!jasmine.Clock.isInstalled()) {
 
1715
      throw new Error("Mock clock is not installed, use jasmine.Clock.useMock()");
 
1716
    }
 
1717
  },
 
1718
 
 
1719
  isInstalled: function() {
 
1720
    return jasmine.Clock.installed == jasmine.Clock.defaultFakeTimer;
 
1721
  },
 
1722
 
 
1723
  installed: null
 
1724
};
 
1725
jasmine.Clock.installed = jasmine.Clock.real;
 
1726
 
 
1727
//else for IE support
 
1728
jasmine.getGlobal().setTimeout = function(funcToCall, millis) {
 
1729
  if (jasmine.Clock.installed.setTimeout.apply) {
 
1730
    return jasmine.Clock.installed.setTimeout.apply(this, arguments);
 
1731
  } else {
 
1732
    return jasmine.Clock.installed.setTimeout(funcToCall, millis);
 
1733
  }
 
1734
};
 
1735
 
 
1736
jasmine.getGlobal().setInterval = function(funcToCall, millis) {
 
1737
  if (jasmine.Clock.installed.setInterval.apply) {
 
1738
    return jasmine.Clock.installed.setInterval.apply(this, arguments);
 
1739
  } else {
 
1740
    return jasmine.Clock.installed.setInterval(funcToCall, millis);
 
1741
  }
 
1742
};
 
1743
 
 
1744
jasmine.getGlobal().clearTimeout = function(timeoutKey) {
 
1745
  if (jasmine.Clock.installed.clearTimeout.apply) {
 
1746
    return jasmine.Clock.installed.clearTimeout.apply(this, arguments);
 
1747
  } else {
 
1748
    return jasmine.Clock.installed.clearTimeout(timeoutKey);
 
1749
  }
 
1750
};
 
1751
 
 
1752
jasmine.getGlobal().clearInterval = function(timeoutKey) {
 
1753
  if (jasmine.Clock.installed.clearTimeout.apply) {
 
1754
    return jasmine.Clock.installed.clearInterval.apply(this, arguments);
 
1755
  } else {
 
1756
    return jasmine.Clock.installed.clearInterval(timeoutKey);
 
1757
  }
 
1758
};
 
1759
 
 
1760
/**
 
1761
 * @constructor
 
1762
 */
 
1763
jasmine.MultiReporter = function() {
 
1764
  this.subReporters_ = [];
 
1765
};
 
1766
jasmine.util.inherit(jasmine.MultiReporter, jasmine.Reporter);
 
1767
 
 
1768
jasmine.MultiReporter.prototype.addReporter = function(reporter) {
 
1769
  this.subReporters_.push(reporter);
 
1770
};
 
1771
 
 
1772
(function() {
 
1773
  var functionNames = [
 
1774
    "reportRunnerStarting",
 
1775
    "reportRunnerResults",
 
1776
    "reportSuiteResults",
 
1777
    "reportSpecStarting",
 
1778
    "reportSpecResults",
 
1779
    "log"
 
1780
  ];
 
1781
  for (var i = 0; i < functionNames.length; i++) {
 
1782
    var functionName = functionNames[i];
 
1783
    jasmine.MultiReporter.prototype[functionName] = (function(functionName) {
 
1784
      return function() {
 
1785
        for (var j = 0; j < this.subReporters_.length; j++) {
 
1786
          var subReporter = this.subReporters_[j];
 
1787
          if (subReporter[functionName]) {
 
1788
            subReporter[functionName].apply(subReporter, arguments);
 
1789
          }
 
1790
        }
 
1791
      };
 
1792
    })(functionName);
 
1793
  }
 
1794
})();
 
1795
/**
 
1796
 * Holds results for a set of Jasmine spec. Allows for the results array to hold another jasmine.NestedResults
 
1797
 *
 
1798
 * @constructor
 
1799
 */
 
1800
jasmine.NestedResults = function() {
 
1801
  /**
 
1802
   * The total count of results
 
1803
   */
 
1804
  this.totalCount = 0;
 
1805
  /**
 
1806
   * Number of passed results
 
1807
   */
 
1808
  this.passedCount = 0;
 
1809
  /**
 
1810
   * Number of failed results
 
1811
   */
 
1812
  this.failedCount = 0;
 
1813
  /**
 
1814
   * Was this suite/spec skipped?
 
1815
   */
 
1816
  this.skipped = false;
 
1817
  /**
 
1818
   * @ignore
 
1819
   */
 
1820
  this.items_ = [];
 
1821
};
 
1822
 
 
1823
/**
 
1824
 * Roll up the result counts.
 
1825
 *
 
1826
 * @param result
 
1827
 */
 
1828
jasmine.NestedResults.prototype.rollupCounts = function(result) {
 
1829
  this.totalCount += result.totalCount;
 
1830
  this.passedCount += result.passedCount;
 
1831
  this.failedCount += result.failedCount;
 
1832
};
 
1833
 
 
1834
/**
 
1835
 * Adds a log message.
 
1836
 * @param values Array of message parts which will be concatenated later.
 
1837
 */
 
1838
jasmine.NestedResults.prototype.log = function(values) {
 
1839
  this.items_.push(new jasmine.MessageResult(values));
 
1840
};
 
1841
 
 
1842
/**
 
1843
 * Getter for the results: message & results.
 
1844
 */
 
1845
jasmine.NestedResults.prototype.getItems = function() {
 
1846
  return this.items_;
 
1847
};
 
1848
 
 
1849
/**
 
1850
 * Adds a result, tracking counts (total, passed, & failed)
 
1851
 * @param {jasmine.ExpectationResult|jasmine.NestedResults} result
 
1852
 */
 
1853
jasmine.NestedResults.prototype.addResult = function(result) {
 
1854
  if (result.type != 'log') {
 
1855
    if (result.items_) {
 
1856
      this.rollupCounts(result);
 
1857
    } else {
 
1858
      this.totalCount++;
 
1859
      if (result.passed()) {
 
1860
        this.passedCount++;
 
1861
      } else {
 
1862
        this.failedCount++;
 
1863
      }
 
1864
    }
 
1865
  }
 
1866
  this.items_.push(result);
 
1867
};
 
1868
 
 
1869
/**
 
1870
 * @returns {Boolean} True if <b>everything</b> below passed
 
1871
 */
 
1872
jasmine.NestedResults.prototype.passed = function() {
 
1873
  return this.passedCount === this.totalCount;
 
1874
};
 
1875
/**
 
1876
 * Base class for pretty printing for expectation results.
 
1877
 */
 
1878
jasmine.PrettyPrinter = function() {
 
1879
  this.ppNestLevel_ = 0;
 
1880
};
 
1881
 
 
1882
/**
 
1883
 * Formats a value in a nice, human-readable string.
 
1884
 *
 
1885
 * @param value
 
1886
 */
 
1887
jasmine.PrettyPrinter.prototype.format = function(value) {
 
1888
  this.ppNestLevel_++;
 
1889
  try {
 
1890
    if (value === jasmine.undefined) {
 
1891
      this.emitScalar('undefined');
 
1892
    } else if (value === null) {
 
1893
      this.emitScalar('null');
 
1894
    } else if (value === jasmine.getGlobal()) {
 
1895
      this.emitScalar('<global>');
 
1896
    } else if (value.jasmineToString) {
 
1897
      this.emitScalar(value.jasmineToString());
 
1898
    } else if (typeof value === 'string') {
 
1899
      this.emitString(value);
 
1900
    } else if (jasmine.isSpy(value)) {
 
1901
      this.emitScalar("spy on " + value.identity);
 
1902
    } else if (value instanceof RegExp) {
 
1903
      this.emitScalar(value.toString());
 
1904
    } else if (typeof value === 'function') {
 
1905
      this.emitScalar('Function');
 
1906
    } else if (typeof value.nodeType === 'number') {
 
1907
      this.emitScalar('HTMLNode');
 
1908
    } else if (value instanceof Date) {
 
1909
      this.emitScalar('Date(' + value + ')');
 
1910
    } else if (value.__Jasmine_been_here_before__) {
 
1911
      this.emitScalar('<circular reference: ' + (jasmine.isArray_(value) ? 'Array' : 'Object') + '>');
 
1912
    } else if (jasmine.isArray_(value) || typeof value == 'object') {
 
1913
      value.__Jasmine_been_here_before__ = true;
 
1914
      if (jasmine.isArray_(value)) {
 
1915
        this.emitArray(value);
 
1916
      } else {
 
1917
        this.emitObject(value);
 
1918
      }
 
1919
      delete value.__Jasmine_been_here_before__;
 
1920
    } else {
 
1921
      this.emitScalar(value.toString());
 
1922
    }
 
1923
  } finally {
 
1924
    this.ppNestLevel_--;
 
1925
  }
 
1926
};
 
1927
 
 
1928
jasmine.PrettyPrinter.prototype.iterateObject = function(obj, fn) {
 
1929
  for (var property in obj) {
 
1930
    if (!obj.hasOwnProperty(property)) continue;
 
1931
    if (property == '__Jasmine_been_here_before__') continue;
 
1932
    fn(property, obj.__lookupGetter__ ? (obj.__lookupGetter__(property) !== jasmine.undefined && 
 
1933
                                         obj.__lookupGetter__(property) !== null) : false);
 
1934
  }
 
1935
};
 
1936
 
 
1937
jasmine.PrettyPrinter.prototype.emitArray = jasmine.unimplementedMethod_;
 
1938
jasmine.PrettyPrinter.prototype.emitObject = jasmine.unimplementedMethod_;
 
1939
jasmine.PrettyPrinter.prototype.emitScalar = jasmine.unimplementedMethod_;
 
1940
jasmine.PrettyPrinter.prototype.emitString = jasmine.unimplementedMethod_;
 
1941
 
 
1942
jasmine.StringPrettyPrinter = function() {
 
1943
  jasmine.PrettyPrinter.call(this);
 
1944
 
 
1945
  this.string = '';
 
1946
};
 
1947
jasmine.util.inherit(jasmine.StringPrettyPrinter, jasmine.PrettyPrinter);
 
1948
 
 
1949
jasmine.StringPrettyPrinter.prototype.emitScalar = function(value) {
 
1950
  this.append(value);
 
1951
};
 
1952
 
 
1953
jasmine.StringPrettyPrinter.prototype.emitString = function(value) {
 
1954
  this.append("'" + value + "'");
 
1955
};
 
1956
 
 
1957
jasmine.StringPrettyPrinter.prototype.emitArray = function(array) {
 
1958
  if (this.ppNestLevel_ > jasmine.MAX_PRETTY_PRINT_DEPTH) {
 
1959
    this.append("Array");
 
1960
    return;
 
1961
  }
 
1962
 
 
1963
  this.append('[ ');
 
1964
  for (var i = 0; i < array.length; i++) {
 
1965
    if (i > 0) {
 
1966
      this.append(', ');
 
1967
    }
 
1968
    this.format(array[i]);
 
1969
  }
 
1970
  this.append(' ]');
 
1971
};
 
1972
 
 
1973
jasmine.StringPrettyPrinter.prototype.emitObject = function(obj) {
 
1974
  if (this.ppNestLevel_ > jasmine.MAX_PRETTY_PRINT_DEPTH) {
 
1975
    this.append("Object");
 
1976
    return;
 
1977
  }
 
1978
 
 
1979
  var self = this;
 
1980
  this.append('{ ');
 
1981
  var first = true;
 
1982
 
 
1983
  this.iterateObject(obj, function(property, isGetter) {
 
1984
    if (first) {
 
1985
      first = false;
 
1986
    } else {
 
1987
      self.append(', ');
 
1988
    }
 
1989
 
 
1990
    self.append(property);
 
1991
    self.append(' : ');
 
1992
    if (isGetter) {
 
1993
      self.append('<getter>');
 
1994
    } else {
 
1995
      self.format(obj[property]);
 
1996
    }
 
1997
  });
 
1998
 
 
1999
  this.append(' }');
 
2000
};
 
2001
 
 
2002
jasmine.StringPrettyPrinter.prototype.append = function(value) {
 
2003
  this.string += value;
 
2004
};
 
2005
jasmine.Queue = function(env) {
 
2006
  this.env = env;
 
2007
 
 
2008
  // parallel to blocks. each true value in this array means the block will
 
2009
  // get executed even if we abort
 
2010
  this.ensured = [];
 
2011
  this.blocks = [];
 
2012
  this.running = false;
 
2013
  this.index = 0;
 
2014
  this.offset = 0;
 
2015
  this.abort = false;
 
2016
};
 
2017
 
 
2018
jasmine.Queue.prototype.addBefore = function(block, ensure) {
 
2019
  if (ensure === jasmine.undefined) {
 
2020
    ensure = false;
 
2021
  }
 
2022
 
 
2023
  this.blocks.unshift(block);
 
2024
  this.ensured.unshift(ensure);
 
2025
};
 
2026
 
 
2027
jasmine.Queue.prototype.add = function(block, ensure) {
 
2028
  if (ensure === jasmine.undefined) {
 
2029
    ensure = false;
 
2030
  }
 
2031
 
 
2032
  this.blocks.push(block);
 
2033
  this.ensured.push(ensure);
 
2034
};
 
2035
 
 
2036
jasmine.Queue.prototype.insertNext = function(block, ensure) {
 
2037
  if (ensure === jasmine.undefined) {
 
2038
    ensure = false;
 
2039
  }
 
2040
 
 
2041
  this.ensured.splice((this.index + this.offset + 1), 0, ensure);
 
2042
  this.blocks.splice((this.index + this.offset + 1), 0, block);
 
2043
  this.offset++;
 
2044
};
 
2045
 
 
2046
jasmine.Queue.prototype.start = function(onComplete) {
 
2047
  this.running = true;
 
2048
  this.onComplete = onComplete;
 
2049
  this.next_();
 
2050
};
 
2051
 
 
2052
jasmine.Queue.prototype.isRunning = function() {
 
2053
  return this.running;
 
2054
};
 
2055
 
 
2056
jasmine.Queue.LOOP_DONT_RECURSE = true;
 
2057
 
 
2058
jasmine.Queue.prototype.next_ = function() {
 
2059
  var self = this;
 
2060
  var goAgain = true;
 
2061
 
 
2062
  while (goAgain) {
 
2063
    goAgain = false;
 
2064
    
 
2065
    if (self.index < self.blocks.length && !(this.abort && !this.ensured[self.index])) {
 
2066
      var calledSynchronously = true;
 
2067
      var completedSynchronously = false;
 
2068
 
 
2069
      var onComplete = function () {
 
2070
        if (jasmine.Queue.LOOP_DONT_RECURSE && calledSynchronously) {
 
2071
          completedSynchronously = true;
 
2072
          return;
 
2073
        }
 
2074
 
 
2075
        if (self.blocks[self.index].abort) {
 
2076
          self.abort = true;
 
2077
        }
 
2078
 
 
2079
        self.offset = 0;
 
2080
        self.index++;
 
2081
 
 
2082
        var now = new Date().getTime();
 
2083
        if (self.env.updateInterval && now - self.env.lastUpdate > self.env.updateInterval) {
 
2084
          self.env.lastUpdate = now;
 
2085
          self.env.setTimeout(function() {
 
2086
            self.next_();
 
2087
          }, 0);
 
2088
        } else {
 
2089
          if (jasmine.Queue.LOOP_DONT_RECURSE && completedSynchronously) {
 
2090
            goAgain = true;
 
2091
          } else {
 
2092
            self.next_();
 
2093
          }
 
2094
        }
 
2095
      };
 
2096
      self.blocks[self.index].execute(onComplete);
 
2097
 
 
2098
      calledSynchronously = false;
 
2099
      if (completedSynchronously) {
 
2100
        onComplete();
 
2101
      }
 
2102
      
 
2103
    } else {
 
2104
      self.running = false;
 
2105
      if (self.onComplete) {
 
2106
        self.onComplete();
 
2107
      }
 
2108
    }
 
2109
  }
 
2110
};
 
2111
 
 
2112
jasmine.Queue.prototype.results = function() {
 
2113
  var results = new jasmine.NestedResults();
 
2114
  for (var i = 0; i < this.blocks.length; i++) {
 
2115
    if (this.blocks[i].results) {
 
2116
      results.addResult(this.blocks[i].results());
 
2117
    }
 
2118
  }
 
2119
  return results;
 
2120
};
 
2121
 
 
2122
 
 
2123
/**
 
2124
 * Runner
 
2125
 *
 
2126
 * @constructor
 
2127
 * @param {jasmine.Env} env
 
2128
 */
 
2129
jasmine.Runner = function(env) {
 
2130
  var self = this;
 
2131
  self.env = env;
 
2132
  self.queue = new jasmine.Queue(env);
 
2133
  self.before_ = [];
 
2134
  self.after_ = [];
 
2135
  self.suites_ = [];
 
2136
};
 
2137
 
 
2138
jasmine.Runner.prototype.execute = function() {
 
2139
  var self = this;
 
2140
  if (self.env.reporter.reportRunnerStarting) {
 
2141
    self.env.reporter.reportRunnerStarting(this);
 
2142
  }
 
2143
  self.queue.start(function () {
 
2144
    self.finishCallback();
 
2145
  });
 
2146
};
 
2147
 
 
2148
jasmine.Runner.prototype.beforeEach = function(beforeEachFunction) {
 
2149
  beforeEachFunction.typeName = 'beforeEach';
 
2150
  this.before_.splice(0,0,beforeEachFunction);
 
2151
};
 
2152
 
 
2153
jasmine.Runner.prototype.afterEach = function(afterEachFunction) {
 
2154
  afterEachFunction.typeName = 'afterEach';
 
2155
  this.after_.splice(0,0,afterEachFunction);
 
2156
};
 
2157
 
 
2158
 
 
2159
jasmine.Runner.prototype.finishCallback = function() {
 
2160
  this.env.reporter.reportRunnerResults(this);
 
2161
};
 
2162
 
 
2163
jasmine.Runner.prototype.addSuite = function(suite) {
 
2164
  this.suites_.push(suite);
 
2165
};
 
2166
 
 
2167
jasmine.Runner.prototype.add = function(block) {
 
2168
  if (block instanceof jasmine.Suite) {
 
2169
    this.addSuite(block);
 
2170
  }
 
2171
  this.queue.add(block);
 
2172
};
 
2173
 
 
2174
jasmine.Runner.prototype.specs = function () {
 
2175
  var suites = this.suites();
 
2176
  var specs = [];
 
2177
  for (var i = 0; i < suites.length; i++) {
 
2178
    specs = specs.concat(suites[i].specs());
 
2179
  }
 
2180
  return specs;
 
2181
};
 
2182
 
 
2183
jasmine.Runner.prototype.suites = function() {
 
2184
  return this.suites_;
 
2185
};
 
2186
 
 
2187
jasmine.Runner.prototype.topLevelSuites = function() {
 
2188
  var topLevelSuites = [];
 
2189
  for (var i = 0; i < this.suites_.length; i++) {
 
2190
    if (!this.suites_[i].parentSuite) {
 
2191
      topLevelSuites.push(this.suites_[i]);
 
2192
    }
 
2193
  }
 
2194
  return topLevelSuites;
 
2195
};
 
2196
 
 
2197
jasmine.Runner.prototype.results = function() {
 
2198
  return this.queue.results();
 
2199
};
 
2200
/**
 
2201
 * Internal representation of a Jasmine specification, or test.
 
2202
 *
 
2203
 * @constructor
 
2204
 * @param {jasmine.Env} env
 
2205
 * @param {jasmine.Suite} suite
 
2206
 * @param {String} description
 
2207
 */
 
2208
jasmine.Spec = function(env, suite, description) {
 
2209
  if (!env) {
 
2210
    throw new Error('jasmine.Env() required');
 
2211
  }
 
2212
  if (!suite) {
 
2213
    throw new Error('jasmine.Suite() required');
 
2214
  }
 
2215
  var spec = this;
 
2216
  spec.id = env.nextSpecId ? env.nextSpecId() : null;
 
2217
  spec.env = env;
 
2218
  spec.suite = suite;
 
2219
  spec.description = description;
 
2220
  spec.queue = new jasmine.Queue(env);
 
2221
 
 
2222
  spec.afterCallbacks = [];
 
2223
  spec.spies_ = [];
 
2224
 
 
2225
  spec.results_ = new jasmine.NestedResults();
 
2226
  spec.results_.description = description;
 
2227
  spec.matchersClass = null;
 
2228
};
 
2229
 
 
2230
jasmine.Spec.prototype.getFullName = function() {
 
2231
  return this.suite.getFullName() + ' ' + this.description + '.';
 
2232
};
 
2233
 
 
2234
 
 
2235
jasmine.Spec.prototype.results = function() {
 
2236
  return this.results_;
 
2237
};
 
2238
 
 
2239
/**
 
2240
 * All parameters are pretty-printed and concatenated together, then written to the spec's output.
 
2241
 *
 
2242
 * Be careful not to leave calls to <code>jasmine.log</code> in production code.
 
2243
 */
 
2244
jasmine.Spec.prototype.log = function() {
 
2245
  return this.results_.log(arguments);
 
2246
};
 
2247
 
 
2248
jasmine.Spec.prototype.runs = function (func) {
 
2249
  var block = new jasmine.Block(this.env, func, this);
 
2250
  this.addToQueue(block);
 
2251
  return this;
 
2252
};
 
2253
 
 
2254
jasmine.Spec.prototype.addToQueue = function (block) {
 
2255
  if (this.queue.isRunning()) {
 
2256
    this.queue.insertNext(block);
 
2257
  } else {
 
2258
    this.queue.add(block);
 
2259
  }
 
2260
};
 
2261
 
 
2262
/**
 
2263
 * @param {jasmine.ExpectationResult} result
 
2264
 */
 
2265
jasmine.Spec.prototype.addMatcherResult = function(result) {
 
2266
  this.results_.addResult(result);
 
2267
};
 
2268
 
 
2269
jasmine.Spec.prototype.expect = function(actual) {
 
2270
  var positive = new (this.getMatchersClass_())(this.env, actual, this);
 
2271
  positive.not = new (this.getMatchersClass_())(this.env, actual, this, true);
 
2272
  return positive;
 
2273
};
 
2274
 
 
2275
/**
 
2276
 * Waits a fixed time period before moving to the next block.
 
2277
 *
 
2278
 * @deprecated Use waitsFor() instead
 
2279
 * @param {Number} timeout milliseconds to wait
 
2280
 */
 
2281
jasmine.Spec.prototype.waits = function(timeout) {
 
2282
  var waitsFunc = new jasmine.WaitsBlock(this.env, timeout, this);
 
2283
  this.addToQueue(waitsFunc);
 
2284
  return this;
 
2285
};
 
2286
 
 
2287
/**
 
2288
 * Waits for the latchFunction to return true before proceeding to the next block.
 
2289
 *
 
2290
 * @param {Function} latchFunction
 
2291
 * @param {String} optional_timeoutMessage
 
2292
 * @param {Number} optional_timeout
 
2293
 */
 
2294
jasmine.Spec.prototype.waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) {
 
2295
  var latchFunction_ = null;
 
2296
  var optional_timeoutMessage_ = null;
 
2297
  var optional_timeout_ = null;
 
2298
 
 
2299
  for (var i = 0; i < arguments.length; i++) {
 
2300
    var arg = arguments[i];
 
2301
    switch (typeof arg) {
 
2302
      case 'function':
 
2303
        latchFunction_ = arg;
 
2304
        break;
 
2305
      case 'string':
 
2306
        optional_timeoutMessage_ = arg;
 
2307
        break;
 
2308
      case 'number':
 
2309
        optional_timeout_ = arg;
 
2310
        break;
 
2311
    }
 
2312
  }
 
2313
 
 
2314
  var waitsForFunc = new jasmine.WaitsForBlock(this.env, optional_timeout_, latchFunction_, optional_timeoutMessage_, this);
 
2315
  this.addToQueue(waitsForFunc);
 
2316
  return this;
 
2317
};
 
2318
 
 
2319
jasmine.Spec.prototype.fail = function (e) {
 
2320
  var expectationResult = new jasmine.ExpectationResult({
 
2321
    passed: false,
 
2322
    message: e ? jasmine.util.formatException(e) : 'Exception',
 
2323
    trace: { stack: e.stack }
 
2324
  });
 
2325
  this.results_.addResult(expectationResult);
 
2326
};
 
2327
 
 
2328
jasmine.Spec.prototype.getMatchersClass_ = function() {
 
2329
  return this.matchersClass || this.env.matchersClass;
 
2330
};
 
2331
 
 
2332
jasmine.Spec.prototype.addMatchers = function(matchersPrototype) {
 
2333
  var parent = this.getMatchersClass_();
 
2334
  var newMatchersClass = function() {
 
2335
    parent.apply(this, arguments);
 
2336
  };
 
2337
  jasmine.util.inherit(newMatchersClass, parent);
 
2338
  jasmine.Matchers.wrapInto_(matchersPrototype, newMatchersClass);
 
2339
  this.matchersClass = newMatchersClass;
 
2340
};
 
2341
 
 
2342
jasmine.Spec.prototype.finishCallback = function() {
 
2343
  this.env.reporter.reportSpecResults(this);
 
2344
};
 
2345
 
 
2346
jasmine.Spec.prototype.finish = function(onComplete) {
 
2347
  this.removeAllSpies();
 
2348
  this.finishCallback();
 
2349
  if (onComplete) {
 
2350
    onComplete();
 
2351
  }
 
2352
};
 
2353
 
 
2354
jasmine.Spec.prototype.after = function(doAfter) {
 
2355
  if (this.queue.isRunning()) {
 
2356
    this.queue.add(new jasmine.Block(this.env, doAfter, this), true);
 
2357
  } else {
 
2358
    this.afterCallbacks.unshift(doAfter);
 
2359
  }
 
2360
};
 
2361
 
 
2362
jasmine.Spec.prototype.execute = function(onComplete) {
 
2363
  var spec = this;
 
2364
  if (!spec.env.specFilter(spec)) {
 
2365
    spec.results_.skipped = true;
 
2366
    spec.finish(onComplete);
 
2367
    return;
 
2368
  }
 
2369
 
 
2370
  this.env.reporter.reportSpecStarting(this);
 
2371
 
 
2372
  spec.env.currentSpec = spec;
 
2373
 
 
2374
  spec.addBeforesAndAftersToQueue();
 
2375
 
 
2376
  spec.queue.start(function () {
 
2377
    spec.finish(onComplete);
 
2378
  });
 
2379
};
 
2380
 
 
2381
jasmine.Spec.prototype.addBeforesAndAftersToQueue = function() {
 
2382
  var runner = this.env.currentRunner();
 
2383
  var i;
 
2384
 
 
2385
  for (var suite = this.suite; suite; suite = suite.parentSuite) {
 
2386
    for (i = 0; i < suite.before_.length; i++) {
 
2387
      this.queue.addBefore(new jasmine.Block(this.env, suite.before_[i], this));
 
2388
    }
 
2389
  }
 
2390
  for (i = 0; i < runner.before_.length; i++) {
 
2391
    this.queue.addBefore(new jasmine.Block(this.env, runner.before_[i], this));
 
2392
  }
 
2393
  for (i = 0; i < this.afterCallbacks.length; i++) {
 
2394
    this.queue.add(new jasmine.Block(this.env, this.afterCallbacks[i], this), true);
 
2395
  }
 
2396
  for (suite = this.suite; suite; suite = suite.parentSuite) {
 
2397
    for (i = 0; i < suite.after_.length; i++) {
 
2398
      this.queue.add(new jasmine.Block(this.env, suite.after_[i], this), true);
 
2399
    }
 
2400
  }
 
2401
  for (i = 0; i < runner.after_.length; i++) {
 
2402
    this.queue.add(new jasmine.Block(this.env, runner.after_[i], this), true);
 
2403
  }
 
2404
};
 
2405
 
 
2406
jasmine.Spec.prototype.explodes = function() {
 
2407
  throw 'explodes function should not have been called';
 
2408
};
 
2409
 
 
2410
jasmine.Spec.prototype.spyOn = function(obj, methodName, ignoreMethodDoesntExist) {
 
2411
  if (obj == jasmine.undefined) {
 
2412
    throw "spyOn could not find an object to spy upon for " + methodName + "()";
 
2413
  }
 
2414
 
 
2415
  if (!ignoreMethodDoesntExist && obj[methodName] === jasmine.undefined) {
 
2416
    throw methodName + '() method does not exist';
 
2417
  }
 
2418
 
 
2419
  if (!ignoreMethodDoesntExist && obj[methodName] && obj[methodName].isSpy) {
 
2420
    throw new Error(methodName + ' has already been spied upon');
 
2421
  }
 
2422
 
 
2423
  var spyObj = jasmine.createSpy(methodName);
 
2424
 
 
2425
  this.spies_.push(spyObj);
 
2426
  spyObj.baseObj = obj;
 
2427
  spyObj.methodName = methodName;
 
2428
  spyObj.originalValue = obj[methodName];
 
2429
 
 
2430
  obj[methodName] = spyObj;
 
2431
 
 
2432
  return spyObj;
 
2433
};
 
2434
 
 
2435
jasmine.Spec.prototype.removeAllSpies = function() {
 
2436
  for (var i = 0; i < this.spies_.length; i++) {
 
2437
    var spy = this.spies_[i];
 
2438
    spy.baseObj[spy.methodName] = spy.originalValue;
 
2439
  }
 
2440
  this.spies_ = [];
 
2441
};
 
2442
 
 
2443
/**
 
2444
 * Internal representation of a Jasmine suite.
 
2445
 *
 
2446
 * @constructor
 
2447
 * @param {jasmine.Env} env
 
2448
 * @param {String} description
 
2449
 * @param {Function} specDefinitions
 
2450
 * @param {jasmine.Suite} parentSuite
 
2451
 */
 
2452
jasmine.Suite = function(env, description, specDefinitions, parentSuite) {
 
2453
  var self = this;
 
2454
  self.id = env.nextSuiteId ? env.nextSuiteId() : null;
 
2455
  self.description = description;
 
2456
  self.queue = new jasmine.Queue(env);
 
2457
  self.parentSuite = parentSuite;
 
2458
  self.env = env;
 
2459
  self.before_ = [];
 
2460
  self.after_ = [];
 
2461
  self.children_ = [];
 
2462
  self.suites_ = [];
 
2463
  self.specs_ = [];
 
2464
};
 
2465
 
 
2466
jasmine.Suite.prototype.getFullName = function() {
 
2467
  var fullName = this.description;
 
2468
  for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) {
 
2469
    fullName = parentSuite.description + ' ' + fullName;
 
2470
  }
 
2471
  return fullName;
 
2472
};
 
2473
 
 
2474
jasmine.Suite.prototype.finish = function(onComplete) {
 
2475
  this.env.reporter.reportSuiteResults(this);
 
2476
  this.finished = true;
 
2477
  if (typeof(onComplete) == 'function') {
 
2478
    onComplete();
 
2479
  }
 
2480
};
 
2481
 
 
2482
jasmine.Suite.prototype.beforeEach = function(beforeEachFunction) {
 
2483
  beforeEachFunction.typeName = 'beforeEach';
 
2484
  this.before_.unshift(beforeEachFunction);
 
2485
};
 
2486
 
 
2487
jasmine.Suite.prototype.afterEach = function(afterEachFunction) {
 
2488
  afterEachFunction.typeName = 'afterEach';
 
2489
  this.after_.unshift(afterEachFunction);
 
2490
};
 
2491
 
 
2492
jasmine.Suite.prototype.results = function() {
 
2493
  return this.queue.results();
 
2494
};
 
2495
 
 
2496
jasmine.Suite.prototype.add = function(suiteOrSpec) {
 
2497
  this.children_.push(suiteOrSpec);
 
2498
  if (suiteOrSpec instanceof jasmine.Suite) {
 
2499
    this.suites_.push(suiteOrSpec);
 
2500
    this.env.currentRunner().addSuite(suiteOrSpec);
 
2501
  } else {
 
2502
    this.specs_.push(suiteOrSpec);
 
2503
  }
 
2504
  this.queue.add(suiteOrSpec);
 
2505
};
 
2506
 
 
2507
jasmine.Suite.prototype.specs = function() {
 
2508
  return this.specs_;
 
2509
};
 
2510
 
 
2511
jasmine.Suite.prototype.suites = function() {
 
2512
  return this.suites_;
 
2513
};
 
2514
 
 
2515
jasmine.Suite.prototype.children = function() {
 
2516
  return this.children_;
 
2517
};
 
2518
 
 
2519
jasmine.Suite.prototype.execute = function(onComplete) {
 
2520
  var self = this;
 
2521
  this.queue.start(function () {
 
2522
    self.finish(onComplete);
 
2523
  });
 
2524
};
 
2525
jasmine.WaitsBlock = function(env, timeout, spec) {
 
2526
  this.timeout = timeout;
 
2527
  jasmine.Block.call(this, env, null, spec);
 
2528
};
 
2529
 
 
2530
jasmine.util.inherit(jasmine.WaitsBlock, jasmine.Block);
 
2531
 
 
2532
jasmine.WaitsBlock.prototype.execute = function (onComplete) {
 
2533
  if (jasmine.VERBOSE) {
 
2534
    this.env.reporter.log('>> Jasmine waiting for ' + this.timeout + ' ms...');
 
2535
  }
 
2536
  this.env.setTimeout(function () {
 
2537
    onComplete();
 
2538
  }, this.timeout);
 
2539
};
 
2540
/**
 
2541
 * A block which waits for some condition to become true, with timeout.
 
2542
 *
 
2543
 * @constructor
 
2544
 * @extends jasmine.Block
 
2545
 * @param {jasmine.Env} env The Jasmine environment.
 
2546
 * @param {Number} timeout The maximum time in milliseconds to wait for the condition to become true.
 
2547
 * @param {Function} latchFunction A function which returns true when the desired condition has been met.
 
2548
 * @param {String} message The message to display if the desired condition hasn't been met within the given time period.
 
2549
 * @param {jasmine.Spec} spec The Jasmine spec.
 
2550
 */
 
2551
jasmine.WaitsForBlock = function(env, timeout, latchFunction, message, spec) {
 
2552
  this.timeout = timeout || env.defaultTimeoutInterval;
 
2553
  this.latchFunction = latchFunction;
 
2554
  this.message = message;
 
2555
  this.totalTimeSpentWaitingForLatch = 0;
 
2556
  jasmine.Block.call(this, env, null, spec);
 
2557
};
 
2558
jasmine.util.inherit(jasmine.WaitsForBlock, jasmine.Block);
 
2559
 
 
2560
jasmine.WaitsForBlock.TIMEOUT_INCREMENT = 10;
 
2561
 
 
2562
jasmine.WaitsForBlock.prototype.execute = function(onComplete) {
 
2563
  if (jasmine.VERBOSE) {
 
2564
    this.env.reporter.log('>> Jasmine waiting for ' + (this.message || 'something to happen'));
 
2565
  }
 
2566
  var latchFunctionResult;
 
2567
  try {
 
2568
    latchFunctionResult = this.latchFunction.apply(this.spec);
 
2569
  } catch (e) {
 
2570
    this.spec.fail(e);
 
2571
    onComplete();
 
2572
    return;
 
2573
  }
 
2574
 
 
2575
  if (latchFunctionResult) {
 
2576
    onComplete();
 
2577
  } else if (this.totalTimeSpentWaitingForLatch >= this.timeout) {
 
2578
    var message = 'timed out after ' + this.timeout + ' msec waiting for ' + (this.message || 'something to happen');
 
2579
    this.spec.fail({
 
2580
      name: 'timeout',
 
2581
      message: message
 
2582
    });
 
2583
 
 
2584
    this.abort = true;
 
2585
    onComplete();
 
2586
  } else {
 
2587
    this.totalTimeSpentWaitingForLatch += jasmine.WaitsForBlock.TIMEOUT_INCREMENT;
 
2588
    var self = this;
 
2589
    this.env.setTimeout(function() {
 
2590
      self.execute(onComplete);
 
2591
    }, jasmine.WaitsForBlock.TIMEOUT_INCREMENT);
 
2592
  }
 
2593
};
 
2594
 
 
2595
jasmine.version_= {
 
2596
  "major": 1,
 
2597
  "minor": 3,
 
2598
  "build": 1,
 
2599
  "revision": 1354556913
 
2600
};