Bug:Fix file validation issue
[vnfsdk/refrepo.git] / vnfmarket / src / main / webapp / vnfmarket / node_modules / karma-jasmine / lib / jasmine.js
1 /*
2 Copyright (c) 2008-2013 Pivotal Labs
3
4 Permission is hereby granted, free of charge, to any person obtaining
5 a copy of this software and associated documentation files (the
6 "Software"), to deal in the Software without restriction, including
7 without limitation the rights to use, copy, modify, merge, publish,
8 distribute, sublicense, and/or sell copies of the Software, and to
9 permit persons to whom the Software is furnished to do so, subject to
10 the following conditions:
11
12 The above copyright notice and this permission notice shall be
13 included in all copies or substantial portions of the Software.
14
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23 function getJasmineRequireObj() {
24   if (typeof module !== "undefined" && module.exports) {
25     return exports;
26   } else {
27     window.jasmineRequire = window.jasmineRequire || {};
28     return window.jasmineRequire;
29   }
30 }
31
32 getJasmineRequireObj().core = function(jRequire) {
33   var j$ = {};
34
35   jRequire.base(j$);
36   j$.util = jRequire.util();
37   j$.Any = jRequire.Any();
38   j$.CallTracker = jRequire.CallTracker();
39   j$.Clock = jRequire.Clock();
40   j$.DelayedFunctionScheduler = jRequire.DelayedFunctionScheduler();
41   j$.Env = jRequire.Env(j$);
42   j$.ExceptionFormatter = jRequire.ExceptionFormatter();
43   j$.Expectation = jRequire.Expectation();
44   j$.buildExpectationResult = jRequire.buildExpectationResult();
45   j$.JsApiReporter = jRequire.JsApiReporter();
46   j$.matchersUtil = jRequire.matchersUtil(j$);
47   j$.ObjectContaining = jRequire.ObjectContaining(j$);
48   j$.pp = jRequire.pp(j$);
49   j$.QueueRunner = jRequire.QueueRunner();
50   j$.ReportDispatcher = jRequire.ReportDispatcher();
51   j$.Spec = jRequire.Spec(j$);
52   j$.SpyStrategy = jRequire.SpyStrategy();
53   j$.Suite = jRequire.Suite();
54   j$.Timer = jRequire.Timer();
55   j$.version = jRequire.version();
56
57   j$.matchers = jRequire.requireMatchers(jRequire, j$);
58
59   return j$;
60 };
61
62 getJasmineRequireObj().requireMatchers = function(jRequire, j$) {
63   var availableMatchers = [
64       "toBe",
65       "toBeCloseTo",
66       "toBeDefined",
67       "toBeFalsy",
68       "toBeGreaterThan",
69       "toBeLessThan",
70       "toBeNaN",
71       "toBeNull",
72       "toBeTruthy",
73       "toBeUndefined",
74       "toContain",
75       "toEqual",
76       "toHaveBeenCalled",
77       "toHaveBeenCalledWith",
78       "toMatch",
79       "toThrow",
80       "toThrowError"
81     ],
82     matchers = {};
83
84   for (var i = 0; i < availableMatchers.length; i++) {
85     var name = availableMatchers[i];
86     matchers[name] = jRequire[name](j$);
87   }
88
89   return matchers;
90 };
91
92 getJasmineRequireObj().base = function(j$) {
93   j$.unimplementedMethod_ = function() {
94     throw new Error("unimplemented method");
95   };
96
97   j$.MAX_PRETTY_PRINT_DEPTH = 40;
98   j$.DEFAULT_TIMEOUT_INTERVAL = 5000;
99
100   j$.getGlobal = (function() {
101     var jasmineGlobal = eval.call(null, "this");
102     return function() {
103       return jasmineGlobal;
104     };
105   })();
106
107   j$.getEnv = function(options) {
108     var env = j$.currentEnv_ = j$.currentEnv_ || new j$.Env(options);
109     //jasmine. singletons in here (setTimeout blah blah).
110     return env;
111   };
112
113   j$.isArray_ = function(value) {
114     return j$.isA_("Array", value);
115   };
116
117   j$.isString_ = function(value) {
118     return j$.isA_("String", value);
119   };
120
121   j$.isNumber_ = function(value) {
122     return j$.isA_("Number", value);
123   };
124
125   j$.isA_ = function(typeName, value) {
126     return Object.prototype.toString.apply(value) === '[object ' + typeName + ']';
127   };
128
129   j$.isDomNode = function(obj) {
130     return obj.nodeType > 0;
131   };
132
133   j$.any = function(clazz) {
134     return new j$.Any(clazz);
135   };
136
137   j$.objectContaining = function(sample) {
138     return new j$.ObjectContaining(sample);
139   };
140
141   j$.createSpy = function(name, originalFn) {
142
143     var spyStrategy = new j$.SpyStrategy({
144         name: name,
145         fn: originalFn,
146         getSpy: function() { return spy; }
147       }),
148       callTracker = new j$.CallTracker(),
149       spy = function() {
150         callTracker.track({
151           object: this,
152           args: Array.prototype.slice.apply(arguments)
153         });
154         return spyStrategy.exec.apply(this, arguments);
155       };
156
157     for (var prop in originalFn) {
158       if (prop === 'and' || prop === 'calls') {
159         throw new Error("Jasmine spies would overwrite the 'and' and 'calls' properties on the object being spied upon");
160       }
161
162       spy[prop] = originalFn[prop];
163     }
164
165     spy.and = spyStrategy;
166     spy.calls = callTracker;
167
168     return spy;
169   };
170
171   j$.isSpy = function(putativeSpy) {
172     if (!putativeSpy) {
173       return false;
174     }
175     return putativeSpy.and instanceof j$.SpyStrategy &&
176       putativeSpy.calls instanceof j$.CallTracker;
177   };
178
179   j$.createSpyObj = function(baseName, methodNames) {
180     if (!j$.isArray_(methodNames) || methodNames.length === 0) {
181       throw "createSpyObj requires a non-empty array of method names to create spies for";
182     }
183     var obj = {};
184     for (var i = 0; i < methodNames.length; i++) {
185       obj[methodNames[i]] = j$.createSpy(baseName + '.' + methodNames[i]);
186     }
187     return obj;
188   };
189 };
190
191 getJasmineRequireObj().util = function() {
192
193   var util = {};
194
195   util.inherit = function(childClass, parentClass) {
196     var Subclass = function() {
197     };
198     Subclass.prototype = parentClass.prototype;
199     childClass.prototype = new Subclass();
200   };
201
202   util.htmlEscape = function(str) {
203     if (!str) {
204       return str;
205     }
206     return str.replace(/&/g, '&amp;')
207       .replace(/</g, '&lt;')
208       .replace(/>/g, '&gt;');
209   };
210
211   util.argsToArray = function(args) {
212     var arrayOfArgs = [];
213     for (var i = 0; i < args.length; i++) {
214       arrayOfArgs.push(args[i]);
215     }
216     return arrayOfArgs;
217   };
218
219   util.isUndefined = function(obj) {
220     return obj === void 0;
221   };
222
223   return util;
224 };
225
226 getJasmineRequireObj().Spec = function(j$) {
227   function Spec(attrs) {
228     this.expectationFactory = attrs.expectationFactory;
229     this.resultCallback = attrs.resultCallback || function() {};
230     this.id = attrs.id;
231     this.description = attrs.description || '';
232     this.fn = attrs.fn;
233     this.beforeFns = attrs.beforeFns || function() { return []; };
234     this.afterFns = attrs.afterFns || function() { return []; };
235     this.onStart = attrs.onStart || function() {};
236     this.exceptionFormatter = attrs.exceptionFormatter || function() {};
237     this.getSpecName = attrs.getSpecName || function() { return ''; };
238     this.expectationResultFactory = attrs.expectationResultFactory || function() { };
239     this.queueRunnerFactory = attrs.queueRunnerFactory || function() {};
240     this.catchingExceptions = attrs.catchingExceptions || function() { return true; };
241
242     this.timer = attrs.timer || {setTimeout: setTimeout, clearTimeout: clearTimeout};
243
244     if (!this.fn) {
245       this.pend();
246     }
247
248     this.result = {
249       id: this.id,
250       description: this.description,
251       fullName: this.getFullName(),
252       failedExpectations: []
253     };
254   }
255
256   Spec.prototype.addExpectationResult = function(passed, data) {
257     if (passed) {
258       return;
259     }
260     this.result.failedExpectations.push(this.expectationResultFactory(data));
261   };
262
263   Spec.prototype.expect = function(actual) {
264     return this.expectationFactory(actual, this);
265   };
266
267   Spec.prototype.execute = function(onComplete) {
268     var self = this,
269         timeout;
270
271     this.onStart(this);
272
273     if (this.markedPending || this.disabled) {
274       complete();
275       return;
276     }
277
278     function timeoutable(fn) {
279       return function(done) {
280         timeout = Function.prototype.apply.apply(self.timer.setTimeout, [j$.getGlobal(), [function() {
281           onException(new Error('Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.'));
282           done();
283         }, j$.DEFAULT_TIMEOUT_INTERVAL]]);
284
285         var callDone = function() {
286           clearTimeoutable();
287           done();
288         };
289
290         fn.call(this, callDone); //TODO: do we care about more than 1 arg?
291       };
292     }
293
294     function clearTimeoutable() {
295       Function.prototype.apply.apply(self.timer.clearTimeout, [j$.getGlobal(), [timeout]]);
296       timeout = void 0;
297     }
298
299     var allFns = this.beforeFns().concat(this.fn).concat(this.afterFns()),
300       allTimeoutableFns = [];
301     for (var i = 0; i < allFns.length; i++) {
302       var fn = allFns[i];
303       allTimeoutableFns.push(fn.length > 0 ? timeoutable(fn) : fn);
304     }
305
306     this.queueRunnerFactory({
307       fns: allTimeoutableFns,
308       onException: onException,
309       onComplete: complete
310     });
311
312     function onException(e) {
313       clearTimeoutable();
314       if (Spec.isPendingSpecException(e)) {
315         self.pend();
316         return;
317       }
318
319       self.addExpectationResult(false, {
320         matcherName: "",
321         passed: false,
322         expected: "",
323         actual: "",
324         error: e
325       });
326     }
327
328     function complete() {
329       self.result.status = self.status();
330       self.resultCallback(self.result);
331
332       if (onComplete) {
333         onComplete();
334       }
335     }
336   };
337
338   Spec.prototype.disable = function() {
339     this.disabled = true;
340   };
341
342   Spec.prototype.pend = function() {
343     this.markedPending = true;
344   };
345
346   Spec.prototype.status = function() {
347     if (this.disabled) {
348       return 'disabled';
349     }
350
351     if (this.markedPending) {
352       return 'pending';
353     }
354
355     if (this.result.failedExpectations.length > 0) {
356       return 'failed';
357     } else {
358       return 'passed';
359     }
360   };
361
362   Spec.prototype.getFullName = function() {
363     return this.getSpecName(this);
364   };
365
366   Spec.pendingSpecExceptionMessage = "=> marked Pending";
367
368   Spec.isPendingSpecException = function(e) {
369     return e.toString().indexOf(Spec.pendingSpecExceptionMessage) !== -1;
370   };
371
372   return Spec;
373 };
374
375 if (typeof window == void 0 && typeof exports == "object") {
376   exports.Spec = jasmineRequire.Spec;
377 }
378
379 getJasmineRequireObj().Env = function(j$) {
380   function Env(options) {
381     options = options || {};
382
383     var self = this;
384     var global = options.global || j$.getGlobal();
385
386     var totalSpecsDefined = 0;
387
388     var catchExceptions = true;
389
390     var realSetTimeout = j$.getGlobal().setTimeout;
391     var realClearTimeout = j$.getGlobal().clearTimeout;
392     this.clock = new j$.Clock(global, new j$.DelayedFunctionScheduler());
393
394     var runnableLookupTable = {};
395
396     var spies = [];
397
398     var currentSpec = null;
399     var currentSuite = null;
400
401     var reporter = new j$.ReportDispatcher([
402       "jasmineStarted",
403       "jasmineDone",
404       "suiteStarted",
405       "suiteDone",
406       "specStarted",
407       "specDone"
408     ]);
409
410     this.specFilter = function() {
411       return true;
412     };
413
414     var equalityTesters = [];
415
416     var customEqualityTesters = [];
417     this.addCustomEqualityTester = function(tester) {
418       customEqualityTesters.push(tester);
419     };
420
421     j$.Expectation.addCoreMatchers(j$.matchers);
422
423     var nextSpecId = 0;
424     var getNextSpecId = function() {
425       return 'spec' + nextSpecId++;
426     };
427
428     var nextSuiteId = 0;
429     var getNextSuiteId = function() {
430       return 'suite' + nextSuiteId++;
431     };
432
433     var expectationFactory = function(actual, spec) {
434       return j$.Expectation.Factory({
435         util: j$.matchersUtil,
436         customEqualityTesters: customEqualityTesters,
437         actual: actual,
438         addExpectationResult: addExpectationResult
439       });
440
441       function addExpectationResult(passed, result) {
442         return spec.addExpectationResult(passed, result);
443       }
444     };
445
446     var specStarted = function(spec) {
447       currentSpec = spec;
448       reporter.specStarted(spec.result);
449     };
450
451     var beforeFns = function(suite) {
452       return function() {
453         var befores = [];
454         while(suite) {
455           befores = befores.concat(suite.beforeFns);
456           suite = suite.parentSuite;
457         }
458         return befores.reverse();
459       };
460     };
461
462     var afterFns = function(suite) {
463       return function() {
464         var afters = [];
465         while(suite) {
466           afters = afters.concat(suite.afterFns);
467           suite = suite.parentSuite;
468         }
469         return afters;
470       };
471     };
472
473     var getSpecName = function(spec, suite) {
474       return suite.getFullName() + ' ' + spec.description;
475     };
476
477     // TODO: we may just be able to pass in the fn instead of wrapping here
478     var buildExpectationResult = j$.buildExpectationResult,
479         exceptionFormatter = new j$.ExceptionFormatter(),
480         expectationResultFactory = function(attrs) {
481           attrs.messageFormatter = exceptionFormatter.message;
482           attrs.stackFormatter = exceptionFormatter.stack;
483
484           return buildExpectationResult(attrs);
485         };
486
487     // TODO: fix this naming, and here's where the value comes in
488     this.catchExceptions = function(value) {
489       catchExceptions = !!value;
490       return catchExceptions;
491     };
492
493     this.catchingExceptions = function() {
494       return catchExceptions;
495     };
496
497     var maximumSpecCallbackDepth = 20;
498     var currentSpecCallbackDepth = 0;
499
500     function clearStack(fn) {
501       currentSpecCallbackDepth++;
502       if (currentSpecCallbackDepth >= maximumSpecCallbackDepth) {
503         currentSpecCallbackDepth = 0;
504         realSetTimeout(fn, 0);
505       } else {
506         fn();
507       }
508     }
509
510     var catchException = function(e) {
511       return j$.Spec.isPendingSpecException(e) || catchExceptions;
512     };
513
514     var queueRunnerFactory = function(options) {
515       options.catchException = catchException;
516       options.clearStack = options.clearStack || clearStack;
517
518       new j$.QueueRunner(options).execute();
519     };
520
521     var topSuite = new j$.Suite({
522       env: this,
523       id: getNextSuiteId(),
524       description: 'Jasmine__TopLevel__Suite',
525       queueRunner: queueRunnerFactory,
526       resultCallback: function() {} // TODO - hook this up
527     });
528     runnableLookupTable[topSuite.id] = topSuite;
529     currentSuite = topSuite;
530
531     this.topSuite = function() {
532       return topSuite;
533     };
534
535     this.execute = function(runnablesToRun) {
536       runnablesToRun = runnablesToRun || [topSuite.id];
537
538       var allFns = [];
539       for(var i = 0; i < runnablesToRun.length; i++) {
540         var runnable = runnableLookupTable[runnablesToRun[i]];
541         allFns.push((function(runnable) { return function(done) { runnable.execute(done); }; })(runnable));
542       }
543
544       reporter.jasmineStarted({
545         totalSpecsDefined: totalSpecsDefined
546       });
547
548       queueRunnerFactory({fns: allFns, onComplete: reporter.jasmineDone});
549     };
550
551     this.addReporter = function(reporterToAdd) {
552       reporter.addReporter(reporterToAdd);
553     };
554
555     this.addMatchers = function(matchersToAdd) {
556       j$.Expectation.addMatchers(matchersToAdd);
557     };
558
559     this.spyOn = function(obj, methodName) {
560       if (j$.util.isUndefined(obj)) {
561         throw new Error("spyOn could not find an object to spy upon for " + methodName + "()");
562       }
563
564       if (j$.util.isUndefined(obj[methodName])) {
565         throw new Error(methodName + '() method does not exist');
566       }
567
568       if (obj[methodName] && j$.isSpy(obj[methodName])) {
569         //TODO?: should this return the current spy? Downside: may cause user confusion about spy state
570         throw new Error(methodName + ' has already been spied upon');
571       }
572
573       var spy = j$.createSpy(methodName, obj[methodName]);
574
575       spies.push({
576         spy: spy,
577         baseObj: obj,
578         methodName: methodName,
579         originalValue: obj[methodName]
580       });
581
582       obj[methodName] = spy;
583
584       return spy;
585     };
586
587     var suiteFactory = function(description) {
588       var suite = new j$.Suite({
589         env: self,
590         id: getNextSuiteId(),
591         description: description,
592         parentSuite: currentSuite,
593         queueRunner: queueRunnerFactory,
594         onStart: suiteStarted,
595         resultCallback: function(attrs) {
596           reporter.suiteDone(attrs);
597         }
598       });
599
600       runnableLookupTable[suite.id] = suite;
601       return suite;
602     };
603
604     this.describe = function(description, specDefinitions) {
605       var suite = suiteFactory(description);
606
607       var parentSuite = currentSuite;
608       parentSuite.addChild(suite);
609       currentSuite = suite;
610
611       var declarationError = null;
612       try {
613         specDefinitions.call(suite);
614       } catch (e) {
615         declarationError = e;
616       }
617
618       if (declarationError) {
619         this.it("encountered a declaration exception", function() {
620           throw declarationError;
621         });
622       }
623
624       currentSuite = parentSuite;
625
626       return suite;
627     };
628
629     this.xdescribe = function(description, specDefinitions) {
630       var suite = this.describe(description, specDefinitions);
631       suite.disable();
632       return suite;
633     };
634
635     var specFactory = function(description, fn, suite) {
636       totalSpecsDefined++;
637
638       var spec = new j$.Spec({
639         id: getNextSpecId(),
640         beforeFns: beforeFns(suite),
641         afterFns: afterFns(suite),
642         expectationFactory: expectationFactory,
643         exceptionFormatter: exceptionFormatter,
644         resultCallback: specResultCallback,
645         getSpecName: function(spec) {
646           return getSpecName(spec, suite);
647         },
648         onStart: specStarted,
649         description: description,
650         expectationResultFactory: expectationResultFactory,
651         queueRunnerFactory: queueRunnerFactory,
652         fn: fn,
653         timer: {setTimeout: realSetTimeout, clearTimeout: realClearTimeout}
654       });
655
656       runnableLookupTable[spec.id] = spec;
657
658       if (!self.specFilter(spec)) {
659         spec.disable();
660       }
661
662       return spec;
663
664       function removeAllSpies() {
665         for (var i = 0; i < spies.length; i++) {
666           var spyEntry = spies[i];
667           spyEntry.baseObj[spyEntry.methodName] = spyEntry.originalValue;
668         }
669         spies = [];
670       }
671
672       function specResultCallback(result) {
673         removeAllSpies();
674         j$.Expectation.resetMatchers();
675         customEqualityTesters = [];
676         currentSpec = null;
677         reporter.specDone(result);
678       }
679     };
680
681     var suiteStarted = function(suite) {
682       reporter.suiteStarted(suite.result);
683     };
684
685     this.it = function(description, fn) {
686       var spec = specFactory(description, fn, currentSuite);
687       currentSuite.addChild(spec);
688       return spec;
689     };
690
691     this.xit = function(description, fn) {
692       var spec = this.it(description, fn);
693       spec.pend();
694       return spec;
695     };
696
697     this.expect = function(actual) {
698       return currentSpec.expect(actual);
699     };
700
701     this.beforeEach = function(beforeEachFunction) {
702       currentSuite.beforeEach(beforeEachFunction);
703     };
704
705     this.afterEach = function(afterEachFunction) {
706       currentSuite.afterEach(afterEachFunction);
707     };
708
709     this.pending = function() {
710       throw j$.Spec.pendingSpecExceptionMessage;
711     };
712   }
713
714   return Env;
715 };
716
717 getJasmineRequireObj().JsApiReporter = function() {
718
719   var noopTimer = {
720     start: function(){},
721     elapsed: function(){ return 0; }
722   };
723
724   function JsApiReporter(options) {
725     var timer = options.timer || noopTimer,
726         status = "loaded";
727
728     this.started = false;
729     this.finished = false;
730
731     this.jasmineStarted = function() {
732       this.started = true;
733       status = 'started';
734       timer.start();
735     };
736
737     var executionTime;
738
739     this.jasmineDone = function() {
740       this.finished = true;
741       executionTime = timer.elapsed();
742       status = 'done';
743     };
744
745     this.status = function() {
746       return status;
747     };
748
749     var suites = {};
750
751     this.suiteStarted = function(result) {
752       storeSuite(result);
753     };
754
755     this.suiteDone = function(result) {
756       storeSuite(result);
757     };
758
759     function storeSuite(result) {
760       suites[result.id] = result;
761     }
762
763     this.suites = function() {
764       return suites;
765     };
766
767     var specs = [];
768     this.specStarted = function(result) { };
769
770     this.specDone = function(result) {
771       specs.push(result);
772     };
773
774     this.specResults = function(index, length) {
775       return specs.slice(index, index + length);
776     };
777
778     this.specs = function() {
779       return specs;
780     };
781
782     this.executionTime = function() {
783       return executionTime;
784     };
785
786   }
787
788   return JsApiReporter;
789 };
790
791 getJasmineRequireObj().Any = function() {
792
793   function Any(expectedObject) {
794     this.expectedObject = expectedObject;
795   }
796
797   Any.prototype.jasmineMatches = function(other) {
798     if (this.expectedObject == String) {
799       return typeof other == 'string' || other instanceof String;
800     }
801
802     if (this.expectedObject == Number) {
803       return typeof other == 'number' || other instanceof Number;
804     }
805
806     if (this.expectedObject == Function) {
807       return typeof other == 'function' || other instanceof Function;
808     }
809
810     if (this.expectedObject == Object) {
811       return typeof other == 'object';
812     }
813     
814     if (this.expectedObject == Boolean) {
815       return typeof other == 'boolean';
816     }
817
818     return other instanceof this.expectedObject;
819   };
820
821   Any.prototype.jasmineToString = function() {
822     return '<jasmine.any(' + this.expectedClass + ')>';
823   };
824
825   return Any;
826 };
827
828 getJasmineRequireObj().CallTracker = function() {
829
830   function CallTracker() {
831     var calls = [];
832
833     this.track = function(context) {
834       calls.push(context);
835     };
836
837     this.any = function() {
838       return !!calls.length;
839     };
840
841     this.count = function() {
842       return calls.length;
843     };
844
845     this.argsFor = function(index) {
846       var call = calls[index];
847       return call ? call.args : [];
848     };
849
850     this.all = function() {
851       return calls;
852     };
853
854     this.allArgs = function() {
855       var callArgs = [];
856       for(var i = 0; i < calls.length; i++){
857         callArgs.push(calls[i].args);
858       }
859
860       return callArgs;
861     };
862
863     this.first = function() {
864       return calls[0];
865     };
866
867     this.mostRecent = function() {
868       return calls[calls.length - 1];
869     };
870
871     this.reset = function() {
872       calls = [];
873     };
874   }
875
876   return CallTracker;
877 };
878
879 getJasmineRequireObj().Clock = function() {
880   function Clock(global, delayedFunctionScheduler) {
881     var self = this,
882       realTimingFunctions = {
883         setTimeout: global.setTimeout,
884         clearTimeout: global.clearTimeout,
885         setInterval: global.setInterval,
886         clearInterval: global.clearInterval
887       },
888       fakeTimingFunctions = {
889         setTimeout: setTimeout,
890         clearTimeout: clearTimeout,
891         setInterval: setInterval,
892         clearInterval: clearInterval
893       },
894       installed = false,
895       timer;
896
897     self.install = function() {
898       replace(global, fakeTimingFunctions);
899       timer = fakeTimingFunctions;
900       installed = true;
901     };
902
903     self.uninstall = function() {
904       delayedFunctionScheduler.reset();
905       replace(global, realTimingFunctions);
906       timer = realTimingFunctions;
907       installed = false;
908     };
909
910     self.setTimeout = function(fn, delay, params) {
911       if (legacyIE()) {
912         if (arguments.length > 2) {
913           throw new Error("IE < 9 cannot support extra params to setTimeout without a polyfill");
914         }
915         return timer.setTimeout(fn, delay);
916       }
917       return Function.prototype.apply.apply(timer.setTimeout, [global, arguments]);
918     };
919
920     self.setInterval = function(fn, delay, params) {
921       if (legacyIE()) {
922         if (arguments.length > 2) {
923           throw new Error("IE < 9 cannot support extra params to setInterval without a polyfill");
924         }
925         return timer.setInterval(fn, delay);
926       }
927       return Function.prototype.apply.apply(timer.setInterval, [global, arguments]);
928     };
929
930     self.clearTimeout = function(id) {
931       return Function.prototype.call.apply(timer.clearTimeout, [global, id]);
932     };
933
934     self.clearInterval = function(id) {
935       return Function.prototype.call.apply(timer.clearInterval, [global, id]);
936     };
937
938     self.tick = function(millis) {
939       if (installed) {
940         delayedFunctionScheduler.tick(millis);
941       } else {
942         throw new Error("Mock clock is not installed, use jasmine.clock().install()");
943       }
944     };
945
946     return self;
947
948     function legacyIE() {
949       //if these methods are polyfilled, apply will be present
950       return !(realTimingFunctions.setTimeout || realTimingFunctions.setInterval).apply;
951     }
952
953     function replace(dest, source) {
954       for (var prop in source) {
955         dest[prop] = source[prop];
956       }
957     }
958
959     function setTimeout(fn, delay) {
960       return delayedFunctionScheduler.scheduleFunction(fn, delay, argSlice(arguments, 2));
961     }
962
963     function clearTimeout(id) {
964       return delayedFunctionScheduler.removeFunctionWithId(id);
965     }
966
967     function setInterval(fn, interval) {
968       return delayedFunctionScheduler.scheduleFunction(fn, interval, argSlice(arguments, 2), true);
969     }
970
971     function clearInterval(id) {
972       return delayedFunctionScheduler.removeFunctionWithId(id);
973     }
974
975     function argSlice(argsObj, n) {
976       return Array.prototype.slice.call(argsObj, 2);
977     }
978   }
979
980   return Clock;
981 };
982
983 getJasmineRequireObj().DelayedFunctionScheduler = function() {
984   function DelayedFunctionScheduler() {
985     var self = this;
986     var scheduledLookup = [];
987     var scheduledFunctions = {};
988     var currentTime = 0;
989     var delayedFnCount = 0;
990
991     self.tick = function(millis) {
992       millis = millis || 0;
993       var endTime = currentTime + millis;
994
995       runScheduledFunctions(endTime);
996       currentTime = endTime;
997     };
998
999     self.scheduleFunction = function(funcToCall, millis, params, recurring, timeoutKey, runAtMillis) {
1000       var f;
1001       if (typeof(funcToCall) === 'string') {
1002         /* jshint evil: true */
1003         f = function() { return eval(funcToCall); };
1004         /* jshint evil: false */
1005       } else {
1006         f = funcToCall;
1007       }
1008
1009       millis = millis || 0;
1010       timeoutKey = timeoutKey || ++delayedFnCount;
1011       runAtMillis = runAtMillis || (currentTime + millis);
1012
1013       var funcToSchedule = {
1014         runAtMillis: runAtMillis,
1015         funcToCall: f,
1016         recurring: recurring,
1017         params: params,
1018         timeoutKey: timeoutKey,
1019         millis: millis
1020       };
1021
1022       if (runAtMillis in scheduledFunctions) {
1023         scheduledFunctions[runAtMillis].push(funcToSchedule);
1024       } else {
1025         scheduledFunctions[runAtMillis] = [funcToSchedule];
1026         scheduledLookup.push(runAtMillis);
1027         scheduledLookup.sort(function (a, b) {
1028           return a - b;
1029         });
1030       }
1031
1032       return timeoutKey;
1033     };
1034
1035     self.removeFunctionWithId = function(timeoutKey) {
1036       for (var runAtMillis in scheduledFunctions) {
1037         var funcs = scheduledFunctions[runAtMillis];
1038         var i = indexOfFirstToPass(funcs, function (func) {
1039           return func.timeoutKey === timeoutKey;
1040         });
1041
1042         if (i > -1) {
1043           if (funcs.length === 1) {
1044             delete scheduledFunctions[runAtMillis];
1045             deleteFromLookup(runAtMillis);
1046           } else {
1047             funcs.splice(i, 1);
1048           }
1049
1050           // intervals get rescheduled when executed, so there's never more
1051           // than a single scheduled function with a given timeoutKey
1052           break;
1053         }
1054       }
1055     };
1056
1057     self.reset = function() {
1058       currentTime = 0;
1059       scheduledLookup = [];
1060       scheduledFunctions = {};
1061       delayedFnCount = 0;
1062     };
1063
1064     return self;
1065
1066     function indexOfFirstToPass(array, testFn) {
1067       var index = -1;
1068
1069       for (var i = 0; i < array.length; ++i) {
1070         if (testFn(array[i])) {
1071           index = i;
1072           break;
1073         }
1074       }
1075
1076       return index;
1077     }
1078
1079     function deleteFromLookup(key) {
1080       var value = Number(key);
1081       var i = indexOfFirstToPass(scheduledLookup, function (millis) {
1082         return millis === value;
1083       });
1084
1085       if (i > -1) {
1086         scheduledLookup.splice(i, 1);
1087       }
1088     }
1089
1090     function reschedule(scheduledFn) {
1091       self.scheduleFunction(scheduledFn.funcToCall,
1092         scheduledFn.millis,
1093         scheduledFn.params,
1094         true,
1095         scheduledFn.timeoutKey,
1096         scheduledFn.runAtMillis + scheduledFn.millis);
1097     }
1098
1099     function runScheduledFunctions(endTime) {
1100       if (scheduledLookup.length === 0 || scheduledLookup[0] > endTime) {
1101         return;
1102       }
1103
1104       do {
1105         currentTime = scheduledLookup.shift();
1106
1107         var funcsToRun = scheduledFunctions[currentTime];
1108         delete scheduledFunctions[currentTime];
1109
1110         for (var i = 0; i < funcsToRun.length; ++i) {
1111           var funcToRun = funcsToRun[i];
1112           funcToRun.funcToCall.apply(null, funcToRun.params || []);
1113
1114           if (funcToRun.recurring) {
1115             reschedule(funcToRun);
1116           }
1117         }
1118       } while (scheduledLookup.length > 0 &&
1119               // checking first if we're out of time prevents setTimeout(0)
1120               // scheduled in a funcToRun from forcing an extra iteration
1121                  currentTime !== endTime  &&
1122                  scheduledLookup[0] <= endTime);
1123     }
1124   }
1125
1126   return DelayedFunctionScheduler;
1127 };
1128
1129 getJasmineRequireObj().ExceptionFormatter = function() {
1130   function ExceptionFormatter() {
1131     this.message = function(error) {
1132       var message = error.name +
1133         ': ' +
1134         error.message;
1135
1136       if (error.fileName || error.sourceURL) {
1137         message += " in " + (error.fileName || error.sourceURL);
1138       }
1139
1140       if (error.line || error.lineNumber) {
1141         message += " (line " + (error.line || error.lineNumber) + ")";
1142       }
1143
1144       return message;
1145     };
1146
1147     this.stack = function(error) {
1148       return error ? error.stack : null;
1149     };
1150   }
1151
1152   return ExceptionFormatter;
1153 };
1154
1155 getJasmineRequireObj().Expectation = function() {
1156
1157   var matchers = {};
1158
1159   function Expectation(options) {
1160     this.util = options.util || { buildFailureMessage: function() {} };
1161     this.customEqualityTesters = options.customEqualityTesters || [];
1162     this.actual = options.actual;
1163     this.addExpectationResult = options.addExpectationResult || function(){};
1164     this.isNot = options.isNot;
1165
1166     for (var matcherName in matchers) {
1167       this[matcherName] = matchers[matcherName];
1168     }
1169   }
1170
1171   Expectation.prototype.wrapCompare = function(name, matcherFactory) {
1172     return function() {
1173       var args = Array.prototype.slice.call(arguments, 0),
1174         expected = args.slice(0),
1175         message = "";
1176
1177       args.unshift(this.actual);
1178
1179       var matcher = matcherFactory(this.util, this.customEqualityTesters),
1180           matcherCompare = matcher.compare;
1181
1182       function defaultNegativeCompare() {
1183         var result = matcher.compare.apply(null, args);
1184         result.pass = !result.pass;
1185         return result;
1186       }
1187
1188       if (this.isNot) {
1189         matcherCompare = matcher.negativeCompare || defaultNegativeCompare;
1190       }
1191
1192       var result = matcherCompare.apply(null, args);
1193
1194       if (!result.pass) {
1195         if (!result.message) {
1196           args.unshift(this.isNot);
1197           args.unshift(name);
1198           message = this.util.buildFailureMessage.apply(null, args);
1199         } else {
1200           message = result.message;
1201         }
1202       }
1203
1204       if (expected.length == 1) {
1205         expected = expected[0];
1206       }
1207
1208       // TODO: how many of these params are needed?
1209       this.addExpectationResult(
1210         result.pass,
1211         {
1212           matcherName: name,
1213           passed: result.pass,
1214           message: message,
1215           actual: this.actual,
1216           expected: expected // TODO: this may need to be arrayified/sliced
1217         }
1218       );
1219     };
1220   };
1221
1222   Expectation.addCoreMatchers = function(matchers) {
1223     var prototype = Expectation.prototype;
1224     for (var matcherName in matchers) {
1225       var matcher = matchers[matcherName];
1226       prototype[matcherName] = prototype.wrapCompare(matcherName, matcher);
1227     }
1228   };
1229
1230   Expectation.addMatchers = function(matchersToAdd) {
1231     for (var name in matchersToAdd) {
1232       var matcher = matchersToAdd[name];
1233       matchers[name] = Expectation.prototype.wrapCompare(name, matcher);
1234     }
1235   };
1236
1237   Expectation.resetMatchers = function() {
1238     for (var name in matchers) {
1239       delete matchers[name];
1240     }
1241   };
1242
1243   Expectation.Factory = function(options) {
1244     options = options || {};
1245
1246     var expect = new Expectation(options);
1247
1248     // TODO: this would be nice as its own Object - NegativeExpectation
1249     // TODO: copy instead of mutate options
1250     options.isNot = true;
1251     expect.not = new Expectation(options);
1252
1253     return expect;
1254   };
1255
1256   return Expectation;
1257 };
1258
1259 //TODO: expectation result may make more sense as a presentation of an expectation.
1260 getJasmineRequireObj().buildExpectationResult = function() {
1261   function buildExpectationResult(options) {
1262     var messageFormatter = options.messageFormatter || function() {},
1263       stackFormatter = options.stackFormatter || function() {};
1264
1265     return {
1266       matcherName: options.matcherName,
1267       expected: options.expected,
1268       actual: options.actual,
1269       message: message(),
1270       stack: stack(),
1271       passed: options.passed
1272     };
1273
1274     function message() {
1275       if (options.passed) {
1276         return "Passed.";
1277       } else if (options.message) {
1278         return options.message;
1279       } else if (options.error) {
1280         return messageFormatter(options.error);
1281       }
1282       return "";
1283     }
1284
1285     function stack() {
1286       if (options.passed) {
1287         return "";
1288       }
1289
1290       var error = options.error;
1291       if (!error) {
1292         try {
1293           throw new Error(message());
1294         } catch (e) {
1295           error = e;
1296         }
1297       }
1298       return stackFormatter(error);
1299     }
1300   }
1301
1302   return buildExpectationResult;
1303 };
1304
1305 getJasmineRequireObj().ObjectContaining = function(j$) {
1306
1307   function ObjectContaining(sample) {
1308     this.sample = sample;
1309   }
1310
1311   ObjectContaining.prototype.jasmineMatches = function(other, mismatchKeys, mismatchValues) {
1312     if (typeof(this.sample) !== "object") { throw new Error("You must provide an object to objectContaining, not '"+this.sample+"'."); }
1313
1314     mismatchKeys = mismatchKeys || [];
1315     mismatchValues = mismatchValues || [];
1316
1317     var hasKey = function(obj, keyName) {
1318       return obj !== null && !j$.util.isUndefined(obj[keyName]);
1319     };
1320
1321     for (var property in this.sample) {
1322       if (!hasKey(other, property) && hasKey(this.sample, property)) {
1323         mismatchKeys.push("expected has key '" + property + "', but missing from actual.");
1324       }
1325       else if (!j$.matchersUtil.equals(this.sample[property], other[property])) {
1326         mismatchValues.push("'" + property + "' was '" + (other[property] ? j$.util.htmlEscape(other[property].toString()) : other[property]) + "' in actual, but was '" + (this.sample[property] ? j$.util.htmlEscape(this.sample[property].toString()) : this.sample[property]) + "' in expected.");
1327       }
1328     }
1329
1330     return (mismatchKeys.length === 0 && mismatchValues.length === 0);
1331   };
1332
1333   ObjectContaining.prototype.jasmineToString = function() {
1334     return "<jasmine.objectContaining(" + j$.pp(this.sample) + ")>";
1335   };
1336
1337   return ObjectContaining;
1338 };
1339
1340 getJasmineRequireObj().pp = function(j$) {
1341
1342   function PrettyPrinter() {
1343     this.ppNestLevel_ = 0;
1344   }
1345
1346   PrettyPrinter.prototype.format = function(value) {
1347     this.ppNestLevel_++;
1348     try {
1349       if (j$.util.isUndefined(value)) {
1350         this.emitScalar('undefined');
1351       } else if (value === null) {
1352         this.emitScalar('null');
1353       } else if (value === j$.getGlobal()) {
1354         this.emitScalar('<global>');
1355       } else if (value.jasmineToString) {
1356         this.emitScalar(value.jasmineToString());
1357       } else if (typeof value === 'string') {
1358         this.emitString(value);
1359       } else if (j$.isSpy(value)) {
1360         this.emitScalar("spy on " + value.and.identity());
1361       } else if (value instanceof RegExp) {
1362         this.emitScalar(value.toString());
1363       } else if (typeof value === 'function') {
1364         this.emitScalar('Function');
1365       } else if (typeof value.nodeType === 'number') {
1366         this.emitScalar('HTMLNode');
1367       } else if (value instanceof Date) {
1368         this.emitScalar('Date(' + value + ')');
1369       } else if (value.__Jasmine_been_here_before__) {
1370         this.emitScalar('<circular reference: ' + (j$.isArray_(value) ? 'Array' : 'Object') + '>');
1371       } else if (j$.isArray_(value) || j$.isA_('Object', value)) {
1372         value.__Jasmine_been_here_before__ = true;
1373         if (j$.isArray_(value)) {
1374           this.emitArray(value);
1375         } else {
1376           this.emitObject(value);
1377         }
1378         delete value.__Jasmine_been_here_before__;
1379       } else {
1380         this.emitScalar(value.toString());
1381       }
1382     } finally {
1383       this.ppNestLevel_--;
1384     }
1385   };
1386
1387   PrettyPrinter.prototype.iterateObject = function(obj, fn) {
1388     for (var property in obj) {
1389       if (!obj.hasOwnProperty(property)) { continue; }
1390       if (property == '__Jasmine_been_here_before__') { continue; }
1391       fn(property, obj.__lookupGetter__ ? (!j$.util.isUndefined(obj.__lookupGetter__(property)) &&
1392           obj.__lookupGetter__(property) !== null) : false);
1393     }
1394   };
1395
1396   PrettyPrinter.prototype.emitArray = j$.unimplementedMethod_;
1397   PrettyPrinter.prototype.emitObject = j$.unimplementedMethod_;
1398   PrettyPrinter.prototype.emitScalar = j$.unimplementedMethod_;
1399   PrettyPrinter.prototype.emitString = j$.unimplementedMethod_;
1400
1401   function StringPrettyPrinter() {
1402     PrettyPrinter.call(this);
1403
1404     this.string = '';
1405   }
1406
1407   j$.util.inherit(StringPrettyPrinter, PrettyPrinter);
1408
1409   StringPrettyPrinter.prototype.emitScalar = function(value) {
1410     this.append(value);
1411   };
1412
1413   StringPrettyPrinter.prototype.emitString = function(value) {
1414     this.append("'" + value + "'");
1415   };
1416
1417   StringPrettyPrinter.prototype.emitArray = function(array) {
1418     if (this.ppNestLevel_ > j$.MAX_PRETTY_PRINT_DEPTH) {
1419       this.append("Array");
1420       return;
1421     }
1422
1423     this.append('[ ');
1424     for (var i = 0; i < array.length; i++) {
1425       if (i > 0) {
1426         this.append(', ');
1427       }
1428       this.format(array[i]);
1429     }
1430     this.append(' ]');
1431   };
1432
1433   StringPrettyPrinter.prototype.emitObject = function(obj) {
1434     if (this.ppNestLevel_ > j$.MAX_PRETTY_PRINT_DEPTH) {
1435       this.append("Object");
1436       return;
1437     }
1438
1439     var self = this;
1440     this.append('{ ');
1441     var first = true;
1442
1443     this.iterateObject(obj, function(property, isGetter) {
1444       if (first) {
1445         first = false;
1446       } else {
1447         self.append(', ');
1448       }
1449
1450       self.append(property);
1451       self.append(' : ');
1452       if (isGetter) {
1453         self.append('<getter>');
1454       } else {
1455         self.format(obj[property]);
1456       }
1457     });
1458
1459     this.append(' }');
1460   };
1461
1462   StringPrettyPrinter.prototype.append = function(value) {
1463     this.string += value;
1464   };
1465
1466   return function(value) {
1467     var stringPrettyPrinter = new StringPrettyPrinter();
1468     stringPrettyPrinter.format(value);
1469     return stringPrettyPrinter.string;
1470   };
1471 };
1472
1473 getJasmineRequireObj().QueueRunner = function() {
1474
1475   function QueueRunner(attrs) {
1476     this.fns = attrs.fns || [];
1477     this.onComplete = attrs.onComplete || function() {};
1478     this.clearStack = attrs.clearStack || function(fn) {fn();};
1479     this.onException = attrs.onException || function() {};
1480     this.catchException = attrs.catchException || function() { return true; };
1481     this.userContext = {};
1482   }
1483
1484   QueueRunner.prototype.execute = function() {
1485     this.run(this.fns, 0);
1486   };
1487
1488   QueueRunner.prototype.run = function(fns, recursiveIndex) {
1489     var length = fns.length,
1490         self = this,
1491         iterativeIndex;
1492
1493     for(iterativeIndex = recursiveIndex; iterativeIndex < length; iterativeIndex++) {
1494       var fn = fns[iterativeIndex];
1495       if (fn.length > 0) {
1496         return attemptAsync(fn);
1497       } else {
1498         attemptSync(fn);
1499       }
1500     }
1501
1502     var runnerDone = iterativeIndex >= length;
1503
1504     if (runnerDone) {
1505       this.clearStack(this.onComplete);
1506     }
1507
1508     function attemptSync(fn) {
1509       try {
1510         fn.call(self.userContext);
1511       } catch (e) {
1512         handleException(e);
1513       }
1514     }
1515
1516     function attemptAsync(fn) {
1517       var next = function () { self.run(fns, iterativeIndex + 1); };
1518
1519       try {
1520         fn.call(self.userContext, next);
1521       } catch (e) {
1522         handleException(e);
1523         next();
1524       }
1525     }
1526
1527     function handleException(e) {
1528       self.onException(e);
1529       if (!self.catchException(e)) {
1530         //TODO: set a var when we catch an exception and
1531         //use a finally block to close the loop in a nice way..
1532         throw e;
1533       }
1534     }
1535   };
1536
1537   return QueueRunner;
1538 };
1539
1540 getJasmineRequireObj().ReportDispatcher = function() {
1541   function ReportDispatcher(methods) {
1542
1543     var dispatchedMethods = methods || [];
1544
1545     for (var i = 0; i < dispatchedMethods.length; i++) {
1546       var method = dispatchedMethods[i];
1547       this[method] = (function(m) {
1548         return function() {
1549           dispatch(m, arguments);
1550         };
1551       }(method));
1552     }
1553
1554     var reporters = [];
1555
1556     this.addReporter = function(reporter) {
1557       reporters.push(reporter);
1558     };
1559
1560     return this;
1561
1562     function dispatch(method, args) {
1563       for (var i = 0; i < reporters.length; i++) {
1564         var reporter = reporters[i];
1565         if (reporter[method]) {
1566           reporter[method].apply(reporter, args);
1567         }
1568       }
1569     }
1570   }
1571
1572   return ReportDispatcher;
1573 };
1574
1575
1576 getJasmineRequireObj().SpyStrategy = function() {
1577
1578   function SpyStrategy(options) {
1579     options = options || {};
1580
1581     var identity = options.name || "unknown",
1582         originalFn = options.fn || function() {},
1583         getSpy = options.getSpy || function() {},
1584         plan = function() {};
1585
1586     this.identity = function() {
1587       return identity;
1588     };
1589
1590     this.exec = function() {
1591       return plan.apply(this, arguments);
1592     };
1593
1594     this.callThrough = function() {
1595       plan = originalFn;
1596       return getSpy();
1597     };
1598
1599     this.returnValue = function(value) {
1600       plan = function() {
1601         return value;
1602       };
1603       return getSpy();
1604     };
1605
1606     this.throwError = function(something) {
1607       var error = (something instanceof Error) ? something : new Error(something);
1608       plan = function() {
1609         throw error;
1610       };
1611       return getSpy();
1612     };
1613
1614     this.callFake = function(fn) {
1615       plan = fn;
1616       return getSpy();
1617     };
1618
1619     this.stub = function(fn) {
1620       plan = function() {};
1621       return getSpy();
1622     };
1623   }
1624
1625   return SpyStrategy;
1626 };
1627
1628 getJasmineRequireObj().Suite = function() {
1629   function Suite(attrs) {
1630     this.env = attrs.env;
1631     this.id = attrs.id;
1632     this.parentSuite = attrs.parentSuite;
1633     this.description = attrs.description;
1634     this.onStart = attrs.onStart || function() {};
1635     this.resultCallback = attrs.resultCallback || function() {};
1636     this.clearStack = attrs.clearStack || function(fn) {fn();};
1637
1638     this.beforeFns = [];
1639     this.afterFns = [];
1640     this.queueRunner = attrs.queueRunner || function() {};
1641     this.disabled = false;
1642
1643     this.children = [];
1644
1645     this.result = {
1646       id: this.id,
1647       status: this.disabled ? 'disabled' : '',
1648       description: this.description,
1649       fullName: this.getFullName()
1650     };
1651   }
1652
1653   Suite.prototype.getFullName = function() {
1654     var fullName = this.description;
1655     for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) {
1656       if (parentSuite.parentSuite) {
1657         fullName = parentSuite.description + ' ' + fullName;
1658       }
1659     }
1660     return fullName;
1661   };
1662
1663   Suite.prototype.disable = function() {
1664     this.disabled = true;
1665   };
1666
1667   Suite.prototype.beforeEach = function(fn) {
1668     this.beforeFns.unshift(fn);
1669   };
1670
1671   Suite.prototype.afterEach = function(fn) {
1672     this.afterFns.unshift(fn);
1673   };
1674
1675   Suite.prototype.addChild = function(child) {
1676     this.children.push(child);
1677   };
1678
1679   Suite.prototype.execute = function(onComplete) {
1680     var self = this;
1681     if (this.disabled) {
1682       complete();
1683       return;
1684     }
1685
1686     var allFns = [];
1687
1688     for (var i = 0; i < this.children.length; i++) {
1689       allFns.push(wrapChildAsAsync(this.children[i]));
1690     }
1691
1692     this.onStart(this);
1693
1694     this.queueRunner({
1695       fns: allFns,
1696       onComplete: complete
1697     });
1698
1699     function complete() {
1700       self.resultCallback(self.result);
1701
1702       if (onComplete) {
1703         onComplete();
1704       }
1705     }
1706
1707     function wrapChildAsAsync(child) {
1708       return function(done) { child.execute(done); };
1709     }
1710   };
1711
1712   return Suite;
1713 };
1714
1715 if (typeof window == void 0 && typeof exports == "object") {
1716   exports.Suite = jasmineRequire.Suite;
1717 }
1718
1719 getJasmineRequireObj().Timer = function() {
1720   function Timer(options) {
1721     options = options || {};
1722
1723     var now = options.now || function() { return new Date().getTime(); },
1724         startTime;
1725
1726     this.start = function() {
1727       startTime = now();
1728     };
1729
1730     this.elapsed = function() {
1731       return now() - startTime;
1732     };
1733   }
1734
1735   return Timer;
1736 };
1737
1738 getJasmineRequireObj().matchersUtil = function(j$) {
1739   // TODO: what to do about jasmine.pp not being inject? move to JSON.stringify? gut PrettyPrinter?
1740
1741   return {
1742     equals: function(a, b, customTesters) {
1743       customTesters = customTesters || [];
1744
1745       return eq(a, b, [], [], customTesters);
1746     },
1747
1748     contains: function(haystack, needle, customTesters) {
1749       customTesters = customTesters || [];
1750
1751       if (Object.prototype.toString.apply(haystack) === "[object Array]") {
1752         for (var i = 0; i < haystack.length; i++) {
1753           if (eq(haystack[i], needle, [], [], customTesters)) {
1754             return true;
1755           }
1756         }
1757         return false;
1758       }
1759       return haystack.indexOf(needle) >= 0;
1760     },
1761
1762     buildFailureMessage: function() {
1763       var args = Array.prototype.slice.call(arguments, 0),
1764         matcherName = args[0],
1765         isNot = args[1],
1766         actual = args[2],
1767         expected = args.slice(3),
1768         englishyPredicate = matcherName.replace(/[A-Z]/g, function(s) { return ' ' + s.toLowerCase(); });
1769
1770       var message = "Expected " +
1771         j$.pp(actual) +
1772         (isNot ? " not " : " ") +
1773         englishyPredicate;
1774
1775       if (expected.length > 0) {
1776         for (var i = 0; i < expected.length; i++) {
1777           if (i > 0) {
1778             message += ",";
1779           }
1780           message += " " + j$.pp(expected[i]);
1781         }
1782       }
1783
1784       return message + ".";
1785     }
1786   };
1787
1788   // Equality function lovingly adapted from isEqual in
1789   //   [Underscore](http://underscorejs.org)
1790   function eq(a, b, aStack, bStack, customTesters) {
1791     var result = true;
1792
1793     for (var i = 0; i < customTesters.length; i++) {
1794       var customTesterResult = customTesters[i](a, b);
1795       if (!j$.util.isUndefined(customTesterResult)) {
1796         return customTesterResult;
1797       }
1798     }
1799
1800     if (a instanceof j$.Any) {
1801       result = a.jasmineMatches(b);
1802       if (result) {
1803         return true;
1804       }
1805     }
1806
1807     if (b instanceof j$.Any) {
1808       result = b.jasmineMatches(a);
1809       if (result) {
1810         return true;
1811       }
1812     }
1813
1814     if (b instanceof j$.ObjectContaining) {
1815       result = b.jasmineMatches(a);
1816       if (result) {
1817         return true;
1818       }
1819     }
1820
1821     if (a instanceof Error && b instanceof Error) {
1822       return a.message == b.message;
1823     }
1824
1825     // Identical objects are equal. `0 === -0`, but they aren't identical.
1826     // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
1827     if (a === b) { return a !== 0 || 1 / a == 1 / b; }
1828     // A strict comparison is necessary because `null == undefined`.
1829     if (a === null || b === null) { return a === b; }
1830     var className = Object.prototype.toString.call(a);
1831     if (className != Object.prototype.toString.call(b)) { return false; }
1832     switch (className) {
1833       // Strings, numbers, dates, and booleans are compared by value.
1834       case '[object String]':
1835         // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
1836         // equivalent to `new String("5")`.
1837         return a == String(b);
1838       case '[object Number]':
1839         // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for
1840         // other numeric values.
1841         return a != +a ? b != +b : (a === 0 ? 1 / a == 1 / b : a == +b);
1842       case '[object Date]':
1843       case '[object Boolean]':
1844         // Coerce dates and booleans to numeric primitive values. Dates are compared by their
1845         // millisecond representations. Note that invalid dates with millisecond representations
1846         // of `NaN` are not equivalent.
1847         return +a == +b;
1848       // RegExps are compared by their source patterns and flags.
1849       case '[object RegExp]':
1850         return a.source == b.source &&
1851           a.global == b.global &&
1852           a.multiline == b.multiline &&
1853           a.ignoreCase == b.ignoreCase;
1854     }
1855     if (typeof a != 'object' || typeof b != 'object') { return false; }
1856     // Assume equality for cyclic structures. The algorithm for detecting cyclic
1857     // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
1858     var length = aStack.length;
1859     while (length--) {
1860       // Linear search. Performance is inversely proportional to the number of
1861       // unique nested structures.
1862       if (aStack[length] == a) { return bStack[length] == b; }
1863     }
1864     // Add the first object to the stack of traversed objects.
1865     aStack.push(a);
1866     bStack.push(b);
1867     var size = 0;
1868     // Recursively compare objects and arrays.
1869     if (className == '[object Array]') {
1870       // Compare array lengths to determine if a deep comparison is necessary.
1871       size = a.length;
1872       result = size == b.length;
1873       if (result) {
1874         // Deep compare the contents, ignoring non-numeric properties.
1875         while (size--) {
1876           if (!(result = eq(a[size], b[size], aStack, bStack, customTesters))) { break; }
1877         }
1878       }
1879     } else {
1880       // Objects with different constructors are not equivalent, but `Object`s
1881       // from different frames are.
1882       var aCtor = a.constructor, bCtor = b.constructor;
1883       if (aCtor !== bCtor && !(isFunction(aCtor) && (aCtor instanceof aCtor) &&
1884         isFunction(bCtor) && (bCtor instanceof bCtor))) {
1885         return false;
1886       }
1887       // Deep compare objects.
1888       for (var key in a) {
1889         if (has(a, key)) {
1890           // Count the expected number of properties.
1891           size++;
1892           // Deep compare each member.
1893           if (!(result = has(b, key) && eq(a[key], b[key], aStack, bStack, customTesters))) { break; }
1894         }
1895       }
1896       // Ensure that both objects contain the same number of properties.
1897       if (result) {
1898         for (key in b) {
1899           if (has(b, key) && !(size--)) { break; }
1900         }
1901         result = !size;
1902       }
1903     }
1904     // Remove the first object from the stack of traversed objects.
1905     aStack.pop();
1906     bStack.pop();
1907
1908     return result;
1909
1910     function has(obj, key) {
1911       return obj.hasOwnProperty(key);
1912     }
1913
1914     function isFunction(obj) {
1915       return typeof obj === 'function';
1916     }
1917   }
1918 };
1919
1920 getJasmineRequireObj().toBe = function() {
1921   function toBe() {
1922     return {
1923       compare: function(actual, expected) {
1924         return {
1925           pass: actual === expected
1926         };
1927       }
1928     };
1929   }
1930
1931   return toBe;
1932 };
1933
1934 getJasmineRequireObj().toBeCloseTo = function() {
1935
1936   function toBeCloseTo() {
1937     return {
1938       compare: function(actual, expected, precision) {
1939         if (precision !== 0) {
1940           precision = precision || 2;
1941         }
1942
1943         return {
1944           pass: Math.abs(expected - actual) < (Math.pow(10, -precision) / 2)
1945         };
1946       }
1947     };
1948   }
1949
1950   return toBeCloseTo;
1951 };
1952
1953 getJasmineRequireObj().toBeDefined = function() {
1954   function toBeDefined() {
1955     return {
1956       compare: function(actual) {
1957         return {
1958           pass: (void 0 !== actual)
1959         };
1960       }
1961     };
1962   }
1963
1964   return toBeDefined;
1965 };
1966
1967 getJasmineRequireObj().toBeFalsy = function() {
1968   function toBeFalsy() {
1969     return {
1970       compare: function(actual) {
1971         return {
1972           pass: !!!actual
1973         };
1974       }
1975     };
1976   }
1977
1978   return toBeFalsy;
1979 };
1980
1981 getJasmineRequireObj().toBeGreaterThan = function() {
1982
1983   function toBeGreaterThan() {
1984     return {
1985       compare: function(actual, expected) {
1986         return {
1987           pass: actual > expected
1988         };
1989       }
1990     };
1991   }
1992
1993   return toBeGreaterThan;
1994 };
1995
1996
1997 getJasmineRequireObj().toBeLessThan = function() {
1998   function toBeLessThan() {
1999     return {
2000
2001       compare: function(actual, expected) {
2002         return {
2003           pass: actual < expected
2004         };
2005       }
2006     };
2007   }
2008
2009   return toBeLessThan;
2010 };
2011 getJasmineRequireObj().toBeNaN = function(j$) {
2012
2013   function toBeNaN() {
2014     return {
2015       compare: function(actual) {
2016         var result = {
2017           pass: (actual !== actual)
2018         };
2019
2020         if (result.pass) {
2021           result.message = "Expected actual not to be NaN.";
2022         } else {
2023           result.message = "Expected " + j$.pp(actual) + " to be NaN.";
2024         }
2025
2026         return result;
2027       }
2028     };
2029   }
2030
2031   return toBeNaN;
2032 };
2033
2034 getJasmineRequireObj().toBeNull = function() {
2035
2036   function toBeNull() {
2037     return {
2038       compare: function(actual) {
2039         return {
2040           pass: actual === null
2041         };
2042       }
2043     };
2044   }
2045
2046   return toBeNull;
2047 };
2048
2049 getJasmineRequireObj().toBeTruthy = function() {
2050
2051   function toBeTruthy() {
2052     return {
2053       compare: function(actual) {
2054         return {
2055           pass: !!actual
2056         };
2057       }
2058     };
2059   }
2060
2061   return toBeTruthy;
2062 };
2063
2064 getJasmineRequireObj().toBeUndefined = function() {
2065
2066   function toBeUndefined() {
2067     return {
2068       compare: function(actual) {
2069         return {
2070           pass: void 0 === actual
2071         };
2072       }
2073     };
2074   }
2075
2076   return toBeUndefined;
2077 };
2078
2079 getJasmineRequireObj().toContain = function() {
2080   function toContain(util, customEqualityTesters) {
2081     customEqualityTesters = customEqualityTesters || [];
2082
2083     return {
2084       compare: function(actual, expected) {
2085
2086         return {
2087           pass: util.contains(actual, expected, customEqualityTesters)
2088         };
2089       }
2090     };
2091   }
2092
2093   return toContain;
2094 };
2095
2096 getJasmineRequireObj().toEqual = function() {
2097
2098   function toEqual(util, customEqualityTesters) {
2099     customEqualityTesters = customEqualityTesters || [];
2100
2101     return {
2102       compare: function(actual, expected) {
2103         var result = {
2104           pass: false
2105         };
2106
2107         result.pass = util.equals(actual, expected, customEqualityTesters);
2108
2109         return result;
2110       }
2111     };
2112   }
2113
2114   return toEqual;
2115 };
2116
2117 getJasmineRequireObj().toHaveBeenCalled = function(j$) {
2118
2119   function toHaveBeenCalled() {
2120     return {
2121       compare: function(actual) {
2122         var result = {};
2123
2124         if (!j$.isSpy(actual)) {
2125           throw new Error('Expected a spy, but got ' + j$.pp(actual) + '.');
2126         }
2127
2128         if (arguments.length > 1) {
2129           throw new Error('toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith');
2130         }
2131
2132         result.pass = actual.calls.any();
2133
2134         result.message = result.pass ?
2135           "Expected spy " + actual.and.identity() + " not to have been called." :
2136           "Expected spy " + actual.and.identity() + " to have been called.";
2137
2138         return result;
2139       }
2140     };
2141   }
2142
2143   return toHaveBeenCalled;
2144 };
2145
2146 getJasmineRequireObj().toHaveBeenCalledWith = function(j$) {
2147
2148   function toHaveBeenCalledWith(util) {
2149     return {
2150       compare: function() {
2151         var args = Array.prototype.slice.call(arguments, 0),
2152           actual = args[0],
2153           expectedArgs = args.slice(1),
2154           result = { pass: false };
2155
2156         if (!j$.isSpy(actual)) {
2157           throw new Error('Expected a spy, but got ' + j$.pp(actual) + '.');
2158         }
2159
2160         if (!actual.calls.any()) {
2161           result.message = "Expected spy " + actual.and.identity() + " to have been called with " + j$.pp(expectedArgs) + " but it was never called.";
2162           return result;
2163         }
2164
2165         if (util.contains(actual.calls.allArgs(), expectedArgs)) {
2166           result.pass = true;
2167           result.message = "Expected spy " + actual.and.identity() + " not to have been called with " + j$.pp(expectedArgs) + " but it was.";
2168         } else {
2169           result.message = "Expected spy " + actual.and.identity() + " to have been called with " + j$.pp(expectedArgs) + " but actual calls were " + j$.pp(actual.calls.allArgs()).replace(/^\[ | \]$/g, '') + ".";
2170         }
2171
2172         return result;
2173       }
2174     };
2175   }
2176
2177   return toHaveBeenCalledWith;
2178 };
2179
2180 getJasmineRequireObj().toMatch = function() {
2181
2182   function toMatch() {
2183     return {
2184       compare: function(actual, expected) {
2185         var regexp = new RegExp(expected);
2186
2187         return {
2188           pass: regexp.test(actual)
2189         };
2190       }
2191     };
2192   }
2193
2194   return toMatch;
2195 };
2196
2197 getJasmineRequireObj().toThrow = function(j$) {
2198
2199   function toThrow(util) {
2200     return {
2201       compare: function(actual, expected) {
2202         var result = { pass: false },
2203           threw = false,
2204           thrown;
2205
2206         if (typeof actual != "function") {
2207           throw new Error("Actual is not a Function");
2208         }
2209
2210         try {
2211           actual();
2212         } catch (e) {
2213           threw = true;
2214           thrown = e;
2215         }
2216
2217         if (!threw) {
2218           result.message = "Expected function to throw an exception.";
2219           return result;
2220         }
2221
2222         if (arguments.length == 1) {
2223           result.pass = true;
2224           result.message = "Expected function not to throw, but it threw " + j$.pp(thrown) + ".";
2225
2226           return result;
2227         }
2228
2229         if (util.equals(thrown, expected)) {
2230           result.pass = true;
2231           result.message = "Expected function not to throw " + j$.pp(expected) + ".";
2232         } else {
2233           result.message = "Expected function to throw " + j$.pp(expected) + ", but it threw " +  j$.pp(thrown) + ".";
2234         }
2235
2236         return result;
2237       }
2238     };
2239   }
2240
2241   return toThrow;
2242 };
2243
2244 getJasmineRequireObj().toThrowError = function(j$) {
2245   function toThrowError (util) {
2246     return {
2247       compare: function(actual) {
2248         var threw = false,
2249           thrown,
2250           errorType,
2251           message,
2252           regexp,
2253           name,
2254           constructorName;
2255
2256         if (typeof actual != "function") {
2257           throw new Error("Actual is not a Function");
2258         }
2259
2260         extractExpectedParams.apply(null, arguments);
2261
2262         try {
2263           actual();
2264         } catch (e) {
2265           threw = true;
2266           thrown = e;
2267         }
2268
2269         if (!threw) {
2270           return fail("Expected function to throw an Error.");
2271         }
2272
2273         if (!(thrown instanceof Error)) {
2274           return fail("Expected function to throw an Error, but it threw " + thrown + ".");
2275         }
2276
2277         if (arguments.length == 1) {
2278           return pass("Expected function not to throw an Error, but it threw " + fnNameFor(thrown) + ".");
2279         }
2280
2281         if (errorType) {
2282           name = fnNameFor(errorType);
2283           constructorName = fnNameFor(thrown.constructor);
2284         }
2285
2286         if (errorType && message) {
2287           if (thrown.constructor == errorType && util.equals(thrown.message, message)) {
2288             return pass("Expected function not to throw " + name + " with message \"" + message + "\".");
2289           } else {
2290             return fail("Expected function to throw " + name + " with message \"" + message +
2291                         "\", but it threw " + constructorName + " with message \"" + thrown.message + "\".");
2292           }
2293         }
2294
2295         if (errorType && regexp) {
2296           if (thrown.constructor == errorType && regexp.test(thrown.message)) {
2297             return pass("Expected function not to throw " + name + " with message matching " + regexp + ".");
2298           } else {
2299             return fail("Expected function to throw " + name + " with message matching " + regexp +
2300                         ", but it threw " + constructorName + " with message \"" + thrown.message + "\".");
2301           }
2302         }
2303
2304         if (errorType) {
2305           if (thrown.constructor == errorType) {
2306             return pass("Expected function not to throw " + name + ".");
2307           } else {
2308             return fail("Expected function to throw " + name + ", but it threw " + constructorName + ".");
2309           }
2310         }
2311
2312         if (message) {
2313           if (thrown.message == message) {
2314             return pass("Expected function not to throw an exception with message " + j$.pp(message) + ".");
2315           } else {
2316             return fail("Expected function to throw an exception with message " + j$.pp(message) +
2317                         ", but it threw an exception with message " + j$.pp(thrown.message) + ".");
2318           }
2319         }
2320
2321         if (regexp) {
2322           if (regexp.test(thrown.message)) {
2323             return pass("Expected function not to throw an exception with a message matching " + j$.pp(regexp) + ".");
2324           } else {
2325             return fail("Expected function to throw an exception with a message matching " + j$.pp(regexp) +
2326                         ", but it threw an exception with message " + j$.pp(thrown.message) + ".");
2327           }
2328         }
2329
2330         function fnNameFor(func) {
2331             return func.name || func.toString().match(/^\s*function\s*(\w*)\s*\(/)[1];
2332         }
2333
2334         function pass(notMessage) {
2335           return {
2336             pass: true,
2337             message: notMessage
2338           };
2339         }
2340
2341         function fail(message) {
2342           return {
2343             pass: false,
2344             message: message
2345           };
2346         }
2347
2348         function extractExpectedParams() {
2349           if (arguments.length == 1) {
2350             return;
2351           }
2352
2353           if (arguments.length == 2) {
2354             var expected = arguments[1];
2355
2356             if (expected instanceof RegExp) {
2357               regexp = expected;
2358             } else if (typeof expected == "string") {
2359               message = expected;
2360             } else if (checkForAnErrorType(expected)) {
2361               errorType = expected;
2362             }
2363
2364             if (!(errorType || message || regexp)) {
2365               throw new Error("Expected is not an Error, string, or RegExp.");
2366             }
2367           } else {
2368             if (checkForAnErrorType(arguments[1])) {
2369               errorType = arguments[1];
2370             } else {
2371               throw new Error("Expected error type is not an Error.");
2372             }
2373
2374             if (arguments[2] instanceof RegExp) {
2375               regexp = arguments[2];
2376             } else if (typeof arguments[2] == "string") {
2377               message = arguments[2];
2378             } else {
2379               throw new Error("Expected error message is not a string or RegExp.");
2380             }
2381           }
2382         }
2383
2384         function checkForAnErrorType(type) {
2385           if (typeof type !== "function") {
2386             return false;
2387           }
2388
2389           var Surrogate = function() {};
2390           Surrogate.prototype = type.prototype;
2391           return (new Surrogate()) instanceof Error;
2392         }
2393       }
2394     };
2395   }
2396
2397   return toThrowError;
2398 };
2399
2400 getJasmineRequireObj().version = function() {
2401   return "2.0.0";
2402 };