github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/public/libs/vue-1.0.24/test/unit/lib/jasmine.js (about)

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