You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by er...@apache.org on 2020/08/06 11:12:17 UTC
[cordova-plugin-test-framework] 02/04: FR-44 : Update Jasmine
version
This is an automated email from the ASF dual-hosted git repository.
erisu pushed a commit to branch feat/jasmine-upgrade
in repository https://gitbox.apache.org/repos/asf/cordova-plugin-test-framework.git
commit 67f08265dcde9099150f17e6b9ca572876f1808d
Author: Sven Emtell <sv...@doremir.com>
AuthorDate: Thu Oct 10 11:00:58 2019 +0200
FR-44 : Update Jasmine version
---
.eslintignore | 2 +-
.ratignore | 2 +-
www/assets/index.html | 6 +-
www/assets/jasmine-2.4.1/jasmine.js | 3454 ------------
.../{jasmine-2.4.1 => jasmine-2.99.0}/boot.js | 5 +-
.../{jasmine-2.4.1 => jasmine-2.99.0}/console.js | 2 +-
.../jasmine-html.js | 144 +-
.../{jasmine-2.4.1 => jasmine-2.99.0}/jasmine.css | 1 +
www/assets/jasmine-2.99.0/jasmine.js | 5584 ++++++++++++++++++++
.../jasmine_favicon.png | Bin
10 files changed, 5703 insertions(+), 3497 deletions(-)
diff --git a/.eslintignore b/.eslintignore
index 85182f7..a5bb78f 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -1,2 +1,2 @@
-www/assets/jasmine-2.4.1
+www/assets/jasmine-2.99.0
www/assets/topcoat-0.7.5
\ No newline at end of file
diff --git a/.ratignore b/.ratignore
index ea255bf..11cc15e 100644
--- a/.ratignore
+++ b/.ratignore
@@ -1 +1 @@
-jasmine-2.4.1
+jasmine-2.99.0
diff --git a/www/assets/index.html b/www/assets/index.html
index 8cd498d..5c42d9a 100644
--- a/www/assets/index.html
+++ b/www/assets/index.html
@@ -36,11 +36,11 @@
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width" />
<link rel="stylesheet" type="text/css" href="topcoat-0.7.5/css/topcoat-mobile-light.min.css">
- <link rel="stylesheet" type="text/css" href="jasmine-2.4.1/jasmine.css" media="screen">
+ <link rel="stylesheet" type="text/css" href="jasmine-2.99.0/jasmine.css" media="screen">
<link rel="stylesheet" type="text/css" href="main.css" media="screen">
- <script type="text/javascript" src="jasmine-2.4.1/jasmine.js"></script>
- <script type="text/javascript" src="jasmine-2.4.1/jasmine-html.js"></script>
+ <script type="text/javascript" src="jasmine-2.99.0/jasmine.js"></script>
+ <script type="text/javascript" src="jasmine-2.99.0/jasmine-html.js"></script>
<script type="text/javascript" src="jasmine-medic.js"></script>
<script type="text/javascript" src="../cordova.js"></script>
diff --git a/www/assets/jasmine-2.4.1/jasmine.js b/www/assets/jasmine-2.4.1/jasmine.js
deleted file mode 100755
index bea469d..0000000
--- a/www/assets/jasmine-2.4.1/jasmine.js
+++ /dev/null
@@ -1,3454 +0,0 @@
-/*
-Copyright (c) 2008-2015 Pivotal Labs
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-var getJasmineRequireObj = (function (jasmineGlobal) {
- var jasmineRequire;
-
- if (typeof module !== 'undefined' && module.exports) {
- if (typeof global !== 'undefined') {
- jasmineGlobal = global;
- } else {
- jasmineGlobal = {};
- }
- jasmineRequire = exports;
- } else {
- if (typeof window !== 'undefined' && typeof window.toString === 'function' && window.toString() === '[object GjsGlobal]') {
- jasmineGlobal = window;
- }
- jasmineRequire = jasmineGlobal.jasmineRequire = jasmineGlobal.jasmineRequire || {};
- }
-
- function getJasmineRequire() {
- return jasmineRequire;
- }
-
- getJasmineRequire().core = function(jRequire) {
- var j$ = {};
-
- jRequire.base(j$, jasmineGlobal);
- j$.util = jRequire.util();
- j$.errors = jRequire.errors();
- j$.Any = jRequire.Any(j$);
- j$.Anything = jRequire.Anything(j$);
- j$.CallTracker = jRequire.CallTracker();
- j$.MockDate = jRequire.MockDate();
- j$.Clock = jRequire.Clock();
- j$.DelayedFunctionScheduler = jRequire.DelayedFunctionScheduler();
- j$.Env = jRequire.Env(j$);
- j$.ExceptionFormatter = jRequire.ExceptionFormatter();
- j$.Expectation = jRequire.Expectation();
- j$.buildExpectationResult = jRequire.buildExpectationResult();
- j$.JsApiReporter = jRequire.JsApiReporter();
- j$.matchersUtil = jRequire.matchersUtil(j$);
- j$.ObjectContaining = jRequire.ObjectContaining(j$);
- j$.ArrayContaining = jRequire.ArrayContaining(j$);
- j$.pp = jRequire.pp(j$);
- j$.QueueRunner = jRequire.QueueRunner(j$);
- j$.ReportDispatcher = jRequire.ReportDispatcher();
- j$.Spec = jRequire.Spec(j$);
- j$.SpyRegistry = jRequire.SpyRegistry(j$);
- j$.SpyStrategy = jRequire.SpyStrategy();
- j$.StringMatching = jRequire.StringMatching(j$);
- j$.Suite = jRequire.Suite(j$);
- j$.Timer = jRequire.Timer();
- j$.TreeProcessor = jRequire.TreeProcessor();
- j$.version = jRequire.version();
- j$.Order = jRequire.Order();
-
- j$.matchers = jRequire.requireMatchers(jRequire, j$);
-
- return j$;
- };
-
- return getJasmineRequire;
-})(this);
-
-getJasmineRequireObj().requireMatchers = function(jRequire, j$) {
- var availableMatchers = [
- 'toBe',
- 'toBeCloseTo',
- 'toBeDefined',
- 'toBeFalsy',
- 'toBeGreaterThan',
- 'toBeLessThan',
- 'toBeNaN',
- 'toBeNull',
- 'toBeTruthy',
- 'toBeUndefined',
- 'toContain',
- 'toEqual',
- 'toHaveBeenCalled',
- 'toHaveBeenCalledWith',
- 'toHaveBeenCalledTimes',
- 'toMatch',
- 'toThrow',
- 'toThrowError'
- ],
- matchers = {};
-
- for (var i = 0; i < availableMatchers.length; i++) {
- var name = availableMatchers[i];
- matchers[name] = jRequire[name](j$);
- }
-
- return matchers;
-};
-
-getJasmineRequireObj().base = function(j$, jasmineGlobal) {
- j$.unimplementedMethod_ = function() {
- throw new Error('unimplemented method');
- };
-
- j$.MAX_PRETTY_PRINT_DEPTH = 40;
- j$.MAX_PRETTY_PRINT_ARRAY_LENGTH = 100;
- j$.DEFAULT_TIMEOUT_INTERVAL = 5000;
-
- j$.getGlobal = function() {
- return jasmineGlobal;
- };
-
- j$.getEnv = function(options) {
- var env = j$.currentEnv_ = j$.currentEnv_ || new j$.Env(options);
- //jasmine. singletons in here (setTimeout blah blah).
- return env;
- };
-
- j$.isArray_ = function(value) {
- return j$.isA_('Array', value);
- };
-
- j$.isString_ = function(value) {
- return j$.isA_('String', value);
- };
-
- j$.isNumber_ = function(value) {
- return j$.isA_('Number', value);
- };
-
- j$.isA_ = function(typeName, value) {
- return Object.prototype.toString.apply(value) === '[object ' + typeName + ']';
- };
-
- j$.isDomNode = function(obj) {
- return obj.nodeType > 0;
- };
-
- j$.fnNameFor = function(func) {
- return func.name || func.toString().match(/^\s*function\s*(\w*)\s*\(/)[1];
- };
-
- j$.any = function(clazz) {
- return new j$.Any(clazz);
- };
-
- j$.anything = function() {
- return new j$.Anything();
- };
-
- j$.objectContaining = function(sample) {
- return new j$.ObjectContaining(sample);
- };
-
- j$.stringMatching = function(expected) {
- return new j$.StringMatching(expected);
- };
-
- j$.arrayContaining = function(sample) {
- return new j$.ArrayContaining(sample);
- };
-
- j$.createSpy = function(name, originalFn) {
-
- var spyStrategy = new j$.SpyStrategy({
- name: name,
- fn: originalFn,
- getSpy: function() { return spy; }
- }),
- callTracker = new j$.CallTracker(),
- spy = function() {
- var callData = {
- object: this,
- args: Array.prototype.slice.apply(arguments)
- };
-
- callTracker.track(callData);
- var returnValue = spyStrategy.exec.apply(this, arguments);
- callData.returnValue = returnValue;
-
- return returnValue;
- };
-
- for (var prop in originalFn) {
- if (prop === 'and' || prop === 'calls') {
- throw new Error('Jasmine spies would overwrite the \'and\' and \'calls\' properties on the object being spied upon');
- }
-
- spy[prop] = originalFn[prop];
- }
-
- spy.and = spyStrategy;
- spy.calls = callTracker;
-
- return spy;
- };
-
- j$.isSpy = function(putativeSpy) {
- if (!putativeSpy) {
- return false;
- }
- return putativeSpy.and instanceof j$.SpyStrategy &&
- putativeSpy.calls instanceof j$.CallTracker;
- };
-
- j$.createSpyObj = function(baseName, methodNames) {
- if (j$.isArray_(baseName) && j$.util.isUndefined(methodNames)) {
- methodNames = baseName;
- baseName = 'unknown';
- }
-
- if (!j$.isArray_(methodNames) || methodNames.length === 0) {
- throw 'createSpyObj requires a non-empty array of method names to create spies for';
- }
- var obj = {};
- for (var i = 0; i < methodNames.length; i++) {
- obj[methodNames[i]] = j$.createSpy(baseName + '.' + methodNames[i]);
- }
- return obj;
- };
-};
-
-getJasmineRequireObj().util = function() {
-
- var util = {};
-
- util.inherit = function(childClass, parentClass) {
- var Subclass = function() {
- };
- Subclass.prototype = parentClass.prototype;
- childClass.prototype = new Subclass();
- };
-
- util.htmlEscape = function(str) {
- if (!str) {
- return str;
- }
- return str.replace(/&/g, '&')
- .replace(/</g, '<')
- .replace(/>/g, '>');
- };
-
- util.argsToArray = function(args) {
- var arrayOfArgs = [];
- for (var i = 0; i < args.length; i++) {
- arrayOfArgs.push(args[i]);
- }
- return arrayOfArgs;
- };
-
- util.isUndefined = function(obj) {
- return obj === void 0;
- };
-
- util.arrayContains = function(array, search) {
- var i = array.length;
- while (i--) {
- if (array[i] === search) {
- return true;
- }
- }
- return false;
- };
-
- util.clone = function(obj) {
- if (Object.prototype.toString.apply(obj) === '[object Array]') {
- return obj.slice();
- }
-
- var cloned = {};
- for (var prop in obj) {
- if (obj.hasOwnProperty(prop)) {
- cloned[prop] = obj[prop];
- }
- }
-
- return cloned;
- };
-
- return util;
-};
-
-getJasmineRequireObj().Spec = function(j$) {
- function Spec(attrs) {
- this.expectationFactory = attrs.expectationFactory;
- this.resultCallback = attrs.resultCallback || function() {};
- this.id = attrs.id;
- this.description = attrs.description || '';
- this.queueableFn = attrs.queueableFn;
- this.beforeAndAfterFns = attrs.beforeAndAfterFns || function() { return {befores: [], afters: []}; };
- this.userContext = attrs.userContext || function() { return {}; };
- this.onStart = attrs.onStart || function() {};
- this.getSpecName = attrs.getSpecName || function() { return ''; };
- this.expectationResultFactory = attrs.expectationResultFactory || function() { };
- this.queueRunnerFactory = attrs.queueRunnerFactory || function() {};
- this.catchingExceptions = attrs.catchingExceptions || function() { return true; };
- this.throwOnExpectationFailure = !!attrs.throwOnExpectationFailure;
-
- if (!this.queueableFn.fn) {
- this.pend();
- }
-
- this.result = {
- id: this.id,
- description: this.description,
- fullName: this.getFullName(),
- failedExpectations: [],
- passedExpectations: [],
- pendingReason: ''
- };
- }
-
- Spec.prototype.addExpectationResult = function(passed, data, isError) {
- var expectationResult = this.expectationResultFactory(data);
- if (passed) {
- this.result.passedExpectations.push(expectationResult);
- } else {
- this.result.failedExpectations.push(expectationResult);
-
- if (this.throwOnExpectationFailure && !isError) {
- throw new j$.errors.ExpectationFailed();
- }
- }
- };
-
- Spec.prototype.expect = function(actual) {
- return this.expectationFactory(actual, this);
- };
-
- Spec.prototype.execute = function(onComplete, enabled) {
- var self = this;
-
- this.onStart(this);
-
- if (!this.isExecutable() || this.markedPending || enabled === false) {
- complete(enabled);
- return;
- }
-
- var fns = this.beforeAndAfterFns();
- var allFns = fns.befores.concat(this.queueableFn).concat(fns.afters);
-
- this.queueRunnerFactory({
- queueableFns: allFns,
- onException: function() { self.onException.apply(self, arguments); },
- onComplete: complete,
- userContext: this.userContext()
- });
-
- function complete(enabledAgain) {
- self.result.status = self.status(enabledAgain);
- self.resultCallback(self.result);
-
- if (onComplete) {
- onComplete();
- }
- }
- };
-
- Spec.prototype.onException = function onException(e) {
- if (Spec.isPendingSpecException(e)) {
- this.pend(extractCustomPendingMessage(e));
- return;
- }
-
- if (e instanceof j$.errors.ExpectationFailed) {
- return;
- }
-
- this.addExpectationResult(false, {
- matcherName: '',
- passed: false,
- expected: '',
- actual: '',
- error: e
- }, true);
- };
-
- Spec.prototype.disable = function() {
- this.disabled = true;
- };
-
- Spec.prototype.pend = function(message) {
- this.markedPending = true;
- if (message) {
- this.result.pendingReason = message;
- }
- };
-
- Spec.prototype.getResult = function() {
- this.result.status = this.status();
- return this.result;
- };
-
- Spec.prototype.status = function(enabled) {
- if (this.disabled || enabled === false) {
- return 'disabled';
- }
-
- if (this.markedPending) {
- return 'pending';
- }
-
- if (this.result.failedExpectations.length > 0) {
- return 'failed';
- } else {
- return 'passed';
- }
- };
-
- Spec.prototype.isExecutable = function() {
- return !this.disabled;
- };
-
- Spec.prototype.getFullName = function() {
- return this.getSpecName(this);
- };
-
- var extractCustomPendingMessage = function(e) {
- var fullMessage = e.toString(),
- boilerplateStart = fullMessage.indexOf(Spec.pendingSpecExceptionMessage),
- boilerplateEnd = boilerplateStart + Spec.pendingSpecExceptionMessage.length;
-
- return fullMessage.substr(boilerplateEnd);
- };
-
- Spec.pendingSpecExceptionMessage = '=> marked Pending';
-
- Spec.isPendingSpecException = function(e) {
- return !!(e && e.toString && e.toString().indexOf(Spec.pendingSpecExceptionMessage) !== -1);
- };
-
- return Spec;
-};
-
-if (typeof window == void 0 && typeof exports == 'object') {
- exports.Spec = jasmineRequire.Spec;
-}
-
-/*jshint bitwise: false*/
-
-getJasmineRequireObj().Order = function() {
- function Order(options) {
- this.random = 'random' in options ? options.random : true;
- var seed = this.seed = options.seed || generateSeed();
- this.sort = this.random ? randomOrder : naturalOrder;
-
- function naturalOrder(items) {
- return items;
- }
-
- function randomOrder(items) {
- var copy = items.slice();
- copy.sort(function(a, b) {
- return jenkinsHash(seed + a.id) - jenkinsHash(seed + b.id);
- });
- return copy;
- }
-
- function generateSeed() {
- return String(Math.random()).slice(-5);
- }
-
- // Bob Jenkins One-at-a-Time Hash algorithm is a non-cryptographic hash function
- // used to get a different output when the key changes slighly.
- // We use your return to sort the children randomly in a consistent way when
- // used in conjunction with a seed
-
- function jenkinsHash(key) {
- var hash, i;
- for(hash = i = 0; i < key.length; ++i) {
- hash += key.charCodeAt(i);
- hash += (hash << 10);
- hash ^= (hash >> 6);
- }
- hash += (hash << 3);
- hash ^= (hash >> 11);
- hash += (hash << 15);
- return hash;
- }
-
- }
-
- return Order;
-};
-
-getJasmineRequireObj().Env = function(j$) {
- function Env(options) {
- options = options || {};
-
- var self = this;
- var global = options.global || j$.getGlobal();
-
- var totalSpecsDefined = 0;
-
- var catchExceptions = true;
-
- var realSetTimeout = j$.getGlobal().setTimeout;
- var realClearTimeout = j$.getGlobal().clearTimeout;
- this.clock = new j$.Clock(global, function () { return new j$.DelayedFunctionScheduler(); }, new j$.MockDate(global));
-
- var runnableLookupTable = {};
- var runnableResources = {};
-
- var currentSpec = null;
- var currentlyExecutingSuites = [];
- var currentDeclarationSuite = null;
- var throwOnExpectationFailure = false;
- var random = false;
- var seed = null;
-
- var currentSuite = function() {
- return currentlyExecutingSuites[currentlyExecutingSuites.length - 1];
- };
-
- var currentRunnable = function() {
- return currentSpec || currentSuite();
- };
-
- var reporter = new j$.ReportDispatcher([
- 'jasmineStarted',
- 'jasmineDone',
- 'suiteStarted',
- 'suiteDone',
- 'specStarted',
- 'specDone'
- ]);
-
- this.specFilter = function() {
- return true;
- };
-
- this.addCustomEqualityTester = function(tester) {
- if(!currentRunnable()) {
- throw new Error('Custom Equalities must be added in a before function or a spec');
- }
- runnableResources[currentRunnable().id].customEqualityTesters.push(tester);
- };
-
- this.addMatchers = function(matchersToAdd) {
- if(!currentRunnable()) {
- throw new Error('Matchers must be added in a before function or a spec');
- }
- var customMatchers = runnableResources[currentRunnable().id].customMatchers;
- for (var matcherName in matchersToAdd) {
- customMatchers[matcherName] = matchersToAdd[matcherName];
- }
- };
-
- j$.Expectation.addCoreMatchers(j$.matchers);
-
- var nextSpecId = 0;
- var getNextSpecId = function() {
- return 'spec' + nextSpecId++;
- };
-
- var nextSuiteId = 0;
- var getNextSuiteId = function() {
- return 'suite' + nextSuiteId++;
- };
-
- var expectationFactory = function(actual, spec) {
- return j$.Expectation.Factory({
- util: j$.matchersUtil,
- customEqualityTesters: runnableResources[spec.id].customEqualityTesters,
- customMatchers: runnableResources[spec.id].customMatchers,
- actual: actual,
- addExpectationResult: addExpectationResult
- });
-
- function addExpectationResult(passed, result) {
- return spec.addExpectationResult(passed, result);
- }
- };
-
- var defaultResourcesForRunnable = function(id, parentRunnableId) {
- var resources = {spies: [], customEqualityTesters: [], customMatchers: {}};
-
- if(runnableResources[parentRunnableId]){
- resources.customEqualityTesters = j$.util.clone(runnableResources[parentRunnableId].customEqualityTesters);
- resources.customMatchers = j$.util.clone(runnableResources[parentRunnableId].customMatchers);
- }
-
- runnableResources[id] = resources;
- };
-
- var clearResourcesForRunnable = function(id) {
- spyRegistry.clearSpies();
- delete runnableResources[id];
- };
-
- var beforeAndAfterFns = function(suite) {
- return function() {
- var befores = [],
- afters = [];
-
- while(suite) {
- befores = befores.concat(suite.beforeFns);
- afters = afters.concat(suite.afterFns);
-
- suite = suite.parentSuite;
- }
-
- return {
- befores: befores.reverse(),
- afters: afters
- };
- };
- };
-
- var getSpecName = function(spec, suite) {
- return suite.getFullName() + ' ' + spec.description;
- };
-
- // TODO: we may just be able to pass in the fn instead of wrapping here
- var buildExpectationResult = j$.buildExpectationResult,
- exceptionFormatter = new j$.ExceptionFormatter(),
- expectationResultFactory = function(attrs) {
- attrs.messageFormatter = exceptionFormatter.message;
- attrs.stackFormatter = exceptionFormatter.stack;
-
- return buildExpectationResult(attrs);
- };
-
- // TODO: fix this naming, and here's where the value comes in
- this.catchExceptions = function(value) {
- catchExceptions = !!value;
- return catchExceptions;
- };
-
- this.catchingExceptions = function() {
- return catchExceptions;
- };
-
- var maximumSpecCallbackDepth = 20;
- var currentSpecCallbackDepth = 0;
-
- function clearStack(fn) {
- currentSpecCallbackDepth++;
- if (currentSpecCallbackDepth >= maximumSpecCallbackDepth) {
- currentSpecCallbackDepth = 0;
- realSetTimeout(fn, 0);
- } else {
- fn();
- }
- }
-
- var catchException = function(e) {
- return j$.Spec.isPendingSpecException(e) || catchExceptions;
- };
-
- this.throwOnExpectationFailure = function(value) {
- throwOnExpectationFailure = !!value;
- };
-
- this.throwingExpectationFailures = function() {
- return throwOnExpectationFailure;
- };
-
- this.randomizeTests = function(value) {
- random = !!value;
- };
-
- this.randomTests = function() {
- return random;
- };
-
- this.seed = function(value) {
- if (value) {
- seed = value;
- }
- return seed;
- };
-
- var queueRunnerFactory = function(options) {
- options.catchException = catchException;
- options.clearStack = options.clearStack || clearStack;
- options.timeout = {setTimeout: realSetTimeout, clearTimeout: realClearTimeout};
- options.fail = self.fail;
-
- new j$.QueueRunner(options).execute();
- };
-
- var topSuite = new j$.Suite({
- env: this,
- id: getNextSuiteId(),
- description: 'Jasmine__TopLevel__Suite',
- queueRunner: queueRunnerFactory
- });
- runnableLookupTable[topSuite.id] = topSuite;
- defaultResourcesForRunnable(topSuite.id);
- currentDeclarationSuite = topSuite;
-
- this.topSuite = function() {
- return topSuite;
- };
-
- this.execute = function(runnablesToRun) {
- if(!runnablesToRun) {
- if (focusedRunnables.length) {
- runnablesToRun = focusedRunnables;
- } else {
- runnablesToRun = [topSuite.id];
- }
- }
-
- var order = new j$.Order({
- random: random,
- seed: seed
- });
-
- var processor = new j$.TreeProcessor({
- tree: topSuite,
- runnableIds: runnablesToRun,
- queueRunnerFactory: queueRunnerFactory,
- nodeStart: function(suite) {
- currentlyExecutingSuites.push(suite);
- defaultResourcesForRunnable(suite.id, suite.parentSuite.id);
- reporter.suiteStarted(suite.result);
- },
- nodeComplete: function(suite, result) {
- if (!suite.disabled) {
- clearResourcesForRunnable(suite.id);
- }
- currentlyExecutingSuites.pop();
- reporter.suiteDone(result);
- },
- orderChildren: function(node) {
- return order.sort(node.children);
- }
- });
-
- if(!processor.processTree().valid) {
- throw new Error('Invalid order: would cause a beforeAll or afterAll to be run multiple times');
- }
-
- reporter.jasmineStarted({
- totalSpecsDefined: totalSpecsDefined
- });
-
- processor.execute(function() {
- reporter.jasmineDone({
- order: order
- });
- });
- };
-
- this.addReporter = function(reporterToAdd) {
- reporter.addReporter(reporterToAdd);
- };
-
- var spyRegistry = new j$.SpyRegistry({currentSpies: function() {
- if(!currentRunnable()) {
- throw new Error('Spies must be created in a before function or a spec');
- }
- return runnableResources[currentRunnable().id].spies;
- }});
-
- this.spyOn = function() {
- return spyRegistry.spyOn.apply(spyRegistry, arguments);
- };
-
- var suiteFactory = function(description) {
- var suite = new j$.Suite({
- env: self,
- id: getNextSuiteId(),
- description: description,
- parentSuite: currentDeclarationSuite,
- expectationFactory: expectationFactory,
- expectationResultFactory: expectationResultFactory,
- throwOnExpectationFailure: throwOnExpectationFailure
- });
-
- runnableLookupTable[suite.id] = suite;
- return suite;
- };
-
- this.describe = function(description, specDefinitions) {
- var suite = suiteFactory(description);
- if (specDefinitions.length > 0) {
- throw new Error('describe does not expect a done parameter');
- }
- if (currentDeclarationSuite.markedPending) {
- suite.pend();
- }
- addSpecsToSuite(suite, specDefinitions);
- return suite;
- };
-
- this.xdescribe = function(description, specDefinitions) {
- var suite = suiteFactory(description);
- suite.pend();
- addSpecsToSuite(suite, specDefinitions);
- return suite;
- };
-
- var focusedRunnables = [];
-
- this.fdescribe = function(description, specDefinitions) {
- var suite = suiteFactory(description);
- suite.isFocused = true;
-
- focusedRunnables.push(suite.id);
- unfocusAncestor();
- addSpecsToSuite(suite, specDefinitions);
-
- return suite;
- };
-
- function addSpecsToSuite(suite, specDefinitions) {
- var parentSuite = currentDeclarationSuite;
- parentSuite.addChild(suite);
- currentDeclarationSuite = suite;
-
- var declarationError = null;
- try {
- specDefinitions.call(suite);
- } catch (e) {
- declarationError = e;
- }
-
- if (declarationError) {
- self.it('encountered a declaration exception', function() {
- throw declarationError;
- });
- }
-
- currentDeclarationSuite = parentSuite;
- }
-
- function findFocusedAncestor(suite) {
- while (suite) {
- if (suite.isFocused) {
- return suite.id;
- }
- suite = suite.parentSuite;
- }
-
- return null;
- }
-
- function unfocusAncestor() {
- var focusedAncestor = findFocusedAncestor(currentDeclarationSuite);
- if (focusedAncestor) {
- for (var i = 0; i < focusedRunnables.length; i++) {
- if (focusedRunnables[i] === focusedAncestor) {
- focusedRunnables.splice(i, 1);
- break;
- }
- }
- }
- }
-
- var specFactory = function(description, fn, suite, timeout) {
- totalSpecsDefined++;
- var spec = new j$.Spec({
- id: getNextSpecId(),
- beforeAndAfterFns: beforeAndAfterFns(suite),
- expectationFactory: expectationFactory,
- resultCallback: specResultCallback,
- getSpecName: function(spec) {
- return getSpecName(spec, suite);
- },
- onStart: specStarted,
- description: description,
- expectationResultFactory: expectationResultFactory,
- queueRunnerFactory: queueRunnerFactory,
- userContext: function() { return suite.clonedSharedUserContext(); },
- queueableFn: {
- fn: fn,
- timeout: function() { return timeout || j$.DEFAULT_TIMEOUT_INTERVAL; }
- },
- throwOnExpectationFailure: throwOnExpectationFailure
- });
-
- runnableLookupTable[spec.id] = spec;
-
- if (!self.specFilter(spec)) {
- spec.disable();
- }
-
- return spec;
-
- function specResultCallback(result) {
- clearResourcesForRunnable(spec.id);
- currentSpec = null;
- reporter.specDone(result);
- }
-
- function specStarted(spec) {
- currentSpec = spec;
- defaultResourcesForRunnable(spec.id, suite.id);
- reporter.specStarted(spec.result);
- }
- };
-
- this.it = function(description, fn, timeout) {
- var spec = specFactory(description, fn, currentDeclarationSuite, timeout);
- if (currentDeclarationSuite.markedPending) {
- spec.pend();
- }
- currentDeclarationSuite.addChild(spec);
- return spec;
- };
-
- this.xit = function() {
- var spec = this.it.apply(this, arguments);
- spec.pend('Temporarily disabled with xit');
- return spec;
- };
-
- this.fit = function(description, fn, timeout){
- var spec = specFactory(description, fn, currentDeclarationSuite, timeout);
- currentDeclarationSuite.addChild(spec);
- focusedRunnables.push(spec.id);
- unfocusAncestor();
- return spec;
- };
-
- this.expect = function(actual) {
- if (!currentRunnable()) {
- throw new Error('\'expect\' was used when there was no current spec, this could be because an asynchronous test timed out');
- }
-
- return currentRunnable().expect(actual);
- };
-
- this.beforeEach = function(beforeEachFunction, timeout) {
- currentDeclarationSuite.beforeEach({
- fn: beforeEachFunction,
- timeout: function() { return timeout || j$.DEFAULT_TIMEOUT_INTERVAL; }
- });
- };
-
- this.beforeAll = function(beforeAllFunction, timeout) {
- currentDeclarationSuite.beforeAll({
- fn: beforeAllFunction,
- timeout: function() { return timeout || j$.DEFAULT_TIMEOUT_INTERVAL; }
- });
- };
-
- this.afterEach = function(afterEachFunction, timeout) {
- currentDeclarationSuite.afterEach({
- fn: afterEachFunction,
- timeout: function() { return timeout || j$.DEFAULT_TIMEOUT_INTERVAL; }
- });
- };
-
- this.afterAll = function(afterAllFunction, timeout) {
- currentDeclarationSuite.afterAll({
- fn: afterAllFunction,
- timeout: function() { return timeout || j$.DEFAULT_TIMEOUT_INTERVAL; }
- });
- };
-
- this.pending = function(message) {
- var fullMessage = j$.Spec.pendingSpecExceptionMessage;
- if(message) {
- fullMessage += message;
- }
- throw fullMessage;
- };
-
- this.fail = function(error) {
- var message = 'Failed';
- if (error) {
- message += ': ';
- message += error.message || error;
- }
-
- currentRunnable().addExpectationResult(false, {
- matcherName: '',
- passed: false,
- expected: '',
- actual: '',
- message: message,
- error: error && error.message ? error : null
- });
- };
- }
-
- return Env;
-};
-
-getJasmineRequireObj().JsApiReporter = function() {
-
- var noopTimer = {
- start: function(){},
- elapsed: function(){ return 0; }
- };
-
- function JsApiReporter(options) {
- var timer = options.timer || noopTimer,
- status = 'loaded';
-
- this.started = false;
- this.finished = false;
- this.runDetails = {};
-
- this.jasmineStarted = function() {
- this.started = true;
- status = 'started';
- timer.start();
- };
-
- var executionTime;
-
- this.jasmineDone = function(runDetails) {
- this.finished = true;
- this.runDetails = runDetails;
- executionTime = timer.elapsed();
- status = 'done';
- };
-
- this.status = function() {
- return status;
- };
-
- var suites = [],
- suites_hash = {};
-
- this.suiteStarted = function(result) {
- suites_hash[result.id] = result;
- };
-
- this.suiteDone = function(result) {
- storeSuite(result);
- };
-
- this.suiteResults = function(index, length) {
- return suites.slice(index, index + length);
- };
-
- function storeSuite(result) {
- suites.push(result);
- suites_hash[result.id] = result;
- }
-
- this.suites = function() {
- return suites_hash;
- };
-
- var specs = [];
-
- this.specDone = function(result) {
- specs.push(result);
- };
-
- this.specResults = function(index, length) {
- return specs.slice(index, index + length);
- };
-
- this.specs = function() {
- return specs;
- };
-
- this.executionTime = function() {
- return executionTime;
- };
-
- }
-
- return JsApiReporter;
-};
-
-getJasmineRequireObj().CallTracker = function() {
-
- function CallTracker() {
- var calls = [];
-
- this.track = function(context) {
- calls.push(context);
- };
-
- this.any = function() {
- return !!calls.length;
- };
-
- this.count = function() {
- return calls.length;
- };
-
- this.argsFor = function(index) {
- var call = calls[index];
- return call ? call.args : [];
- };
-
- this.all = function() {
- return calls;
- };
-
- this.allArgs = function() {
- var callArgs = [];
- for(var i = 0; i < calls.length; i++){
- callArgs.push(calls[i].args);
- }
-
- return callArgs;
- };
-
- this.first = function() {
- return calls[0];
- };
-
- this.mostRecent = function() {
- return calls[calls.length - 1];
- };
-
- this.reset = function() {
- calls = [];
- };
- }
-
- return CallTracker;
-};
-
-getJasmineRequireObj().Clock = function() {
- function Clock(global, delayedFunctionSchedulerFactory, mockDate) {
- var self = this,
- realTimingFunctions = {
- setTimeout: global.setTimeout,
- clearTimeout: global.clearTimeout,
- setInterval: global.setInterval,
- clearInterval: global.clearInterval
- },
- fakeTimingFunctions = {
- setTimeout: setTimeout,
- clearTimeout: clearTimeout,
- setInterval: setInterval,
- clearInterval: clearInterval
- },
- installed = false,
- delayedFunctionScheduler,
- timer;
-
-
- self.install = function() {
- if(!originalTimingFunctionsIntact()) {
- throw new Error('Jasmine Clock was unable to install over custom global timer functions. Is the clock already installed?');
- }
- replace(global, fakeTimingFunctions);
- timer = fakeTimingFunctions;
- delayedFunctionScheduler = delayedFunctionSchedulerFactory();
- installed = true;
-
- return self;
- };
-
- self.uninstall = function() {
- delayedFunctionScheduler = null;
- mockDate.uninstall();
- replace(global, realTimingFunctions);
-
- timer = realTimingFunctions;
- installed = false;
- };
-
- self.withMock = function(closure) {
- this.install();
- try {
- closure();
- } finally {
- this.uninstall();
- }
- };
-
- self.mockDate = function(initialDate) {
- mockDate.install(initialDate);
- };
-
- self.setTimeout = function(fn, delay, params) {
- if (legacyIE()) {
- if (arguments.length > 2) {
- throw new Error('IE < 9 cannot support extra params to setTimeout without a polyfill');
- }
- return timer.setTimeout(fn, delay);
- }
- return Function.prototype.apply.apply(timer.setTimeout, [global, arguments]);
- };
-
- self.setInterval = function(fn, delay, params) {
- if (legacyIE()) {
- if (arguments.length > 2) {
- throw new Error('IE < 9 cannot support extra params to setInterval without a polyfill');
- }
- return timer.setInterval(fn, delay);
- }
- return Function.prototype.apply.apply(timer.setInterval, [global, arguments]);
- };
-
- self.clearTimeout = function(id) {
- return Function.prototype.call.apply(timer.clearTimeout, [global, id]);
- };
-
- self.clearInterval = function(id) {
- return Function.prototype.call.apply(timer.clearInterval, [global, id]);
- };
-
- self.tick = function(millis) {
- if (installed) {
- mockDate.tick(millis);
- delayedFunctionScheduler.tick(millis);
- } else {
- throw new Error('Mock clock is not installed, use jasmine.clock().install()');
- }
- };
-
- return self;
-
- function originalTimingFunctionsIntact() {
- return global.setTimeout === realTimingFunctions.setTimeout &&
- global.clearTimeout === realTimingFunctions.clearTimeout &&
- global.setInterval === realTimingFunctions.setInterval &&
- global.clearInterval === realTimingFunctions.clearInterval;
- }
-
- function legacyIE() {
- //if these methods are polyfilled, apply will be present
- return !(realTimingFunctions.setTimeout || realTimingFunctions.setInterval).apply;
- }
-
- function replace(dest, source) {
- for (var prop in source) {
- dest[prop] = source[prop];
- }
- }
-
- function setTimeout(fn, delay) {
- return delayedFunctionScheduler.scheduleFunction(fn, delay, argSlice(arguments, 2));
- }
-
- function clearTimeout(id) {
- return delayedFunctionScheduler.removeFunctionWithId(id);
- }
-
- function setInterval(fn, interval) {
- return delayedFunctionScheduler.scheduleFunction(fn, interval, argSlice(arguments, 2), true);
- }
-
- function clearInterval(id) {
- return delayedFunctionScheduler.removeFunctionWithId(id);
- }
-
- function argSlice(argsObj, n) {
- return Array.prototype.slice.call(argsObj, n);
- }
- }
-
- return Clock;
-};
-
-getJasmineRequireObj().DelayedFunctionScheduler = function() {
- function DelayedFunctionScheduler() {
- var self = this;
- var scheduledLookup = [];
- var scheduledFunctions = {};
- var currentTime = 0;
- var delayedFnCount = 0;
-
- self.tick = function(millis) {
- millis = millis || 0;
- var endTime = currentTime + millis;
-
- runScheduledFunctions(endTime);
- currentTime = endTime;
- };
-
- self.scheduleFunction = function(funcToCall, millis, params, recurring, timeoutKey, runAtMillis) {
- var f;
- if (typeof(funcToCall) === 'string') {
- /* jshint evil: true */
- f = function() { return eval(funcToCall); };
- /* jshint evil: false */
- } else {
- f = funcToCall;
- }
-
- millis = millis || 0;
- timeoutKey = timeoutKey || ++delayedFnCount;
- runAtMillis = runAtMillis || (currentTime + millis);
-
- var funcToSchedule = {
- runAtMillis: runAtMillis,
- funcToCall: f,
- recurring: recurring,
- params: params,
- timeoutKey: timeoutKey,
- millis: millis
- };
-
- if (runAtMillis in scheduledFunctions) {
- scheduledFunctions[runAtMillis].push(funcToSchedule);
- } else {
- scheduledFunctions[runAtMillis] = [funcToSchedule];
- scheduledLookup.push(runAtMillis);
- scheduledLookup.sort(function (a, b) {
- return a - b;
- });
- }
-
- return timeoutKey;
- };
-
- self.removeFunctionWithId = function(timeoutKey) {
- for (var runAtMillis in scheduledFunctions) {
- var funcs = scheduledFunctions[runAtMillis];
- var i = indexOfFirstToPass(funcs, function (func) {
- return func.timeoutKey === timeoutKey;
- });
-
- if (i > -1) {
- if (funcs.length === 1) {
- delete scheduledFunctions[runAtMillis];
- deleteFromLookup(runAtMillis);
- } else {
- funcs.splice(i, 1);
- }
-
- // intervals get rescheduled when executed, so there's never more
- // than a single scheduled function with a given timeoutKey
- break;
- }
- }
- };
-
- return self;
-
- function indexOfFirstToPass(array, testFn) {
- var index = -1;
-
- for (var i = 0; i < array.length; ++i) {
- if (testFn(array[i])) {
- index = i;
- break;
- }
- }
-
- return index;
- }
-
- function deleteFromLookup(key) {
- var value = Number(key);
- var i = indexOfFirstToPass(scheduledLookup, function (millis) {
- return millis === value;
- });
-
- if (i > -1) {
- scheduledLookup.splice(i, 1);
- }
- }
-
- function reschedule(scheduledFn) {
- self.scheduleFunction(scheduledFn.funcToCall,
- scheduledFn.millis,
- scheduledFn.params,
- true,
- scheduledFn.timeoutKey,
- scheduledFn.runAtMillis + scheduledFn.millis);
- }
-
- function forEachFunction(funcsToRun, callback) {
- for (var i = 0; i < funcsToRun.length; ++i) {
- callback(funcsToRun[i]);
- }
- }
-
- function runScheduledFunctions(endTime) {
- if (scheduledLookup.length === 0 || scheduledLookup[0] > endTime) {
- return;
- }
-
- do {
- currentTime = scheduledLookup.shift();
-
- var funcsToRun = scheduledFunctions[currentTime];
- delete scheduledFunctions[currentTime];
-
- forEachFunction(funcsToRun, function(funcToRun) {
- if (funcToRun.recurring) {
- reschedule(funcToRun);
- }
- });
-
- forEachFunction(funcsToRun, function(funcToRun) {
- funcToRun.funcToCall.apply(null, funcToRun.params || []);
- });
- } while (scheduledLookup.length > 0 &&
- // checking first if we're out of time prevents setTimeout(0)
- // scheduled in a funcToRun from forcing an extra iteration
- currentTime !== endTime &&
- scheduledLookup[0] <= endTime);
- }
- }
-
- return DelayedFunctionScheduler;
-};
-
-getJasmineRequireObj().ExceptionFormatter = function() {
- function ExceptionFormatter() {
- this.message = function(error) {
- var message = '';
-
- if (error.name && error.message) {
- message += error.name + ': ' + error.message;
- } else {
- message += error.toString() + ' thrown';
- }
-
- if (error.fileName || error.sourceURL) {
- message += ' in ' + (error.fileName || error.sourceURL);
- }
-
- if (error.line || error.lineNumber) {
- message += ' (line ' + (error.line || error.lineNumber) + ')';
- }
-
- return message;
- };
-
- this.stack = function(error) {
- return error ? error.stack : null;
- };
- }
-
- return ExceptionFormatter;
-};
-
-getJasmineRequireObj().Expectation = function() {
-
- function Expectation(options) {
- this.util = options.util || { buildFailureMessage: function() {} };
- this.customEqualityTesters = options.customEqualityTesters || [];
- this.actual = options.actual;
- this.addExpectationResult = options.addExpectationResult || function(){};
- this.isNot = options.isNot;
-
- var customMatchers = options.customMatchers || {};
- for (var matcherName in customMatchers) {
- this[matcherName] = Expectation.prototype.wrapCompare(matcherName, customMatchers[matcherName]);
- }
- }
-
- Expectation.prototype.wrapCompare = function(name, matcherFactory) {
- return function() {
- var args = Array.prototype.slice.call(arguments, 0),
- expected = args.slice(0),
- message = '';
-
- args.unshift(this.actual);
-
- var matcher = matcherFactory(this.util, this.customEqualityTesters),
- matcherCompare = matcher.compare;
-
- function defaultNegativeCompare() {
- var result = matcher.compare.apply(null, args);
- result.pass = !result.pass;
- return result;
- }
-
- if (this.isNot) {
- matcherCompare = matcher.negativeCompare || defaultNegativeCompare;
- }
-
- var result = matcherCompare.apply(null, args);
-
- if (!result.pass) {
- if (!result.message) {
- args.unshift(this.isNot);
- args.unshift(name);
- message = this.util.buildFailureMessage.apply(null, args);
- } else {
- if (Object.prototype.toString.apply(result.message) === '[object Function]') {
- message = result.message();
- } else {
- message = result.message;
- }
- }
- }
-
- if (expected.length == 1) {
- expected = expected[0];
- }
-
- // TODO: how many of these params are needed?
- this.addExpectationResult(
- result.pass,
- {
- matcherName: name,
- passed: result.pass,
- message: message,
- actual: this.actual,
- expected: expected // TODO: this may need to be arrayified/sliced
- }
- );
- };
- };
-
- Expectation.addCoreMatchers = function(matchers) {
- var prototype = Expectation.prototype;
- for (var matcherName in matchers) {
- var matcher = matchers[matcherName];
- prototype[matcherName] = prototype.wrapCompare(matcherName, matcher);
- }
- };
-
- Expectation.Factory = function(options) {
- options = options || {};
-
- var expect = new Expectation(options);
-
- // TODO: this would be nice as its own Object - NegativeExpectation
- // TODO: copy instead of mutate options
- options.isNot = true;
- expect.not = new Expectation(options);
-
- return expect;
- };
-
- return Expectation;
-};
-
-//TODO: expectation result may make more sense as a presentation of an expectation.
-getJasmineRequireObj().buildExpectationResult = function() {
- function buildExpectationResult(options) {
- var messageFormatter = options.messageFormatter || function() {},
- stackFormatter = options.stackFormatter || function() {};
-
- var result = {
- matcherName: options.matcherName,
- message: message(),
- stack: stack(),
- passed: options.passed
- };
-
- if(!result.passed) {
- result.expected = options.expected;
- result.actual = options.actual;
- }
-
- return result;
-
- function message() {
- if (options.passed) {
- return 'Passed.';
- } else if (options.message) {
- return options.message;
- } else if (options.error) {
- return messageFormatter(options.error);
- }
- return '';
- }
-
- function stack() {
- if (options.passed) {
- return '';
- }
-
- var error = options.error;
- if (!error) {
- try {
- throw new Error(message());
- } catch (e) {
- error = e;
- }
- }
- return stackFormatter(error);
- }
- }
-
- return buildExpectationResult;
-};
-
-getJasmineRequireObj().MockDate = function() {
- function MockDate(global) {
- var self = this;
- var currentTime = 0;
-
- if (!global || !global.Date) {
- self.install = function() {};
- self.tick = function() {};
- self.uninstall = function() {};
- return self;
- }
-
- var GlobalDate = global.Date;
-
- self.install = function(mockDate) {
- if (mockDate instanceof GlobalDate) {
- currentTime = mockDate.getTime();
- } else {
- currentTime = new GlobalDate().getTime();
- }
-
- global.Date = FakeDate;
- };
-
- self.tick = function(millis) {
- millis = millis || 0;
- currentTime = currentTime + millis;
- };
-
- self.uninstall = function() {
- currentTime = 0;
- global.Date = GlobalDate;
- };
-
- createDateProperties();
-
- return self;
-
- function FakeDate() {
- switch(arguments.length) {
- case 0:
- return new GlobalDate(currentTime);
- case 1:
- return new GlobalDate(arguments[0]);
- case 2:
- return new GlobalDate(arguments[0], arguments[1]);
- case 3:
- return new GlobalDate(arguments[0], arguments[1], arguments[2]);
- case 4:
- return new GlobalDate(arguments[0], arguments[1], arguments[2], arguments[3]);
- case 5:
- return new GlobalDate(arguments[0], arguments[1], arguments[2], arguments[3],
- arguments[4]);
- case 6:
- return new GlobalDate(arguments[0], arguments[1], arguments[2], arguments[3],
- arguments[4], arguments[5]);
- default:
- return new GlobalDate(arguments[0], arguments[1], arguments[2], arguments[3],
- arguments[4], arguments[5], arguments[6]);
- }
- }
-
- function createDateProperties() {
- FakeDate.prototype = GlobalDate.prototype;
-
- FakeDate.now = function() {
- if (GlobalDate.now) {
- return currentTime;
- } else {
- throw new Error('Browser does not support Date.now()');
- }
- };
-
- FakeDate.toSource = GlobalDate.toSource;
- FakeDate.toString = GlobalDate.toString;
- FakeDate.parse = GlobalDate.parse;
- FakeDate.UTC = GlobalDate.UTC;
- }
- }
-
- return MockDate;
-};
-
-getJasmineRequireObj().pp = function(j$) {
-
- function PrettyPrinter() {
- this.ppNestLevel_ = 0;
- this.seen = [];
- }
-
- PrettyPrinter.prototype.format = function(value) {
- this.ppNestLevel_++;
- try {
- if (j$.util.isUndefined(value)) {
- this.emitScalar('undefined');
- } else if (value === null) {
- this.emitScalar('null');
- } else if (value === 0 && 1/value === -Infinity) {
- this.emitScalar('-0');
- } else if (value === j$.getGlobal()) {
- this.emitScalar('<global>');
- } else if (value.jasmineToString) {
- this.emitScalar(value.jasmineToString());
- } else if (typeof value === 'string') {
- this.emitString(value);
- } else if (j$.isSpy(value)) {
- this.emitScalar('spy on ' + value.and.identity());
- } else if (value instanceof RegExp) {
- this.emitScalar(value.toString());
- } else if (typeof value === 'function') {
- this.emitScalar('Function');
- } else if (typeof value.nodeType === 'number') {
- this.emitScalar('HTMLNode');
- } else if (value instanceof Date) {
- this.emitScalar('Date(' + value + ')');
- } else if (value.toString && typeof value === 'object' && !(value instanceof Array) && value.toString !== Object.prototype.toString) {
- this.emitScalar(value.toString());
- } else if (j$.util.arrayContains(this.seen, value)) {
- this.emitScalar('<circular reference: ' + (j$.isArray_(value) ? 'Array' : 'Object') + '>');
- } else if (j$.isArray_(value) || j$.isA_('Object', value)) {
- this.seen.push(value);
- if (j$.isArray_(value)) {
- this.emitArray(value);
- } else {
- this.emitObject(value);
- }
- this.seen.pop();
- } else {
- this.emitScalar(value.toString());
- }
- } finally {
- this.ppNestLevel_--;
- }
- };
-
- PrettyPrinter.prototype.iterateObject = function(obj, fn) {
- for (var property in obj) {
- if (!Object.prototype.hasOwnProperty.call(obj, property)) { continue; }
- fn(property, obj.__lookupGetter__ ? (!j$.util.isUndefined(obj.__lookupGetter__(property)) &&
- obj.__lookupGetter__(property) !== null) : false);
- }
- };
-
- PrettyPrinter.prototype.emitArray = j$.unimplementedMethod_;
- PrettyPrinter.prototype.emitObject = j$.unimplementedMethod_;
- PrettyPrinter.prototype.emitScalar = j$.unimplementedMethod_;
- PrettyPrinter.prototype.emitString = j$.unimplementedMethod_;
-
- function StringPrettyPrinter() {
- PrettyPrinter.call(this);
-
- this.string = '';
- }
-
- j$.util.inherit(StringPrettyPrinter, PrettyPrinter);
-
- StringPrettyPrinter.prototype.emitScalar = function(value) {
- this.append(value);
- };
-
- StringPrettyPrinter.prototype.emitString = function(value) {
- this.append('\'' + value + '\'');
- };
-
- StringPrettyPrinter.prototype.emitArray = function(array) {
- if (this.ppNestLevel_ > j$.MAX_PRETTY_PRINT_DEPTH) {
- this.append('Array');
- return;
- }
- var length = Math.min(array.length, j$.MAX_PRETTY_PRINT_ARRAY_LENGTH);
- this.append('[ ');
- for (var i = 0; i < length; i++) {
- if (i > 0) {
- this.append(', ');
- }
- this.format(array[i]);
- }
- if(array.length > length){
- this.append(', ...');
- }
-
- var self = this;
- var first = array.length === 0;
- this.iterateObject(array, function(property, isGetter) {
- if (property.match(/^\d+$/)) {
- return;
- }
-
- if (first) {
- first = false;
- } else {
- self.append(', ');
- }
-
- self.formatProperty(array, property, isGetter);
- });
-
- this.append(' ]');
- };
-
- StringPrettyPrinter.prototype.emitObject = function(obj) {
- var constructorName = obj.constructor ? j$.fnNameFor(obj.constructor) : 'null';
- this.append(constructorName);
-
- if (this.ppNestLevel_ > j$.MAX_PRETTY_PRINT_DEPTH) {
- return;
- }
-
- var self = this;
- this.append('({ ');
- var first = true;
-
- this.iterateObject(obj, function(property, isGetter) {
- if (first) {
- first = false;
- } else {
- self.append(', ');
- }
-
- self.formatProperty(obj, property, isGetter);
- });
-
- this.append(' })');
- };
-
- StringPrettyPrinter.prototype.formatProperty = function(obj, property, isGetter) {
- this.append(property);
- this.append(': ');
- if (isGetter) {
- this.append('<getter>');
- } else {
- this.format(obj[property]);
- }
- };
-
- StringPrettyPrinter.prototype.append = function(value) {
- this.string += value;
- };
-
- return function(value) {
- var stringPrettyPrinter = new StringPrettyPrinter();
- stringPrettyPrinter.format(value);
- return stringPrettyPrinter.string;
- };
-};
-
-getJasmineRequireObj().QueueRunner = function(j$) {
-
- function once(fn) {
- var called = false;
- return function() {
- if (!called) {
- called = true;
- fn();
- }
- };
- }
-
- function QueueRunner(attrs) {
- this.queueableFns = attrs.queueableFns || [];
- this.onComplete = attrs.onComplete || function() {};
- this.clearStack = attrs.clearStack || function(fn) {fn();};
- this.onException = attrs.onException || function() {};
- this.catchException = attrs.catchException || function() { return true; };
- this.userContext = attrs.userContext || {};
- this.timeout = attrs.timeout || {setTimeout: setTimeout, clearTimeout: clearTimeout};
- this.fail = attrs.fail || function() {};
- }
-
- QueueRunner.prototype.execute = function() {
- this.run(this.queueableFns, 0);
- };
-
- QueueRunner.prototype.run = function(queueableFns, recursiveIndex) {
- var length = queueableFns.length,
- self = this,
- iterativeIndex;
-
-
- for(iterativeIndex = recursiveIndex; iterativeIndex < length; iterativeIndex++) {
- var queueableFn = queueableFns[iterativeIndex];
- if (queueableFn.fn.length > 0) {
- attemptAsync(queueableFn);
- return;
- } else {
- attemptSync(queueableFn);
- }
- }
-
- var runnerDone = iterativeIndex >= length;
-
- if (runnerDone) {
- this.clearStack(this.onComplete);
- }
-
- function attemptSync(queueableFn) {
- try {
- queueableFn.fn.call(self.userContext);
- } catch (e) {
- handleException(e, queueableFn);
- }
- }
-
- function attemptAsync(queueableFn) {
- var clearTimeout = function () {
- Function.prototype.apply.apply(self.timeout.clearTimeout, [j$.getGlobal(), [timeoutId]]);
- },
- next = once(function () {
- clearTimeout(timeoutId);
- self.run(queueableFns, iterativeIndex + 1);
- }),
- timeoutId;
-
- next.fail = function() {
- self.fail.apply(null, arguments);
- next();
- };
-
- if (queueableFn.timeout) {
- timeoutId = Function.prototype.apply.apply(self.timeout.setTimeout, [j$.getGlobal(), [function() {
- var error = new Error('Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.');
- onException(error);
- next();
- }, queueableFn.timeout()]]);
- }
-
- try {
- queueableFn.fn.call(self.userContext, next);
- } catch (e) {
- handleException(e, queueableFn);
- next();
- }
- }
-
- function onException(e) {
- self.onException(e);
- }
-
- function handleException(e, queueableFn) {
- onException(e);
- if (!self.catchException(e)) {
- //TODO: set a var when we catch an exception and
- //use a finally block to close the loop in a nice way..
- throw e;
- }
- }
- };
-
- return QueueRunner;
-};
-
-getJasmineRequireObj().ReportDispatcher = function() {
- function ReportDispatcher(methods) {
-
- var dispatchedMethods = methods || [];
-
- for (var i = 0; i < dispatchedMethods.length; i++) {
- var method = dispatchedMethods[i];
- this[method] = (function(m) {
- return function() {
- dispatch(m, arguments);
- };
- }(method));
- }
-
- var reporters = [];
-
- this.addReporter = function(reporter) {
- reporters.push(reporter);
- };
-
- return this;
-
- function dispatch(method, args) {
- for (var i = 0; i < reporters.length; i++) {
- var reporter = reporters[i];
- if (reporter[method]) {
- reporter[method].apply(reporter, args);
- }
- }
- }
- }
-
- return ReportDispatcher;
-};
-
-
-getJasmineRequireObj().SpyRegistry = function(j$) {
-
- function SpyRegistry(options) {
- options = options || {};
- var currentSpies = options.currentSpies || function() { return []; };
-
- this.spyOn = function(obj, methodName) {
- if (j$.util.isUndefined(obj)) {
- throw new Error('spyOn could not find an object to spy upon for ' + methodName + '()');
- }
-
- if (j$.util.isUndefined(methodName)) {
- throw new Error('No method name supplied');
- }
-
- if (j$.util.isUndefined(obj[methodName])) {
- throw new Error(methodName + '() method does not exist');
- }
-
- if (obj[methodName] && j$.isSpy(obj[methodName])) {
- //TODO?: should this return the current spy? Downside: may cause user confusion about spy state
- throw new Error(methodName + ' has already been spied upon');
- }
-
- var descriptor;
- try {
- descriptor = Object.getOwnPropertyDescriptor(obj, methodName);
- } catch(e) {
- // IE 8 doesn't support `definePropery` on non-DOM nodes
- }
-
- if (descriptor && !(descriptor.writable || descriptor.set)) {
- throw new Error(methodName + ' is not declared writable or has no setter');
- }
-
- var spy = j$.createSpy(methodName, obj[methodName]);
-
- currentSpies().push({
- spy: spy,
- baseObj: obj,
- methodName: methodName,
- originalValue: obj[methodName]
- });
-
- obj[methodName] = spy;
-
- return spy;
- };
-
- this.clearSpies = function() {
- var spies = currentSpies();
- for (var i = 0; i < spies.length; i++) {
- var spyEntry = spies[i];
- spyEntry.baseObj[spyEntry.methodName] = spyEntry.originalValue;
- }
- };
- }
-
- return SpyRegistry;
-};
-
-getJasmineRequireObj().SpyStrategy = function() {
-
- function SpyStrategy(options) {
- options = options || {};
-
- var identity = options.name || 'unknown',
- originalFn = options.fn || function() {},
- getSpy = options.getSpy || function() {},
- plan = function() {};
-
- this.identity = function() {
- return identity;
- };
-
- this.exec = function() {
- return plan.apply(this, arguments);
- };
-
- this.callThrough = function() {
- plan = originalFn;
- return getSpy();
- };
-
- this.returnValue = function(value) {
- plan = function() {
- return value;
- };
- return getSpy();
- };
-
- this.returnValues = function() {
- var values = Array.prototype.slice.call(arguments);
- plan = function () {
- return values.shift();
- };
- return getSpy();
- };
-
- this.throwError = function(something) {
- var error = (something instanceof Error) ? something : new Error(something);
- plan = function() {
- throw error;
- };
- return getSpy();
- };
-
- this.callFake = function(fn) {
- plan = fn;
- return getSpy();
- };
-
- this.stub = function(fn) {
- plan = function() {};
- return getSpy();
- };
- }
-
- return SpyStrategy;
-};
-
-getJasmineRequireObj().Suite = function(j$) {
- function Suite(attrs) {
- this.env = attrs.env;
- this.id = attrs.id;
- this.parentSuite = attrs.parentSuite;
- this.description = attrs.description;
- this.expectationFactory = attrs.expectationFactory;
- this.expectationResultFactory = attrs.expectationResultFactory;
- this.throwOnExpectationFailure = !!attrs.throwOnExpectationFailure;
-
- this.beforeFns = [];
- this.afterFns = [];
- this.beforeAllFns = [];
- this.afterAllFns = [];
- this.disabled = false;
-
- this.children = [];
-
- this.result = {
- id: this.id,
- description: this.description,
- fullName: this.getFullName(),
- failedExpectations: []
- };
- }
-
- Suite.prototype.expect = function(actual) {
- return this.expectationFactory(actual, this);
- };
-
- Suite.prototype.getFullName = function() {
- var fullName = this.description;
- for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) {
- if (parentSuite.parentSuite) {
- fullName = parentSuite.description + ' ' + fullName;
- }
- }
- return fullName;
- };
-
- Suite.prototype.disable = function() {
- this.disabled = true;
- };
-
- Suite.prototype.pend = function(message) {
- this.markedPending = true;
- };
-
- Suite.prototype.beforeEach = function(fn) {
- this.beforeFns.unshift(fn);
- };
-
- Suite.prototype.beforeAll = function(fn) {
- this.beforeAllFns.push(fn);
- };
-
- Suite.prototype.afterEach = function(fn) {
- this.afterFns.unshift(fn);
- };
-
- Suite.prototype.afterAll = function(fn) {
- this.afterAllFns.push(fn);
- };
-
- Suite.prototype.addChild = function(child) {
- this.children.push(child);
- };
-
- Suite.prototype.status = function() {
- if (this.disabled) {
- return 'disabled';
- }
-
- if (this.markedPending) {
- return 'pending';
- }
-
- if (this.result.failedExpectations.length > 0) {
- return 'failed';
- } else {
- return 'finished';
- }
- };
-
- Suite.prototype.isExecutable = function() {
- return !this.disabled;
- };
-
- Suite.prototype.canBeReentered = function() {
- return this.beforeAllFns.length === 0 && this.afterAllFns.length === 0;
- };
-
- Suite.prototype.getResult = function() {
- this.result.status = this.status();
- return this.result;
- };
-
- Suite.prototype.sharedUserContext = function() {
- if (!this.sharedContext) {
- this.sharedContext = this.parentSuite ? clone(this.parentSuite.sharedUserContext()) : {};
- }
-
- return this.sharedContext;
- };
-
- Suite.prototype.clonedSharedUserContext = function() {
- return clone(this.sharedUserContext());
- };
-
- Suite.prototype.onException = function() {
- if (arguments[0] instanceof j$.errors.ExpectationFailed) {
- return;
- }
-
- if(isAfterAll(this.children)) {
- var data = {
- matcherName: '',
- passed: false,
- expected: '',
- actual: '',
- error: arguments[0]
- };
- this.result.failedExpectations.push(this.expectationResultFactory(data));
- } else {
- for (var i = 0; i < this.children.length; i++) {
- var child = this.children[i];
- child.onException.apply(child, arguments);
- }
- }
- };
-
- Suite.prototype.addExpectationResult = function () {
- if(isAfterAll(this.children) && isFailure(arguments)){
- var data = arguments[1];
- this.result.failedExpectations.push(this.expectationResultFactory(data));
- if(this.throwOnExpectationFailure) {
- throw new j$.errors.ExpectationFailed();
- }
- } else {
- for (var i = 0; i < this.children.length; i++) {
- var child = this.children[i];
- try {
- child.addExpectationResult.apply(child, arguments);
- } catch(e) {
- // keep going
- }
- }
- }
- };
-
- function isAfterAll(children) {
- return children && children[0].result.status;
- }
-
- function isFailure(args) {
- return !args[0];
- }
-
- function clone(obj) {
- var clonedObj = {};
- for (var prop in obj) {
- if (obj.hasOwnProperty(prop)) {
- clonedObj[prop] = obj[prop];
- }
- }
-
- return clonedObj;
- }
-
- return Suite;
-};
-
-if (typeof window == void 0 && typeof exports == 'object') {
- exports.Suite = jasmineRequire.Suite;
-}
-
-getJasmineRequireObj().Timer = function() {
- var defaultNow = (function(Date) {
- return function() { return new Date().getTime(); };
- })(Date);
-
- function Timer(options) {
- options = options || {};
-
- var now = options.now || defaultNow,
- startTime;
-
- this.start = function() {
- startTime = now();
- };
-
- this.elapsed = function() {
- return now() - startTime;
- };
- }
-
- return Timer;
-};
-
-getJasmineRequireObj().TreeProcessor = function() {
- function TreeProcessor(attrs) {
- var tree = attrs.tree,
- runnableIds = attrs.runnableIds,
- queueRunnerFactory = attrs.queueRunnerFactory,
- nodeStart = attrs.nodeStart || function() {},
- nodeComplete = attrs.nodeComplete || function() {},
- orderChildren = attrs.orderChildren || function(node) { return node.children; },
- stats = { valid: true },
- processed = false,
- defaultMin = Infinity,
- defaultMax = 1 - Infinity;
-
- this.processTree = function() {
- processNode(tree, false);
- processed = true;
- return stats;
- };
-
- this.execute = function(done) {
- if (!processed) {
- this.processTree();
- }
-
- if (!stats.valid) {
- throw 'invalid order';
- }
-
- var childFns = wrapChildren(tree, 0);
-
- queueRunnerFactory({
- queueableFns: childFns,
- userContext: tree.sharedUserContext(),
- onException: function() {
- tree.onException.apply(tree, arguments);
- },
- onComplete: done
- });
- };
-
- function runnableIndex(id) {
- for (var i = 0; i < runnableIds.length; i++) {
- if (runnableIds[i] === id) {
- return i;
- }
- }
- }
-
- function processNode(node, parentEnabled) {
- var executableIndex = runnableIndex(node.id);
-
- if (executableIndex !== undefined) {
- parentEnabled = true;
- }
-
- parentEnabled = parentEnabled && node.isExecutable();
-
- if (!node.children) {
- stats[node.id] = {
- executable: parentEnabled && node.isExecutable(),
- segments: [{
- index: 0,
- owner: node,
- nodes: [node],
- min: startingMin(executableIndex),
- max: startingMax(executableIndex)
- }]
- };
- } else {
- var hasExecutableChild = false;
-
- var orderedChildren = orderChildren(node);
-
- for (var i = 0; i < orderedChildren.length; i++) {
- var child = orderedChildren[i];
-
- processNode(child, parentEnabled);
-
- if (!stats.valid) {
- return;
- }
-
- var childStats = stats[child.id];
-
- hasExecutableChild = hasExecutableChild || childStats.executable;
- }
-
- stats[node.id] = {
- executable: hasExecutableChild
- };
-
- segmentChildren(node, orderedChildren, stats[node.id], executableIndex);
-
- if (!node.canBeReentered() && stats[node.id].segments.length > 1) {
- stats = { valid: false };
- }
- }
- }
-
- function startingMin(executableIndex) {
- return executableIndex === undefined ? defaultMin : executableIndex;
- }
-
- function startingMax(executableIndex) {
- return executableIndex === undefined ? defaultMax : executableIndex;
- }
-
- function segmentChildren(node, orderedChildren, nodeStats, executableIndex) {
- var currentSegment = { index: 0, owner: node, nodes: [], min: startingMin(executableIndex), max: startingMax(executableIndex) },
- result = [currentSegment],
- lastMax = defaultMax,
- orderedChildSegments = orderChildSegments(orderedChildren);
-
- function isSegmentBoundary(minIndex) {
- return lastMax !== defaultMax && minIndex !== defaultMin && lastMax < minIndex - 1;
- }
-
- for (var i = 0; i < orderedChildSegments.length; i++) {
- var childSegment = orderedChildSegments[i],
- maxIndex = childSegment.max,
- minIndex = childSegment.min;
-
- if (isSegmentBoundary(minIndex)) {
- currentSegment = {index: result.length, owner: node, nodes: [], min: defaultMin, max: defaultMax};
- result.push(currentSegment);
- }
-
- currentSegment.nodes.push(childSegment);
- currentSegment.min = Math.min(currentSegment.min, minIndex);
- currentSegment.max = Math.max(currentSegment.max, maxIndex);
- lastMax = maxIndex;
- }
-
- nodeStats.segments = result;
- }
-
- function orderChildSegments(children) {
- var specifiedOrder = [],
- unspecifiedOrder = [];
-
- for (var i = 0; i < children.length; i++) {
- var child = children[i],
- segments = stats[child.id].segments;
-
- for (var j = 0; j < segments.length; j++) {
- var seg = segments[j];
-
- if (seg.min === defaultMin) {
- unspecifiedOrder.push(seg);
- } else {
- specifiedOrder.push(seg);
- }
- }
- }
-
- specifiedOrder.sort(function(a, b) {
- return a.min - b.min;
- });
-
- return specifiedOrder.concat(unspecifiedOrder);
- }
-
- function executeNode(node, segmentNumber) {
- if (node.children) {
- return {
- fn: function(done) {
- nodeStart(node);
-
- queueRunnerFactory({
- onComplete: function() {
- nodeComplete(node, node.getResult());
- done();
- },
- queueableFns: wrapChildren(node, segmentNumber),
- userContext: node.sharedUserContext(),
- onException: function() {
- node.onException.apply(node, arguments);
- }
- });
- }
- };
- } else {
- return {
- fn: function(done) { node.execute(done, stats[node.id].executable); }
- };
- }
- }
-
- function wrapChildren(node, segmentNumber) {
- var result = [],
- segmentChildren = stats[node.id].segments[segmentNumber].nodes;
-
- for (var i = 0; i < segmentChildren.length; i++) {
- result.push(executeNode(segmentChildren[i].owner, segmentChildren[i].index));
- }
-
- if (!stats[node.id].executable) {
- return result;
- }
-
- return node.beforeAllFns.concat(result).concat(node.afterAllFns);
- }
- }
-
- return TreeProcessor;
-};
-
-getJasmineRequireObj().Any = function(j$) {
-
- function Any(expectedObject) {
- if (typeof expectedObject === 'undefined') {
- throw new TypeError(
- 'jasmine.any() expects to be passed a constructor function. ' +
- 'Please pass one or use jasmine.anything() to match any object.'
- );
- }
- this.expectedObject = expectedObject;
- }
-
- Any.prototype.asymmetricMatch = function(other) {
- if (this.expectedObject == String) {
- return typeof other == 'string' || other instanceof String;
- }
-
- if (this.expectedObject == Number) {
- return typeof other == 'number' || other instanceof Number;
- }
-
- if (this.expectedObject == Function) {
- return typeof other == 'function' || other instanceof Function;
- }
-
- if (this.expectedObject == Object) {
- return typeof other == 'object';
- }
-
- if (this.expectedObject == Boolean) {
- return typeof other == 'boolean';
- }
-
- return other instanceof this.expectedObject;
- };
-
- Any.prototype.jasmineToString = function() {
- return '<jasmine.any(' + j$.fnNameFor(this.expectedObject) + ')>';
- };
-
- return Any;
-};
-
-getJasmineRequireObj().Anything = function(j$) {
-
- function Anything() {}
-
- Anything.prototype.asymmetricMatch = function(other) {
- return !j$.util.isUndefined(other) && other !== null;
- };
-
- Anything.prototype.jasmineToString = function() {
- return '<jasmine.anything>';
- };
-
- return Anything;
-};
-
-getJasmineRequireObj().ArrayContaining = function(j$) {
- function ArrayContaining(sample) {
- this.sample = sample;
- }
-
- ArrayContaining.prototype.asymmetricMatch = function(other) {
- var className = Object.prototype.toString.call(this.sample);
- if (className !== '[object Array]') { throw new Error('You must provide an array to arrayContaining, not \'' + this.sample + '\'.'); }
-
- for (var i = 0; i < this.sample.length; i++) {
- var item = this.sample[i];
- if (!j$.matchersUtil.contains(other, item)) {
- return false;
- }
- }
-
- return true;
- };
-
- ArrayContaining.prototype.jasmineToString = function () {
- return '<jasmine.arrayContaining(' + jasmine.pp(this.sample) +')>';
- };
-
- return ArrayContaining;
-};
-
-getJasmineRequireObj().ObjectContaining = function(j$) {
-
- function ObjectContaining(sample) {
- this.sample = sample;
- }
-
- function getPrototype(obj) {
- if (Object.getPrototypeOf) {
- return Object.getPrototypeOf(obj);
- }
-
- if (obj.constructor.prototype == obj) {
- return null;
- }
-
- return obj.constructor.prototype;
- }
-
- function hasProperty(obj, property) {
- if (!obj) {
- return false;
- }
-
- if (Object.prototype.hasOwnProperty.call(obj, property)) {
- return true;
- }
-
- return hasProperty(getPrototype(obj), property);
- }
-
- ObjectContaining.prototype.asymmetricMatch = function(other) {
- if (typeof(this.sample) !== 'object') { throw new Error('You must provide an object to objectContaining, not \''+this.sample+'\'.'); }
-
- for (var property in this.sample) {
- if (!hasProperty(other, property) ||
- !j$.matchersUtil.equals(this.sample[property], other[property])) {
- return false;
- }
- }
-
- return true;
- };
-
- ObjectContaining.prototype.jasmineToString = function() {
- return '<jasmine.objectContaining(' + j$.pp(this.sample) + ')>';
- };
-
- return ObjectContaining;
-};
-
-getJasmineRequireObj().StringMatching = function(j$) {
-
- function StringMatching(expected) {
- if (!j$.isString_(expected) && !j$.isA_('RegExp', expected)) {
- throw new Error('Expected is not a String or a RegExp');
- }
-
- this.regexp = new RegExp(expected);
- }
-
- StringMatching.prototype.asymmetricMatch = function(other) {
- return this.regexp.test(other);
- };
-
- StringMatching.prototype.jasmineToString = function() {
- return '<jasmine.stringMatching(' + this.regexp + ')>';
- };
-
- return StringMatching;
-};
-
-getJasmineRequireObj().errors = function() {
- function ExpectationFailed() {}
-
- ExpectationFailed.prototype = new Error();
- ExpectationFailed.prototype.constructor = ExpectationFailed;
-
- return {
- ExpectationFailed: ExpectationFailed
- };
-};
-getJasmineRequireObj().matchersUtil = function(j$) {
- // TODO: what to do about jasmine.pp not being inject? move to JSON.stringify? gut PrettyPrinter?
-
- return {
- equals: function(a, b, customTesters) {
- customTesters = customTesters || [];
-
- return eq(a, b, [], [], customTesters);
- },
-
- contains: function(haystack, needle, customTesters) {
- customTesters = customTesters || [];
-
- if ((Object.prototype.toString.apply(haystack) === '[object Array]') ||
- (!!haystack && !haystack.indexOf))
- {
- for (var i = 0; i < haystack.length; i++) {
- if (eq(haystack[i], needle, [], [], customTesters)) {
- return true;
- }
- }
- return false;
- }
-
- return !!haystack && haystack.indexOf(needle) >= 0;
- },
-
- buildFailureMessage: function() {
- var args = Array.prototype.slice.call(arguments, 0),
- matcherName = args[0],
- isNot = args[1],
- actual = args[2],
- expected = args.slice(3),
- englishyPredicate = matcherName.replace(/[A-Z]/g, function(s) { return ' ' + s.toLowerCase(); });
-
- var message = 'Expected ' +
- j$.pp(actual) +
- (isNot ? ' not ' : ' ') +
- englishyPredicate;
-
- if (expected.length > 0) {
- for (var i = 0; i < expected.length; i++) {
- if (i > 0) {
- message += ',';
- }
- message += ' ' + j$.pp(expected[i]);
- }
- }
-
- return message + '.';
- }
- };
-
- function isAsymmetric(obj) {
- return obj && j$.isA_('Function', obj.asymmetricMatch);
- }
-
- function asymmetricMatch(a, b) {
- var asymmetricA = isAsymmetric(a),
- asymmetricB = isAsymmetric(b);
-
- if (asymmetricA && asymmetricB) {
- return undefined;
- }
-
- if (asymmetricA) {
- return a.asymmetricMatch(b);
- }
-
- if (asymmetricB) {
- return b.asymmetricMatch(a);
- }
- }
-
- // Equality function lovingly adapted from isEqual in
- // [Underscore](http://underscorejs.org)
- function eq(a, b, aStack, bStack, customTesters) {
- var result = true;
-
- var asymmetricResult = asymmetricMatch(a, b);
- if (!j$.util.isUndefined(asymmetricResult)) {
- return asymmetricResult;
- }
-
- for (var i = 0; i < customTesters.length; i++) {
- var customTesterResult = customTesters[i](a, b);
- if (!j$.util.isUndefined(customTesterResult)) {
- return customTesterResult;
- }
- }
-
- if (a instanceof Error && b instanceof Error) {
- return a.message == b.message;
- }
-
- // Identical objects are equal. `0 === -0`, but they aren't identical.
- // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
- if (a === b) { return a !== 0 || 1 / a == 1 / b; }
- // A strict comparison is necessary because `null == undefined`.
- if (a === null || b === null) { return a === b; }
- var className = Object.prototype.toString.call(a);
- if (className != Object.prototype.toString.call(b)) { return false; }
- switch (className) {
- // Strings, numbers, dates, and booleans are compared by value.
- case '[object String]':
- // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
- // equivalent to `new String("5")`.
- return a == String(b);
- case '[object Number]':
- // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for
- // other numeric values.
- return a != +a ? b != +b : (a === 0 ? 1 / a == 1 / b : a == +b);
- case '[object Date]':
- case '[object Boolean]':
- // Coerce dates and booleans to numeric primitive values. Dates are compared by their
- // millisecond representations. Note that invalid dates with millisecond representations
- // of `NaN` are not equivalent.
- return +a == +b;
- // RegExps are compared by their source patterns and flags.
- case '[object RegExp]':
- return a.source == b.source &&
- a.global == b.global &&
- a.multiline == b.multiline &&
- a.ignoreCase == b.ignoreCase;
- }
- if (typeof a != 'object' || typeof b != 'object') { return false; }
-
- var aIsDomNode = j$.isDomNode(a);
- var bIsDomNode = j$.isDomNode(b);
- if (aIsDomNode && bIsDomNode) {
- // At first try to use DOM3 method isEqualNode
- if (a.isEqualNode) {
- return a.isEqualNode(b);
- }
- // IE8 doesn't support isEqualNode, try to use outerHTML && innerText
- var aIsElement = a instanceof Element;
- var bIsElement = b instanceof Element;
- if (aIsElement && bIsElement) {
- return a.outerHTML == b.outerHTML;
- }
- if (aIsElement || bIsElement) {
- return false;
- }
- return a.innerText == b.innerText && a.textContent == b.textContent;
- }
- if (aIsDomNode || bIsDomNode) {
- return false;
- }
-
- // Assume equality for cyclic structures. The algorithm for detecting cyclic
- // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
- var length = aStack.length;
- while (length--) {
- // Linear search. Performance is inversely proportional to the number of
- // unique nested structures.
- if (aStack[length] == a) { return bStack[length] == b; }
- }
- // Add the first object to the stack of traversed objects.
- aStack.push(a);
- bStack.push(b);
- var size = 0;
- // Recursively compare objects and arrays.
- // Compare array lengths to determine if a deep comparison is necessary.
- if (className == '[object Array]' && a.length !== b.length) {
- result = false;
- }
-
- if (result) {
- // Objects with different constructors are not equivalent, but `Object`s
- // or `Array`s from different frames are.
- if (className !== '[object Array]') {
- var aCtor = a.constructor, bCtor = b.constructor;
- if (aCtor !== bCtor && !(isFunction(aCtor) && aCtor instanceof aCtor &&
- isFunction(bCtor) && bCtor instanceof bCtor)) {
- return false;
- }
- }
- // Deep compare objects.
- for (var key in a) {
- if (has(a, key)) {
- // Count the expected number of properties.
- size++;
- // Deep compare each member.
- if (!(result = has(b, key) && eq(a[key], b[key], aStack, bStack, customTesters))) { break; }
- }
- }
- // Ensure that both objects contain the same number of properties.
- if (result) {
- for (key in b) {
- if (has(b, key) && !(size--)) { break; }
- }
- result = !size;
- }
- }
- // Remove the first object from the stack of traversed objects.
- aStack.pop();
- bStack.pop();
-
- return result;
-
- function has(obj, key) {
- return Object.prototype.hasOwnProperty.call(obj, key);
- }
-
- function isFunction(obj) {
- return typeof obj === 'function';
- }
- }
-};
-
-getJasmineRequireObj().toBe = function() {
- function toBe() {
- return {
- compare: function(actual, expected) {
- return {
- pass: actual === expected
- };
- }
- };
- }
-
- return toBe;
-};
-
-getJasmineRequireObj().toBeCloseTo = function() {
-
- function toBeCloseTo() {
- return {
- compare: function(actual, expected, precision) {
- if (precision !== 0) {
- precision = precision || 2;
- }
-
- return {
- pass: Math.abs(expected - actual) < (Math.pow(10, -precision) / 2)
- };
- }
- };
- }
-
- return toBeCloseTo;
-};
-
-getJasmineRequireObj().toBeDefined = function() {
- function toBeDefined() {
- return {
- compare: function(actual) {
- return {
- pass: (void 0 !== actual)
- };
- }
- };
- }
-
- return toBeDefined;
-};
-
-getJasmineRequireObj().toBeFalsy = function() {
- function toBeFalsy() {
- return {
- compare: function(actual) {
- return {
- pass: !!!actual
- };
- }
- };
- }
-
- return toBeFalsy;
-};
-
-getJasmineRequireObj().toBeGreaterThan = function() {
-
- function toBeGreaterThan() {
- return {
- compare: function(actual, expected) {
- return {
- pass: actual > expected
- };
- }
- };
- }
-
- return toBeGreaterThan;
-};
-
-
-getJasmineRequireObj().toBeLessThan = function() {
- function toBeLessThan() {
- return {
-
- compare: function(actual, expected) {
- return {
- pass: actual < expected
- };
- }
- };
- }
-
- return toBeLessThan;
-};
-getJasmineRequireObj().toBeNaN = function(j$) {
-
- function toBeNaN() {
- return {
- compare: function(actual) {
- var result = {
- pass: (actual !== actual)
- };
-
- if (result.pass) {
- result.message = 'Expected actual not to be NaN.';
- } else {
- result.message = function() { return 'Expected ' + j$.pp(actual) + ' to be NaN.'; };
- }
-
- return result;
- }
- };
- }
-
- return toBeNaN;
-};
-
-getJasmineRequireObj().toBeNull = function() {
-
- function toBeNull() {
- return {
- compare: function(actual) {
- return {
- pass: actual === null
- };
- }
- };
- }
-
- return toBeNull;
-};
-
-getJasmineRequireObj().toBeTruthy = function() {
-
- function toBeTruthy() {
- return {
- compare: function(actual) {
- return {
- pass: !!actual
- };
- }
- };
- }
-
- return toBeTruthy;
-};
-
-getJasmineRequireObj().toBeUndefined = function() {
-
- function toBeUndefined() {
- return {
- compare: function(actual) {
- return {
- pass: void 0 === actual
- };
- }
- };
- }
-
- return toBeUndefined;
-};
-
-getJasmineRequireObj().toContain = function() {
- function toContain(util, customEqualityTesters) {
- customEqualityTesters = customEqualityTesters || [];
-
- return {
- compare: function(actual, expected) {
-
- return {
- pass: util.contains(actual, expected, customEqualityTesters)
- };
- }
- };
- }
-
- return toContain;
-};
-
-getJasmineRequireObj().toEqual = function() {
-
- function toEqual(util, customEqualityTesters) {
- customEqualityTesters = customEqualityTesters || [];
-
- return {
- compare: function(actual, expected) {
- var result = {
- pass: false
- };
-
- result.pass = util.equals(actual, expected, customEqualityTesters);
-
- return result;
- }
- };
- }
-
- return toEqual;
-};
-
-getJasmineRequireObj().toHaveBeenCalled = function(j$) {
-
- function toHaveBeenCalled() {
- return {
- compare: function(actual) {
- var result = {};
-
- if (!j$.isSpy(actual)) {
- throw new Error('Expected a spy, but got ' + j$.pp(actual) + '.');
- }
-
- if (arguments.length > 1) {
- throw new Error('toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith');
- }
-
- result.pass = actual.calls.any();
-
- result.message = result.pass ?
- 'Expected spy ' + actual.and.identity() + ' not to have been called.' :
- 'Expected spy ' + actual.and.identity() + ' to have been called.';
-
- return result;
- }
- };
- }
-
- return toHaveBeenCalled;
-};
-
-getJasmineRequireObj().toHaveBeenCalledTimes = function(j$) {
-
- function toHaveBeenCalledTimes() {
- return {
- compare: function(actual, expected) {
- if (!j$.isSpy(actual)) {
- throw new Error('Expected a spy, but got ' + j$.pp(actual) + '.');
- }
-
- var args = Array.prototype.slice.call(arguments, 0),
- result = { pass: false };
-
- if(!expected){
- throw new Error('Expected times failed is required as an argument.');
- }
-
- actual = args[0];
- var calls = actual.calls.count();
- var timesMessage = expected === 1 ? 'once' : expected + ' times';
- result.pass = calls === expected;
- result.message = result.pass ?
- 'Expected spy ' + actual.and.identity() + ' not to have been called ' + timesMessage + '. It was called ' + calls + ' times.' :
- 'Expected spy ' + actual.and.identity() + ' to have been called ' + timesMessage + '. It was called ' + calls + ' times.';
- return result;
- }
- };
- }
-
- return toHaveBeenCalledTimes;
-};
-
-getJasmineRequireObj().toHaveBeenCalledWith = function(j$) {
-
- function toHaveBeenCalledWith(util, customEqualityTesters) {
- return {
- compare: function() {
- var args = Array.prototype.slice.call(arguments, 0),
- actual = args[0],
- expectedArgs = args.slice(1),
- result = { pass: false };
-
- if (!j$.isSpy(actual)) {
- throw new Error('Expected a spy, but got ' + j$.pp(actual) + '.');
- }
-
- if (!actual.calls.any()) {
- result.message = function() { return 'Expected spy ' + actual.and.identity() + ' to have been called with ' + j$.pp(expectedArgs) + ' but it was never called.'; };
- return result;
- }
-
- if (util.contains(actual.calls.allArgs(), expectedArgs, customEqualityTesters)) {
- result.pass = true;
- result.message = function() { return 'Expected spy ' + actual.and.identity() + ' not to have been called with ' + j$.pp(expectedArgs) + ' but it was.'; };
- } else {
- 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, '') + '.'; };
- }
-
- return result;
- }
- };
- }
-
- return toHaveBeenCalledWith;
-};
-
-getJasmineRequireObj().toMatch = function(j$) {
-
- function toMatch() {
- return {
- compare: function(actual, expected) {
- if (!j$.isString_(expected) && !j$.isA_('RegExp', expected)) {
- throw new Error('Expected is not a String or a RegExp');
- }
-
- var regexp = new RegExp(expected);
-
- return {
- pass: regexp.test(actual)
- };
- }
- };
- }
-
- return toMatch;
-};
-
-getJasmineRequireObj().toThrow = function(j$) {
-
- function toThrow(util) {
- return {
- compare: function(actual, expected) {
- var result = { pass: false },
- threw = false,
- thrown;
-
- if (typeof actual != 'function') {
- throw new Error('Actual is not a Function');
- }
-
- try {
- actual();
- } catch (e) {
- threw = true;
- thrown = e;
- }
-
- if (!threw) {
- result.message = 'Expected function to throw an exception.';
- return result;
- }
-
- if (arguments.length == 1) {
- result.pass = true;
- result.message = function() { return 'Expected function not to throw, but it threw ' + j$.pp(thrown) + '.'; };
-
- return result;
- }
-
- if (util.equals(thrown, expected)) {
- result.pass = true;
- result.message = function() { return 'Expected function not to throw ' + j$.pp(expected) + '.'; };
- } else {
- result.message = function() { return 'Expected function to throw ' + j$.pp(expected) + ', but it threw ' + j$.pp(thrown) + '.'; };
- }
-
- return result;
- }
- };
- }
-
- return toThrow;
-};
-
-getJasmineRequireObj().toThrowError = function(j$) {
- function toThrowError () {
- return {
- compare: function(actual) {
- var threw = false,
- pass = {pass: true},
- fail = {pass: false},
- thrown;
-
- if (typeof actual != 'function') {
- throw new Error('Actual is not a Function');
- }
-
- var errorMatcher = getMatcher.apply(null, arguments);
-
- try {
- actual();
- } catch (e) {
- threw = true;
- thrown = e;
- }
-
- if (!threw) {
- fail.message = 'Expected function to throw an Error.';
- return fail;
- }
-
- if (!(thrown instanceof Error)) {
- fail.message = function() { return 'Expected function to throw an Error, but it threw ' + j$.pp(thrown) + '.'; };
- return fail;
- }
-
- if (errorMatcher.hasNoSpecifics()) {
- pass.message = 'Expected function not to throw an Error, but it threw ' + j$.fnNameFor(thrown) + '.';
- return pass;
- }
-
- if (errorMatcher.matches(thrown)) {
- pass.message = function() {
- return 'Expected function not to throw ' + errorMatcher.errorTypeDescription + errorMatcher.messageDescription() + '.';
- };
- return pass;
- } else {
- fail.message = function() {
- return 'Expected function to throw ' + errorMatcher.errorTypeDescription + errorMatcher.messageDescription() +
- ', but it threw ' + errorMatcher.thrownDescription(thrown) + '.';
- };
- return fail;
- }
- }
- };
-
- function getMatcher() {
- var expected = null,
- errorType = null;
-
- if (arguments.length == 2) {
- expected = arguments[1];
- if (isAnErrorType(expected)) {
- errorType = expected;
- expected = null;
- }
- } else if (arguments.length > 2) {
- errorType = arguments[1];
- expected = arguments[2];
- if (!isAnErrorType(errorType)) {
- throw new Error('Expected error type is not an Error.');
- }
- }
-
- if (expected && !isStringOrRegExp(expected)) {
- if (errorType) {
- throw new Error('Expected error message is not a string or RegExp.');
- } else {
- throw new Error('Expected is not an Error, string, or RegExp.');
- }
- }
-
- function messageMatch(message) {
- if (typeof expected == 'string') {
- return expected == message;
- } else {
- return expected.test(message);
- }
- }
-
- return {
- errorTypeDescription: errorType ? j$.fnNameFor(errorType) : 'an exception',
- thrownDescription: function(thrown) {
- var thrownName = errorType ? j$.fnNameFor(thrown.constructor) : 'an exception',
- thrownMessage = '';
-
- if (expected) {
- thrownMessage = ' with message ' + j$.pp(thrown.message);
- }
-
- return thrownName + thrownMessage;
- },
- messageDescription: function() {
- if (expected === null) {
- return '';
- } else if (expected instanceof RegExp) {
- return ' with a message matching ' + j$.pp(expected);
- } else {
- return ' with message ' + j$.pp(expected);
- }
- },
- hasNoSpecifics: function() {
- return expected === null && errorType === null;
- },
- matches: function(error) {
- return (errorType === null || error instanceof errorType) &&
- (expected === null || messageMatch(error.message));
- }
- };
- }
-
- function isStringOrRegExp(potential) {
- return potential instanceof RegExp || (typeof potential == 'string');
- }
-
- function isAnErrorType(type) {
- if (typeof type !== 'function') {
- return false;
- }
-
- var Surrogate = function() {};
- Surrogate.prototype = type.prototype;
- return (new Surrogate()) instanceof Error;
- }
- }
-
- return toThrowError;
-};
-
-getJasmineRequireObj().interface = function(jasmine, env) {
- var jasmineInterface = {
- describe: function(description, specDefinitions) {
- return env.describe(description, specDefinitions);
- },
-
- xdescribe: function(description, specDefinitions) {
- return env.xdescribe(description, specDefinitions);
- },
-
- fdescribe: function(description, specDefinitions) {
- return env.fdescribe(description, specDefinitions);
- },
-
- it: function() {
- return env.it.apply(env, arguments);
- },
-
- xit: function() {
- return env.xit.apply(env, arguments);
- },
-
- fit: function() {
- return env.fit.apply(env, arguments);
- },
-
- beforeEach: function() {
- return env.beforeEach.apply(env, arguments);
- },
-
- afterEach: function() {
- return env.afterEach.apply(env, arguments);
- },
-
- beforeAll: function() {
- return env.beforeAll.apply(env, arguments);
- },
-
- afterAll: function() {
- return env.afterAll.apply(env, arguments);
- },
-
- expect: function(actual) {
- return env.expect(actual);
- },
-
- pending: function() {
- return env.pending.apply(env, arguments);
- },
-
- fail: function() {
- return env.fail.apply(env, arguments);
- },
-
- spyOn: function(obj, methodName) {
- return env.spyOn(obj, methodName);
- },
-
- jsApiReporter: new jasmine.JsApiReporter({
- timer: new jasmine.Timer()
- }),
-
- jasmine: jasmine
- };
-
- jasmine.addCustomEqualityTester = function(tester) {
- env.addCustomEqualityTester(tester);
- };
-
- jasmine.addMatchers = function(matchers) {
- return env.addMatchers(matchers);
- };
-
- jasmine.clock = function() {
- return env.clock;
- };
-
- return jasmineInterface;
-};
-
-getJasmineRequireObj().version = function() {
- return '2.4.1';
-};
diff --git a/www/assets/jasmine-2.4.1/boot.js b/www/assets/jasmine-2.99.0/boot.js
old mode 100755
new mode 100644
similarity index 97%
rename from www/assets/jasmine-2.4.1/boot.js
rename to www/assets/jasmine-2.99.0/boot.js
index a99774d..d9b5a80
--- a/www/assets/jasmine-2.4.1/boot.js
+++ b/www/assets/jasmine-2.99.0/boot.js
@@ -49,6 +49,8 @@
getWindowLocation: function() { return window.location; }
});
+ var filterSpecs = !!queryString.getParam("spec");
+
var catchingExceptions = queryString.getParam("catch");
env.catchExceptions(typeof catchingExceptions === "undefined" ? true : catchingExceptions);
@@ -76,7 +78,8 @@
getContainer: function() { return document.body; },
createElement: function() { return document.createElement.apply(document, arguments); },
createTextNode: function() { return document.createTextNode.apply(document, arguments); },
- timer: new jasmine.Timer()
+ timer: new jasmine.Timer(),
+ filterSpecs: filterSpecs
});
/**
diff --git a/www/assets/jasmine-2.4.1/console.js b/www/assets/jasmine-2.99.0/console.js
old mode 100755
new mode 100644
similarity index 99%
rename from www/assets/jasmine-2.4.1/console.js
rename to www/assets/jasmine-2.99.0/console.js
index e154806..43a82ac
--- a/www/assets/jasmine-2.4.1/console.js
+++ b/www/assets/jasmine-2.99.0/console.js
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2008-2015 Pivotal Labs
+Copyright (c) 2008-2018 Pivotal Labs
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
diff --git a/www/assets/jasmine-2.4.1/jasmine-html.js b/www/assets/jasmine-2.99.0/jasmine-html.js
old mode 100755
new mode 100644
similarity index 79%
rename from www/assets/jasmine-2.4.1/jasmine-html.js
rename to www/assets/jasmine-2.99.0/jasmine-html.js
index da23532..7dd2f5e
--- a/www/assets/jasmine-2.4.1/jasmine-html.js
+++ b/www/assets/jasmine-2.99.0/jasmine-html.js
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2008-2015 Pivotal Labs
+Copyright (c) 2008-2018 Pivotal Labs
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
@@ -34,6 +34,46 @@ jasmineRequire.HtmlReporter = function(j$) {
elapsed: function() { return 0; }
};
+ function ResultsStateBuilder() {
+ this.topResults = new j$.ResultsNode({}, '', null);
+ this.currentParent = this.topResults;
+ this.specsExecuted = 0;
+ this.failureCount = 0;
+ this.pendingSpecCount = 0;
+ }
+
+ ResultsStateBuilder.prototype.suiteStarted = function(result) {
+ this.currentParent.addChild(result, 'suite');
+ this.currentParent = this.currentParent.last();
+ };
+
+ ResultsStateBuilder.prototype.suiteDone = function(result) {
+ if (this.currentParent !== this.topResults) {
+ this.currentParent = this.currentParent.parent;
+ }
+ };
+
+ ResultsStateBuilder.prototype.specStarted = function(result) {
+ };
+
+ ResultsStateBuilder.prototype.specDone = function(result) {
+ this.currentParent.addChild(result, 'spec');
+
+ if (result.status !== 'disabled') {
+ this.specsExecuted++;
+ }
+
+ if (result.status === 'failed') {
+ this.failureCount++;
+ }
+
+ if (result.status == 'pending') {
+ this.pendingSpecCount++;
+ }
+ };
+
+
+
function HtmlReporter(options) {
var env = options.env || {},
getContainer = options.getContainer,
@@ -43,14 +83,13 @@ jasmineRequire.HtmlReporter = function(j$) {
onThrowExpectationsClick = options.onThrowExpectationsClick || function() {},
onRandomClick = options.onRandomClick || function() {},
addToExistingQueryString = options.addToExistingQueryString || defaultQueryString,
+ filterSpecs = options.filterSpecs,
timer = options.timer || noopTimer,
results = [],
- specsExecuted = 0,
- failureCount = 0,
- pendingSpecCount = 0,
htmlReporterMain,
symbols,
- failedSuites = [];
+ failedSuites = [],
+ deprecationWarnings = [];
this.initialize = function() {
clearPrior();
@@ -76,12 +115,10 @@ jasmineRequire.HtmlReporter = function(j$) {
var summary = createDom('div', {className: 'jasmine-summary'});
- var topResults = new j$.ResultsNode({}, '', null),
- currentParent = topResults;
+ var stateBuilder = new ResultsStateBuilder();
this.suiteStarted = function(result) {
- currentParent.addChild(result, 'suite');
- currentParent = currentParent.last();
+ stateBuilder.suiteStarted(result);
};
this.suiteDone = function(result) {
@@ -89,27 +126,22 @@ jasmineRequire.HtmlReporter = function(j$) {
failedSuites.push(result);
}
- if (currentParent == topResults) {
- return;
- }
-
- currentParent = currentParent.parent;
+ stateBuilder.suiteDone(result);
+ addDeprecationWarnings(result);
};
this.specStarted = function(result) {
- currentParent.addChild(result, 'spec');
+ stateBuilder.specStarted(result);
};
var failures = [];
this.specDone = function(result) {
+ stateBuilder.specDone(result);
+
if(noExpectations(result) && typeof console !== 'undefined' && typeof console.error !== 'undefined') {
console.error('Spec \'' + result.fullName + '\' has no expectations.');
}
- if (result.status != 'disabled') {
- specsExecuted++;
- }
-
if (!symbols){
symbols = find('.jasmine-symbol-summary');
}
@@ -122,8 +154,6 @@ jasmineRequire.HtmlReporter = function(j$) {
));
if (result.status == 'failed') {
- failureCount++;
-
var failure =
createDom('div', {className: 'jasmine-spec-detail jasmine-failed'},
createDom('div', {className: 'jasmine-description'},
@@ -142,9 +172,7 @@ jasmineRequire.HtmlReporter = function(j$) {
failures.push(failure);
}
- if (result.status == 'pending') {
- pendingSpecCount++;
- }
+ addDeprecationWarnings(result);
};
this.jasmineDone = function(doneResult) {
@@ -207,11 +235,12 @@ jasmineRequire.HtmlReporter = function(j$) {
}
};
- if (specsExecuted < totalSpecsDefined) {
- var skippedMessage = 'Ran ' + specsExecuted + ' of ' + totalSpecsDefined + ' specs - run all';
+ if (stateBuilder.specsExecuted < totalSpecsDefined) {
+ var skippedMessage = 'Ran ' + stateBuilder.specsExecuted + ' of ' + totalSpecsDefined + ' specs - run all';
+ var skippedLink = addToExistingQueryString('spec', '');
alert.appendChild(
createDom('span', {className: 'jasmine-bar jasmine-skipped'},
- createDom('a', {href: '?', title: 'Run all specs'}, skippedMessage)
+ createDom('a', {href: skippedLink, title: 'Run all specs'}, skippedMessage)
)
);
}
@@ -219,9 +248,9 @@ jasmineRequire.HtmlReporter = function(j$) {
var statusBarClassName = 'jasmine-bar ';
if (totalSpecsDefined > 0) {
- statusBarMessage += pluralize('spec', specsExecuted) + ', ' + pluralize('failure', failureCount);
- if (pendingSpecCount) { statusBarMessage += ', ' + pluralize('pending spec', pendingSpecCount); }
- statusBarClassName += (failureCount > 0) ? 'jasmine-failed' : 'jasmine-passed';
+ statusBarMessage += pluralize('spec', stateBuilder.specsExecuted) + ', ' + pluralize('failure', stateBuilder.failureCount);
+ if (stateBuilder.pendingSpecCount) { statusBarMessage += ', ' + pluralize('pending spec', stateBuilder.pendingSpecCount); }
+ statusBarClassName += (stateBuilder.failureCount > 0) ? 'jasmine-failed' : 'jasmine-passed';
} else {
statusBarClassName += 'jasmine-skipped';
statusBarMessage += 'No specs found';
@@ -237,24 +266,42 @@ jasmineRequire.HtmlReporter = function(j$) {
alert.appendChild(createDom('span', {className: statusBarClassName}, statusBarMessage, seedBar));
- for(i = 0; i < failedSuites.length; i++) {
+ var errorBarClassName = 'jasmine-bar jasmine-errored';
+ var errorBarMessagePrefix = 'AfterAll ';
+
+ for(var i = 0; i < failedSuites.length; i++) {
var failedSuite = failedSuites[i];
for(var j = 0; j < failedSuite.failedExpectations.length; j++) {
- var errorBarMessage = 'AfterAll ' + failedSuite.failedExpectations[j].message;
- var errorBarClassName = 'jasmine-bar jasmine-errored';
- alert.appendChild(createDom('span', {className: errorBarClassName}, errorBarMessage));
+ alert.appendChild(createDom('span', {className: errorBarClassName}, errorBarMessagePrefix + failedSuite.failedExpectations[j].message));
}
}
+ var globalFailures = (doneResult && doneResult.failedExpectations) || [];
+ for(i = 0; i < globalFailures.length; i++) {
+ var failure = globalFailures[i];
+ alert.appendChild(createDom('span', {className: errorBarClassName}, errorBarMessagePrefix + failure.message));
+ }
+
+ addDeprecationWarnings(doneResult);
+
+ var warningBarClassName = 'jasmine-bar jasmine-warning';
+ for(i = 0; i < deprecationWarnings.length; i++) {
+ var warning = deprecationWarnings[i];
+ alert.appendChild(createDom('span', {className: warningBarClassName}, 'DEPRECATION: ' + warning));
+ }
+
var results = find('.jasmine-results');
results.appendChild(summary);
- summaryList(topResults, summary);
+ summaryList(stateBuilder.topResults, summary);
function summaryList(resultsTree, domParent) {
var specListNode;
for (var i = 0; i < resultsTree.children.length; i++) {
var resultNode = resultsTree.children[i];
+ if (filterSpecs && !hasActiveSpec(resultNode)) {
+ continue;
+ }
if (resultNode.type == 'suite') {
var suiteListNode = createDom('ul', {className: 'jasmine-suite', id: 'suite-' + resultNode.result.id},
createDom('li', {className: 'jasmine-suite-detail'},
@@ -309,7 +356,7 @@ jasmineRequire.HtmlReporter = function(j$) {
setMenuModeTo('jasmine-failure-list');
var failureNode = find('.jasmine-failures');
- for (var i = 0; i < failures.length; i++) {
+ for (i = 0; i < failures.length; i++) {
failureNode.appendChild(failures[i]);
}
}
@@ -317,6 +364,17 @@ jasmineRequire.HtmlReporter = function(j$) {
return this;
+ function addDeprecationWarnings(result) {
+ if (result && result.deprecationWarnings) {
+ for(var i = 0; i < result.deprecationWarnings.length; i++) {
+ var warning = result.deprecationWarnings[i].message;
+ if (!j$.util.arrayContains(warning)) {
+ deprecationWarnings.push(warning);
+ }
+ }
+ }
+ }
+
function find(selector) {
return getContainer().querySelector('.jasmine_html-reporter ' + selector);
}
@@ -382,6 +440,20 @@ jasmineRequire.HtmlReporter = function(j$) {
return (result.failedExpectations.length + result.passedExpectations.length) === 0 &&
result.status === 'passed';
}
+
+ function hasActiveSpec(resultNode) {
+ if (resultNode.type == 'spec' && resultNode.result.status != 'disabled') {
+ return true;
+ }
+
+ if (resultNode.type == 'suite') {
+ for (var i = 0, j = resultNode.children.length; i < j; i++) {
+ if (hasActiveSpec(resultNode.children[i])) {
+ return true;
+ }
+ }
+ }
+ }
}
return HtmlReporter;
diff --git a/www/assets/jasmine-2.4.1/jasmine.css b/www/assets/jasmine-2.99.0/jasmine.css
old mode 100755
new mode 100644
similarity index 99%
rename from www/assets/jasmine-2.4.1/jasmine.css
rename to www/assets/jasmine-2.99.0/jasmine.css
index 6319982..5207c5b
--- a/www/assets/jasmine-2.4.1/jasmine.css
+++ b/www/assets/jasmine-2.99.0/jasmine.css
@@ -33,6 +33,7 @@ body { overflow-y: scroll; }
.jasmine_html-reporter .jasmine-bar.jasmine-passed { background-color: #007069; }
.jasmine_html-reporter .jasmine-bar.jasmine-skipped { background-color: #bababa; }
.jasmine_html-reporter .jasmine-bar.jasmine-errored { background-color: #ca3a11; }
+.jasmine_html-reporter .jasmine-bar.jasmine-warning { background-color: #ba9d37; color: #333; }
.jasmine_html-reporter .jasmine-bar.jasmine-menu { background-color: #fff; color: #aaa; }
.jasmine_html-reporter .jasmine-bar.jasmine-menu a { color: #333; }
.jasmine_html-reporter .jasmine-bar a { color: white; }
diff --git a/www/assets/jasmine-2.99.0/jasmine.js b/www/assets/jasmine-2.99.0/jasmine.js
new file mode 100644
index 0000000..9e6c424
--- /dev/null
+++ b/www/assets/jasmine-2.99.0/jasmine.js
@@ -0,0 +1,5584 @@
+/*
+Copyright (c) 2008-2018 Pivotal Labs
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+var getJasmineRequireObj = (function (jasmineGlobal) {
+ var jasmineRequire;
+
+ if (typeof module !== 'undefined' && module.exports && typeof exports !== 'undefined') {
+ if (typeof global !== 'undefined') {
+ jasmineGlobal = global;
+ } else {
+ jasmineGlobal = {};
+ }
+ jasmineRequire = exports;
+ } else {
+ if (typeof window !== 'undefined' && typeof window.toString === 'function' && window.toString() === '[object GjsGlobal]') {
+ jasmineGlobal = window;
+ }
+ jasmineRequire = jasmineGlobal.jasmineRequire = {};
+ }
+
+ function getJasmineRequire() {
+ return jasmineRequire;
+ }
+
+ getJasmineRequire().core = function(jRequire) {
+ var j$ = {};
+
+ jRequire.base(j$, jasmineGlobal);
+ j$.util = jRequire.util(j$);
+ j$.errors = jRequire.errors();
+ j$.formatErrorMsg = jRequire.formatErrorMsg();
+ j$.Any = jRequire.Any(j$);
+ j$.Anything = jRequire.Anything(j$);
+ j$.CallTracker = jRequire.CallTracker(j$);
+ j$.MockDate = jRequire.MockDate();
+ j$.getClearStack = jRequire.clearStack(j$);
+ j$.Clock = jRequire.Clock();
+ j$.DelayedFunctionScheduler = jRequire.DelayedFunctionScheduler(j$);
+ j$.Env = jRequire.Env(j$);
+ j$.ExceptionFormatter = jRequire.ExceptionFormatter();
+ j$.Expectation = jRequire.Expectation();
+ j$.buildExpectationResult = jRequire.buildExpectationResult();
+ j$.JsApiReporter = jRequire.JsApiReporter();
+ j$.matchersUtil = jRequire.matchersUtil(j$);
+ j$.ObjectContaining = jRequire.ObjectContaining(j$);
+ j$.ArrayContaining = jRequire.ArrayContaining(j$);
+ j$.ArrayWithExactContents = jRequire.ArrayWithExactContents(j$);
+ j$.pp = jRequire.pp(j$);
+ j$.QueueRunner = jRequire.QueueRunner(j$);
+ j$.ReportDispatcher = jRequire.ReportDispatcher(j$);
+ j$.Spec = jRequire.Spec(j$);
+ j$.Spy = jRequire.Spy(j$);
+ j$.SpyRegistry = jRequire.SpyRegistry(j$);
+ j$.SpyStrategy = jRequire.SpyStrategy(j$);
+ j$.StringMatching = jRequire.StringMatching(j$);
+ j$.UserContext = jRequire.UserContext(j$);
+ j$.Suite = jRequire.Suite(j$);
+ j$.Timer = jRequire.Timer();
+ j$.TreeProcessor = jRequire.TreeProcessor();
+ j$.version = jRequire.version();
+ j$.Order = jRequire.Order();
+ j$.DiffBuilder = jRequire.DiffBuilder(j$);
+ j$.NullDiffBuilder = jRequire.NullDiffBuilder(j$);
+ j$.ObjectPath = jRequire.ObjectPath(j$);
+ j$.GlobalErrors = jRequire.GlobalErrors(j$);
+
+ j$.matchers = jRequire.requireMatchers(jRequire, j$);
+
+ return j$;
+ };
+
+ return getJasmineRequire;
+})(this);
+
+getJasmineRequireObj().requireMatchers = function(jRequire, j$) {
+ var availableMatchers = [
+ 'nothing',
+ 'toBe',
+ 'toBeCloseTo',
+ 'toBeDefined',
+ 'toBeFalsy',
+ 'toBeGreaterThan',
+ 'toBeGreaterThanOrEqual',
+ 'toBeLessThan',
+ 'toBeLessThanOrEqual',
+ 'toBeNaN',
+ 'toBeNegativeInfinity',
+ 'toBeNull',
+ 'toBePositiveInfinity',
+ 'toBeTruthy',
+ 'toBeUndefined',
+ 'toContain',
+ 'toEqual',
+ 'toHaveBeenCalled',
+ 'toHaveBeenCalledBefore',
+ 'toHaveBeenCalledTimes',
+ 'toHaveBeenCalledWith',
+ 'toMatch',
+ 'toThrow',
+ 'toThrowError'
+ ],
+ matchers = {};
+
+ for (var i = 0; i < availableMatchers.length; i++) {
+ var name = availableMatchers[i];
+ matchers[name] = jRequire[name](j$);
+ }
+
+ return matchers;
+};
+
+getJasmineRequireObj().base = function(j$, jasmineGlobal) {
+ j$.unimplementedMethod_ = function() {
+ throw new Error('unimplemented method');
+ };
+
+ /**
+ * Maximum object depth the pretty printer will print to.
+ * Set this to a lower value to speed up pretty printing if you have large objects.
+ * @name jasmine.MAX_PRETTY_PRINT_DEPTH
+ */
+ j$.MAX_PRETTY_PRINT_DEPTH = 8;
+ /**
+ * Maximum number of array elements to display when pretty printing objects.
+ * This will also limit the number of keys and values displayed for an object.
+ * Elements past this number will be ellipised.
+ * @name jasmine.MAX_PRETTY_PRINT_ARRAY_LENGTH
+ */
+ j$.MAX_PRETTY_PRINT_ARRAY_LENGTH = 50;
+ /**
+ * Maximum number of charasters to display when pretty printing objects.
+ * Characters past this number will be ellipised.
+ * @name jasmine.MAX_PRETTY_PRINT_CHARS
+ */
+ j$.MAX_PRETTY_PRINT_CHARS = 1000;
+ /**
+ * Default number of milliseconds Jasmine will wait for an asynchronous spec to complete.
+ * @name jasmine.DEFAULT_TIMEOUT_INTERVAL
+ */
+ j$.DEFAULT_TIMEOUT_INTERVAL = 5000;
+
+ j$.getGlobal = function() {
+ return jasmineGlobal;
+ };
+
+ /**
+ * Get the currently booted Jasmine Environment.
+ *
+ * @name jasmine.getEnv
+ * @function
+ * @return {Env}
+ */
+ j$.getEnv = function(options) {
+ var env = j$.currentEnv_ = j$.currentEnv_ || new j$.Env(options);
+ //jasmine. singletons in here (setTimeout blah blah).
+ return env;
+ };
+
+ j$.isArray_ = function(value) {
+ return j$.isA_('Array', value);
+ };
+
+ j$.isObject_ = function(value) {
+ return !j$.util.isUndefined(value) && value !== null && j$.isA_('Object', value);
+ };
+
+ j$.isString_ = function(value) {
+ return j$.isA_('String', value);
+ };
+
+ j$.isNumber_ = function(value) {
+ return j$.isA_('Number', value);
+ };
+
+ j$.isFunction_ = function(value) {
+ return j$.isA_('Function', value);
+ };
+
+ j$.isAsyncFunction_ = function(value) {
+ return j$.isA_('AsyncFunction', value);
+ };
+
+ j$.isTypedArray_ = function(value) {
+ return j$.isA_('Float32Array', value) ||
+ j$.isA_('Float64Array', value) ||
+ j$.isA_('Int16Array', value) ||
+ j$.isA_('Int32Array', value) ||
+ j$.isA_('Int8Array', value) ||
+ j$.isA_('Uint16Array', value) ||
+ j$.isA_('Uint32Array', value) ||
+ j$.isA_('Uint8Array', value) ||
+ j$.isA_('Uint8ClampedArray', value);
+ };
+
+ j$.isA_ = function(typeName, value) {
+ return j$.getType_(value) === '[object ' + typeName + ']';
+ };
+
+ j$.getType_ = function(value) {
+ return Object.prototype.toString.apply(value);
+ };
+
+ j$.isDomNode = function(obj) {
+ return obj.nodeType > 0;
+ };
+
+ j$.isMap = function(obj) {
+ return typeof jasmineGlobal.Map !== 'undefined' && obj.constructor === jasmineGlobal.Map;
+ };
+
+ j$.isSet = function(obj) {
+ return typeof jasmineGlobal.Set !== 'undefined' && obj.constructor === jasmineGlobal.Set;
+ };
+
+ j$.isPromise = function(obj) {
+ return typeof jasmineGlobal.Promise !== 'undefined' && obj.constructor === jasmineGlobal.Promise;
+ };
+
+ j$.fnNameFor = function(func) {
+ if (func.name) {
+ return func.name;
+ }
+
+ var matches = func.toString().match(/^\s*function\s*(\w*)\s*\(/) ||
+ func.toString().match(/^\s*\[object\s*(\w*)Constructor\]/);
+
+ return matches ? matches[1] : '<anonymous>';
+ };
+
+ /**
+ * Get a matcher, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),
+ * that will succeed if the actual value being compared is an instance of the specified class/constructor.
+ * @name jasmine.any
+ * @function
+ * @param {Constructor} clazz - The constructor to check against.
+ */
+ j$.any = function(clazz) {
+ return new j$.Any(clazz);
+ };
+
+ /**
+ * Get a matcher, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),
+ * that will succeed if the actual value being compared is not `null` and not `undefined`.
+ * @name jasmine.anything
+ * @function
+ */
+ j$.anything = function() {
+ return new j$.Anything();
+ };
+
+ /**
+ * Get a matcher, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),
+ * that will succeed if the actual value being compared contains at least the keys and values.
+ * @name jasmine.objectContaining
+ * @function
+ * @param {Object} sample - The subset of properties that _must_ be in the actual.
+ */
+ j$.objectContaining = function(sample) {
+ return new j$.ObjectContaining(sample);
+ };
+
+ /**
+ * Get a matcher, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),
+ * that will succeed if the actual value is a `String` that matches the `RegExp` or `String`.
+ * @name jasmine.stringMatching
+ * @function
+ * @param {RegExp|String} expected
+ */
+ j$.stringMatching = function(expected) {
+ return new j$.StringMatching(expected);
+ };
+
+ /**
+ * Get a matcher, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),
+ * that will succeed if the actual value is an `Array` that contains at least the elements in the sample.
+ * @name jasmine.arrayContaining
+ * @function
+ * @param {Array} sample
+ */
+ j$.arrayContaining = function(sample) {
+ return new j$.ArrayContaining(sample);
+ };
+
+ /**
+ * Get a matcher, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),
+ * that will succeed if the actual value is an `Array` that contains all of the elements in the sample in any order.
+ * @name jasmine.arrayWithExactContents
+ * @function
+ * @param {Array} sample
+ */
+ j$.arrayWithExactContents = function(sample) {
+ return new j$.ArrayWithExactContents(sample);
+ };
+
+ /**
+ * Create a bare {@link Spy} object. This won't be installed anywhere and will not have any implementation behind it.
+ * @name jasmine.createSpy
+ * @function
+ * @param {String} [name] - Name to give the spy. This will be displayed in failure messages.
+ * @param {Function} [originalFn] - Function to act as the real implementation.
+ * @return {Spy}
+ */
+ j$.createSpy = function(name, originalFn) {
+ return j$.Spy(name, originalFn);
+ };
+
+ j$.isSpy = function(putativeSpy) {
+ if (!putativeSpy) {
+ return false;
+ }
+ return putativeSpy.and instanceof j$.SpyStrategy &&
+ putativeSpy.calls instanceof j$.CallTracker;
+ };
+
+ /**
+ * Create an object with multiple {@link Spy}s as its members.
+ * @name jasmine.createSpyObj
+ * @function
+ * @param {String} [baseName] - Base name for the spies in the object.
+ * @param {String[]|Object} methodNames - Array of method names to create spies for, or Object whose keys will be method names and values the {@link Spy#and#returnValue|returnValue}.
+ * @return {Object}
+ */
+ j$.createSpyObj = function(baseName, methodNames) {
+ var baseNameIsCollection = j$.isObject_(baseName) || j$.isArray_(baseName);
+
+ if (baseNameIsCollection && j$.util.isUndefined(methodNames)) {
+ methodNames = baseName;
+ baseName = 'unknown';
+ }
+
+ var obj = {};
+ var spiesWereSet = false;
+
+ if (j$.isArray_(methodNames)) {
+ for (var i = 0; i < methodNames.length; i++) {
+ obj[methodNames[i]] = j$.createSpy(baseName + '.' + methodNames[i]);
+ spiesWereSet = true;
+ }
+ } else if (j$.isObject_(methodNames)) {
+ for (var key in methodNames) {
+ if (methodNames.hasOwnProperty(key)) {
+ obj[key] = j$.createSpy(baseName + '.' + key);
+ obj[key].and.returnValue(methodNames[key]);
+ spiesWereSet = true;
+ }
+ }
+ }
+
+ if (!spiesWereSet) {
+ throw 'createSpyObj requires a non-empty array or object of method names to create spies for';
+ }
+
+ return obj;
+ };
+};
+
+getJasmineRequireObj().util = function(j$) {
+
+ var util = {};
+
+ util.inherit = function(childClass, parentClass) {
+ var Subclass = function() {
+ };
+ Subclass.prototype = parentClass.prototype;
+ childClass.prototype = new Subclass();
+ };
+
+ util.htmlEscape = function(str) {
+ if (!str) {
+ return str;
+ }
+ return str.replace(/&/g, '&')
+ .replace(/</g, '<')
+ .replace(/>/g, '>');
+ };
+
+ util.argsToArray = function(args) {
+ var arrayOfArgs = [];
+ for (var i = 0; i < args.length; i++) {
+ arrayOfArgs.push(args[i]);
+ }
+ return arrayOfArgs;
+ };
+
+ util.isUndefined = function(obj) {
+ return obj === void 0;
+ };
+
+ util.arrayContains = function(array, search) {
+ var i = array.length;
+ while (i--) {
+ if (array[i] === search) {
+ return true;
+ }
+ }
+ return false;
+ };
+
+ util.clone = function(obj) {
+ if (Object.prototype.toString.apply(obj) === '[object Array]') {
+ return obj.slice();
+ }
+
+ var cloned = {};
+ for (var prop in obj) {
+ if (obj.hasOwnProperty(prop)) {
+ cloned[prop] = obj[prop];
+ }
+ }
+
+ return cloned;
+ };
+
+ util.cloneArgs = function(args) {
+ var clonedArgs = [];
+ var argsAsArray = j$.util.argsToArray(args);
+ for(var i = 0; i < argsAsArray.length; i++) {
+ var str = Object.prototype.toString.apply(argsAsArray[i]),
+ primitives = /^\[object (Boolean|String|RegExp|Number)/;
+
+ // All falsey values are either primitives, `null`, or `undefined.
+ if (!argsAsArray[i] || str.match(primitives)) {
+ clonedArgs.push(argsAsArray[i]);
+ } else {
+ clonedArgs.push(j$.util.clone(argsAsArray[i]));
+ }
+ }
+ return clonedArgs;
+ };
+
+ util.getPropertyDescriptor = function(obj, methodName) {
+ var descriptor,
+ proto = obj;
+
+ do {
+ descriptor = Object.getOwnPropertyDescriptor(proto, methodName);
+ proto = Object.getPrototypeOf(proto);
+ } while (!descriptor && proto);
+
+ return descriptor;
+ };
+
+ util.objectDifference = function(obj, toRemove) {
+ var diff = {};
+
+ for (var key in obj) {
+ if (util.has(obj, key) && !util.has(toRemove, key)) {
+ diff[key] = obj[key];
+ }
+ }
+
+ return diff;
+ };
+
+ util.has = function(obj, key) {
+ return Object.prototype.hasOwnProperty.call(obj, key);
+ };
+
+ return util;
+};
+
+getJasmineRequireObj().Spec = function(j$) {
+ function Spec(attrs) {
+ this.expectationFactory = attrs.expectationFactory;
+ this.resultCallback = attrs.resultCallback || function() {};
+ this.id = attrs.id;
+ this.description = attrs.description || '';
+ this.queueableFn = attrs.queueableFn;
+ this.beforeAndAfterFns = attrs.beforeAndAfterFns || function() { return {befores: [], afters: []}; };
+ this.userContext = attrs.userContext || function() { return {}; };
+ this.onStart = attrs.onStart || function() {};
+ this.getSpecName = attrs.getSpecName || function() { return ''; };
+ this.expectationResultFactory = attrs.expectationResultFactory || function() { };
+ this.queueRunnerFactory = attrs.queueRunnerFactory || function() {};
+ this.catchingExceptions = attrs.catchingExceptions || function() { return true; };
+ this.throwOnExpectationFailure = !!attrs.throwOnExpectationFailure;
+
+ if (!this.queueableFn.fn) {
+ this.pend();
+ }
+
+ /**
+ * @typedef SpecResult
+ * @property {Int} id - The unique id of this spec.
+ * @property {String} description - The description passed to the {@link it} that created this spec.
+ * @property {String} fullName - The full description including all ancestors of this spec.
+ * @property {Expectation[]} failedExpectations - The list of expectations that failed during execution of this spec.
+ * @property {Expectation[]} passedExpectations - The list of expectations that passed during execution of this spec.
+ * @property {Expectation[]} deprecationWarnings - The list of deprecation warnings that occurred during execution this spec.
+ * @property {String} pendingReason - If the spec is {@link pending}, this will be the reason.
+ * @property {String} status - Once the spec has completed, this string represents the pass/fail status of this spec.
+ */
+ this.result = {
+ id: this.id,
+ description: this.description,
+ fullName: this.getFullName(),
+ failedExpectations: [],
+ passedExpectations: [],
+ deprecationWarnings: [],
+ pendingReason: ''
+ };
+ }
+
+ Spec.prototype.addExpectationResult = function(passed, data, isError) {
+ var expectationResult = this.expectationResultFactory(data);
+ if (passed) {
+ this.result.passedExpectations.push(expectationResult);
+ } else {
+ this.result.failedExpectations.push(expectationResult);
+
+ if (this.throwOnExpectationFailure && !isError) {
+ throw new j$.errors.ExpectationFailed();
+ }
+ }
+ };
+
+ Spec.prototype.expect = function(actual) {
+ return this.expectationFactory(actual, this);
+ };
+
+ Spec.prototype.execute = function(onComplete, enabled) {
+ var self = this;
+
+ this.onStart(this);
+
+ var fns = this.beforeAndAfterFns();
+ var regularFns = fns.befores.concat(this.queueableFn);
+
+ var runnerConfig = {
+ isLeaf: true,
+ queueableFns: regularFns,
+ cleanupFns: fns.afters,
+ onException: function() { self.onException.apply(self, arguments); },
+ onComplete: complete,
+ userContext: this.userContext()
+ };
+
+ if (!this.isExecutable() || this.markedPending || enabled === false) {
+ runnerConfig.queueableFns = [];
+ runnerConfig.cleanupFns = [];
+ runnerConfig.onComplete = function() { complete(enabled); };
+ }
+
+ this.queueRunnerFactory(runnerConfig);
+
+ function complete(enabledAgain) {
+ self.result.status = self.status(enabledAgain);
+ self.resultCallback(self.result);
+
+ if (onComplete) {
+ onComplete();
+ }
+ }
+ };
+
+ Spec.prototype.onException = function onException(e) {
+ if (Spec.isPendingSpecException(e)) {
+ this.pend(extractCustomPendingMessage(e));
+ return;
+ }
+
+ if (e instanceof j$.errors.ExpectationFailed) {
+ return;
+ }
+
+ this.addExpectationResult(false, {
+ matcherName: '',
+ passed: false,
+ expected: '',
+ actual: '',
+ error: e
+ }, true);
+ };
+
+ Spec.prototype.disable = function() {
+ this.disabled = true;
+ };
+
+ Spec.prototype.pend = function(message) {
+ this.markedPending = true;
+ if (message) {
+ this.result.pendingReason = message;
+ }
+ };
+
+ Spec.prototype.getResult = function() {
+ this.result.status = this.status();
+ return this.result;
+ };
+
+ Spec.prototype.status = function(enabled) {
+ if (this.disabled || enabled === false) {
+ return 'disabled';
+ }
+
+ if (this.markedPending) {
+ return 'pending';
+ }
+
+ if (this.result.failedExpectations.length > 0) {
+ return 'failed';
+ } else {
+ return 'passed';
+ }
+ };
+
+ Spec.prototype.isExecutable = function() {
+ return !this.disabled;
+ };
+
+ Spec.prototype.getFullName = function() {
+ return this.getSpecName(this);
+ };
+
+ Spec.prototype.addDeprecationWarning = function(msg) {
+ this.result.deprecationWarnings.push(this.expectationResultFactory({ message: msg }));
+ };
+
+ var extractCustomPendingMessage = function(e) {
+ var fullMessage = e.toString(),
+ boilerplateStart = fullMessage.indexOf(Spec.pendingSpecExceptionMessage),
+ boilerplateEnd = boilerplateStart + Spec.pendingSpecExceptionMessage.length;
+
+ return fullMessage.substr(boilerplateEnd);
+ };
+
+ Spec.pendingSpecExceptionMessage = '=> marked Pending';
+
+ Spec.isPendingSpecException = function(e) {
+ return !!(e && e.toString && e.toString().indexOf(Spec.pendingSpecExceptionMessage) !== -1);
+ };
+
+ return Spec;
+};
+
+if (typeof window == void 0 && typeof exports == 'object') {
+ exports.Spec = jasmineRequire.Spec;
+}
+
+/*jshint bitwise: false*/
+
+getJasmineRequireObj().Order = function() {
+ function Order(options) {
+ this.random = 'random' in options ? options.random : true;
+ var seed = this.seed = options.seed || generateSeed();
+ this.sort = this.random ? randomOrder : naturalOrder;
+
+ function naturalOrder(items) {
+ return items;
+ }
+
+ function randomOrder(items) {
+ var copy = items.slice();
+ copy.sort(function(a, b) {
+ return jenkinsHash(seed + a.id) - jenkinsHash(seed + b.id);
+ });
+ return copy;
+ }
+
+ function generateSeed() {
+ return String(Math.random()).slice(-5);
+ }
+
+ // Bob Jenkins One-at-a-Time Hash algorithm is a non-cryptographic hash function
+ // used to get a different output when the key changes slighly.
+ // We use your return to sort the children randomly in a consistent way when
+ // used in conjunction with a seed
+
+ function jenkinsHash(key) {
+ var hash, i;
+ for(hash = i = 0; i < key.length; ++i) {
+ hash += key.charCodeAt(i);
+ hash += (hash << 10);
+ hash ^= (hash >> 6);
+ }
+ hash += (hash << 3);
+ hash ^= (hash >> 11);
+ hash += (hash << 15);
+ return hash;
+ }
+
+ }
+
+ return Order;
+};
+
+getJasmineRequireObj().Env = function(j$) {
+ /**
+ * _Note:_ Do not construct this directly, Jasmine will make one during booting.
+ * @name Env
+ * @classdesc The Jasmine environment
+ * @constructor
+ */
+ function Env(options) {
+ options = options || {};
+
+ var self = this;
+ var global = options.global || j$.getGlobal();
+
+ var hasExecuted = false;
+
+ var totalSpecsDefined = 0;
+
+ var catchExceptions = true;
+
+ var realSetTimeout = j$.getGlobal().setTimeout;
+ var realClearTimeout = j$.getGlobal().clearTimeout;
+ var clearStack = j$.getClearStack(j$.getGlobal());
+ this.clock = new j$.Clock(global, function () { return new j$.DelayedFunctionScheduler(); }, new j$.MockDate(global));
+
+ var runnableResources = {};
+
+ var currentSpec = null;
+ var currentlyExecutingSuites = [];
+ var currentDeclarationSuite = null;
+ var throwOnExpectationFailure = false;
+ var random = false;
+ var seed = null;
+
+ var currentSuite = function() {
+ return currentlyExecutingSuites[currentlyExecutingSuites.length - 1];
+ };
+
+ var currentRunnable = function() {
+ return currentSpec || currentSuite();
+ };
+
+ /**
+ * This represents the available reporter callback for an object passed to {@link Env#addReporter}.
+ * @interface Reporter
+ */
+ var reporter = new j$.ReportDispatcher([
+ /**
+ * `jasmineStarted` is called after all of the specs have been loaded, but just before execution starts.
+ * @function
+ * @name Reporter#jasmineStarted
+ * @param {JasmineStartedInfo} suiteInfo Information about the full Jasmine suite that is being run
+ */
+ 'jasmineStarted',
+ /**
+ * When the entire suite has finished execution `jasmineDone` is called
+ * @function
+ * @name Reporter#jasmineDone
+ * @param {JasmineDoneInfo} suiteInfo Information about the full Jasmine suite that just finished running.
+ */
+ 'jasmineDone',
+ /**
+ * `suiteStarted` is invoked when a `describe` starts to run
+ * @function
+ * @name Reporter#suiteStarted
+ * @param {SuiteResult} result Information about the individual {@link describe} being run
+ */
+ 'suiteStarted',
+ /**
+ * `suiteDone` is invoked when all of the child specs and suites for a given suite have been run
+ *
+ * While jasmine doesn't require any specific functions, not defining a `suiteDone` will make it impossible for a reporter to know when a suite has failures in an `afterAll`.
+ * @function
+ * @name Reporter#suiteDone
+ * @param {SuiteResult} result
+ */
+ 'suiteDone',
+ /**
+ * `specStarted` is invoked when an `it` starts to run (including associated `beforeEach` functions)
+ * @function
+ * @name Reporter#specStarted
+ * @param {SpecResult} result Information about the individual {@link it} being run
+ */
+ 'specStarted',
+ /**
+ * `specDone` is invoked when an `it` and its associated `beforeEach` and `afterEach` functions have been run.
+ *
+ * While jasmine doesn't require any specific functions, not defining a `specDone` will make it impossible for a reporter to know when a spec has failed.
+ * @function
+ * @name Reporter#specDone
+ * @param {SpecResult} result
+ */
+ 'specDone'
+ ]);
+
+ var globalErrors = new j$.GlobalErrors();
+
+ this.specFilter = function() {
+ return true;
+ };
+
+ this.addCustomEqualityTester = function(tester) {
+ if(!currentRunnable()) {
+ throw new Error('Custom Equalities must be added in a before function or a spec');
+ }
+ runnableResources[currentRunnable().id].customEqualityTesters.push(tester);
+ };
+
+ this.addMatchers = function(matchersToAdd) {
+ if(!currentRunnable()) {
+ throw new Error('Matchers must be added in a before function or a spec');
+ }
+ var customMatchers = runnableResources[currentRunnable().id].customMatchers;
+ for (var matcherName in matchersToAdd) {
+ customMatchers[matcherName] = matchersToAdd[matcherName];
+ }
+ };
+
+ j$.Expectation.addCoreMatchers(j$.matchers);
+
+ var nextSpecId = 0;
+ var getNextSpecId = function() {
+ return 'spec' + nextSpecId++;
+ };
+
+ var nextSuiteId = 0;
+ var getNextSuiteId = function() {
+ return 'suite' + nextSuiteId++;
+ };
+
+ var expectationFactory = function(actual, spec) {
+ return j$.Expectation.Factory({
+ util: j$.matchersUtil,
+ customEqualityTesters: runnableResources[spec.id].customEqualityTesters,
+ customMatchers: runnableResources[spec.id].customMatchers,
+ actual: actual,
+ addExpectationResult: addExpectationResult
+ });
+
+ function addExpectationResult(passed, result) {
+ return spec.addExpectationResult(passed, result);
+ }
+ };
+
+ var defaultResourcesForRunnable = function(id, parentRunnableId) {
+ var resources = {spies: [], customEqualityTesters: [], customMatchers: {}};
+
+ if(runnableResources[parentRunnableId]){
+ resources.customEqualityTesters = j$.util.clone(runnableResources[parentRunnableId].customEqualityTesters);
+ resources.customMatchers = j$.util.clone(runnableResources[parentRunnableId].customMatchers);
+ }
+
+ runnableResources[id] = resources;
+ };
+
+ var clearResourcesForRunnable = function(id) {
+ spyRegistry.clearSpies();
+ delete runnableResources[id];
+ };
+
+ var beforeAndAfterFns = function(suite) {
+ return function() {
+ var befores = [],
+ afters = [];
+
+ while(suite) {
+ befores = befores.concat(suite.beforeFns);
+ afters = afters.concat(suite.afterFns);
+
+ suite = suite.parentSuite;
+ }
+
+ return {
+ befores: befores.reverse(),
+ afters: afters
+ };
+ };
+ };
+
+ var getSpecName = function(spec, suite) {
+ var fullName = [spec.description],
+ suiteFullName = suite.getFullName();
+
+ if (suiteFullName !== '') {
+ fullName.unshift(suiteFullName);
+ }
+ return fullName.join(' ');
+ };
+
+ // TODO: we may just be able to pass in the fn instead of wrapping here
+ var buildExpectationResult = j$.buildExpectationResult,
+ exceptionFormatter = new j$.ExceptionFormatter(),
+ expectationResultFactory = function(attrs) {
+ attrs.messageFormatter = exceptionFormatter.message;
+ attrs.stackFormatter = exceptionFormatter.stack;
+
+ return buildExpectationResult(attrs);
+ };
+
+ // TODO: fix this naming, and here's where the value comes in
+ this.catchExceptions = function(value) {
+ this.deprecated('The catchExceptions option is deprecated and will be replaced with stopOnSpecFailure in Jasmine 3.0');
+ catchExceptions = !!value;
+ return catchExceptions;
+ };
+
+ this.catchingExceptions = function() {
+ return catchExceptions;
+ };
+
+ var maximumSpecCallbackDepth = 20;
+ var currentSpecCallbackDepth = 0;
+
+ var catchException = function(e) {
+ return j$.Spec.isPendingSpecException(e) || catchExceptions;
+ };
+
+ this.throwOnExpectationFailure = function(value) {
+ throwOnExpectationFailure = !!value;
+ };
+
+ this.throwingExpectationFailures = function() {
+ return throwOnExpectationFailure;
+ };
+
+ this.randomizeTests = function(value) {
+ random = !!value;
+ };
+
+ this.randomTests = function() {
+ return random;
+ };
+
+ this.seed = function(value) {
+ if (value) {
+ seed = value;
+ }
+ return seed;
+ };
+
+ this.deprecated = function(msg) {
+ var runnable = currentRunnable() || topSuite;
+ runnable.addDeprecationWarning(msg);
+ if(typeof console !== 'undefined' && typeof console.warn !== 'undefined') {
+ console.error('DEPRECATION: ' + msg);
+ }
+ };
+
+ var queueRunnerFactory = function(options) {
+ options.catchException = catchException;
+ options.clearStack = options.clearStack || clearStack;
+ options.timeout = {setTimeout: realSetTimeout, clearTimeout: realClearTimeout};
+ options.fail = self.fail;
+ options.globalErrors = globalErrors;
+ options.completeOnFirstError = throwOnExpectationFailure && options.isLeaf;
+ options.deprecated = self.deprecated;
+
+ new j$.QueueRunner(options).execute();
+ };
+
+ var topSuite = new j$.Suite({
+ env: this,
+ id: getNextSuiteId(),
+ description: 'Jasmine__TopLevel__Suite',
+ expectationFactory: expectationFactory,
+ expectationResultFactory: expectationResultFactory
+ });
+ defaultResourcesForRunnable(topSuite.id);
+ currentDeclarationSuite = topSuite;
+
+ this.topSuite = function() {
+ return topSuite;
+ };
+
+ this.execute = function(runnablesToRun) {
+ if (hasExecuted) {
+ this.deprecated('Executing the same Jasmine multiple times will no longer work in Jasmine 3.0');
+ }
+
+ hasExecuted = true;
+
+ if(!runnablesToRun) {
+ if (focusedRunnables.length) {
+ runnablesToRun = focusedRunnables;
+ } else {
+ runnablesToRun = [topSuite.id];
+ }
+ }
+
+ var order = new j$.Order({
+ random: random,
+ seed: seed
+ });
+
+ var processor = new j$.TreeProcessor({
+ tree: topSuite,
+ runnableIds: runnablesToRun,
+ queueRunnerFactory: queueRunnerFactory,
+ nodeStart: function(suite) {
+ currentlyExecutingSuites.push(suite);
+ defaultResourcesForRunnable(suite.id, suite.parentSuite.id);
+ reporter.suiteStarted(suite.result);
+ },
+ nodeComplete: function(suite, result) {
+ if (suite !== currentSuite()) {
+ throw new Error('Tried to complete the wrong suite');
+ }
+
+ if (!suite.markedPending) {
+ clearResourcesForRunnable(suite.id);
+ }
+ currentlyExecutingSuites.pop();
+ reporter.suiteDone(result);
+ },
+ orderChildren: function(node) {
+ return order.sort(node.children);
+ }
+ });
+
+ if(!processor.processTree().valid) {
+ throw new Error('Invalid order: would cause a beforeAll or afterAll to be run multiple times');
+ }
+
+ /**
+ * Information passed to the {@link Reporter#jasmineStarted} event.
+ * @typedef JasmineStartedInfo
+ * @property {Int} totalSpecsDefined - The total number of specs defined in this suite.
+ * @property {Order} order - Information about the ordering (random or not) of this execution of the suite.
+ */
+ reporter.jasmineStarted({
+ totalSpecsDefined: totalSpecsDefined,
+ order: order
+ });
+
+ currentlyExecutingSuites.push(topSuite);
+
+ globalErrors.install();
+ processor.execute(function() {
+ clearResourcesForRunnable(topSuite.id);
+ currentlyExecutingSuites.pop();
+ globalErrors.uninstall();
+
+ /**
+ * Information passed to the {@link Reporter#jasmineDone} event.
+ * @typedef JasmineDoneInfo
+ * @property {Order} order - Information about the ordering (random or not) of this execution of the suite.
+ * @property {Expectation[]} failedExpectations - List of expectations that failed in an {@link afterAll} at the global level.
+ * @property {Expectation[]} deprecationWarnings - List of deprecation warnings that occurred at the global level.
+ */
+ reporter.jasmineDone({
+ order: order,
+ failedExpectations: topSuite.result.failedExpectations,
+ deprecationWarnings: topSuite.result.deprecationWarnings
+ });
+ });
+ };
+
+ /**
+ * Add a custom reporter to the Jasmine environment.
+ * @name Env#addReporter
+ * @function
+ * @param {Reporter} reporterToAdd The reporter to be added.
+ * @see custom_reporter
+ */
+ this.addReporter = function(reporterToAdd) {
+ reporter.addReporter(reporterToAdd);
+ };
+
+ this.provideFallbackReporter = function(reporterToAdd) {
+ reporter.provideFallbackReporter(reporterToAdd);
+ };
+
+ this.clearReporters = function() {
+ reporter.clearReporters();
+ };
+
+ var spyRegistry = new j$.SpyRegistry({currentSpies: function() {
+ if(!currentRunnable()) {
+ throw new Error('Spies must be created in a before function or a spec');
+ }
+ return runnableResources[currentRunnable().id].spies;
+ }});
+
+ this.allowRespy = function(allow){
+ spyRegistry.allowRespy(allow);
+ };
+
+ this.spyOn = function() {
+ return spyRegistry.spyOn.apply(spyRegistry, arguments);
+ };
+
+ this.spyOnProperty = function() {
+ return spyRegistry.spyOnProperty.apply(spyRegistry, arguments);
+ };
+
+ var ensureIsFunction = function(fn, caller) {
+ if (!j$.isFunction_(fn)) {
+ throw new Error(caller + ' expects a function argument; received ' + j$.getType_(fn));
+ }
+ };
+
+ var ensureIsFunctionOrAsync = function(fn, caller) {
+ if (!j$.isFunction_(fn) && !j$.isAsyncFunction_(fn)) {
+ throw new Error(caller + ' expects a function argument; received ' + j$.getType_(fn));
+ }
+ };
+
+ function ensureIsNotNested(method) {
+ var runnable = currentRunnable();
+ if (runnable !== null && runnable !== undefined) {
+ throw new Error('\'' + method + '\' should only be used in \'describe\' function');
+ }
+ }
+
+ var suiteFactory = function(description) {
+ var suite = new j$.Suite({
+ env: self,
+ id: getNextSuiteId(),
+ description: description,
+ parentSuite: currentDeclarationSuite,
+ expectationFactory: expectationFactory,
+ expectationResultFactory: expectationResultFactory,
+ throwOnExpectationFailure: throwOnExpectationFailure
+ });
+
+ return suite;
+ };
+
+ this.describe = function(description, specDefinitions) {
+ ensureIsNotNested('describe');
+ ensureIsFunction(specDefinitions, 'describe');
+ var suite = suiteFactory(description);
+ if (specDefinitions.length > 0) {
+ throw new Error('describe does not expect any arguments');
+ }
+ if (currentDeclarationSuite.markedPending) {
+ suite.pend();
+ }
+ addSpecsToSuite(suite, specDefinitions);
+ return suite;
+ };
+
+ this.xdescribe = function(description, specDefinitions) {
+ ensureIsNotNested('xdescribe');
+ ensureIsFunction(specDefinitions, 'xdescribe');
+ var suite = suiteFactory(description);
+ suite.pend();
+ addSpecsToSuite(suite, specDefinitions);
+ return suite;
+ };
+
+ var focusedRunnables = [];
+
+ this.fdescribe = function(description, specDefinitions) {
+ this.deprecated('fit and fdescribe will cause your suite to report an \'incomplete\' status in Jasmine 3.0');
+ ensureIsNotNested('fdescribe');
+ ensureIsFunction(specDefinitions, 'fdescribe');
+ var suite = suiteFactory(description);
+ suite.isFocused = true;
+
+ focusedRunnables.push(suite.id);
+ unfocusAncestor();
+ addSpecsToSuite(suite, specDefinitions);
+
+ return suite;
+ };
+
+ function addSpecsToSuite(suite, specDefinitions) {
+ var parentSuite = currentDeclarationSuite;
+ parentSuite.addChild(suite);
+ currentDeclarationSuite = suite;
+
+ var declarationError = null;
+ try {
+ specDefinitions.call(suite);
+ } catch (e) {
+ declarationError = e;
+ }
+
+ if (declarationError) {
+ self.it('encountered a declaration exception', function() {
+ throw declarationError;
+ });
+ }
+
+ currentDeclarationSuite = parentSuite;
+ }
+
+ function findFocusedAncestor(suite) {
+ while (suite) {
+ if (suite.isFocused) {
+ return suite.id;
+ }
+ suite = suite.parentSuite;
+ }
+
+ return null;
+ }
+
+ function unfocusAncestor() {
+ var focusedAncestor = findFocusedAncestor(currentDeclarationSuite);
+ if (focusedAncestor) {
+ for (var i = 0; i < focusedRunnables.length; i++) {
+ if (focusedRunnables[i] === focusedAncestor) {
+ focusedRunnables.splice(i, 1);
+ break;
+ }
+ }
+ }
+ }
+
+ var specFactory = function(description, fn, suite, timeout) {
+ totalSpecsDefined++;
+ var spec = new j$.Spec({
+ id: getNextSpecId(),
+ beforeAndAfterFns: beforeAndAfterFns(suite),
+ expectationFactory: expectationFactory,
+ resultCallback: specResultCallback,
+ getSpecName: function(spec) {
+ return getSpecName(spec, suite);
+ },
+ onStart: specStarted,
+ description: description,
+ expectationResultFactory: expectationResultFactory,
+ queueRunnerFactory: queueRunnerFactory,
+ userContext: function() { return suite.clonedSharedUserContext(); },
+ queueableFn: {
+ fn: fn,
+ timeout: function() { return timeout || j$.DEFAULT_TIMEOUT_INTERVAL; }
+ },
+ throwOnExpectationFailure: throwOnExpectationFailure
+ });
+
+ if (!self.specFilter(spec)) {
+ spec.disable();
+ }
+
+ return spec;
+
+ function specResultCallback(result) {
+ clearResourcesForRunnable(spec.id);
+ currentSpec = null;
+ reporter.specDone(result);
+ }
+
+ function specStarted(spec) {
+ currentSpec = spec;
+ defaultResourcesForRunnable(spec.id, suite.id);
+ reporter.specStarted(spec.result);
+ }
+ };
+
+ this.it = function(description, fn, timeout) {
+ ensureIsNotNested('it');
+ // it() sometimes doesn't have a fn argument, so only check the type if
+ // it's given.
+ if (arguments.length > 1 && typeof fn !== 'undefined') {
+ ensureIsFunctionOrAsync(fn, 'it');
+ }
+ var spec = specFactory(description, fn, currentDeclarationSuite, timeout);
+ if (currentDeclarationSuite.markedPending) {
+ spec.pend();
+ }
+ currentDeclarationSuite.addChild(spec);
+ return spec;
+ };
+
+ this.xit = function(description, fn, timeout) {
+ ensureIsNotNested('xit');
+ // xit(), like it(), doesn't always have a fn argument, so only check the
+ // type when needed.
+ if (arguments.length > 1 && typeof fn !== 'undefined') {
+ ensureIsFunctionOrAsync(fn, 'xit');
+ }
+ var spec = this.it.apply(this, arguments);
+ spec.pend('Temporarily disabled with xit');
+ return spec;
+ };
+
+ this.fit = function(description, fn, timeout){
+ this.deprecated('fit and fdescribe will cause your suite to report an \'incomplete\' status in Jasmine 3.0');
+ ensureIsNotNested('fit');
+ ensureIsFunctionOrAsync(fn, 'fit');
+ var spec = specFactory(description, fn, currentDeclarationSuite, timeout);
+ currentDeclarationSuite.addChild(spec);
+ focusedRunnables.push(spec.id);
+ unfocusAncestor();
+ return spec;
+ };
+
+ this.expect = function(actual) {
+ if (!currentRunnable()) {
+ throw new Error('\'expect\' was used when there was no current spec, this could be because an asynchronous test timed out');
+ }
+
+ return currentRunnable().expect(actual);
+ };
+
+ this.beforeEach = function(beforeEachFunction, timeout) {
+ ensureIsNotNested('beforeEach');
+ ensureIsFunctionOrAsync(beforeEachFunction, 'beforeEach');
+ currentDeclarationSuite.beforeEach({
+ fn: beforeEachFunction,
+ timeout: function() { return timeout || j$.DEFAULT_TIMEOUT_INTERVAL; }
+ });
+ };
+
+ this.beforeAll = function(beforeAllFunction, timeout) {
+ ensureIsNotNested('beforeAll');
+ ensureIsFunctionOrAsync(beforeAllFunction, 'beforeAll');
+ currentDeclarationSuite.beforeAll({
+ fn: beforeAllFunction,
+ timeout: function() { return timeout || j$.DEFAULT_TIMEOUT_INTERVAL; }
+ });
+ };
+
+ this.afterEach = function(afterEachFunction, timeout) {
+ ensureIsNotNested('afterEach');
+ ensureIsFunctionOrAsync(afterEachFunction, 'afterEach');
+ afterEachFunction.isCleanup = true;
+ currentDeclarationSuite.afterEach({
+ fn: afterEachFunction,
+ timeout: function() { return timeout || j$.DEFAULT_TIMEOUT_INTERVAL; }
+ });
+ };
+
+ this.afterAll = function(afterAllFunction, timeout) {
+ ensureIsNotNested('afterAll');
+ ensureIsFunctionOrAsync(afterAllFunction, 'afterAll');
+ currentDeclarationSuite.afterAll({
+ fn: afterAllFunction,
+ timeout: function() { return timeout || j$.DEFAULT_TIMEOUT_INTERVAL; }
+ });
+ };
+
+ this.pending = function(message) {
+ var fullMessage = j$.Spec.pendingSpecExceptionMessage;
+ if(message) {
+ fullMessage += message;
+ }
+ throw fullMessage;
+ };
+
+ this.fail = function(error) {
+ if (!currentRunnable()) {
+ throw new Error('\'fail\' was used when there was no current spec, this could be because an asynchronous test timed out');
+ }
+
+ var message = 'Failed';
+ if (error) {
+ message += ': ';
+ if (error.message) {
+ message += error.message;
+ } else if (jasmine.isString_(error)) {
+ message += error;
+ } else {
+ // pretty print all kind of objects. This includes arrays.
+ message += jasmine.pp(error);
+ }
+ }
+
+ currentRunnable().addExpectationResult(false, {
+ matcherName: '',
+ passed: false,
+ expected: '',
+ actual: '',
+ message: message,
+ error: error && error.message ? error : null
+ });
+
+ if (self.throwingExpectationFailures()) {
+ throw new Error(message);
+ }
+ };
+ }
+
+ return Env;
+};
+
+getJasmineRequireObj().JsApiReporter = function() {
+
+ var noopTimer = {
+ start: function(){},
+ elapsed: function(){ return 0; }
+ };
+
+ /**
+ * @name jsApiReporter
+ * @classdesc {@link Reporter} added by default in `boot.js` to record results for retrieval in javascript code. An instance is made available as `jsApiReporter` on the global object.
+ * @class
+ * @hideconstructor
+ */
+ function JsApiReporter(options) {
+ var timer = options.timer || noopTimer,
+ status = 'loaded';
+
+ this.started = false;
+ this.finished = false;
+ this.runDetails = {};
+
+ this.jasmineStarted = function() {
+ this.started = true;
+ status = 'started';
+ timer.start();
+ };
+
+ var executionTime;
+
+ this.jasmineDone = function(runDetails) {
+ this.finished = true;
+ this.runDetails = runDetails;
+ executionTime = timer.elapsed();
+ status = 'done';
+ };
+
+ /**
+ * Get the current status for the Jasmine environment.
+ * @name jsApiReporter#status
+ * @function
+ * @return {String} - One of `loaded`, `started`, or `done`
+ */
+ this.status = function() {
+ return status;
+ };
+
+ var suites = [],
+ suites_hash = {};
+
+ this.suiteStarted = function(result) {
+ suites_hash[result.id] = result;
+ };
+
+ this.suiteDone = function(result) {
+ storeSuite(result);
+ };
+
+ /**
+ * Get the results for a set of suites.
+ *
+ * Retrievable in slices for easier serialization.
+ * @name jsApiReporter#suiteResults
+ * @function
+ * @param {Number} index - The position in the suites list to start from.
+ * @param {Number} length - Maximum number of suite results to return.
+ * @return {SuiteResult[]}
+ */
+ this.suiteResults = function(index, length) {
+ return suites.slice(index, index + length);
+ };
+
+ function storeSuite(result) {
+ suites.push(result);
+ suites_hash[result.id] = result;
+ }
+
+ /**
+ * Get all of the suites in a single object, with their `id` as the key.
+ * @name jsApiReporter#suites
+ * @function
+ * @return {Object} - Map of suite id to {@link SuiteResult}
+ */
+ this.suites = function() {
+ return suites_hash;
+ };
+
+ var specs = [];
+
+ this.specDone = function(result) {
+ specs.push(result);
+ };
+
+ /**
+ * Get the results for a set of specs.
+ *
+ * Retrievable in slices for easier serialization.
+ * @name jsApiReporter#specResults
+ * @function
+ * @param {Number} index - The position in the specs list to start from.
+ * @param {Number} length - Maximum number of specs results to return.
+ * @return {SpecResult[]}
+ */
+ this.specResults = function(index, length) {
+ return specs.slice(index, index + length);
+ };
+
+ /**
+ * Get all spec results.
+ * @name jsApiReporter#specs
+ * @function
+ * @return {SpecResult[]}
+ */
+ this.specs = function() {
+ return specs;
+ };
+
+ /**
+ * Get the number of milliseconds it took for the full Jasmine suite to run.
+ * @name jsApiReporter#executionTime
+ * @function
+ * @return {Number}
+ */
+ this.executionTime = function() {
+ return executionTime;
+ };
+
+ }
+
+ return JsApiReporter;
+};
+
+getJasmineRequireObj().Any = function(j$) {
+
+ function Any(expectedObject) {
+ if (typeof expectedObject === 'undefined') {
+ throw new TypeError(
+ 'jasmine.any() expects to be passed a constructor function. ' +
+ 'Please pass one or use jasmine.anything() to match any object.'
+ );
+ }
+ this.expectedObject = expectedObject;
+ }
+
+ Any.prototype.asymmetricMatch = function(other) {
+ if (this.expectedObject == String) {
+ return typeof other == 'string' || other instanceof String;
+ }
+
+ if (this.expectedObject == Number) {
+ return typeof other == 'number' || other instanceof Number;
+ }
+
+ if (this.expectedObject == Function) {
+ return typeof other == 'function' || other instanceof Function;
+ }
+
+ if (this.expectedObject == Object) {
+ if (other === null) {
+ j$.getEnv().deprecated('jasmine.Any(Object) will no longer match null in Jasmine 3.0');
+ }
+ return typeof other == 'object';
+ }
+
+ if (this.expectedObject == Boolean) {
+ return typeof other == 'boolean';
+ }
+
+ /* jshint -W122 */
+ if (typeof Symbol != 'undefined' && this.expectedObject == Symbol) {
+ return typeof other == 'symbol';
+ }
+ /* jshint +W122 */
+
+ return other instanceof this.expectedObject;
+ };
+
+ Any.prototype.jasmineToString = function() {
+ return '<jasmine.any(' + j$.fnNameFor(this.expectedObject) + ')>';
+ };
+
+ return Any;
+};
+
+getJasmineRequireObj().Anything = function(j$) {
+
+ function Anything() {}
+
+ Anything.prototype.asymmetricMatch = function(other) {
+ return !j$.util.isUndefined(other) && other !== null;
+ };
+
+ Anything.prototype.jasmineToString = function() {
+ return '<jasmine.anything>';
+ };
+
+ return Anything;
+};
+
+getJasmineRequireObj().ArrayContaining = function(j$) {
+ function ArrayContaining(sample) {
+ this.sample = sample;
+ }
+
+ ArrayContaining.prototype.asymmetricMatch = function(other, customTesters) {
+ if (!j$.isArray_(this.sample)) {
+ throw new Error('You must provide an array to arrayContaining, not ' + j$.pp(this.sample) + '.');
+ }
+
+ for (var i = 0; i < this.sample.length; i++) {
+ var item = this.sample[i];
+ if (!j$.matchersUtil.contains(other, item, customTesters)) {
+ return false;
+ }
+ }
+
+ return true;
+ };
+
+ ArrayContaining.prototype.jasmineToString = function () {
+ return '<jasmine.arrayContaining(' + jasmine.pp(this.sample) +')>';
+ };
+
+ return ArrayContaining;
+};
+
+getJasmineRequireObj().ArrayWithExactContents = function(j$) {
+
+ function ArrayWithExactContents(sample) {
+ this.sample = sample;
+ }
+
+ ArrayWithExactContents.prototype.asymmetricMatch = function(other, customTesters) {
+ if (!j$.isArray_(this.sample)) {
+ throw new Error('You must provide an array to arrayWithExactContents, not ' + j$.pp(this.sample) + '.');
+ }
+
+ if (this.sample.length !== other.length) {
+ return false;
+ }
+
+ for (var i = 0; i < this.sample.length; i++) {
+ var item = this.sample[i];
+ if (!j$.matchersUtil.contains(other, item, customTesters)) {
+ return false;
+ }
+ }
+
+ return true;
+ };
+
+ ArrayWithExactContents.prototype.jasmineToString = function() {
+ return '<jasmine.arrayWithExactContents ' + j$.pp(this.sample) + '>';
+ };
+
+ return ArrayWithExactContents;
+};
+
+getJasmineRequireObj().ObjectContaining = function(j$) {
+
+ function ObjectContaining(sample) {
+ this.sample = sample;
+ }
+
+ function getPrototype(obj) {
+ if (Object.getPrototypeOf) {
+ return Object.getPrototypeOf(obj);
+ }
+
+ if (obj.constructor.prototype == obj) {
+ return null;
+ }
+
+ return obj.constructor.prototype;
+ }
+
+ function hasProperty(obj, property) {
+ if (!obj) {
+ return false;
+ }
+
+ if (Object.prototype.hasOwnProperty.call(obj, property)) {
+ return true;
+ }
+
+ return hasProperty(getPrototype(obj), property);
+ }
+
+ ObjectContaining.prototype.asymmetricMatch = function(other, customTesters) {
+ if (typeof(this.sample) !== 'object') { throw new Error('You must provide an object to objectContaining, not \''+this.sample+'\'.'); }
+
+ for (var property in this.sample) {
+ if (!hasProperty(other, property) ||
+ !j$.matchersUtil.equals(this.sample[property], other[property], customTesters)) {
+ return false;
+ }
+ }
+
+ return true;
+ };
+
+ ObjectContaining.prototype.jasmineToString = function() {
+ return '<jasmine.objectContaining(' + j$.pp(this.sample) + ')>';
+ };
+
+ return ObjectContaining;
+};
+
+getJasmineRequireObj().StringMatching = function(j$) {
+
+ function StringMatching(expected) {
+ if (!j$.isString_(expected) && !j$.isA_('RegExp', expected)) {
+ throw new Error('Expected is not a String or a RegExp');
+ }
+
+ this.regexp = new RegExp(expected);
+ }
+
+ StringMatching.prototype.asymmetricMatch = function(other) {
+ return this.regexp.test(other);
+ };
+
+ StringMatching.prototype.jasmineToString = function() {
+ return '<jasmine.stringMatching(' + this.regexp + ')>';
+ };
+
+ return StringMatching;
+};
+
+getJasmineRequireObj().CallTracker = function(j$) {
+
+ /**
+ * @namespace Spy#calls
+ */
+ function CallTracker() {
+ var calls = [];
+ var opts = {};
+
+ this.track = function(context) {
+ if(opts.cloneArgs) {
+ context.args = j$.util.cloneArgs(context.args);
+ }
+ calls.push(context);
+ };
+
+ /**
+ * Check whether this spy has been invoked.
+ * @name Spy#calls#any
+ * @function
+ * @return {Boolean}
+ */
+ this.any = function() {
+ return !!calls.length;
+ };
+
+ /**
+ * Get the number of invocations of this spy.
+ * @name Spy#calls#count
+ * @function
+ * @return {Integer}
+ */
+ this.count = function() {
+ return calls.length;
+ };
+
+ /**
+ * Get the arguments that were passed to a specific invocation of this spy.
+ * @name Spy#calls#argsFor
+ * @function
+ * @param {Integer} index The 0-based invocation index.
+ * @return {Array}
+ */
+ this.argsFor = function(index) {
+ var call = calls[index];
+ return call ? call.args : [];
+ };
+
+ /**
+ * Get the raw calls array for this spy.
+ * @name Spy#calls#all
+ * @function
+ * @return {Spy.callData[]}
+ */
+ this.all = function() {
+ return calls;
+ };
+
+ /**
+ * Get all of the arguments for each invocation of this spy in the order they were received.
+ * @name Spy#calls#allArgs
+ * @function
+ * @return {Array}
+ */
+ this.allArgs = function() {
+ var callArgs = [];
+ for(var i = 0; i < calls.length; i++){
+ callArgs.push(calls[i].args);
+ }
+
+ return callArgs;
+ };
+
+ /**
+ * Get the first invocation of this spy.
+ * @name Spy#calls#first
+ * @function
+ * @return {ObjecSpy.callData}
+ */
+ this.first = function() {
+ return calls[0];
+ };
+
+ /**
+ * Get the most recent invocation of this spy.
+ * @name Spy#calls#mostRecent
+ * @function
+ * @return {ObjecSpy.callData}
+ */
+ this.mostRecent = function() {
+ return calls[calls.length - 1];
+ };
+
+ /**
+ * Reset this spy as if it has never been called.
+ * @name Spy#calls#reset
+ * @function
+ */
+ this.reset = function() {
+ calls = [];
+ };
+
+ /**
+ * Set this spy to do a shallow clone of arguments passed to each invocation.
+ * @name Spy#calls#saveArgumentsByValue
+ * @function
+ */
+ this.saveArgumentsByValue = function() {
+ opts.cloneArgs = true;
+ };
+
+ }
+
+ return CallTracker;
+};
+
+getJasmineRequireObj().clearStack = function(j$) {
+ var maxInlineCallCount = 10;
+
+ function messageChannelImpl(global, setTimeout) {
+ var channel = new global.MessageChannel(),
+ head = {},
+ tail = head;
+
+ var taskRunning = false;
+ channel.port1.onmessage = function() {
+ head = head.next;
+ var task = head.task;
+ delete head.task;
+
+ if (taskRunning) {
+ global.setTimeout(task, 0);
+ } else {
+ try {
+ taskRunning = true;
+ task();
+ } finally {
+ taskRunning = false;
+ }
+ }
+ };
+
+ var currentCallCount = 0;
+ return function clearStack(fn) {
+ currentCallCount++;
+
+ if (currentCallCount < maxInlineCallCount) {
+ tail = tail.next = { task: fn };
+ channel.port2.postMessage(0);
+ } else {
+ currentCallCount = 0;
+ setTimeout(fn);
+ }
+ };
+ }
+
+ function getClearStack(global) {
+ var currentCallCount = 0;
+ var realSetTimeout = global.setTimeout;
+ var setTimeoutImpl = function clearStack(fn) {
+ Function.prototype.apply.apply(realSetTimeout, [global, [fn, 0]]);
+ };
+
+ if (j$.isFunction_(global.setImmediate)) {
+ var realSetImmediate = global.setImmediate;
+ return function(fn) {
+ currentCallCount++;
+
+ if (currentCallCount < maxInlineCallCount) {
+ realSetImmediate(fn);
+ } else {
+ currentCallCount = 0;
+
+ setTimeoutImpl(fn);
+ }
+ };
+ } else if (!j$.util.isUndefined(global.MessageChannel)) {
+ return messageChannelImpl(global, setTimeoutImpl);
+ } else {
+ return setTimeoutImpl;
+ }
+ }
+
+ return getClearStack;
+};
+
+getJasmineRequireObj().Clock = function() {
+
+ var NODE_JS = typeof process !== 'undefined' && process.versions && typeof process.versions.node === 'string';
+
+ /**
+ * _Note:_ Do not construct this directly, Jasmine will make one during booting. You can get the current clock with {@link jasmine.clock}.
+ * @class Clock
+ * @classdesc Jasmine's mock clock is used when testing time dependent code.
+ */
+ function Clock(global, delayedFunctionSchedulerFactory, mockDate) {
+ var self = this,
+ realTimingFunctions = {
+ setTimeout: global.setTimeout,
+ clearTimeout: global.clearTimeout,
+ setInterval: global.setInterval,
+ clearInterval: global.clearInterval
+ },
+ fakeTimingFunctions = {
+ setTimeout: setTimeout,
+ clearTimeout: clearTimeout,
+ setInterval: setInterval,
+ clearInterval: clearInterval
+ },
+ installed = false,
+ delayedFunctionScheduler,
+ timer;
+
+ self.FakeTimeout = FakeTimeout;
+
+ /**
+ * Install the mock clock over the built-in methods.
+ * @name Clock#install
+ * @function
+ * @return {Clock}
+ */
+ self.install = function() {
+ if(!originalTimingFunctionsIntact()) {
+ throw new Error('Jasmine Clock was unable to install over custom global timer functions. Is the clock already installed?');
+ }
+ replace(global, fakeTimingFunctions);
+ timer = fakeTimingFunctions;
+ delayedFunctionScheduler = delayedFunctionSchedulerFactory();
+ installed = true;
+
+ return self;
+ };
+
+ /**
+ * Uninstall the mock clock, returning the built-in methods to their places.
+ * @name Clock#uninstall
+ * @function
+ */
+ self.uninstall = function() {
+ delayedFunctionScheduler = null;
+ mockDate.uninstall();
+ replace(global, realTimingFunctions);
+
+ timer = realTimingFunctions;
+ installed = false;
+ };
+
+ /**
+ * Execute a function with a mocked Clock
+ *
+ * The clock will be {@link Clock#install|install}ed before the function is called and {@link Clock#uninstall|uninstall}ed in a `finally` after the function completes.
+ * @name Clock#withMock
+ * @function
+ * @param {closure} Function The function to be called.
+ */
+ self.withMock = function(closure) {
+ this.install();
+ try {
+ closure();
+ } finally {
+ this.uninstall();
+ }
+ };
+
+ /**
+ * Instruct the installed Clock to also mock the date returned by `new Date()`
+ * @name Clock#mockDate
+ * @function
+ * @param {Date} [initialDate=now] The `Date` to provide.
+ */
+ self.mockDate = function(initialDate) {
+ mockDate.install(initialDate);
+ };
+
+ self.setTimeout = function(fn, delay, params) {
+ if (legacyIE()) {
+ if (arguments.length > 2) {
+ throw new Error('IE < 9 cannot support extra params to setTimeout without a polyfill');
+ }
+ return timer.setTimeout(fn, delay);
+ }
+ return Function.prototype.apply.apply(timer.setTimeout, [global, arguments]);
+ };
+
+ self.setInterval = function(fn, delay, params) {
+ if (legacyIE()) {
+ if (arguments.length > 2) {
+ throw new Error('IE < 9 cannot support extra params to setInterval without a polyfill');
+ }
+ return timer.setInterval(fn, delay);
+ }
+ return Function.prototype.apply.apply(timer.setInterval, [global, arguments]);
+ };
+
+ self.clearTimeout = function(id) {
+ return Function.prototype.call.apply(timer.clearTimeout, [global, id]);
+ };
+
+ self.clearInterval = function(id) {
+ return Function.prototype.call.apply(timer.clearInterval, [global, id]);
+ };
+
+ /**
+ * Tick the Clock forward, running any enqueued timeouts along the way
+ * @name Clock#tick
+ * @function
+ * @param {int} millis The number of milliseconds to tick.
+ */
+ self.tick = function(millis) {
+ if (installed) {
+ delayedFunctionScheduler.tick(millis, function(millis) { mockDate.tick(millis); });
+ } else {
+ throw new Error('Mock clock is not installed, use jasmine.clock().install()');
+ }
+ };
+
+ return self;
+
+ function originalTimingFunctionsIntact() {
+ return global.setTimeout === realTimingFunctions.setTimeout &&
+ global.clearTimeout === realTimingFunctions.clearTimeout &&
+ global.setInterval === realTimingFunctions.setInterval &&
+ global.clearInterval === realTimingFunctions.clearInterval;
+ }
+
+ function legacyIE() {
+ //if these methods are polyfilled, apply will be present
+ return !(realTimingFunctions.setTimeout || realTimingFunctions.setInterval).apply;
+ }
+
+ function replace(dest, source) {
+ for (var prop in source) {
+ dest[prop] = source[prop];
+ }
+ }
+
+ function setTimeout(fn, delay) {
+ if (!NODE_JS) {
+ return delayedFunctionScheduler.scheduleFunction(fn, delay, argSlice(arguments, 2));
+ }
+
+ var timeout = new FakeTimeout();
+
+ delayedFunctionScheduler.scheduleFunction(fn, delay, argSlice(arguments, 2), false, timeout);
+
+ return timeout;
+ }
+
+ function clearTimeout(id) {
+ return delayedFunctionScheduler.removeFunctionWithId(id);
+ }
+
+ function setInterval(fn, interval) {
+ if (!NODE_JS) {
+ return delayedFunctionScheduler.scheduleFunction(fn, interval, argSlice(arguments, 2), true);
+ }
+
+ var timeout = new FakeTimeout();
+
+ delayedFunctionScheduler.scheduleFunction(fn, interval, argSlice(arguments, 2), true, timeout);
+
+ return timeout;
+ }
+
+ function clearInterval(id) {
+ return delayedFunctionScheduler.removeFunctionWithId(id);
+ }
+
+ function argSlice(argsObj, n) {
+ return Array.prototype.slice.call(argsObj, n);
+ }
+ }
+
+ /**
+ * Mocks Node.js Timeout class
+ */
+ function FakeTimeout() {}
+
+ FakeTimeout.prototype.ref = function () {
+ return this;
+ };
+
+ FakeTimeout.prototype.unref = function () {
+ return this;
+ };
+
+ return Clock;
+};
+
+getJasmineRequireObj().DelayedFunctionScheduler = function(j$) {
+ function DelayedFunctionScheduler() {
+ var self = this;
+ var scheduledLookup = [];
+ var scheduledFunctions = {};
+ var currentTime = 0;
+ var delayedFnCount = 0;
+ var deletedKeys = [];
+
+ self.tick = function(millis, tickDate) {
+ millis = millis || 0;
+ var endTime = currentTime + millis;
+
+ runScheduledFunctions(endTime, tickDate);
+ currentTime = endTime;
+ };
+
+ self.scheduleFunction = function(funcToCall, millis, params, recurring, timeoutKey, runAtMillis) {
+ var f;
+ if (typeof(funcToCall) === 'string') {
+ /* jshint evil: true */
+ f = function() { return eval(funcToCall); };
+ /* jshint evil: false */
+ } else {
+ f = funcToCall;
+ }
+
+ millis = millis || 0;
+ timeoutKey = timeoutKey || ++delayedFnCount;
+ runAtMillis = runAtMillis || (currentTime + millis);
+
+ var funcToSchedule = {
+ runAtMillis: runAtMillis,
+ funcToCall: f,
+ recurring: recurring,
+ params: params,
+ timeoutKey: timeoutKey,
+ millis: millis
+ };
+
+ if (runAtMillis in scheduledFunctions) {
+ scheduledFunctions[runAtMillis].push(funcToSchedule);
+ } else {
+ scheduledFunctions[runAtMillis] = [funcToSchedule];
+ scheduledLookup.push(runAtMillis);
+ scheduledLookup.sort(function (a, b) {
+ return a - b;
+ });
+ }
+
+ return timeoutKey;
+ };
+
+ self.removeFunctionWithId = function(timeoutKey) {
+ deletedKeys.push(timeoutKey);
+
+ for (var runAtMillis in scheduledFunctions) {
+ var funcs = scheduledFunctions[runAtMillis];
+ var i = indexOfFirstToPass(funcs, function (func) {
+ return func.timeoutKey === timeoutKey;
+ });
+
+ if (i > -1) {
+ if (funcs.length === 1) {
+ delete scheduledFunctions[runAtMillis];
+ deleteFromLookup(runAtMillis);
+ } else {
+ funcs.splice(i, 1);
+ }
+
+ // intervals get rescheduled when executed, so there's never more
+ // than a single scheduled function with a given timeoutKey
+ break;
+ }
+ }
+ };
+
+ return self;
+
+ function indexOfFirstToPass(array, testFn) {
+ var index = -1;
+
+ for (var i = 0; i < array.length; ++i) {
+ if (testFn(array[i])) {
+ index = i;
+ break;
+ }
+ }
+
+ return index;
+ }
+
+ function deleteFromLookup(key) {
+ var value = Number(key);
+ var i = indexOfFirstToPass(scheduledLookup, function (millis) {
+ return millis === value;
+ });
+
+ if (i > -1) {
+ scheduledLookup.splice(i, 1);
+ }
+ }
+
+ function reschedule(scheduledFn) {
+ self.scheduleFunction(scheduledFn.funcToCall,
+ scheduledFn.millis,
+ scheduledFn.params,
+ true,
+ scheduledFn.timeoutKey,
+ scheduledFn.runAtMillis + scheduledFn.millis);
+ }
+
+ function forEachFunction(funcsToRun, callback) {
+ for (var i = 0; i < funcsToRun.length; ++i) {
+ callback(funcsToRun[i]);
+ }
+ }
+
+ function runScheduledFunctions(endTime, tickDate) {
+ tickDate = tickDate || function() {};
+ if (scheduledLookup.length === 0 || scheduledLookup[0] > endTime) {
+ tickDate(endTime - currentTime);
+ return;
+ }
+
+ do {
+ deletedKeys = [];
+ var newCurrentTime = scheduledLookup.shift();
+ tickDate(newCurrentTime - currentTime);
+
+ currentTime = newCurrentTime;
+
+ var funcsToRun = scheduledFunctions[currentTime];
+
+ delete scheduledFunctions[currentTime];
+
+ forEachFunction(funcsToRun, function(funcToRun) {
+ if (funcToRun.recurring) {
+ reschedule(funcToRun);
+ }
+ });
+
+ forEachFunction(funcsToRun, function(funcToRun) {
+ if (j$.util.arrayContains(deletedKeys, funcToRun.timeoutKey)) {
+ // skip a timeoutKey deleted whilst we were running
+ return;
+ }
+ funcToRun.funcToCall.apply(null, funcToRun.params || []);
+ });
+ } while (scheduledLookup.length > 0 &&
+ // checking first if we're out of time prevents setTimeout(0)
+ // scheduled in a funcToRun from forcing an extra iteration
+ currentTime !== endTime &&
+ scheduledLookup[0] <= endTime);
+
+ // ran out of functions to call, but still time left on the clock
+ if (currentTime !== endTime) {
+ tickDate(endTime - currentTime);
+ }
+ }
+ }
+
+ return DelayedFunctionScheduler;
+};
+
+getJasmineRequireObj().errors = function() {
+ function ExpectationFailed() {}
+
+ ExpectationFailed.prototype = new Error();
+ ExpectationFailed.prototype.constructor = ExpectationFailed;
+
+ return {
+ ExpectationFailed: ExpectationFailed
+ };
+};
+getJasmineRequireObj().ExceptionFormatter = function() {
+ function ExceptionFormatter() {
+ this.message = function(error) {
+ var message = '';
+
+ if (error.name && error.message) {
+ message += error.name + ': ' + error.message;
+ } else {
+ message += error.toString() + ' thrown';
+ }
+
+ if (error.fileName || error.sourceURL) {
+ message += ' in ' + (error.fileName || error.sourceURL);
+ }
+
+ if (error.line || error.lineNumber) {
+ message += ' (line ' + (error.line || error.lineNumber) + ')';
+ }
+
+ return message;
+ };
+
+ this.stack = function(error) {
+ return error ? error.stack : null;
+ };
+ }
+
+ return ExceptionFormatter;
+};
+
+getJasmineRequireObj().Expectation = function() {
+
+ /**
+ * Matchers that come with Jasmine out of the box.
+ * @namespace matchers
+ */
+ function Expectation(options) {
+ this.util = options.util || { buildFailureMessage: function() {} };
+ this.customEqualityTesters = options.customEqualityTesters || [];
+ this.actual = options.actual;
+ this.addExpectationResult = options.addExpectationResult || function(){};
+ this.isNot = options.isNot;
+
+ var customMatchers = options.customMatchers || {};
+ for (var matcherName in customMatchers) {
+ this[matcherName] = Expectation.prototype.wrapCompare(matcherName, customMatchers[matcherName]);
+ }
+ }
+
+ Expectation.prototype.wrapCompare = function(name, matcherFactory) {
+ return function() {
+ var args = Array.prototype.slice.call(arguments, 0),
+ expected = args.slice(0),
+ message = '';
+
+ args.unshift(this.actual);
+
+ var matcher = matcherFactory(this.util, this.customEqualityTesters),
+ matcherCompare = matcher.compare;
+
+ function defaultNegativeCompare() {
+ var result = matcher.compare.apply(null, args);
+ result.pass = !result.pass;
+ return result;
+ }
+
+ if (this.isNot) {
+ matcherCompare = matcher.negativeCompare || defaultNegativeCompare;
+ }
+
+ var result = matcherCompare.apply(null, args);
+
+ if (!result.pass) {
+ if (!result.message) {
+ args.unshift(this.isNot);
+ args.unshift(name);
+ message = this.util.buildFailureMessage.apply(null, args);
+ } else {
+ if (Object.prototype.toString.apply(result.message) === '[object Function]') {
+ message = result.message();
+ } else {
+ message = result.message;
+ }
+ }
+ }
+
+ if (expected.length == 1) {
+ expected = expected[0];
+ }
+
+ // TODO: how many of these params are needed?
+ this.addExpectationResult(
+ result.pass,
+ {
+ matcherName: name,
+ passed: result.pass,
+ message: message,
+ error: result.error,
+ actual: this.actual,
+ expected: expected // TODO: this may need to be arrayified/sliced
+ }
+ );
+ };
+ };
+
+ Expectation.addCoreMatchers = function(matchers) {
+ var prototype = Expectation.prototype;
+ for (var matcherName in matchers) {
+ var matcher = matchers[matcherName];
+ prototype[matcherName] = prototype.wrapCompare(matcherName, matcher);
+ }
+ };
+
+ Expectation.Factory = function(options) {
+ options = options || {};
+
+ var expect = new Expectation(options);
+
+ // TODO: this would be nice as its own Object - NegativeExpectation
+ // TODO: copy instead of mutate options
+ options.isNot = true;
+ expect.not = new Expectation(options);
+
+ return expect;
+ };
+
+ return Expectation;
+};
+
+//TODO: expectation result may make more sense as a presentation of an expectation.
+getJasmineRequireObj().buildExpectationResult = function() {
+ function buildExpectationResult(options) {
+ var messageFormatter = options.messageFormatter || function() {},
+ stackFormatter = options.stackFormatter || function() {};
+
+ /**
+ * @typedef Expectation
+ * @property {String} matcherName - The name of the matcher that was executed for this expectation.
+ * @property {String} message - The failure message for the expectation.
+ * @property {String} stack - The stack trace for the failure if available.
+ * @property {Boolean} passed - Whether the expectation passed or failed.
+ * @property {Object} expected - If the expectation failed, what was the expected value.
+ * @property {Object} actual - If the expectation failed, what actual value was produced.
+ */
+ var result = {
+ matcherName: options.matcherName,
+ message: message(),
+ stack: stack(),
+ passed: options.passed
+ };
+
+ if(!result.passed) {
+ result.expected = options.expected;
+ result.actual = options.actual;
+ }
+
+ return result;
+
+ function message() {
+ if (options.passed) {
+ return 'Passed.';
+ } else if (options.message) {
+ return options.message;
+ } else if (options.error) {
+ return messageFormatter(options.error);
+ }
+ return '';
+ }
+
+ function stack() {
+ if (options.passed) {
+ return '';
+ }
+
+ var error = options.error;
+ if (!error) {
+ try {
+ throw new Error(message());
+ } catch (e) {
+ error = e;
+ }
+ }
+ return stackFormatter(error);
+ }
+ }
+
+ return buildExpectationResult;
+};
+
+getJasmineRequireObj().formatErrorMsg = function() {
+ function generateErrorMsg(domain, usage) {
+ var usageDefinition = usage ? '\nUsage: ' + usage : '';
+
+ return function errorMsg(msg) {
+ return domain + ' : ' + msg + usageDefinition;
+ };
+ }
+
+ return generateErrorMsg;
+};
+
+getJasmineRequireObj().GlobalErrors = function(j$) {
+ function GlobalErrors(global) {
+ var handlers = [];
+ global = global || j$.getGlobal();
+
+ var onerror = function onerror() {
+ var handler = handlers[handlers.length - 1];
+
+ if (handler) {
+ handler.apply(null, Array.prototype.slice.call(arguments, 0));
+ } else {
+ throw arguments[0];
+ }
+ };
+
+ this.uninstall = function noop() {};
+
+ this.install = function install() {
+ if (global.process && global.process.listeners && j$.isFunction_(global.process.on)) {
+ var originalHandlers = global.process.listeners('uncaughtException');
+ global.process.removeAllListeners('uncaughtException');
+ global.process.on('uncaughtException', onerror);
+
+ this.uninstall = function uninstall() {
+ global.process.removeListener('uncaughtException', onerror);
+ for (var i = 0; i < originalHandlers.length; i++) {
+ global.process.on('uncaughtException', originalHandlers[i]);
+ }
+ };
+ } else {
+ var originalHandler = global.onerror;
+ global.onerror = onerror;
+
+ this.uninstall = function uninstall() {
+ global.onerror = originalHandler;
+ };
+ }
+ };
+
+ this.pushListener = function pushListener(listener) {
+ handlers.push(listener);
+ };
+
+ this.popListener = function popListener() {
+ handlers.pop();
+ };
+ }
+
+ return GlobalErrors;
+};
+
+getJasmineRequireObj().DiffBuilder = function(j$) {
+ return function DiffBuilder() {
+ var path = new j$.ObjectPath(),
+ mismatches = [];
+
+ return {
+ record: function (actual, expected, formatter) {
+ formatter = formatter || defaultFormatter;
+ mismatches.push(formatter(actual, expected, path));
+ },
+
+ getMessage: function () {
+ return mismatches.join('\n');
+ },
+
+ withPath: function (pathComponent, block) {
+ var oldPath = path;
+ path = path.add(pathComponent);
+ block();
+ path = oldPath;
+ }
+ };
+
+ function defaultFormatter (actual, expected, path) {
+ return 'Expected ' +
+ path + (path.depth() ? ' = ' : '') +
+ j$.pp(actual) +
+ ' to equal ' +
+ j$.pp(expected) +
+ '.';
+ }
+ };
+};
+
+getJasmineRequireObj().matchersUtil = function(j$) {
+ // TODO: what to do about jasmine.pp not being inject? move to JSON.stringify? gut PrettyPrinter?
+
+ return {
+ equals: equals,
+
+ contains: function(haystack, needle, customTesters) {
+ customTesters = customTesters || [];
+
+ if ((Object.prototype.toString.apply(haystack) === '[object Set]')) {
+ return haystack.has(needle);
+ }
+
+ if ((Object.prototype.toString.apply(haystack) === '[object Array]') ||
+ (!!haystack && !haystack.indexOf))
+ {
+ for (var i = 0; i < haystack.length; i++) {
+ if (equals(haystack[i], needle, customTesters)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ return !!haystack && haystack.indexOf(needle) >= 0;
+ },
+
+ buildFailureMessage: function() {
+ var args = Array.prototype.slice.call(arguments, 0),
+ matcherName = args[0],
+ isNot = args[1],
+ actual = args[2],
+ expected = args.slice(3),
+ englishyPredicate = matcherName.replace(/[A-Z]/g, function(s) { return ' ' + s.toLowerCase(); });
+
+ var message = 'Expected ' +
+ j$.pp(actual) +
+ (isNot ? ' not ' : ' ') +
+ englishyPredicate;
+
+ if (expected.length > 0) {
+ for (var i = 0; i < expected.length; i++) {
+ if (i > 0) {
+ message += ',';
+ }
+ message += ' ' + j$.pp(expected[i]);
+ }
+ }
+
+ return message + '.';
+ }
+ };
+
+ function isAsymmetric(obj) {
+ return obj && j$.isA_('Function', obj.asymmetricMatch);
+ }
+
+ function asymmetricMatch(a, b, customTesters, diffBuilder) {
+ var asymmetricA = isAsymmetric(a),
+ asymmetricB = isAsymmetric(b),
+ result;
+
+ if (asymmetricA && asymmetricB) {
+ return undefined;
+ }
+
+ if (asymmetricA) {
+ result = a.asymmetricMatch(b, customTesters);
+ if (!result) {
+ diffBuilder.record(a, b);
+ }
+ return result;
+ }
+
+ if (asymmetricB) {
+ result = b.asymmetricMatch(a, customTesters);
+ if (!result) {
+ diffBuilder.record(a, b);
+ }
+ return result;
+ }
+ }
+
+ function equals(a, b, customTesters, diffBuilder) {
+ customTesters = customTesters || [];
+ diffBuilder = diffBuilder || j$.NullDiffBuilder();
+
+ return eq(a, b, [], [], customTesters, diffBuilder);
+ }
+
+ // Equality function lovingly adapted from isEqual in
+ // [Underscore](http://underscorejs.org)
+ function eq(a, b, aStack, bStack, customTesters, diffBuilder) {
+ var result = true, i;
+
+ var asymmetricResult = asymmetricMatch(a, b, customTesters, diffBuilder);
+ if (!j$.util.isUndefined(asymmetricResult)) {
+ return asymmetricResult;
+ }
+
+ for (i = 0; i < customTesters.length; i++) {
+ var customTesterResult = customTesters[i](a, b);
+ if (!j$.util.isUndefined(customTesterResult)) {
+ if (!customTesterResult) {
+ diffBuilder.record(a, b);
+ }
+ return customTesterResult;
+ }
+ }
+
+ if (a instanceof Error && b instanceof Error) {
+ result = a.message == b.message;
+ if (!result) {
+ diffBuilder.record(a, b);
+ }
+ return result;
+ }
+
+ // Identical objects are equal. `0 === -0`, but they aren't identical.
+ // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
+ if (a === b) {
+ result = a !== 0 || 1 / a == 1 / b;
+ if (!result) {
+ diffBuilder.record(a, b);
+ }
+ return result;
+ }
+ // A strict comparison is necessary because `null == undefined`.
+ if (a === null || b === null) {
+ result = a === b;
+ if (!result) {
+ diffBuilder.record(a, b);
+ }
+ return result;
+ }
+ var className = Object.prototype.toString.call(a);
+ if (className != Object.prototype.toString.call(b)) {
+ diffBuilder.record(a, b);
+ return false;
+ }
+ switch (className) {
+ // Strings, numbers, dates, and booleans are compared by value.
+ case '[object String]':
+ // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
+ // equivalent to `new String("5")`.
+ result = a == String(b);
+ if (!result) {
+ diffBuilder.record(a, b);
+ }
+ return result;
+ case '[object Number]':
+ // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for
+ // other numeric values.
+ result = a != +a ? b != +b : (a === 0 ? 1 / a == 1 / b : a == +b);
+ if (!result) {
+ diffBuilder.record(a, b);
+ }
+ return result;
+ case '[object Date]':
+ case '[object Boolean]':
+ // Coerce dates and booleans to numeric primitive values. Dates are compared by their
+ // millisecond representations. Note that invalid dates with millisecond representations
+ // of `NaN` are not equivalent.
+ result = +a == +b;
+ if (!result) {
+ diffBuilder.record(a, b);
+ }
+ return result;
+ // RegExps are compared by their source patterns and flags.
+ case '[object RegExp]':
+ return a.source == b.source &&
+ a.global == b.global &&
+ a.multiline == b.multiline &&
+ a.ignoreCase == b.ignoreCase;
+ }
+ if (typeof a != 'object' || typeof b != 'object') {
+ diffBuilder.record(a, b);
+ return false;
+ }
+
+ var aIsDomNode = j$.isDomNode(a);
+ var bIsDomNode = j$.isDomNode(b);
+ if (aIsDomNode && bIsDomNode) {
+ // At first try to use DOM3 method isEqualNode
+ if (a.isEqualNode) {
+ result = a.isEqualNode(b);
+ if (!result) {
+ diffBuilder.record(a, b);
+ }
+ return result;
+ }
+ // IE8 doesn't support isEqualNode, try to use outerHTML && innerText
+ var aIsElement = a instanceof Element;
+ var bIsElement = b instanceof Element;
+ if (aIsElement && bIsElement) {
+ result = a.outerHTML == b.outerHTML;
+ if (!result) {
+ diffBuilder.record(a, b);
+ }
+ return result;
+ }
+ if (aIsElement || bIsElement) {
+ diffBuilder.record(a, b);
+ return false;
+ }
+ result = a.innerText == b.innerText && a.textContent == b.textContent;
+ if (!result) {
+ diffBuilder.record(a, b);
+ }
+ return result;
+ }
+ if (aIsDomNode || bIsDomNode) {
+ diffBuilder.record(a, b);
+ return false;
+ }
+
+ var aIsPromise = j$.isPromise(a);
+ var bIsPromise = j$.isPromise(b);
+ if (aIsPromise && bIsPromise) {
+ return a === b;
+ }
+
+ // Assume equality for cyclic structures. The algorithm for detecting cyclic
+ // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
+ var length = aStack.length;
+ while (length--) {
+ // Linear search. Performance is inversely proportional to the number of
+ // unique nested structures.
+ if (aStack[length] == a) { return bStack[length] == b; }
+ }
+ // Add the first object to the stack of traversed objects.
+ aStack.push(a);
+ bStack.push(b);
+ var size = 0;
+ // Recursively compare objects and arrays.
+ // Compare array lengths to determine if a deep comparison is necessary.
+ if (className == '[object Array]') {
+ var aLength = a.length;
+ var bLength = b.length;
+
+ diffBuilder.withPath('length', function() {
+ if (aLength !== bLength) {
+ diffBuilder.record(aLength, bLength);
+ result = false;
+ }
+ });
+
+ for (i = 0; i < aLength || i < bLength; i++) {
+ diffBuilder.withPath(i, function() {
+ result = eq(i < aLength ? a[i] : void 0, i < bLength ? b[i] : void 0, aStack, bStack, customTesters, diffBuilder) && result;
+ });
+ }
+ if (!result) {
+ return false;
+ }
+ } else if (j$.isMap(a) && j$.isMap(b)) {
+ if (a.size != b.size) {
+ diffBuilder.record(a, b);
+ return false;
+ }
+
+ var keysA = [];
+ var keysB = [];
+ a.forEach( function( valueA, keyA ) {
+ keysA.push( keyA );
+ });
+ b.forEach( function( valueB, keyB ) {
+ keysB.push( keyB );
+ });
+
+ // For both sets of keys, check they map to equal values in both maps.
+ // Keep track of corresponding keys (in insertion order) in order to handle asymmetric obj keys.
+ var mapKeys = [keysA, keysB];
+ var cmpKeys = [keysB, keysA];
+ var mapIter, mapKey, mapValueA, mapValueB;
+ var cmpIter, cmpKey;
+ for (i = 0; result && i < mapKeys.length; i++) {
+ mapIter = mapKeys[i];
+ cmpIter = cmpKeys[i];
+
+ for (var j = 0; result && j < mapIter.length; j++) {
+ mapKey = mapIter[j];
+ cmpKey = cmpIter[j];
+ mapValueA = a.get(mapKey);
+
+ // Only use the cmpKey when one of the keys is asymmetric and the corresponding key matches,
+ // otherwise explicitly look up the mapKey in the other Map since we want keys with unique
+ // obj identity (that are otherwise equal) to not match.
+ if (isAsymmetric(mapKey) || isAsymmetric(cmpKey) &&
+ eq(mapKey, cmpKey, aStack, bStack, customTesters, j$.NullDiffBuilder())) {
+ mapValueB = b.get(cmpKey);
+ } else {
+ mapValueB = b.get(mapKey);
+ }
+ result = eq(mapValueA, mapValueB, aStack, bStack, customTesters, j$.NullDiffBuilder());
+ }
+ }
+
+ if (!result) {
+ diffBuilder.record(a, b);
+ return false;
+ }
+ } else if (j$.isSet(a) && j$.isSet(b)) {
+ if (a.size != b.size) {
+ diffBuilder.record(a, b);
+ return false;
+ }
+
+ var valuesA = [];
+ a.forEach( function( valueA ) {
+ valuesA.push( valueA );
+ });
+ var valuesB = [];
+ b.forEach( function( valueB ) {
+ valuesB.push( valueB );
+ });
+
+ // For both sets, check they are all contained in the other set
+ var setPairs = [[valuesA, valuesB], [valuesB, valuesA]];
+ var stackPairs = [[aStack, bStack], [bStack, aStack]];
+ var baseValues, baseValue, baseStack;
+ var otherValues, otherValue, otherStack;
+ var found;
+ var prevStackSize;
+ for (i = 0; result && i < setPairs.length; i++) {
+ baseValues = setPairs[i][0];
+ otherValues = setPairs[i][1];
+ baseStack = stackPairs[i][0];
+ otherStack = stackPairs[i][1];
+ // For each value in the base set...
+ for (var k = 0; result && k < baseValues.length; k++) {
+ baseValue = baseValues[k];
+ found = false;
+ // ... test that it is present in the other set
+ for (var l = 0; !found && l < otherValues.length; l++) {
+ otherValue = otherValues[l];
+ prevStackSize = baseStack.length;
+ // compare by value equality
+ found = eq(baseValue, otherValue, baseStack, otherStack, customTesters, j$.NullDiffBuilder());
+ if (!found && prevStackSize !== baseStack.length) {
+ baseStack.splice(prevStackSize);
+ otherStack.splice(prevStackSize);
+ }
+ }
+ result = result && found;
+ }
+ }
+
+ if (!result) {
+ diffBuilder.record(a, b);
+ return false;
+ }
+ } else {
+
+ // Objects with different constructors are not equivalent, but `Object`s
+ // or `Array`s from different frames are.
+ var aCtor = a.constructor, bCtor = b.constructor;
+ if (aCtor !== bCtor &&
+ isFunction(aCtor) && isFunction(bCtor) &&
+ a instanceof aCtor && b instanceof bCtor &&
+ !(aCtor instanceof aCtor && bCtor instanceof bCtor)) {
+
+ diffBuilder.record(a, b, constructorsAreDifferentFormatter);
+ return false;
+ }
+ }
+
+ // Deep compare objects.
+ var aKeys = keys(a, className == '[object Array]'), key;
+ size = aKeys.length;
+
+ // Ensure that both objects contain the same number of properties before comparing deep equality.
+ if (keys(b, className == '[object Array]').length !== size) {
+ diffBuilder.record(a, b, objectKeysAreDifferentFormatter);
+ return false;
+ }
+
+ for (i = 0; i < size; i++) {
+ key = aKeys[i];
+ // Deep compare each member
+ if (!j$.util.has(b, key)) {
+ diffBuilder.record(a, b, objectKeysAreDifferentFormatter);
+ result = false;
+ continue;
+ }
+
+ diffBuilder.withPath(key, function() {
+ if(!eq(a[key], b[key], aStack, bStack, customTesters, diffBuilder)) {
+ result = false;
+ }
+ });
+ }
+
+ if (!result) {
+ return false;
+ }
+
+ // Remove the first object from the stack of traversed objects.
+ aStack.pop();
+ bStack.pop();
+
+ return result;
+ }
+
+ function keys(obj, isArray) {
+ var allKeys = Object.keys ? Object.keys(obj) :
+ (function(o) {
+ var keys = [];
+ for (var key in o) {
+ if (j$.util.has(o, key)) {
+ keys.push(key);
+ }
+ }
+ return keys;
+ })(obj);
+
+ if (!isArray) {
+ return allKeys;
+ }
+
+ if (allKeys.length === 0) {
+ return allKeys;
+ }
+
+ var extraKeys = [];
+ for (var i = 0; i < allKeys.length; i++) {
+ if (!/^[0-9]+$/.test(allKeys[i])) {
+ extraKeys.push(allKeys[i]);
+ }
+ }
+
+ return extraKeys;
+ }
+
+ function has(obj, key) {
+ return Object.prototype.hasOwnProperty.call(obj, key);
+ }
+
+ function isFunction(obj) {
+ return typeof obj === 'function';
+ }
+
+ function objectKeysAreDifferentFormatter(actual, expected, path) {
+ var missingProperties = j$.util.objectDifference(expected, actual),
+ extraProperties = j$.util.objectDifference(actual, expected),
+ missingPropertiesMessage = formatKeyValuePairs(missingProperties),
+ extraPropertiesMessage = formatKeyValuePairs(extraProperties),
+ messages = [];
+
+ if (!path.depth()) {
+ path = 'object';
+ }
+
+ if (missingPropertiesMessage.length) {
+ messages.push('Expected ' + path + ' to have properties' + missingPropertiesMessage);
+ }
+
+ if (extraPropertiesMessage.length) {
+ messages.push('Expected ' + path + ' not to have properties' + extraPropertiesMessage);
+ }
+
+ return messages.join('\n');
+ }
+
+ function constructorsAreDifferentFormatter(actual, expected, path) {
+ if (!path.depth()) {
+ path = 'object';
+ }
+
+ return 'Expected ' +
+ path + ' to be a kind of ' +
+ j$.fnNameFor(expected.constructor) +
+ ', but was ' + j$.pp(actual) + '.';
+ }
+
+ function formatKeyValuePairs(obj) {
+ var formatted = '';
+ for (var key in obj) {
+ formatted += '\n ' + key + ': ' + j$.pp(obj[key]);
+ }
+ return formatted;
+ }
+};
+
+getJasmineRequireObj().nothing = function() {
+ /**
+ * {@link expect} nothing explicitly.
+ * @function
+ * @name matchers#nothing
+ * @example
+ * expect().nothing();
+ */
+ function nothing() {
+ return {
+ compare: function() {
+ return {
+ pass: true
+ };
+ }
+ };
+ }
+
+ return nothing;
+};
+
+getJasmineRequireObj().NullDiffBuilder = function(j$) {
+ return function() {
+ return {
+ withPath: function(_, block) {
+ block();
+ },
+ record: function() {}
+ };
+ };
+};
+
+getJasmineRequireObj().ObjectPath = function(j$) {
+ function ObjectPath(components) {
+ this.components = components || [];
+ }
+
+ ObjectPath.prototype.toString = function() {
+ if (this.components.length) {
+ return '$' + map(this.components, formatPropertyAccess).join('');
+ } else {
+ return '';
+ }
+ };
+
+ ObjectPath.prototype.add = function(component) {
+ return new ObjectPath(this.components.concat([component]));
+ };
+
+ ObjectPath.prototype.depth = function() {
+ return this.components.length;
+ };
+
+ function formatPropertyAccess(prop) {
+ if (typeof prop === 'number') {
+ return '[' + prop + ']';
+ }
+
+ if (isValidIdentifier(prop)) {
+ return '.' + prop;
+ }
+
+ return '[\'' + prop + '\']';
+ }
+
+ function map(array, fn) {
+ var results = [];
+ for (var i = 0; i < array.length; i++) {
+ results.push(fn(array[i]));
+ }
+ return results;
+ }
+
+ function isValidIdentifier(string) {
+ return /^[A-Za-z\$_][A-Za-z0-9\$_]*$/.test(string);
+ }
+
+ return ObjectPath;
+};
+
+getJasmineRequireObj().toBe = function() {
+ /**
+ * {@link expect} the actual value to be `===` to the expected value.
+ * @function
+ * @name matchers#toBe
+ * @param {Object} expected - The expected value to compare against.
+ * @example
+ * expect(thing).toBe(realThing);
+ */
+ function toBe() {
+ return {
+ compare: function(actual, expected) {
+ return {
+ pass: actual === expected
+ };
+ }
+ };
+ }
+
+ return toBe;
+};
+
+getJasmineRequireObj().toBeCloseTo = function() {
+ /**
+ * {@link expect} the actual value to be within a specified precision of the expected value.
+ * @function
+ * @name matchers#toBeCloseTo
+ * @param {Object} expected - The expected value to compare against.
+ * @param {Number} [precision=2] - The number of decimal points to check.
+ * @example
+ * expect(number).toBeCloseTo(42.2, 3);
+ */
+ function toBeCloseTo() {
+ return {
+ compare: function(actual, expected, precision) {
+ if (precision !== 0) {
+ precision = precision || 2;
+ }
+
+ if (expected === null || actual === null) {
+ throw new Error('Cannot use toBeCloseTo with null. Arguments evaluated to: ' +
+ 'expect(' + actual + ').toBeCloseTo(' + expected + ').'
+ );
+ }
+
+ var pow = Math.pow(10, precision + 1);
+ var delta = Math.abs(expected - actual);
+ var maxDelta = Math.pow(10, -precision) / 2;
+
+ return {
+ pass: Math.round(delta * pow) / pow <= maxDelta
+ };
+ }
+ };
+ }
+
+ return toBeCloseTo;
+};
+
+getJasmineRequireObj().toBeDefined = function() {
+ /**
+ * {@link expect} the actual value to be defined. (Not `undefined`)
+ * @function
+ * @name matchers#toBeDefined
+ * @example
+ * expect(result).toBeDefined();
+ */
+ function toBeDefined() {
+ return {
+ compare: function(actual) {
+ return {
+ pass: (void 0 !== actual)
+ };
+ }
+ };
+ }
+
+ return toBeDefined;
+};
+
+getJasmineRequireObj().toBeFalsy = function() {
+ /**
+ * {@link expect} the actual value to be falsy
+ * @function
+ * @name matchers#toBeFalsy
+ * @example
+ * expect(result).toBeFalsy();
+ */
+ function toBeFalsy() {
+ return {
+ compare: function(actual) {
+ return {
+ pass: !!!actual
+ };
+ }
+ };
+ }
+
+ return toBeFalsy;
+};
+
+getJasmineRequireObj().toBeGreaterThan = function() {
+ /**
+ * {@link expect} the actual value to be greater than the expected value.
+ * @function
+ * @name matchers#toBeGreaterThan
+ * @param {Number} expected - The value to compare against.
+ * @example
+ * expect(result).toBeGreaterThan(3);
+ */
+ function toBeGreaterThan() {
+ return {
+ compare: function(actual, expected) {
+ return {
+ pass: actual > expected
+ };
+ }
+ };
+ }
+
+ return toBeGreaterThan;
+};
+
+
+getJasmineRequireObj().toBeGreaterThanOrEqual = function() {
+ /**
+ * {@link expect} the actual value to be greater than or equal to the expected value.
+ * @function
+ * @name matchers#toBeGreaterThanOrEqual
+ * @param {Number} expected - The expected value to compare against.
+ * @example
+ * expect(result).toBeGreaterThanOrEqual(25);
+ */
+ function toBeGreaterThanOrEqual() {
+ return {
+ compare: function(actual, expected) {
+ return {
+ pass: actual >= expected
+ };
+ }
+ };
+ }
+
+ return toBeGreaterThanOrEqual;
+};
+
+getJasmineRequireObj().toBeLessThan = function() {
+ /**
+ * {@link expect} the actual value to be less than the expected value.
+ * @function
+ * @name matchers#toBeLessThan
+ * @param {Number} expected - The expected value to compare against.
+ * @example
+ * expect(result).toBeLessThan(0);
+ */
+ function toBeLessThan() {
+ return {
+
+ compare: function(actual, expected) {
+ return {
+ pass: actual < expected
+ };
+ }
+ };
+ }
+
+ return toBeLessThan;
+};
+
+getJasmineRequireObj().toBeLessThanOrEqual = function() {
+ /**
+ * {@link expect} the actual value to be less than or equal to the expected value.
+ * @function
+ * @name matchers#toBeLessThanOrEqual
+ * @param {Number} expected - The expected value to compare against.
+ * @example
+ * expect(result).toBeLessThanOrEqual(123);
+ */
+ function toBeLessThanOrEqual() {
+ return {
+
+ compare: function(actual, expected) {
+ return {
+ pass: actual <= expected
+ };
+ }
+ };
+ }
+
+ return toBeLessThanOrEqual;
+};
+
+getJasmineRequireObj().toBeNaN = function(j$) {
+ /**
+ * {@link expect} the actual value to be `NaN` (Not a Number).
+ * @function
+ * @name matchers#toBeNaN
+ * @example
+ * expect(thing).toBeNaN();
+ */
+ function toBeNaN() {
+ return {
+ compare: function(actual) {
+ var result = {
+ pass: (actual !== actual)
+ };
+
+ if (result.pass) {
+ result.message = 'Expected actual not to be NaN.';
+ } else {
+ result.message = function() { return 'Expected ' + j$.pp(actual) + ' to be NaN.'; };
+ }
+
+ return result;
+ }
+ };
+ }
+
+ return toBeNaN;
+};
+
+getJasmineRequireObj().toBeNegativeInfinity = function(j$) {
+ /**
+ * {@link expect} the actual value to be `-Infinity` (-infinity).
+ * @function
+ * @name matchers#toBeNegativeInfinity
+ * @example
+ * expect(thing).toBeNegativeInfinity();
+ */
+ function toBeNegativeInfinity() {
+ return {
+ compare: function(actual) {
+ var result = {
+ pass: (actual === Number.NEGATIVE_INFINITY)
+ };
+
+ if (result.pass) {
+ result.message = 'Expected actual to be -Infinity.';
+ } else {
+ result.message = function() { return 'Expected ' + j$.pp(actual) + ' not to be -Infinity.'; };
+ }
+
+ return result;
+ }
+ };
+ }
+
+ return toBeNegativeInfinity;
+};
+
+getJasmineRequireObj().toBeNull = function() {
+ /**
+ * {@link expect} the actual value to be `null`.
+ * @function
+ * @name matchers#toBeNull
+ * @example
+ * expect(result).toBeNull();
+ */
+ function toBeNull() {
+ return {
+ compare: function(actual) {
+ return {
+ pass: actual === null
+ };
+ }
+ };
+ }
+
+ return toBeNull;
+};
+
+getJasmineRequireObj().toBePositiveInfinity = function(j$) {
+ /**
+ * {@link expect} the actual value to be `Infinity` (infinity).
+ * @function
+ * @name matchers#toBePositiveInfinity
+ * @example
+ * expect(thing).toBePositiveInfinity();
+ */
+ function toBePositiveInfinity() {
+ return {
+ compare: function(actual) {
+ var result = {
+ pass: (actual === Number.POSITIVE_INFINITY)
+ };
+
+ if (result.pass) {
+ result.message = 'Expected actual to be Infinity.';
+ } else {
+ result.message = function() { return 'Expected ' + j$.pp(actual) + ' not to be Infinity.'; };
+ }
+
+ return result;
+ }
+ };
+ }
+
+ return toBePositiveInfinity;
+};
+
+getJasmineRequireObj().toBeTruthy = function() {
+ /**
+ * {@link expect} the actual value to be truthy.
+ * @function
+ * @name matchers#toBeTruthy
+ * @example
+ * expect(thing).toBeTruthy();
+ */
+ function toBeTruthy() {
+ return {
+ compare: function(actual) {
+ return {
+ pass: !!actual
+ };
+ }
+ };
+ }
+
+ return toBeTruthy;
+};
+
+getJasmineRequireObj().toBeUndefined = function() {
+ /**
+ * {@link expect} the actual value to be `undefined`.
+ * @function
+ * @name matchers#toBeUndefined
+ * @example
+ * expect(result).toBeUndefined():
+ */
+ function toBeUndefined() {
+ return {
+ compare: function(actual) {
+ return {
+ pass: void 0 === actual
+ };
+ }
+ };
+ }
+
+ return toBeUndefined;
+};
+
+getJasmineRequireObj().toContain = function() {
+ /**
+ * {@link expect} the actual value to contain a specific value.
+ * @function
+ * @name matchers#toContain
+ * @param {Object} expected - The value to look for.
+ * @example
+ * expect(array).toContain(anElement);
+ * expect(string).toContain(substring);
+ */
+ function toContain(util, customEqualityTesters) {
+ customEqualityTesters = customEqualityTesters || [];
+
+ return {
+ compare: function(actual, expected) {
+
+ return {
+ pass: util.contains(actual, expected, customEqualityTesters)
+ };
+ }
+ };
+ }
+
+ return toContain;
+};
+
+getJasmineRequireObj().toEqual = function(j$) {
+ /**
+ * {@link expect} the actual value to be equal to the expected, using deep equality comparison.
+ * @function
+ * @name matchers#toEqual
+ * @param {Object} expected - Expected value
+ * @example
+ * expect(bigObject).toEqual({"foo": ['bar', 'baz']});
+ */
+ function toEqual(util, customEqualityTesters) {
+ customEqualityTesters = customEqualityTesters || [];
+
+ return {
+ compare: function(actual, expected) {
+ var result = {
+ pass: false
+ },
+ diffBuilder = j$.DiffBuilder();
+
+ result.pass = util.equals(actual, expected, customEqualityTesters, diffBuilder);
+
+ // TODO: only set error message if test fails
+ result.message = diffBuilder.getMessage();
+
+ return result;
+ }
+ };
+ }
+
+ return toEqual;
+};
+
+getJasmineRequireObj().toHaveBeenCalled = function(j$) {
+
+ var getErrorMsg = j$.formatErrorMsg('<toHaveBeenCalled>', 'expect(<spyObj>).toHaveBeenCalled()');
+
+ /**
+ * {@link expect} the actual (a {@link Spy}) to have been called.
+ * @function
+ * @name matchers#toHaveBeenCalled
+ * @example
+ * expect(mySpy).toHaveBeenCalled();
+ * expect(mySpy).not.toHaveBeenCalled();
+ */
+ function toHaveBeenCalled() {
+ return {
+ compare: function(actual) {
+ var result = {};
+
+ if (!j$.isSpy(actual)) {
+ throw new Error(getErrorMsg('Expected a spy, but got ' + j$.pp(actual) + '.'));
+ }
+
+ if (arguments.length > 1) {
+ throw new Error(getErrorMsg('Does not take arguments, use toHaveBeenCalledWith'));
+ }
+
+ result.pass = actual.calls.any();
+
+ result.message = result.pass ?
+ 'Expected spy ' + actual.and.identity() + ' not to have been called.' :
+ 'Expected spy ' + actual.and.identity() + ' to have been called.';
+
+ return result;
+ }
+ };
+ }
+
+ return toHaveBeenCalled;
+};
+
+getJasmineRequireObj().toHaveBeenCalledBefore = function(j$) {
+
+ var getErrorMsg = j$.formatErrorMsg('<toHaveBeenCalledBefore>', 'expect(<spyObj>).toHaveBeenCalledBefore(<spyObj>)');
+
+ /**
+ * {@link expect} the actual value (a {@link Spy}) to have been called before another {@link Spy}.
+ * @function
+ * @name matchers#toHaveBeenCalledBefore
+ * @param {Spy} expected - {@link Spy} that should have been called after the `actual` {@link Spy}.
+ * @example
+ * expect(mySpy).toHaveBeenCalledBefore(otherSpy);
+ */
+ function toHaveBeenCalledBefore() {
+ return {
+ compare: function(firstSpy, latterSpy) {
+ if (!j$.isSpy(firstSpy)) {
+ throw new Error(getErrorMsg('Expected a spy, but got ' + j$.pp(firstSpy) + '.'));
+ }
+ if (!j$.isSpy(latterSpy)) {
+ throw new Error(getErrorMsg('Expected a spy, but got ' + j$.pp(latterSpy) + '.'));
+ }
+
+ var result = { pass: false };
+
+ if (!firstSpy.calls.count()) {
+ result.message = 'Expected spy ' + firstSpy.and.identity() + ' to have been called.';
+ return result;
+ }
+ if (!latterSpy.calls.count()) {
+ result.message = 'Expected spy ' + latterSpy.and.identity() + ' to have been called.';
+ return result;
+ }
+
+ var latest1stSpyCall = firstSpy.calls.mostRecent().invocationOrder;
+ var first2ndSpyCall = latterSpy.calls.first().invocationOrder;
+
+ result.pass = latest1stSpyCall < first2ndSpyCall;
+
+ if (result.pass) {
+ result.message = 'Expected spy ' + firstSpy.and.identity() + ' to not have been called before spy ' + latterSpy.and.identity() + ', but it was';
+ } else {
+ var first1stSpyCall = firstSpy.calls.first().invocationOrder;
+ var latest2ndSpyCall = latterSpy.calls.mostRecent().invocationOrder;
+
+ if(first1stSpyCall < first2ndSpyCall) {
+ result.message = 'Expected latest call to spy ' + firstSpy.and.identity() + ' to have been called before first call to spy ' + latterSpy.and.identity() + ' (no interleaved calls)';
+ } else if (latest2ndSpyCall > latest1stSpyCall) {
+ result.message = 'Expected first call to spy ' + latterSpy.and.identity() + ' to have been called after latest call to spy ' + firstSpy.and.identity() + ' (no interleaved calls)';
+ } else {
+ result.message = 'Expected spy ' + firstSpy.and.identity() + ' to have been called before spy ' + latterSpy.and.identity();
+ }
+ }
+
+ return result;
+ }
+ };
+ }
+
+ return toHaveBeenCalledBefore;
+};
+
+getJasmineRequireObj().toHaveBeenCalledTimes = function(j$) {
+
+ var getErrorMsg = j$.formatErrorMsg('<toHaveBeenCalledTimes>', 'expect(<spyObj>).toHaveBeenCalledTimes(<Number>)');
+
+ /**
+ * {@link expect} the actual (a {@link Spy}) to have been called the specified number of times.
+ * @function
+ * @name matchers#toHaveBeenCalledTimes
+ * @param {Number} expected - The number of invocations to look for.
+ * @example
+ * expect(mySpy).toHaveBeenCalledTimes(3);
+ */
+ function toHaveBeenCalledTimes() {
+ return {
+ compare: function(actual, expected) {
+ if (!j$.isSpy(actual)) {
+ throw new Error(getErrorMsg('Expected a spy, but got ' + j$.pp(actual) + '.'));
+ }
+
+ var args = Array.prototype.slice.call(arguments, 0),
+ result = { pass: false };
+
+ if (!j$.isNumber_(expected)){
+ throw new Error(getErrorMsg('The expected times failed is a required argument and must be a number.'));
+ }
+
+ actual = args[0];
+ var calls = actual.calls.count();
+ var timesMessage = expected === 1 ? 'once' : expected + ' times';
+ result.pass = calls === expected;
+ result.message = result.pass ?
+ 'Expected spy ' + actual.and.identity() + ' not to have been called ' + timesMessage + '. It was called ' + calls + ' times.' :
+ 'Expected spy ' + actual.and.identity() + ' to have been called ' + timesMessage + '. It was called ' + calls + ' times.';
+ return result;
+ }
+ };
+ }
+
+ return toHaveBeenCalledTimes;
+};
+
+getJasmineRequireObj().toHaveBeenCalledWith = function(j$) {
+
+ var getErrorMsg = j$.formatErrorMsg('<toHaveBeenCalledWith>', 'expect(<spyObj>).toHaveBeenCalledWith(...arguments)');
+
+ /**
+ * {@link expect} the actual (a {@link Spy}) to have been called with particular arguments at least once.
+ * @function
+ * @name matchers#toHaveBeenCalledWith
+ * @param {...Object} - The arguments to look for
+ * @example
+ * expect(mySpy).toHaveBeenCalledWith('foo', 'bar', 2);
+ */
+ function toHaveBeenCalledWith(util, customEqualityTesters) {
+ return {
+ compare: function() {
+ var args = Array.prototype.slice.call(arguments, 0),
+ actual = args[0],
+ expectedArgs = args.slice(1),
+ result = { pass: false };
+
+ if (!j$.isSpy(actual)) {
+ throw new Error(getErrorMsg('Expected a spy, but got ' + j$.pp(actual) + '.'));
+ }
+
+ if (!actual.calls.any()) {
+ result.message = function() { return 'Expected spy ' + actual.and.identity() + ' to have been called with ' + j$.pp(expectedArgs) + ' but it was never called.'; };
+ return result;
+ }
+
+ if (util.contains(actual.calls.allArgs(), expectedArgs, customEqualityTesters)) {
+ result.pass = true;
+ result.message = function() { return 'Expected spy ' + actual.and.identity() + ' not to have been called with ' + j$.pp(expectedArgs) + ' but it was.'; };
+ } else {
+ 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, '') + '.'; };
+ }
+
+ return result;
+ }
+ };
+ }
+
+ return toHaveBeenCalledWith;
+};
+
+getJasmineRequireObj().toMatch = function(j$) {
+
+ var getErrorMsg = j$.formatErrorMsg('<toMatch>', 'expect(<expectation>).toMatch(<string> || <regexp>)');
+
+ /**
+ * {@link expect} the actual value to match a regular expression
+ * @function
+ * @name matchers#toMatch
+ * @param {RegExp|String} expected - Value to look for in the string.
+ * @example
+ * expect("my string").toMatch(/string$/);
+ * expect("other string").toMatch("her");
+ */
+ function toMatch() {
+ return {
+ compare: function(actual, expected) {
+ if (!j$.isString_(expected) && !j$.isA_('RegExp', expected)) {
+ throw new Error(getErrorMsg('Expected is not a String or a RegExp'));
+ }
+
+ var regexp = new RegExp(expected);
+
+ return {
+ pass: regexp.test(actual)
+ };
+ }
+ };
+ }
+
+ return toMatch;
+};
+
+getJasmineRequireObj().toThrow = function(j$) {
+
+ var getErrorMsg = j$.formatErrorMsg('<toThrow>', 'expect(function() {<expectation>}).toThrow()');
+
+ /**
+ * {@link expect} a function to `throw` something.
+ * @function
+ * @name matchers#toThrow
+ * @param {Object} [expected] - Value that should be thrown. If not provided, simply the fact that something was thrown will be checked.
+ * @example
+ * expect(function() { return 'things'; }).toThrow('foo');
+ * expect(function() { return 'stuff'; }).toThrow();
+ */
+ function toThrow(util) {
+ return {
+ compare: function(actual, expected) {
+ var result = { pass: false },
+ threw = false,
+ thrown;
+
+ if (typeof actual != 'function') {
+ throw new Error(getErrorMsg('Actual is not a Function'));
+ }
+
+ try {
+ actual();
+ } catch (e) {
+ threw = true;
+ thrown = e;
+ }
+
+ if (!threw) {
+ result.message = 'Expected function to throw an exception.';
+ return result;
+ }
+
+ if (arguments.length == 1) {
+ result.pass = true;
+ result.message = function() { return 'Expected function not to throw, but it threw ' + j$.pp(thrown) + '.'; };
+
+ return result;
+ }
+
+ if (util.equals(thrown, expected)) {
+ result.pass = true;
+ result.message = function() { return 'Expected function not to throw ' + j$.pp(expected) + '.'; };
+ } else {
+ result.message = function() { return 'Expected function to throw ' + j$.pp(expected) + ', but it threw ' + j$.pp(thrown) + '.'; };
+ }
+
+ return result;
+ }
+ };
+ }
+
+ return toThrow;
+};
+
+getJasmineRequireObj().toThrowError = function(j$) {
+
+ var getErrorMsg = j$.formatErrorMsg('<toThrowError>', 'expect(function() {<expectation>}).toThrowError(<ErrorConstructor>, <message>)');
+
+ /**
+ * {@link expect} a function to `throw` an `Error`.
+ * @function
+ * @name matchers#toThrowError
+ * @param {Error} [expected] - `Error` constructor the object that was thrown needs to be an instance of. If not provided, `Error` will be used.
+ * @param {RegExp|String} [message] - The message that should be set on the thrown `Error`
+ * @example
+ * expect(function() { return 'things'; }).toThrowError(MyCustomError, 'message');
+ * expect(function() { return 'things'; }).toThrowError(MyCustomError, /bar/);
+ * expect(function() { return 'stuff'; }).toThrowError(MyCustomError);
+ * expect(function() { return 'other'; }).toThrowError(/foo/);
+ * expect(function() { return 'other'; }).toThrowError();
+ */
+ function toThrowError () {
+ return {
+ compare: function(actual) {
+ var threw = false,
+ pass = {pass: true},
+ fail = {pass: false},
+ thrown;
+
+ if (typeof actual != 'function') {
+ throw new Error(getErrorMsg('Actual is not a Function'));
+ }
+
+ var errorMatcher = getMatcher.apply(null, arguments);
+
+ try {
+ actual();
+ } catch (e) {
+ threw = true;
+ thrown = e;
+ }
+
+ if (!threw) {
+ fail.message = 'Expected function to throw an Error.';
+ return fail;
+ }
+
+ // Get Error constructor of thrown
+ if (!isErrorObject(thrown)) {
+ fail.message = function() { return 'Expected function to throw an Error, but it threw ' + j$.pp(thrown) + '.'; };
+ return fail;
+ }
+
+ if (errorMatcher.hasNoSpecifics()) {
+ pass.message = 'Expected function not to throw an Error, but it threw ' + j$.fnNameFor(thrown) + '.';
+ return pass;
+ }
+
+ if (errorMatcher.matches(thrown)) {
+ pass.message = function() {
+ return 'Expected function not to throw ' + errorMatcher.errorTypeDescription + errorMatcher.messageDescription() + '.';
+ };
+ return pass;
+ } else {
+ fail.message = function() {
+ return 'Expected function to throw ' + errorMatcher.errorTypeDescription + errorMatcher.messageDescription() +
+ ', but it threw ' + errorMatcher.thrownDescription(thrown) + '.';
+ };
+ return fail;
+ }
+ }
+ };
+
+ function getMatcher() {
+ var expected = null,
+ errorType = null;
+
+ if (arguments.length == 2) {
+ expected = arguments[1];
+ if (isAnErrorType(expected)) {
+ errorType = expected;
+ expected = null;
+ }
+ } else if (arguments.length > 2) {
+ errorType = arguments[1];
+ expected = arguments[2];
+ if (!isAnErrorType(errorType)) {
+ throw new Error(getErrorMsg('Expected error type is not an Error.'));
+ }
+ }
+
+ if (expected && !isStringOrRegExp(expected)) {
+ if (errorType) {
+ throw new Error(getErrorMsg('Expected error message is not a string or RegExp.'));
+ } else {
+ throw new Error(getErrorMsg('Expected is not an Error, string, or RegExp.'));
+ }
+ }
+
+ function messageMatch(message) {
+ if (typeof expected == 'string') {
+ return expected == message;
+ } else {
+ return expected.test(message);
+ }
+ }
+
+ return {
+ errorTypeDescription: errorType ? j$.fnNameFor(errorType) : 'an exception',
+ thrownDescription: function(thrown) {
+ var thrownName = errorType ? j$.fnNameFor(thrown.constructor) : 'an exception',
+ thrownMessage = '';
+
+ if (expected) {
+ thrownMessage = ' with message ' + j$.pp(thrown.message);
+ }
+
+ return thrownName + thrownMessage;
+ },
+ messageDescription: function() {
+ if (expected === null) {
+ return '';
+ } else if (expected instanceof RegExp) {
+ return ' with a message matching ' + j$.pp(expected);
+ } else {
+ return ' with message ' + j$.pp(expected);
+ }
+ },
+ hasNoSpecifics: function() {
+ return expected === null && errorType === null;
+ },
+ matches: function(error) {
+ return (errorType === null || error instanceof errorType) &&
+ (expected === null || messageMatch(error.message));
+ }
+ };
+ }
+
+ function isStringOrRegExp(potential) {
+ return potential instanceof RegExp || (typeof potential == 'string');
+ }
+
+ function isAnErrorType(type) {
+ if (typeof type !== 'function') {
+ return false;
+ }
+
+ var Surrogate = function() {};
+ Surrogate.prototype = type.prototype;
+ return isErrorObject(new Surrogate());
+ }
+
+ function isErrorObject(thrown) {
+ if (thrown instanceof Error) {
+ return true;
+ }
+ if (thrown && thrown.constructor && thrown.constructor.constructor &&
+ (thrown instanceof (thrown.constructor.constructor('return this')()).Error)) {
+ return true;
+ }
+ return false;
+ }
+ }
+
+ return toThrowError;
+};
+
+getJasmineRequireObj().MockDate = function() {
+ function MockDate(global) {
+ var self = this;
+ var currentTime = 0;
+
+ if (!global || !global.Date) {
+ self.install = function() {};
+ self.tick = function() {};
+ self.uninstall = function() {};
+ return self;
+ }
+
+ var GlobalDate = global.Date;
+
+ self.install = function(mockDate) {
+ if (mockDate instanceof GlobalDate) {
+ currentTime = mockDate.getTime();
+ } else {
+ currentTime = new GlobalDate().getTime();
+ }
+
+ global.Date = FakeDate;
+ };
+
+ self.tick = function(millis) {
+ millis = millis || 0;
+ currentTime = currentTime + millis;
+ };
+
+ self.uninstall = function() {
+ currentTime = 0;
+ global.Date = GlobalDate;
+ };
+
+ createDateProperties();
+
+ return self;
+
+ function FakeDate() {
+ switch(arguments.length) {
+ case 0:
+ return new GlobalDate(currentTime);
+ case 1:
+ return new GlobalDate(arguments[0]);
+ case 2:
+ return new GlobalDate(arguments[0], arguments[1]);
+ case 3:
+ return new GlobalDate(arguments[0], arguments[1], arguments[2]);
+ case 4:
+ return new GlobalDate(arguments[0], arguments[1], arguments[2], arguments[3]);
+ case 5:
+ return new GlobalDate(arguments[0], arguments[1], arguments[2], arguments[3],
+ arguments[4]);
+ case 6:
+ return new GlobalDate(arguments[0], arguments[1], arguments[2], arguments[3],
+ arguments[4], arguments[5]);
+ default:
+ return new GlobalDate(arguments[0], arguments[1], arguments[2], arguments[3],
+ arguments[4], arguments[5], arguments[6]);
+ }
+ }
+
+ function createDateProperties() {
+ FakeDate.prototype = GlobalDate.prototype;
+
+ FakeDate.now = function() {
+ if (GlobalDate.now) {
+ return currentTime;
+ } else {
+ throw new Error('Browser does not support Date.now()');
+ }
+ };
+
+ FakeDate.toSource = GlobalDate.toSource;
+ FakeDate.toString = GlobalDate.toString;
+ FakeDate.parse = GlobalDate.parse;
+ FakeDate.UTC = GlobalDate.UTC;
+ }
+ }
+
+ return MockDate;
+};
+
+getJasmineRequireObj().pp = function(j$) {
+
+ function PrettyPrinter() {
+ this.ppNestLevel_ = 0;
+ this.seen = [];
+ this.length = 0;
+ this.stringParts = [];
+ }
+
+ function hasCustomToString(value) {
+ // value.toString !== Object.prototype.toString if value has no custom toString but is from another context (e.g.
+ // iframe, web worker)
+ return j$.isFunction_(value.toString) && value.toString !== Object.prototype.toString && (value.toString() !== Object.prototype.toString.call(value));
+ }
+
+ PrettyPrinter.prototype.format = function(value) {
+ this.ppNestLevel_++;
+ try {
+ if (j$.util.isUndefined(value)) {
+ this.emitScalar('undefined');
+ } else if (value === null) {
+ this.emitScalar('null');
+ } else if (value === 0 && 1/value === -Infinity) {
+ this.emitScalar('-0');
+ } else if (value === j$.getGlobal()) {
+ this.emitScalar('<global>');
+ } else if (value.jasmineToString) {
+ this.emitScalar(value.jasmineToString());
+ } else if (typeof value === 'string') {
+ this.emitString(value);
+ } else if (j$.isSpy(value)) {
+ this.emitScalar('spy on ' + value.and.identity());
+ } else if (value instanceof RegExp) {
+ this.emitScalar(value.toString());
+ } else if (typeof value === 'function') {
+ this.emitScalar('Function');
+ } else if (typeof value.nodeType === 'number') {
+ this.emitScalar('HTMLNode');
+ } else if (value instanceof Date) {
+ this.emitScalar('Date(' + value + ')');
+ } else if (j$.isSet(value)) {
+ this.emitSet(value);
+ } else if (j$.isMap(value)) {
+ this.emitMap(value);
+ } else if (j$.isTypedArray_(value)) {
+ this.emitTypedArray(value);
+ } else if (value.toString && typeof value === 'object' && !j$.isArray_(value) && hasCustomToString(value)) {
+ this.emitScalar(value.toString());
+ } else if (j$.util.arrayContains(this.seen, value)) {
+ this.emitScalar('<circular reference: ' + (j$.isArray_(value) ? 'Array' : 'Object') + '>');
+ } else if (j$.isArray_(value) || j$.isA_('Object', value)) {
+ this.seen.push(value);
+ if (j$.isArray_(value)) {
+ this.emitArray(value);
+ } else {
+ this.emitObject(value);
+ }
+ this.seen.pop();
+ } else {
+ this.emitScalar(value.toString());
+ }
+ } catch (e) {
+ if (this.ppNestLevel_ > 1 || !(e instanceof MaxCharsReachedError)) {
+ throw e;
+ }
+ } finally {
+ this.ppNestLevel_--;
+ }
+ };
+
+ PrettyPrinter.prototype.iterateObject = function(obj, fn) {
+ var objKeys = keys(obj, j$.isArray_(obj));
+ var isGetter = function isGetter(prop) {};
+
+ if (obj.__lookupGetter__) {
+ isGetter = function isGetter(prop) {
+ var getter = obj.__lookupGetter__(prop);
+ return !j$.util.isUndefined(getter) && getter !== null;
+ };
+
+ }
+ var length = Math.min(objKeys.length, j$.MAX_PRETTY_PRINT_ARRAY_LENGTH);
+ for (var i = 0; i < length; i++) {
+ var property = objKeys[i];
+ fn(property, isGetter(property));
+ }
+
+ return objKeys.length > length;
+ };
+
+ PrettyPrinter.prototype.emitScalar = function(value) {
+ this.append(value);
+ };
+
+ PrettyPrinter.prototype.emitString = function(value) {
+ this.append('\'' + value + '\'');
+ };
+
+ PrettyPrinter.prototype.emitArray = function(array) {
+ if (this.ppNestLevel_ > j$.MAX_PRETTY_PRINT_DEPTH) {
+ this.append('Array');
+ return;
+ }
+ var length = Math.min(array.length, j$.MAX_PRETTY_PRINT_ARRAY_LENGTH);
+ this.append('[ ');
+ for (var i = 0; i < length; i++) {
+ if (i > 0) {
+ this.append(', ');
+ }
+ this.format(array[i]);
+ }
+ if(array.length > length){
+ this.append(', ...');
+ }
+
+ var self = this;
+ var first = array.length === 0;
+ var truncated = this.iterateObject(array, function(property, isGetter) {
+ if (first) {
+ first = false;
+ } else {
+ self.append(', ');
+ }
+
+ self.formatProperty(array, property, isGetter);
+ });
+
+ if (truncated) { this.append(', ...'); }
+
+ this.append(' ]');
+ };
+
+ PrettyPrinter.prototype.emitSet = function(set) {
+ if (this.ppNestLevel_ > j$.MAX_PRETTY_PRINT_DEPTH) {
+ this.append('Set');
+ return;
+ }
+ this.append('Set( ');
+ var size = Math.min(set.size, j$.MAX_PRETTY_PRINT_ARRAY_LENGTH);
+ var i = 0;
+ set.forEach( function( value, key ) {
+ if (i >= size) {
+ return;
+ }
+ if (i > 0) {
+ this.append(', ');
+ }
+ this.format(value);
+
+ i++;
+ }, this );
+ if (set.size > size){
+ this.append(', ...');
+ }
+ this.append(' )');
+ };
+
+ PrettyPrinter.prototype.emitMap = function(map) {
+ if (this.ppNestLevel_ > j$.MAX_PRETTY_PRINT_DEPTH) {
+ this.append('Map');
+ return;
+ }
+ this.append('Map( ');
+ var size = Math.min(map.size, j$.MAX_PRETTY_PRINT_ARRAY_LENGTH);
+ var i = 0;
+ map.forEach( function( value, key ) {
+ if (i >= size) {
+ return;
+ }
+ if (i > 0) {
+ this.append(', ');
+ }
+ this.format([key,value]);
+
+ i++;
+ }, this );
+ if (map.size > size){
+ this.append(', ...');
+ }
+ this.append(' )');
+ };
+
+ PrettyPrinter.prototype.emitObject = function(obj) {
+ var ctor = obj.constructor,
+ constructorName;
+
+ constructorName = typeof ctor === 'function' && obj instanceof ctor ?
+ j$.fnNameFor(obj.constructor) :
+ 'null';
+
+ this.append(constructorName);
+
+ if (this.ppNestLevel_ > j$.MAX_PRETTY_PRINT_DEPTH) {
+ return;
+ }
+
+ var self = this;
+ this.append('({ ');
+ var first = true;
+
+ var truncated = this.iterateObject(obj, function(property, isGetter) {
+ if (first) {
+ first = false;
+ } else {
+ self.append(', ');
+ }
+
+ self.formatProperty(obj, property, isGetter);
+ });
+
+ if (truncated) { this.append(', ...'); }
+
+ this.append(' })');
+ };
+
+ PrettyPrinter.prototype.emitTypedArray = function(arr) {
+ var constructorName = j$.fnNameFor(arr.constructor),
+ limitedArray = Array.prototype.slice.call(arr, 0, j$.MAX_PRETTY_PRINT_ARRAY_LENGTH),
+ itemsString = Array.prototype.join.call(limitedArray, ', ');
+
+ if (limitedArray.length !== arr.length) {
+ itemsString += ', ...';
+ }
+
+ this.append(constructorName + ' [ ' + itemsString + ' ]');
+ };
+
+ PrettyPrinter.prototype.formatProperty = function(obj, property, isGetter) {
+ this.append(property);
+ this.append(': ');
+ if (isGetter) {
+ this.append('<getter>');
+ } else {
+ this.format(obj[property]);
+ }
+ };
+
+ PrettyPrinter.prototype.append = function(value) {
+ var result = truncate(value, j$.MAX_PRETTY_PRINT_CHARS - this.length);
+ this.length += result.value.length;
+ this.stringParts.push(result.value);
+
+ if (result.truncated) {
+ throw new MaxCharsReachedError();
+ }
+ };
+
+
+ function truncate(s, maxlen) {
+ if (s.length <= maxlen) {
+ return { value: s, truncated: false };
+ }
+
+ s = s.substring(0, maxlen - 4) + ' ...';
+ return { value: s, truncated: true };
+ }
+
+ function MaxCharsReachedError() {
+ this.message = 'Exceeded ' + j$.MAX_PRETTY_PRINT_CHARS +
+ ' characters while pretty-printing a value';
+ }
+
+ MaxCharsReachedError.prototype = new Error();
+
+ function keys(obj, isArray) {
+ var allKeys = Object.keys ? Object.keys(obj) :
+ (function(o) {
+ var keys = [];
+ for (var key in o) {
+ if (j$.util.has(o, key)) {
+ keys.push(key);
+ }
+ }
+ return keys;
+ })(obj);
+
+ if (!isArray) {
+ return allKeys;
+ }
+
+ if (allKeys.length === 0) {
+ return allKeys;
+ }
+
+ var extraKeys = [];
+ for (var i = 0; i < allKeys.length; i++) {
+ if (!/^[0-9]+$/.test(allKeys[i])) {
+ extraKeys.push(allKeys[i]);
+ }
+ }
+
+ return extraKeys;
+ }
+ return function(value) {
+ var prettyPrinter = new PrettyPrinter();
+ prettyPrinter.format(value);
+ return prettyPrinter.stringParts.join('');
+ };
+};
+
+getJasmineRequireObj().QueueRunner = function(j$) {
+
+ function once(fn) {
+ var called = false;
+ return function() {
+ if (!called) {
+ called = true;
+ fn.apply(null, arguments);
+ }
+ return null;
+ };
+ }
+
+ function QueueRunner(attrs) {
+ var queueableFns = attrs.queueableFns || [];
+ this.queueableFns = queueableFns.concat(attrs.cleanupFns || []);
+ this.firstCleanupIx = queueableFns.length;
+ this.onComplete = attrs.onComplete || function() {};
+ this.clearStack = attrs.clearStack || function(fn) {fn();};
+ this.onException = attrs.onException || function() {};
+ this.catchException = attrs.catchException || function() { return true; };
+ this.userContext = attrs.userContext || new j$.UserContext();
+ this.timeout = attrs.timeout || {setTimeout: setTimeout, clearTimeout: clearTimeout};
+ this.fail = attrs.fail || function() {};
+ this.globalErrors = attrs.globalErrors || { pushListener: function() {}, popListener: function() {} };
+ this.completeOnFirstError = !!attrs.completeOnFirstError;
+ this.deprecated = attrs.deprecated;
+ }
+
+ QueueRunner.prototype.execute = function() {
+ var self = this;
+ this.handleFinalError = function(error) {
+ self.onException(error);
+ };
+ this.globalErrors.pushListener(this.handleFinalError);
+ this.run(0);
+ };
+
+ QueueRunner.prototype.skipToCleanup = function(lastRanIndex) {
+ if (lastRanIndex < this.firstCleanupIx) {
+ this.run(this.firstCleanupIx);
+ } else {
+ this.run(lastRanIndex + 1);
+ }
+ };
+
+ QueueRunner.prototype.run = function(recursiveIndex) {
+ var length = this.queueableFns.length,
+ self = this,
+ iterativeIndex;
+
+
+ for(iterativeIndex = recursiveIndex; iterativeIndex < length; iterativeIndex++) {
+ var result = attempt(iterativeIndex);
+
+ if (!result.completedSynchronously) {
+ return;
+ }
+
+ if (this.completeOnFirstError && result.errored) {
+ this.skipToCleanup(iterativeIndex);
+ return;
+ }
+ }
+
+ this.clearStack(function() {
+ self.globalErrors.popListener(self.handleFinalError);
+ self.onComplete();
+ });
+
+ function attempt() {
+ var clearTimeout = function () {
+ Function.prototype.apply.apply(self.timeout.clearTimeout, [j$.getGlobal(), [timeoutId]]);
+ },
+ setTimeout = function(delayedFn, delay) {
+ return Function.prototype.apply.apply(self.timeout.setTimeout, [j$.getGlobal(), [delayedFn, delay]]);
+ },
+ completedSynchronously = true,
+ handleError = function(error) {
+ onException(error);
+ next();
+ },
+ cleanup = once(function() {
+ clearTimeout(timeoutId);
+ self.globalErrors.popListener(handleError);
+ }),
+ next = once(function (err) {
+ cleanup();
+
+ if (err instanceof Error) {
+ self.deprecated('done callback received an Error object. Jasmine 3.0 will treat this as a failure');
+ }
+
+ function runNext() {
+ if (self.completeOnFirstError && errored) {
+ self.skipToCleanup(iterativeIndex);
+ } else {
+ self.run(iterativeIndex + 1);
+ }
+ }
+
+ if (completedSynchronously) {
+ setTimeout(runNext);
+ } else {
+ runNext();
+ }
+ }),
+ errored = false,
+ queueableFn = self.queueableFns[iterativeIndex],
+ timeoutId;
+
+ next.fail = function() {
+ self.fail.apply(null, arguments);
+ errored = true;
+ next();
+ };
+
+ self.globalErrors.pushListener(handleError);
+
+ if (queueableFn.timeout) {
+ timeoutId = setTimeout(function() {
+ var error = new Error('Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.');
+ onException(error);
+ next();
+ }, queueableFn.timeout());
+ }
+
+ try {
+ if (queueableFn.fn.length === 0) {
+ var maybeThenable = queueableFn.fn.call(self.userContext);
+
+ if (maybeThenable && j$.isFunction_(maybeThenable.then)) {
+ maybeThenable.then(next, onPromiseRejection);
+ completedSynchronously = false;
+ return { completedSynchronously: false };
+ }
+ } else {
+ queueableFn.fn.call(self.userContext, next);
+ completedSynchronously = false;
+ return { completedSynchronously: false };
+ }
+ } catch (e) {
+ handleException(e, queueableFn);
+ errored = true;
+ }
+
+ cleanup();
+ return { completedSynchronously: true, errored: errored };
+
+ function onException(e) {
+ self.onException(e);
+ errored = true;
+ }
+
+ function onPromiseRejection(e) {
+ onException(e);
+ next();
+ }
+
+ function handleException(e, queueableFn) {
+ onException(e);
+ if (!self.catchException(e)) {
+ //TODO: set a var when we catch an exception and
+ //use a finally block to close the loop in a nice way..
+ throw e;
+ }
+ }
+ }
+ };
+
+ return QueueRunner;
+};
+
+getJasmineRequireObj().ReportDispatcher = function(j$) {
+ function ReportDispatcher(methods) {
+
+ var dispatchedMethods = methods || [];
+
+ for (var i = 0; i < dispatchedMethods.length; i++) {
+ var method = dispatchedMethods[i];
+ this[method] = (function(m) {
+ return function() {
+ dispatch(m, arguments);
+ };
+ }(method));
+ }
+
+ var reporters = [];
+ var fallbackReporter = null;
+
+ this.addReporter = function(reporter) {
+ reporters.push(reporter);
+ };
+
+ this.provideFallbackReporter = function(reporter) {
+ fallbackReporter = reporter;
+ };
+
+ this.clearReporters = function() {
+ reporters = [];
+ };
+
+ return this;
+
+ function dispatch(method, args) {
+ if (reporters.length === 0 && fallbackReporter !== null) {
+ reporters.push(fallbackReporter);
+ }
+ for (var i = 0; i < reporters.length; i++) {
+ var reporter = reporters[i];
+ if (reporter[method]) {
+ reporter[method].apply(reporter, j$.util.cloneArgs(args));
+ }
+ }
+ }
+ }
+
+ return ReportDispatcher;
+};
+
+
+getJasmineRequireObj().interface = function(jasmine, env) {
+ var jasmineInterface = {
+ /**
+ * Callback passed to parts of the Jasmine base interface.
+ *
+ * By default Jasmine assumes this function completes synchronously.
+ * If you have code that you need to test asynchronously, you can declare that you receive a `done` callback, return a Promise, or use the `async` keyword if it is supported in your environment.
+ * @callback implementationCallback
+ * @param {Function} [done] Used to specify to Jasmine that this callback is asynchronous and Jasmine should wait until it has been called before moving on.
+ * @returns {} Optionally return a Promise instead of using `done` to cause Jasmine to wait for completion.
+ */
+
+ /**
+ * Create a group of specs (often called a suite).
+ *
+ * Calls to `describe` can be nested within other calls to compose your suite as a tree.
+ * @name describe
+ * @function
+ * @global
+ * @param {String} description Textual description of the group
+ * @param {Function} specDefinitions Function for Jasmine to invoke that will define inner suites and specs
+ */
+ describe: function(description, specDefinitions) {
+ return env.describe(description, specDefinitions);
+ },
+
+ /**
+ * A temporarily disabled [`describe`]{@link describe}
+ *
+ * Specs within an `xdescribe` will be marked pending and not executed
+ * @name xdescribe
+ * @function
+ * @global
+ * @param {String} description Textual description of the group
+ * @param {Function} specDefinitions Function for Jasmine to invoke that will define inner suites and specs
+ */
+ xdescribe: function(description, specDefinitions) {
+ return env.xdescribe(description, specDefinitions);
+ },
+
+ /**
+ * A focused [`describe`]{@link describe}
+ *
+ * If suites or specs are focused, only those that are focused will be executed
+ * @see fit
+ * @name fdescribe
+ * @function
+ * @global
+ * @param {String} description Textual description of the group
+ * @param {Function} specDefinitions Function for Jasmine to invoke that will define inner suites and specs
+ */
+ fdescribe: function(description, specDefinitions) {
+ return env.fdescribe(description, specDefinitions);
+ },
+
+ /**
+ * Define a single spec. A spec should contain one or more {@link expect|expectations} that test the state of the code.
+ *
+ * A spec whose expectations all succeed will be passing and a spec with any failures will fail.
+ * @name it
+ * @function
+ * @global
+ * @param {String} description Textual description of what this spec is checking
+ * @param {implementationCallback} [testFunction] Function that contains the code of your test. If not provided the test will be `pending`.
+ * @param {Int} [timeout={@link jasmine.DEFAULT_TIMEOUT_INTERVAL}] Custom timeout for an async spec.
+ */
+ it: function() {
+ return env.it.apply(env, arguments);
+ },
+
+ /**
+ * A temporarily disabled [`it`]{@link it}
+ *
+ * The spec will report as `pending` and will not be executed.
+ * @name xit
+ * @function
+ * @global
+ * @param {String} description Textual description of what this spec is checking.
+ * @param {implementationCallback} [testFunction] Function that contains the code of your test. Will not be executed.
+ */
+ xit: function() {
+ return env.xit.apply(env, arguments);
+ },
+
+ /**
+ * A focused [`it`]{@link it}
+ *
+ * If suites or specs are focused, only those that are focused will be executed.
+ * @name fit
+ * @function
+ * @global
+ * @param {String} description Textual description of what this spec is checking.
+ * @param {implementationCallback} testFunction Function that contains the code of your test.
+ * @param {Int} [timeout={@link jasmine.DEFAULT_TIMEOUT_INTERVAL}] Custom timeout for an async spec.
+ */
+ fit: function() {
+ return env.fit.apply(env, arguments);
+ },
+
+ /**
+ * Run some shared setup before each of the specs in the {@link describe} in which it is called.
+ * @name beforeEach
+ * @function
+ * @global
+ * @param {implementationCallback} [function] Function that contains the code to setup your specs.
+ * @param {Int} [timeout={@link jasmine.DEFAULT_TIMEOUT_INTERVAL}] Custom timeout for an async beforeEach.
+ */
+ beforeEach: function() {
+ return env.beforeEach.apply(env, arguments);
+ },
+
+ /**
+ * Run some shared teardown after each of the specs in the {@link describe} in which it is called.
+ * @name afterEach
+ * @function
+ * @global
+ * @param {implementationCallback} [function] Function that contains the code to teardown your specs.
+ * @param {Int} [timeout={@link jasmine.DEFAULT_TIMEOUT_INTERVAL}] Custom timeout for an async afterEach.
+ */
+ afterEach: function() {
+ return env.afterEach.apply(env, arguments);
+ },
+
+ /**
+ * Run some shared setup once before all of the specs in the {@link describe} are run.
+ *
+ * _Note:_ Be careful, sharing the setup from a beforeAll makes it easy to accidentally leak state between your specs so that they erroneously pass or fail.
+ * @name beforeAll
+ * @function
+ * @global
+ * @param {implementationCallback} [function] Function that contains the code to setup your specs.
+ * @param {Int} [timeout={@link jasmine.DEFAULT_TIMEOUT_INTERVAL}] Custom timeout for an async beforeAll.
+ */
+ beforeAll: function() {
+ return env.beforeAll.apply(env, arguments);
+ },
+
+ /**
+ * Run some shared teardown once after all of the specs in the {@link describe} are run.
+ *
+ * _Note:_ Be careful, sharing the teardown from a afterAll makes it easy to accidentally leak state between your specs so that they erroneously pass or fail.
+ * @name afterAll
+ * @function
+ * @global
+ * @param {implementationCallback} [function] Function that contains the code to teardown your specs.
+ * @param {Int} [timeout={@link jasmine.DEFAULT_TIMEOUT_INTERVAL}] Custom timeout for an async afterAll.
+ */
+ afterAll: function() {
+ return env.afterAll.apply(env, arguments);
+ },
+
+ /**
+ * Create an expectation for a spec.
+ * @name expect
+ * @function
+ * @global
+ * @param {Object} actual - Actual computed value to test expectations against.
+ * @return {matchers}
+ */
+ expect: function(actual) {
+ return env.expect(actual);
+ },
+
+ /**
+ * Mark a spec as pending, expectation results will be ignored.
+ * @name pending
+ * @function
+ * @global
+ * @param {String} [message] - Reason the spec is pending.
+ */
+ pending: function() {
+ return env.pending.apply(env, arguments);
+ },
+
+ /**
+ * Explicitly mark a spec as failed.
+ * @name fail
+ * @function
+ * @global
+ * @param {String|Error} [error] - Reason for the failure.
+ */
+ fail: function() {
+ return env.fail.apply(env, arguments);
+ },
+
+ /**
+ * Install a spy onto an existing object.
+ * @name spyOn
+ * @function
+ * @global
+ * @param {Object} obj - The object upon which to install the {@link Spy}.
+ * @param {String} methodName - The name of the method to replace with a {@link Spy}.
+ * @returns {Spy}
+ */
+ spyOn: function(obj, methodName) {
+ return env.spyOn(obj, methodName);
+ },
+
+ /**
+ * Install a spy on a property installed with `Object.defineProperty` onto an existing object.
+ * @name spyOnProperty
+ * @function
+ * @global
+ * @param {Object} obj - The object upon which to install the {@link Spy}
+ * @param {String} propertyName - The name of the property to replace with a {@link Spy}.
+ * @param {String} [accessType=get] - The access type (get|set) of the property to {@link Spy} on.
+ * @returns {Spy}
+ */
+ spyOnProperty: function(obj, methodName, accessType) {
+ return env.spyOnProperty(obj, methodName, accessType);
+ },
+
+ jsApiReporter: new jasmine.JsApiReporter({
+ timer: new jasmine.Timer()
+ }),
+
+ /**
+ * @namespace jasmine
+ */
+ jasmine: jasmine
+ };
+
+ /**
+ * Add a custom equality tester for the current scope of specs.
+ *
+ * _Note:_ This is only callable from within a {@link beforeEach}, {@link it}, or {@link beforeAll}.
+ * @name jasmine.addCustomEqualityTester
+ * @function
+ * @param {Function} tester - A function which takes two arguments to compare and returns a `true` or `false` comparison result if it knows how to compare them, and `undefined` otherwise.
+ * @see custom_equality
+ */
+ jasmine.addCustomEqualityTester = function(tester) {
+ env.addCustomEqualityTester(tester);
+ };
+
+ /**
+ * Add custom matchers for the current scope of specs.
+ *
+ * _Note:_ This is only callable from within a {@link beforeEach}, {@link it}, or {@link beforeAll}.
+ * @name jasmine.addMatchers
+ * @function
+ * @param {Object} matchers - Keys from this object will be the new matcher names.
+ * @see custom_matcher
+ */
+ jasmine.addMatchers = function(matchers) {
+ return env.addMatchers(matchers);
+ };
+
+ /**
+ * Get the currently booted mock {Clock} for this Jasmine environment.
+ * @name jasmine.clock
+ * @function
+ * @returns {Clock}
+ */
+ jasmine.clock = function() {
+ return env.clock;
+ };
+
+ return jasmineInterface;
+};
+
+getJasmineRequireObj().Spy = function (j$) {
+
+ var nextOrder = (function() {
+ var order = 0;
+
+ return function() {
+ return order++;
+ };
+ })();
+
+ /**
+ * _Note:_ Do not construct this directly, use {@link spyOn}, {@link spyOnProperty}, {@link jasmine.createSpy}, or {@link jasmine.createSpyObj}
+ * @constructor
+ * @name Spy
+ */
+ function Spy(name, originalFn) {
+ var numArgs = (typeof originalFn === 'function' ? originalFn.length : 0),
+ wrapper = makeFunc(numArgs, function () {
+ return spy.apply(this, Array.prototype.slice.call(arguments));
+ }),
+ spyStrategy = new j$.SpyStrategy({
+ name: name,
+ fn: originalFn,
+ getSpy: function () {
+ return wrapper;
+ }
+ }),
+ callTracker = new j$.CallTracker(),
+ spy = function () {
+ /**
+ * @name Spy.callData
+ * @property {object} object - `this` context for the invocation.
+ * @property {number} invocationOrder - Order of the invocation.
+ * @property {Array} args - The arguments passed for this invocation.
+ */
+ var callData = {
+ object: this,
+ invocationOrder: nextOrder(),
+ args: Array.prototype.slice.apply(arguments)
+ };
+
+ callTracker.track(callData);
+ var returnValue = spyStrategy.exec.apply(this, arguments);
+ callData.returnValue = returnValue;
+
+ return returnValue;
+ };
+
+ function makeFunc(length, fn) {
+ switch (length) {
+ case 1 : return function (a) { return fn.apply(this, arguments); };
+ case 2 : return function (a,b) { return fn.apply(this, arguments); };
+ case 3 : return function (a,b,c) { return fn.apply(this, arguments); };
+ case 4 : return function (a,b,c,d) { return fn.apply(this, arguments); };
+ case 5 : return function (a,b,c,d,e) { return fn.apply(this, arguments); };
+ case 6 : return function (a,b,c,d,e,f) { return fn.apply(this, arguments); };
+ case 7 : return function (a,b,c,d,e,f,g) { return fn.apply(this, arguments); };
+ case 8 : return function (a,b,c,d,e,f,g,h) { return fn.apply(this, arguments); };
+ case 9 : return function (a,b,c,d,e,f,g,h,i) { return fn.apply(this, arguments); };
+ default : return function () { return fn.apply(this, arguments); };
+ }
+ }
+
+ for (var prop in originalFn) {
+ if (prop === 'and' || prop === 'calls') {
+ throw new Error('Jasmine spies would overwrite the \'and\' and \'calls\' properties on the object being spied upon');
+ }
+
+ wrapper[prop] = originalFn[prop];
+ }
+
+ wrapper.and = spyStrategy;
+ wrapper.calls = callTracker;
+
+ return wrapper;
+ }
+
+ return Spy;
+};
+
+getJasmineRequireObj().SpyRegistry = function(j$) {
+
+ var getErrorMsg = j$.formatErrorMsg('<spyOn>', 'spyOn(<object>, <methodName>)');
+
+ function SpyRegistry(options) {
+ options = options || {};
+ var global = options.global || j$.getGlobal();
+ var currentSpies = options.currentSpies || function() { return []; };
+
+ this.allowRespy = function(allow){
+ this.respy = allow;
+ };
+
+ this.spyOn = function(obj, methodName) {
+
+ if (j$.util.isUndefined(obj) || obj === null) {
+ throw new Error(getErrorMsg('could not find an object to spy upon for ' + methodName + '()'));
+ }
+
+ if (j$.util.isUndefined(methodName) || methodName === null) {
+ throw new Error(getErrorMsg('No method name supplied'));
+ }
+
+ if (j$.util.isUndefined(obj[methodName])) {
+ throw new Error(getErrorMsg(methodName + '() method does not exist'));
+ }
+
+ if (obj[methodName] && j$.isSpy(obj[methodName]) ) {
+ if ( !!this.respy ){
+ return obj[methodName];
+ }else {
+ throw new Error(getErrorMsg(methodName + ' has already been spied upon'));
+ }
+ }
+
+ var descriptor;
+ try {
+ descriptor = Object.getOwnPropertyDescriptor(obj, methodName);
+ } catch(e) {
+ // IE 8 doesn't support `definePropery` on non-DOM nodes
+ }
+
+ if (descriptor && !(descriptor.writable || descriptor.set)) {
+ throw new Error(getErrorMsg(methodName + ' is not declared writable or has no setter'));
+ }
+
+ var originalMethod = obj[methodName],
+ spiedMethod = j$.createSpy(methodName, originalMethod),
+ restoreStrategy;
+
+ if (Object.prototype.hasOwnProperty.call(obj, methodName) || (obj === global && methodName === 'onerror')) {
+ restoreStrategy = function() {
+ obj[methodName] = originalMethod;
+ };
+ } else {
+ restoreStrategy = function() {
+ if (!delete obj[methodName]) {
+ obj[methodName] = originalMethod;
+ }
+ };
+ }
+
+ currentSpies().push({
+ restoreObjectToOriginalState: restoreStrategy
+ });
+
+ obj[methodName] = spiedMethod;
+
+ return spiedMethod;
+ };
+
+ this.spyOnProperty = function (obj, propertyName, accessType) {
+ accessType = accessType || 'get';
+
+ if (j$.util.isUndefined(obj)) {
+ throw new Error('spyOn could not find an object to spy upon for ' + propertyName + '');
+ }
+
+ if (j$.util.isUndefined(propertyName)) {
+ throw new Error('No property name supplied');
+ }
+
+ var descriptor;
+ try {
+ descriptor = j$.util.getPropertyDescriptor(obj, propertyName);
+ } catch(e) {
+ // IE 8 doesn't support `definePropery` on non-DOM nodes
+ }
+
+ if (!descriptor) {
+ throw new Error(propertyName + ' property does not exist');
+ }
+
+ if (!descriptor.configurable) {
+ throw new Error(propertyName + ' is not declared configurable');
+ }
+
+ if(!descriptor[accessType]) {
+ throw new Error('Property ' + propertyName + ' does not have access type ' + accessType);
+ }
+
+ if (j$.isSpy(descriptor[accessType])) {
+ //TODO?: should this return the current spy? Downside: may cause user confusion about spy state
+ throw new Error(propertyName + ' has already been spied upon');
+ }
+
+ var originalDescriptor = j$.util.clone(descriptor),
+ spy = j$.createSpy(propertyName, descriptor[accessType]),
+ restoreStrategy;
+
+ if (Object.prototype.hasOwnProperty.call(obj, propertyName)) {
+ restoreStrategy = function() {
+ Object.defineProperty(obj, propertyName, originalDescriptor);
+ };
+ } else {
+ restoreStrategy = function() {
+ delete obj[propertyName];
+ };
+ }
+
+ currentSpies().push({
+ restoreObjectToOriginalState: restoreStrategy
+ });
+
+ descriptor[accessType] = spy;
+
+ Object.defineProperty(obj, propertyName, descriptor);
+
+ return spy;
+ };
+
+ this.clearSpies = function() {
+ var spies = currentSpies();
+ for (var i = spies.length - 1; i >= 0; i--) {
+ var spyEntry = spies[i];
+ spyEntry.restoreObjectToOriginalState();
+ }
+ };
+ }
+
+ return SpyRegistry;
+};
+
+getJasmineRequireObj().SpyStrategy = function(j$) {
+
+ /**
+ * @namespace Spy#and
+ */
+ function SpyStrategy(options) {
+ options = options || {};
+
+ var identity = options.name || 'unknown',
+ originalFn = options.fn || function() {},
+ getSpy = options.getSpy || function() {},
+ plan = function() {};
+
+ /**
+ * Return the identifying information for the spy.
+ * @name Spy#and#identity
+ * @function
+ * @returns {String}
+ */
+ this.identity = function() {
+ return identity;
+ };
+
+ /**
+ * Execute the current spy strategy.
+ * @name Spy#and#exec
+ * @function
+ */
+ this.exec = function() {
+ return plan.apply(this, arguments);
+ };
+
+ /**
+ * Tell the spy to call through to the real implementation when invoked.
+ * @name Spy#and#callThrough
+ * @function
+ */
+ this.callThrough = function() {
+ plan = originalFn;
+ return getSpy();
+ };
+
+ /**
+ * Tell the spy to return the value when invoked.
+ * @name Spy#and#returnValue
+ * @function
+ * @param {*} value The value to return.
+ */
+ this.returnValue = function(value) {
+ plan = function() {
+ return value;
+ };
+ return getSpy();
+ };
+
+ /**
+ * Tell the spy to return one of the specified values (sequentially) each time the spy is invoked.
+ * @name Spy#and#returnValues
+ * @function
+ * @param {...*} values - Values to be returned on subsequent calls to the spy.
+ */
+ this.returnValues = function() {
+ var values = Array.prototype.slice.call(arguments);
+ plan = function () {
+ return values.shift();
+ };
+ return getSpy();
+ };
+
+ /**
+ * Tell the spy to throw an error when invoked.
+ * @name Spy#and#throwError
+ * @function
+ * @param {Error|String} something Thing to throw
+ */
+ this.throwError = function(something) {
+ var error = (something instanceof Error) ? something : new Error(something);
+ plan = function() {
+ throw error;
+ };
+ return getSpy();
+ };
+
+ /**
+ * Tell the spy to call a fake implementation when invoked.
+ * @name Spy#and#callFake
+ * @function
+ * @param {Function} fn The function to invoke with the passed parameters.
+ */
+ this.callFake = function(fn) {
+ if(!(j$.isFunction_(fn) || j$.isAsyncFunction_(fn))) {
+ throw new Error('Argument passed to callFake should be a function, got ' + fn);
+ }
+ plan = fn;
+ return getSpy();
+ };
+
+ /**
+ * Tell the spy to do nothing when invoked. This is the default.
+ * @name Spy#and#stub
+ * @function
+ */
+ this.stub = function(fn) {
+ plan = function() {};
+ return getSpy();
+ };
+ }
+
+ return SpyStrategy;
+};
+
+getJasmineRequireObj().Suite = function(j$) {
+ function Suite(attrs) {
+ this.env = attrs.env;
+ this.id = attrs.id;
+ this.parentSuite = attrs.parentSuite;
+ this.description = attrs.description;
+ this.expectationFactory = attrs.expectationFactory;
+ this.expectationResultFactory = attrs.expectationResultFactory;
+ this.throwOnExpectationFailure = !!attrs.throwOnExpectationFailure;
+
+ this.beforeFns = [];
+ this.afterFns = [];
+ this.beforeAllFns = [];
+ this.afterAllFns = [];
+
+ this.children = [];
+
+ /**
+ * @typedef SuiteResult
+ * @property {Int} id - The unique id of this suite.
+ * @property {String} description - The description text passed to the {@link describe} that made this suite.
+ * @property {String} fullName - The full description including all ancestors of this suite.
+ * @property {Expectation[]} failedExpectations - The list of expectations that failed in an {@link afterAll} for this suite.
+ * @property {Expectation[]} deprecationWarnings - The list of deprecation warnings that occurred on this suite.
+ * @property {String} status - Once the suite has completed, this string represents the pass/fail status of this suite.
+ */
+ this.result = {
+ id: this.id,
+ description: this.description,
+ fullName: this.getFullName(),
+ failedExpectations: [],
+ deprecationWarnings: []
+ };
+ }
+
+ Suite.prototype.expect = function(actual) {
+ return this.expectationFactory(actual, this);
+ };
+
+ Suite.prototype.getFullName = function() {
+ var fullName = [];
+ for (var parentSuite = this; parentSuite; parentSuite = parentSuite.parentSuite) {
+ if (parentSuite.parentSuite) {
+ fullName.unshift(parentSuite.description);
+ }
+ }
+ return fullName.join(' ');
+ };
+
+ Suite.prototype.pend = function() {
+ this.markedPending = true;
+ };
+
+ Suite.prototype.beforeEach = function(fn) {
+ this.beforeFns.unshift(fn);
+ };
+
+ Suite.prototype.beforeAll = function(fn) {
+ this.beforeAllFns.push(fn);
+ };
+
+ Suite.prototype.afterEach = function(fn) {
+ this.afterFns.unshift(fn);
+ };
+
+ Suite.prototype.afterAll = function(fn) {
+ this.afterAllFns.unshift(fn);
+ };
+
+ Suite.prototype.addChild = function(child) {
+ this.children.push(child);
+ };
+
+ Suite.prototype.status = function() {
+ if (this.markedPending) {
+ return 'pending';
+ }
+
+ if (this.result.failedExpectations.length > 0) {
+ return 'failed';
+ } else {
+ return 'finished';
+ }
+ };
+
+ Suite.prototype.isExecutable = function() {
+ return !this.markedPending;
+ };
+
+ Suite.prototype.canBeReentered = function() {
+ return this.beforeAllFns.length === 0 && this.afterAllFns.length === 0;
+ };
+
+ Suite.prototype.getResult = function() {
+ this.result.status = this.status();
+ return this.result;
+ };
+
+ Suite.prototype.sharedUserContext = function() {
+ if (!this.sharedContext) {
+ this.sharedContext = this.parentSuite ? this.parentSuite.clonedSharedUserContext() : new j$.UserContext();
+ }
+
+ return this.sharedContext;
+ };
+
+ Suite.prototype.clonedSharedUserContext = function() {
+ return j$.UserContext.fromExisting(this.sharedUserContext());
+ };
+
+ Suite.prototype.onException = function() {
+ if (arguments[0] instanceof j$.errors.ExpectationFailed) {
+ return;
+ }
+
+ if(isAfterAll(this.children)) {
+ var data = {
+ matcherName: '',
+ passed: false,
+ expected: '',
+ actual: '',
+ error: arguments[0]
+ };
+ this.result.failedExpectations.push(this.expectationResultFactory(data));
+ } else {
+ for (var i = 0; i < this.children.length; i++) {
+ var child = this.children[i];
+ child.onException.apply(child, arguments);
+ }
+ }
+ };
+
+ Suite.prototype.addExpectationResult = function () {
+ if(isAfterAll(this.children) && isFailure(arguments)){
+ var data = arguments[1];
+ this.result.failedExpectations.push(this.expectationResultFactory(data));
+ if(this.throwOnExpectationFailure) {
+ throw new j$.errors.ExpectationFailed();
+ }
+ } else {
+ for (var i = 0; i < this.children.length; i++) {
+ var child = this.children[i];
+ try {
+ child.addExpectationResult.apply(child, arguments);
+ } catch(e) {
+ // keep going
+ }
+ }
+ }
+ };
+
+ Suite.prototype.addDeprecationWarning = function(msg) {
+ this.result.deprecationWarnings.push(this.expectationResultFactory({ message: msg }));
+ };
+
+ function isAfterAll(children) {
+ return children && children[0].result.status;
+ }
+
+ function isFailure(args) {
+ return !args[0];
+ }
+
+ return Suite;
+};
+
+if (typeof window == void 0 && typeof exports == 'object') {
+ exports.Suite = jasmineRequire.Suite;
+}
+
+getJasmineRequireObj().Timer = function() {
+ var defaultNow = (function(Date) {
+ return function() { return new Date().getTime(); };
+ })(Date);
+
+ function Timer(options) {
+ options = options || {};
+
+ var now = options.now || defaultNow,
+ startTime;
+
+ this.start = function() {
+ startTime = now();
+ };
+
+ this.elapsed = function() {
+ return now() - startTime;
+ };
+ }
+
+ return Timer;
+};
+
+getJasmineRequireObj().TreeProcessor = function() {
+ function TreeProcessor(attrs) {
+ var tree = attrs.tree,
+ runnableIds = attrs.runnableIds,
+ queueRunnerFactory = attrs.queueRunnerFactory,
+ nodeStart = attrs.nodeStart || function() {},
+ nodeComplete = attrs.nodeComplete || function() {},
+ orderChildren = attrs.orderChildren || function(node) { return node.children; },
+ stats = { valid: true },
+ processed = false,
+ defaultMin = Infinity,
+ defaultMax = 1 - Infinity;
+
+ this.processTree = function() {
+ processNode(tree, false);
+ processed = true;
+ return stats;
+ };
+
+ this.execute = function(done) {
+ if (!processed) {
+ this.processTree();
+ }
+
+ if (!stats.valid) {
+ throw 'invalid order';
+ }
+
+ var childFns = wrapChildren(tree, 0);
+
+ queueRunnerFactory({
+ queueableFns: childFns,
+ userContext: tree.sharedUserContext(),
+ onException: function() {
+ tree.onException.apply(tree, arguments);
+ },
+ onComplete: done
+ });
+ };
+
+ function runnableIndex(id) {
+ for (var i = 0; i < runnableIds.length; i++) {
+ if (runnableIds[i] === id) {
+ return i;
+ }
+ }
+ }
+
+ function processNode(node, parentEnabled) {
+ var executableIndex = runnableIndex(node.id);
+
+ if (executableIndex !== undefined) {
+ parentEnabled = true;
+ }
+
+ parentEnabled = parentEnabled && node.isExecutable();
+
+ if (!node.children) {
+ stats[node.id] = {
+ executable: parentEnabled && node.isExecutable(),
+ segments: [{
+ index: 0,
+ owner: node,
+ nodes: [node],
+ min: startingMin(executableIndex),
+ max: startingMax(executableIndex)
+ }]
+ };
+ } else {
+ var hasExecutableChild = false;
+
+ var orderedChildren = orderChildren(node);
+
+ for (var i = 0; i < orderedChildren.length; i++) {
+ var child = orderedChildren[i];
+
+ processNode(child, parentEnabled);
+
+ if (!stats.valid) {
+ return;
+ }
+
+ var childStats = stats[child.id];
+
+ hasExecutableChild = hasExecutableChild || childStats.executable;
+ }
+
+ stats[node.id] = {
+ executable: hasExecutableChild
+ };
+
+ segmentChildren(node, orderedChildren, stats[node.id], executableIndex);
+
+ if (!node.canBeReentered() && stats[node.id].segments.length > 1) {
+ stats = { valid: false };
+ }
+ }
+ }
+
+ function startingMin(executableIndex) {
+ return executableIndex === undefined ? defaultMin : executableIndex;
+ }
+
+ function startingMax(executableIndex) {
+ return executableIndex === undefined ? defaultMax : executableIndex;
+ }
+
+ function segmentChildren(node, orderedChildren, nodeStats, executableIndex) {
+ var currentSegment = { index: 0, owner: node, nodes: [], min: startingMin(executableIndex), max: startingMax(executableIndex) },
+ result = [currentSegment],
+ lastMax = defaultMax,
+ orderedChildSegments = orderChildSegments(orderedChildren);
+
+ function isSegmentBoundary(minIndex) {
+ return lastMax !== defaultMax && minIndex !== defaultMin && lastMax < minIndex - 1;
+ }
+
+ for (var i = 0; i < orderedChildSegments.length; i++) {
+ var childSegment = orderedChildSegments[i],
+ maxIndex = childSegment.max,
+ minIndex = childSegment.min;
+
+ if (isSegmentBoundary(minIndex)) {
+ currentSegment = {index: result.length, owner: node, nodes: [], min: defaultMin, max: defaultMax};
+ result.push(currentSegment);
+ }
+
+ currentSegment.nodes.push(childSegment);
+ currentSegment.min = Math.min(currentSegment.min, minIndex);
+ currentSegment.max = Math.max(currentSegment.max, maxIndex);
+ lastMax = maxIndex;
+ }
+
+ nodeStats.segments = result;
+ }
+
+ function orderChildSegments(children) {
+ var specifiedOrder = [],
+ unspecifiedOrder = [];
+
+ for (var i = 0; i < children.length; i++) {
+ var child = children[i],
+ segments = stats[child.id].segments;
+
+ for (var j = 0; j < segments.length; j++) {
+ var seg = segments[j];
+
+ if (seg.min === defaultMin) {
+ unspecifiedOrder.push(seg);
+ } else {
+ specifiedOrder.push(seg);
+ }
+ }
+ }
+
+ specifiedOrder.sort(function(a, b) {
+ return a.min - b.min;
+ });
+
+ return specifiedOrder.concat(unspecifiedOrder);
+ }
+
+ function executeNode(node, segmentNumber) {
+ if (node.children) {
+ return {
+ fn: function(done) {
+ nodeStart(node);
+
+ queueRunnerFactory({
+ onComplete: function() {
+ nodeComplete(node, node.getResult());
+ done();
+ },
+ queueableFns: wrapChildren(node, segmentNumber),
+ userContext: node.sharedUserContext(),
+ onException: function() {
+ node.onException.apply(node, arguments);
+ }
+ });
+ }
+ };
+ } else {
+ return {
+ fn: function(done) { node.execute(done, stats[node.id].executable); }
+ };
+ }
+ }
+
+ function wrapChildren(node, segmentNumber) {
+ var result = [],
+ segmentChildren = stats[node.id].segments[segmentNumber].nodes;
+
+ for (var i = 0; i < segmentChildren.length; i++) {
+ result.push(executeNode(segmentChildren[i].owner, segmentChildren[i].index));
+ }
+
+ if (!stats[node.id].executable) {
+ return result;
+ }
+
+ return node.beforeAllFns.concat(result).concat(node.afterAllFns);
+ }
+ }
+
+ return TreeProcessor;
+};
+
+getJasmineRequireObj().UserContext = function(j$) {
+ function UserContext() {
+ }
+
+ UserContext.fromExisting = function(oldContext) {
+ var context = new UserContext();
+
+ for (var prop in oldContext) {
+ if (oldContext.hasOwnProperty(prop)) {
+ context[prop] = oldContext[prop];
+ }
+ }
+
+ return context;
+ };
+
+ return UserContext;
+};
+
+getJasmineRequireObj().version = function() {
+ return '2.99.0';
+};
diff --git a/www/assets/jasmine-2.4.1/jasmine_favicon.png b/www/assets/jasmine-2.99.0/jasmine_favicon.png
old mode 100755
new mode 100644
similarity index 100%
rename from www/assets/jasmine-2.4.1/jasmine_favicon.png
rename to www/assets/jasmine-2.99.0/jasmine_favicon.png
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org