gravityframework 0.0.2

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