Merge pull request #14020 from edx/andya/update-gemnasium-libraries
Clean up npm-installed packages
This commit is contained in:
@@ -1,3 +1,6 @@
|
||||
/* globals _, requirejs */
|
||||
/* eslint-disable quote-props */
|
||||
|
||||
(function(require, define) {
|
||||
'use strict';
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/* globals requirejs, requireSerial */
|
||||
/* eslint-disable quote-props */
|
||||
|
||||
(function(requirejs, requireSerial) {
|
||||
'use strict';
|
||||
@@ -48,8 +49,8 @@
|
||||
'xblock': 'common/js/xblock',
|
||||
'utility': 'xmodule_js/common_static/js/src/utility',
|
||||
'accessibility': 'xmodule_js/common_static/js/src/accessibility_tools',
|
||||
'sinon': 'xmodule_js/common_static/js/vendor/sinon-1.17.0',
|
||||
'squire': 'xmodule_js/common_static/js/vendor/Squire',
|
||||
'sinon': 'common/js/vendor/sinon',
|
||||
'squire': 'common/js/vendor/Squire',
|
||||
'jasmine-imagediff': 'xmodule_js/common_static/js/vendor/jasmine-imagediff',
|
||||
'draggabilly': 'xmodule_js/common_static/js/vendor/draggabilly',
|
||||
'domReady': 'xmodule_js/common_static/js/vendor/domReady',
|
||||
@@ -289,6 +290,6 @@
|
||||
];
|
||||
|
||||
requireSerial(specHelpers.concat(testFiles), function() {
|
||||
return window.__karma__.start();
|
||||
return window.__karma__.start(); // eslint-disable-line no-underscore-dangle
|
||||
});
|
||||
}).call(this, requirejs, requireSerial);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/* globals requirejs, requireSerial */
|
||||
/* eslint-disable quote-props */
|
||||
|
||||
(function(requirejs, requireSerial) {
|
||||
'use strict';
|
||||
@@ -43,8 +44,8 @@
|
||||
'xblock/cms.runtime.v1': 'cms/js/xblock/cms.runtime.v1',
|
||||
'xblock': 'common/js/xblock',
|
||||
'utility': 'xmodule_js/common_static/js/src/utility',
|
||||
'sinon': 'xmodule_js/common_static/js/vendor/sinon-1.17.0',
|
||||
'squire': 'xmodule_js/common_static/js/vendor/Squire',
|
||||
'sinon': 'common/js/vendor/sinon',
|
||||
'squire': 'common/js/vendor/Squire',
|
||||
'draggabilly': 'xmodule_js/common_static/js/vendor/draggabilly',
|
||||
'domReady': 'xmodule_js/common_static/js/vendor/domReady',
|
||||
'URI': 'xmodule_js/common_static/js/vendor/URI.min',
|
||||
@@ -206,6 +207,6 @@
|
||||
];
|
||||
|
||||
requireSerial(specHelpers.concat(testFiles), function() {
|
||||
return window.__karma__.start();
|
||||
return window.__karma__.start(); // eslint-disable-line no-underscore-dangle
|
||||
});
|
||||
}).call(this, requirejs, requireSerial);
|
||||
|
||||
@@ -60,7 +60,7 @@ from openedx.core.djangolib.js_utils import (
|
||||
window.baseUrl = "${settings.STATIC_URL | n, js_escaped_string}";
|
||||
var require = {baseUrl: window.baseUrl};
|
||||
</script>
|
||||
<script type="text/javascript" src="${static.url("js/vendor/requirejs/require.js")}"></script>
|
||||
<script type="text/javascript" src="${static.url("common/js/vendor/require.js")}"></script>
|
||||
<script type="text/javascript" src="${static.url("cms/js/require-config.js")}"></script>
|
||||
|
||||
<!-- view -->
|
||||
|
||||
@@ -31,7 +31,7 @@ var options = {
|
||||
{pattern: 'common_static/js/vendor/jquery-ui.min.js', included: true},
|
||||
{pattern: 'common_static/js/vendor/jquery.ui.draggable.js', included: true},
|
||||
{pattern: 'common_static/js/vendor/json2.js', included: true},
|
||||
{pattern: 'common_static/js/vendor/moment-with-locales.js', included: true},
|
||||
{pattern: 'common_static/common/js/vendor/moment-with-locales.js', included: true},
|
||||
{pattern: 'common_static/js/vendor/tinymce/js/tinymce/jquery.tinymce.min.js', included: true},
|
||||
{pattern: 'common_static/js/vendor/tinymce/js/tinymce/tinymce.full.min.js', included: true},
|
||||
{pattern: 'common_static/js/src/accessibility_tools.js', included: true},
|
||||
@@ -46,7 +46,7 @@ var options = {
|
||||
{pattern: 'common_static/js/vendor/jasmine-imagediff.js', included: true},
|
||||
{pattern: 'common_static/common/js/spec_helpers/jasmine-waituntil.js', included: true},
|
||||
{pattern: 'common_static/common/js/spec_helpers/jasmine-extensions.js', included: true},
|
||||
{pattern: 'common_static/js/vendor/sinon-1.17.0.js', included: true},
|
||||
{pattern: 'common_static/common/js/vendor/sinon.js', included: true},
|
||||
|
||||
// Load the edX global namespace before RequireJS is installed
|
||||
{pattern: 'common_static/edx-ui-toolkit/js/utils/global-loader.js', included: true},
|
||||
@@ -54,7 +54,7 @@ var options = {
|
||||
{pattern: 'common_static/edx-ui-toolkit/js/utils/html-utils.js', included: true},
|
||||
|
||||
// Load RequireJS and move it into the RequireJS namespace
|
||||
{pattern: 'common_static/js/vendor/requirejs/require.js', included: true},
|
||||
{pattern: 'common_static/common/js/vendor/require.js', included: true},
|
||||
{pattern: 'RequireJS-namespace-undefine.js', included: true},
|
||||
{pattern: 'spec/main_requirejs.js', included: true}
|
||||
],
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
requirejs.config({
|
||||
baseUrl: '/base/',
|
||||
paths: {
|
||||
moment: 'common_static/js/vendor/moment-with-locales',
|
||||
moment: 'common_static/common/js/vendor/moment-with-locales',
|
||||
'draggabilly': 'common_static/js/vendor/draggabilly',
|
||||
'edx-ui-toolkit': 'common_static/edx-ui-toolkit'
|
||||
},
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
(function(requirejs, define) {
|
||||
/* globals _, requirejs */
|
||||
/* eslint-disable quote-props */
|
||||
|
||||
(function(requirejs) {
|
||||
'use strict';
|
||||
|
||||
var testFiles, i, specHelpers;
|
||||
|
||||
requirejs.config({
|
||||
baseUrl: '/base/',
|
||||
paths: {
|
||||
@@ -24,7 +29,7 @@
|
||||
'jquery.immediateDescendents': 'coffee/src/jquery.immediateDescendents',
|
||||
'jquery.simulate': 'js/vendor/jquery.simulate',
|
||||
'jquery.url': 'js/vendor/url.min',
|
||||
'sinon': 'js/vendor/sinon-1.17.0',
|
||||
'sinon': 'common/js/vendor/sinon',
|
||||
'text': 'js/vendor/requirejs/text',
|
||||
'underscore': 'common/js/vendor/underscore',
|
||||
'underscore.string': 'common/js/vendor/underscore.string',
|
||||
@@ -152,7 +157,7 @@
|
||||
}
|
||||
});
|
||||
|
||||
var testFiles = [
|
||||
testFiles = [
|
||||
'common/js/spec/components/tabbed_view_spec.js',
|
||||
'common/js/spec/components/feedback_spec.js',
|
||||
'common/js/spec/components/list_spec.js',
|
||||
@@ -164,11 +169,11 @@
|
||||
'common/js/spec/utils/edx.utils.validate_spec.js'
|
||||
];
|
||||
|
||||
for (var i = 0; i < testFiles.length; i++) {
|
||||
for (i = 0; i < testFiles.length; i++) {
|
||||
testFiles[i] = '/base/' + testFiles[i];
|
||||
}
|
||||
|
||||
var specHelpers = [
|
||||
specHelpers = [
|
||||
'common/js/spec_helpers/jasmine-extensions',
|
||||
'common/js/spec_helpers/jasmine-stealth',
|
||||
'common/js/spec_helpers/jasmine-waituntil'
|
||||
@@ -178,6 +183,6 @@
|
||||
// spec files one by one, otherwise some end up getting nested under others.
|
||||
window.requireSerial(specHelpers.concat(testFiles), function() {
|
||||
// start test run, once Require.js is done
|
||||
window.__karma__.start();
|
||||
window.__karma__.start(); // eslint-disable-line no-underscore-dangle
|
||||
});
|
||||
}).call(this, requirejs, define);
|
||||
|
||||
250
common/static/js/vendor/Squire.js
vendored
250
common/static/js/vendor/Squire.js
vendored
@@ -1,250 +0,0 @@
|
||||
define(function() {
|
||||
|
||||
/**
|
||||
* Utility Functions
|
||||
*/
|
||||
|
||||
var toString = Object.prototype.toString;
|
||||
|
||||
var isArray = function(arr) {
|
||||
return toString.call(arr) === '[object Array]';
|
||||
};
|
||||
|
||||
var indexOf = function(arr, search) {
|
||||
for (var i = 0, length = arr.length; i < length; i++) {
|
||||
if (arr[i] === search) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
};
|
||||
|
||||
var each = function(obj, iterator, context) {
|
||||
var breaker = {};
|
||||
|
||||
if (obj === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Array.prototype.forEach && obj.forEach === Array.prototype.forEach) {
|
||||
obj.forEach(iterator, context);
|
||||
} else if (obj.length === +obj.length) {
|
||||
for (var i = 0, l = obj.length; i < l; i++) {
|
||||
if (iterator.call(context, obj[i], i, obj) === breaker){
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (var key in obj) {
|
||||
if (obj.hasOwnProperty(key)) {
|
||||
if (iterator.call(context, obj[key], key, obj) === breaker) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Require.js Abstractions
|
||||
*/
|
||||
|
||||
var getContext = function(id) {
|
||||
return requirejs.s.contexts[id];
|
||||
};
|
||||
|
||||
var undef = function(context, module) {
|
||||
if (context.undef) {
|
||||
return context.undef(module);
|
||||
}
|
||||
|
||||
return context.require.undef(module);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a context name incrementor.
|
||||
*/
|
||||
var idCounter = 0;
|
||||
var uniqueId = function(prefix) {
|
||||
var id = idCounter++;
|
||||
return 'context' + id;
|
||||
};
|
||||
|
||||
var Squire = function() {
|
||||
this.mocks = {};
|
||||
this._store = [];
|
||||
this.requiredCallbacks = [];
|
||||
this.configure.apply(this, arguments);
|
||||
};
|
||||
|
||||
/**
|
||||
* Hook to call when the require function is called.
|
||||
*/
|
||||
Squire.prototype.onRequired = function(cb) {
|
||||
this.requiredCallbacks.push(cb);
|
||||
};
|
||||
|
||||
/**
|
||||
* Configuration of Squire.js, called from constructor or manually takes the
|
||||
* name of a require.js context to configure it.
|
||||
*/
|
||||
Squire.prototype.configure = function(context) {
|
||||
var configuration = {};
|
||||
var property;
|
||||
|
||||
this.id = uniqueId();
|
||||
|
||||
// Default the context
|
||||
if (typeof context === 'undefined') {
|
||||
context = '_'; // Default require.js context
|
||||
}
|
||||
|
||||
context = getContext(context);
|
||||
|
||||
if ( ! context) {
|
||||
throw new Error('This context has not been created!');
|
||||
}
|
||||
|
||||
each(context.config, function(property, key) {
|
||||
if (key !== 'deps') {
|
||||
configuration[key] = property;
|
||||
}
|
||||
});
|
||||
|
||||
configuration.context = this.id;
|
||||
|
||||
this.load = requirejs.config(configuration);
|
||||
};
|
||||
|
||||
Squire.prototype.mock = function(path, mock) {
|
||||
var alias;
|
||||
if (typeof path === 'object') {
|
||||
each(path, function(alias, key) {
|
||||
this.mock(key, alias);
|
||||
}, this);
|
||||
} else {
|
||||
this.mocks[path] = mock;
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
Squire.prototype.store = function(path) {
|
||||
if (path && typeof path === 'string') {
|
||||
this._store.push(path);
|
||||
} else if(path && isArray(path)) {
|
||||
each(path, function(pathToStore) {
|
||||
this.store(pathToStore);
|
||||
}, this);
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
Squire.prototype.require = function(dependencies, callback, errback) {
|
||||
var magicModuleName = 'mocks';
|
||||
var self = this;
|
||||
var path, magicModuleLocation;
|
||||
|
||||
magicModuleLocation = indexOf(dependencies, magicModuleName);
|
||||
|
||||
if (magicModuleLocation !== -1) {
|
||||
dependencies.splice(magicModuleLocation, 1);
|
||||
}
|
||||
|
||||
each(this.mocks, function(mock, path) {
|
||||
define(path, mock);
|
||||
});
|
||||
|
||||
this.load(dependencies, function() {
|
||||
var store = {};
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
var dependency;
|
||||
|
||||
if (magicModuleLocation !== -1) {
|
||||
each(self._store, function(dependency) {
|
||||
store[dependency] = getContext(self.id).defined[dependency];
|
||||
});
|
||||
|
||||
args.splice(magicModuleLocation, 0, {
|
||||
mocks: self.mocks,
|
||||
store: store
|
||||
});
|
||||
}
|
||||
|
||||
callback.apply(null, args);
|
||||
|
||||
each(self.requiredCallbacks, function(cb) {
|
||||
cb.call(null, dependencies, args);
|
||||
});
|
||||
}, errback);
|
||||
};
|
||||
|
||||
Squire.prototype.clean = function(mock) {
|
||||
var path;
|
||||
|
||||
if (mock && typeof mock === 'string') {
|
||||
undef(getContext(this.id), mock);
|
||||
delete this.mocks[mock];
|
||||
} else if(mock && isArray(mock)) {
|
||||
each(mock, function(mockToClean) {
|
||||
this.clean(mockToClean);
|
||||
}, this);
|
||||
} else {
|
||||
each(this.mocks, function(mock, path){
|
||||
this.clean(path);
|
||||
}, this);
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
Squire.prototype.remove = function() {
|
||||
var path, context = getContext(this.id);
|
||||
if(!context) { return; }
|
||||
|
||||
each(context.defined, function(dependency, path) {
|
||||
undef(context, path);
|
||||
}, this);
|
||||
|
||||
delete requirejs.s.contexts[this.id];
|
||||
};
|
||||
|
||||
Squire.prototype.run = function(deps, callback) {
|
||||
var self = this;
|
||||
var run = function(done) {
|
||||
self.require(deps, function() {
|
||||
callback.apply(null, arguments);
|
||||
done();
|
||||
});
|
||||
};
|
||||
|
||||
run.toString = function() {
|
||||
return callback.toString();
|
||||
};
|
||||
|
||||
return run;
|
||||
};
|
||||
|
||||
/**
|
||||
* Utilities
|
||||
*/
|
||||
|
||||
Squire.Helpers = {};
|
||||
|
||||
Squire.Helpers.returns = function(what) {
|
||||
return function() {
|
||||
return what;
|
||||
};
|
||||
};
|
||||
|
||||
Squire.Helpers.constructs = function(what) {
|
||||
return function() {
|
||||
return function() {
|
||||
return what;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
return Squire;
|
||||
});
|
||||
1
common/static/js/vendor/Squire.min.js
vendored
1
common/static/js/vendor/Squire.min.js
vendored
@@ -1 +0,0 @@
|
||||
define(function(){var a=Object.prototype.toString,b=function(b){return"[object Array]"===a.call(b)},c=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},d=function(a,b,c){var d={};if(null!==a)if(Array.prototype.forEach&&a.forEach===Array.prototype.forEach)a.forEach(b,c);else if(a.length===+a.length){for(var e=0,f=a.length;f>e;e++)if(b.call(c,a[e],e,a)===d)return}else for(var g in a)if(a.hasOwnProperty(g)&&b.call(c,a[g],g,a)===d)return},e=function(a){return requirejs.s.contexts[a]},f=function(a,b){return a.undef?a.undef(b):a.require.undef(b)},g=0,h=function(){var b=g++;return"context"+b},i=function(){this.mocks={},this._store=[],this.requiredCallbacks=[],this.configure.apply(this,arguments)};return i.prototype.onRequired=function(a){this.requiredCallbacks.push(a)},i.prototype.configure=function(a){var b={};if(this.id=h(),"undefined"==typeof a&&(a="_"),a=e(a),!a)throw new Error("This context has not been created!");d(a.config,function(a,c){"deps"!==c&&(b[c]=a)}),b.context=this.id,this.load=requirejs.config(b)},i.prototype.mock=function(a,b){return"object"==typeof a?d(a,function(a,b){this.mock(b,a)},this):this.mocks[a]=b,this},i.prototype.store=function(a){return a&&"string"==typeof a?this._store.push(a):a&&b(a)&&d(a,function(a){this.store(a)},this),this},i.prototype.require=function(a,b,f){var j,g="mocks",h=this;j=c(a,g),-1!==j&&a.splice(j,1),d(this.mocks,function(a,b){define(b,a)}),this.load(a,function(){var c={},f=Array.prototype.slice.call(arguments);-1!==j&&(d(h._store,function(a){c[a]=e(h.id).defined[a]}),f.splice(j,0,{mocks:h.mocks,store:c})),b.apply(null,f),d(h.requiredCallbacks,function(b){b.call(null,a,f)})},f)},i.prototype.clean=function(a){return a&&"string"==typeof a?(f(e(this.id),a),delete this.mocks[a]):a&&b(a)?d(a,function(a){this.clean(a)},this):d(this.mocks,function(a,b){this.clean(b)},this),this},i.prototype.remove=function(){var b=e(this.id);b&&(d(e(this.id).defined,function(a,c){f(b,c)},this),delete requirejs.s.contexts[this.id])},i.prototype.run=function(a,b){var c=this,d=function(d){c.require(a,function(){b.apply(null,arguments),d()})};return d.toString=function(){return b.toString()},d},i.Helpers={},i.Helpers.returns=function(a){return function(){return a}},i.Helpers.constructs=function(a){return function(){return function(){return a}}},i});
|
||||
12251
common/static/js/vendor/moment-with-locales.js
vendored
12251
common/static/js/vendor/moment-with-locales.js
vendored
File diff suppressed because it is too large
Load Diff
495
common/static/js/vendor/moment.min.js
vendored
495
common/static/js/vendor/moment.min.js
vendored
@@ -1,495 +0,0 @@
|
||||
//! moment.js
|
||||
//! version : 2.15.1
|
||||
//! authors : Tim Wood, Iskren Chernev, Moment.js contributors
|
||||
//! license : MIT
|
||||
//! momentjs.com
|
||||
!function(a,b){"object"==typeof exports&&"undefined"!=typeof module?module.exports=b():"function"==typeof define&&define.amd?define(b):a.moment=b()}(this,function(){"use strict";function a(){return md.apply(null,arguments)}
|
||||
// This is done to register the method called with moment()
|
||||
// without creating circular dependencies.
|
||||
function b(a){md=a}function c(a){return a instanceof Array||"[object Array]"===Object.prototype.toString.call(a)}function d(a){
|
||||
// IE8 will treat undefined and null as object if it wasn't for
|
||||
// input != null
|
||||
return null!=a&&"[object Object]"===Object.prototype.toString.call(a)}function e(a){var b;for(b in a)
|
||||
// even if its not own property I'd still call it non-empty
|
||||
return!1;return!0}function f(a){return a instanceof Date||"[object Date]"===Object.prototype.toString.call(a)}function g(a,b){var c,d=[];for(c=0;c<a.length;++c)d.push(b(a[c],c));return d}function h(a,b){return Object.prototype.hasOwnProperty.call(a,b)}function i(a,b){for(var c in b)h(b,c)&&(a[c]=b[c]);return h(b,"toString")&&(a.toString=b.toString),h(b,"valueOf")&&(a.valueOf=b.valueOf),a}function j(a,b,c,d){return qb(a,b,c,d,!0).utc()}function k(){
|
||||
// We need to deep clone this object.
|
||||
return{empty:!1,unusedTokens:[],unusedInput:[],overflow:-2,charsLeftOver:0,nullInput:!1,invalidMonth:null,invalidFormat:!1,userInvalidated:!1,iso:!1,parsedDateParts:[],meridiem:null}}function l(a){return null==a._pf&&(a._pf=k()),a._pf}function m(a){if(null==a._isValid){var b=l(a),c=nd.call(b.parsedDateParts,function(a){return null!=a}),d=!isNaN(a._d.getTime())&&b.overflow<0&&!b.empty&&!b.invalidMonth&&!b.invalidWeekday&&!b.nullInput&&!b.invalidFormat&&!b.userInvalidated&&(!b.meridiem||b.meridiem&&c);if(a._strict&&(d=d&&0===b.charsLeftOver&&0===b.unusedTokens.length&&void 0===b.bigHour),null!=Object.isFrozen&&Object.isFrozen(a))return d;a._isValid=d}return a._isValid}function n(a){var b=j(NaN);return null!=a?i(l(b),a):l(b).userInvalidated=!0,b}function o(a){return void 0===a}function p(a,b){var c,d,e;if(o(b._isAMomentObject)||(a._isAMomentObject=b._isAMomentObject),o(b._i)||(a._i=b._i),o(b._f)||(a._f=b._f),o(b._l)||(a._l=b._l),o(b._strict)||(a._strict=b._strict),o(b._tzm)||(a._tzm=b._tzm),o(b._isUTC)||(a._isUTC=b._isUTC),o(b._offset)||(a._offset=b._offset),o(b._pf)||(a._pf=l(b)),o(b._locale)||(a._locale=b._locale),od.length>0)for(c in od)d=od[c],e=b[d],o(e)||(a[d]=e);return a}
|
||||
// Moment prototype object
|
||||
function q(b){p(this,b),this._d=new Date(null!=b._d?b._d.getTime():NaN),pd===!1&&(pd=!0,a.updateOffset(this),pd=!1)}function r(a){return a instanceof q||null!=a&&null!=a._isAMomentObject}function s(a){return 0>a?Math.ceil(a)||0:Math.floor(a)}function t(a){var b=+a,c=0;return 0!==b&&isFinite(b)&&(c=s(b)),c}
|
||||
// compare two arrays, return the number of differences
|
||||
function u(a,b,c){var d,e=Math.min(a.length,b.length),f=Math.abs(a.length-b.length),g=0;for(d=0;e>d;d++)(c&&a[d]!==b[d]||!c&&t(a[d])!==t(b[d]))&&g++;return g+f}function v(b){a.suppressDeprecationWarnings===!1&&"undefined"!=typeof console&&console.warn&&console.warn("Deprecation warning: "+b)}function w(b,c){var d=!0;return i(function(){if(null!=a.deprecationHandler&&a.deprecationHandler(null,b),d){for(var e,f=[],g=0;g<arguments.length;g++){if(e="","object"==typeof arguments[g]){e+="\n["+g+"] ";for(var h in arguments[0])e+=h+": "+arguments[0][h]+", ";e=e.slice(0,-2)}else e=arguments[g];f.push(e)}v(b+"\nArguments: "+Array.prototype.slice.call(f).join("")+"\n"+(new Error).stack),d=!1}return c.apply(this,arguments)},c)}function x(b,c){null!=a.deprecationHandler&&a.deprecationHandler(b,c),qd[b]||(v(c),qd[b]=!0)}function y(a){return a instanceof Function||"[object Function]"===Object.prototype.toString.call(a)}function z(a){var b,c;for(c in a)b=a[c],y(b)?this[c]=b:this["_"+c]=b;this._config=a,
|
||||
// Lenient ordinal parsing accepts just a number in addition to
|
||||
// number + (possibly) stuff coming from _ordinalParseLenient.
|
||||
this._ordinalParseLenient=new RegExp(this._ordinalParse.source+"|"+/\d{1,2}/.source)}function A(a,b){var c,e=i({},a);for(c in b)h(b,c)&&(d(a[c])&&d(b[c])?(e[c]={},i(e[c],a[c]),i(e[c],b[c])):null!=b[c]?e[c]=b[c]:delete e[c]);for(c in a)h(a,c)&&!h(b,c)&&d(a[c])&&(
|
||||
// make sure changes to properties don't modify parent config
|
||||
e[c]=i({},e[c]));return e}function B(a){null!=a&&this.set(a)}function C(a,b,c){var d=this._calendar[a]||this._calendar.sameElse;return y(d)?d.call(b,c):d}function D(a){var b=this._longDateFormat[a],c=this._longDateFormat[a.toUpperCase()];return b||!c?b:(this._longDateFormat[a]=c.replace(/MMMM|MM|DD|dddd/g,function(a){return a.slice(1)}),this._longDateFormat[a])}function E(){return this._invalidDate}function F(a){return this._ordinal.replace("%d",a)}function G(a,b,c,d){var e=this._relativeTime[c];return y(e)?e(a,b,c,d):e.replace(/%d/i,a)}function H(a,b){var c=this._relativeTime[a>0?"future":"past"];return y(c)?c(b):c.replace(/%s/i,b)}function I(a,b){var c=a.toLowerCase();zd[c]=zd[c+"s"]=zd[b]=a}function J(a){return"string"==typeof a?zd[a]||zd[a.toLowerCase()]:void 0}function K(a){var b,c,d={};for(c in a)h(a,c)&&(b=J(c),b&&(d[b]=a[c]));return d}function L(a,b){Ad[a]=b}function M(a){var b=[];for(var c in a)b.push({unit:c,priority:Ad[c]});return b.sort(function(a,b){return a.priority-b.priority}),b}function N(b,c){return function(d){return null!=d?(P(this,b,d),a.updateOffset(this,c),this):O(this,b)}}function O(a,b){return a.isValid()?a._d["get"+(a._isUTC?"UTC":"")+b]():NaN}function P(a,b,c){a.isValid()&&a._d["set"+(a._isUTC?"UTC":"")+b](c)}
|
||||
// MOMENTS
|
||||
function Q(a){return a=J(a),y(this[a])?this[a]():this}function R(a,b){if("object"==typeof a){a=K(a);for(var c=M(a),d=0;d<c.length;d++)this[c[d].unit](a[c[d].unit])}else if(a=J(a),y(this[a]))return this[a](b);return this}function S(a,b,c){var d=""+Math.abs(a),e=b-d.length,f=a>=0;return(f?c?"+":"":"-")+Math.pow(10,Math.max(0,e)).toString().substr(1)+d}
|
||||
// token: 'M'
|
||||
// padded: ['MM', 2]
|
||||
// ordinal: 'Mo'
|
||||
// callback: function () { this.month() + 1 }
|
||||
function T(a,b,c,d){var e=d;"string"==typeof d&&(e=function(){return this[d]()}),a&&(Ed[a]=e),b&&(Ed[b[0]]=function(){return S(e.apply(this,arguments),b[1],b[2])}),c&&(Ed[c]=function(){return this.localeData().ordinal(e.apply(this,arguments),a)})}function U(a){return a.match(/\[[\s\S]/)?a.replace(/^\[|\]$/g,""):a.replace(/\\/g,"")}function V(a){var b,c,d=a.match(Bd);for(b=0,c=d.length;c>b;b++)Ed[d[b]]?d[b]=Ed[d[b]]:d[b]=U(d[b]);return function(b){var e,f="";for(e=0;c>e;e++)f+=d[e]instanceof Function?d[e].call(b,a):d[e];return f}}
|
||||
// format date using native date object
|
||||
function W(a,b){return a.isValid()?(b=X(b,a.localeData()),Dd[b]=Dd[b]||V(b),Dd[b](a)):a.localeData().invalidDate()}function X(a,b){function c(a){return b.longDateFormat(a)||a}var d=5;for(Cd.lastIndex=0;d>=0&&Cd.test(a);)a=a.replace(Cd,c),Cd.lastIndex=0,d-=1;return a}function Y(a,b,c){Wd[a]=y(b)?b:function(a,d){return a&&c?c:b}}function Z(a,b){return h(Wd,a)?Wd[a](b._strict,b._locale):new RegExp($(a))}
|
||||
// Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
|
||||
function $(a){return _(a.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(a,b,c,d,e){return b||c||d||e}))}function _(a){return a.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}function aa(a,b){var c,d=b;for("string"==typeof a&&(a=[a]),"number"==typeof b&&(d=function(a,c){c[b]=t(a)}),c=0;c<a.length;c++)Xd[a[c]]=d}function ba(a,b){aa(a,function(a,c,d,e){d._w=d._w||{},b(a,d._w,d,e)})}function ca(a,b,c){null!=b&&h(Xd,a)&&Xd[a](b,c._a,c,a)}function da(a,b){return new Date(Date.UTC(a,b+1,0)).getUTCDate()}function ea(a,b){return a?c(this._months)?this._months[a.month()]:this._months[(this._months.isFormat||fe).test(b)?"format":"standalone"][a.month()]:this._months}function fa(a,b){return a?c(this._monthsShort)?this._monthsShort[a.month()]:this._monthsShort[fe.test(b)?"format":"standalone"][a.month()]:this._monthsShort}function ga(a,b,c){var d,e,f,g=a.toLocaleLowerCase();if(!this._monthsParse)for(
|
||||
// this is not used
|
||||
this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[],d=0;12>d;++d)f=j([2e3,d]),this._shortMonthsParse[d]=this.monthsShort(f,"").toLocaleLowerCase(),this._longMonthsParse[d]=this.months(f,"").toLocaleLowerCase();return c?"MMM"===b?(e=sd.call(this._shortMonthsParse,g),-1!==e?e:null):(e=sd.call(this._longMonthsParse,g),-1!==e?e:null):"MMM"===b?(e=sd.call(this._shortMonthsParse,g),-1!==e?e:(e=sd.call(this._longMonthsParse,g),-1!==e?e:null)):(e=sd.call(this._longMonthsParse,g),-1!==e?e:(e=sd.call(this._shortMonthsParse,g),-1!==e?e:null))}function ha(a,b,c){var d,e,f;if(this._monthsParseExact)return ga.call(this,a,b,c);
|
||||
// TODO: add sorting
|
||||
// Sorting makes sure if one month (or abbr) is a prefix of another
|
||||
// see sorting in computeMonthsParse
|
||||
for(this._monthsParse||(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[]),d=0;12>d;d++){
|
||||
// test the regex
|
||||
if(e=j([2e3,d]),c&&!this._longMonthsParse[d]&&(this._longMonthsParse[d]=new RegExp("^"+this.months(e,"").replace(".","")+"$","i"),this._shortMonthsParse[d]=new RegExp("^"+this.monthsShort(e,"").replace(".","")+"$","i")),c||this._monthsParse[d]||(f="^"+this.months(e,"")+"|^"+this.monthsShort(e,""),this._monthsParse[d]=new RegExp(f.replace(".",""),"i")),c&&"MMMM"===b&&this._longMonthsParse[d].test(a))return d;if(c&&"MMM"===b&&this._shortMonthsParse[d].test(a))return d;if(!c&&this._monthsParse[d].test(a))return d}}
|
||||
// MOMENTS
|
||||
function ia(a,b){var c;if(!a.isValid())
|
||||
// No op
|
||||
return a;if("string"==typeof b)if(/^\d+$/.test(b))b=t(b);else
|
||||
// TODO: Another silent failure?
|
||||
if(b=a.localeData().monthsParse(b),"number"!=typeof b)return a;return c=Math.min(a.date(),da(a.year(),b)),a._d["set"+(a._isUTC?"UTC":"")+"Month"](b,c),a}function ja(b){return null!=b?(ia(this,b),a.updateOffset(this,!0),this):O(this,"Month")}function ka(){return da(this.year(),this.month())}function la(a){return this._monthsParseExact?(h(this,"_monthsRegex")||na.call(this),a?this._monthsShortStrictRegex:this._monthsShortRegex):(h(this,"_monthsShortRegex")||(this._monthsShortRegex=ie),this._monthsShortStrictRegex&&a?this._monthsShortStrictRegex:this._monthsShortRegex)}function ma(a){return this._monthsParseExact?(h(this,"_monthsRegex")||na.call(this),a?this._monthsStrictRegex:this._monthsRegex):(h(this,"_monthsRegex")||(this._monthsRegex=je),this._monthsStrictRegex&&a?this._monthsStrictRegex:this._monthsRegex)}function na(){function a(a,b){return b.length-a.length}var b,c,d=[],e=[],f=[];for(b=0;12>b;b++)c=j([2e3,b]),d.push(this.monthsShort(c,"")),e.push(this.months(c,"")),f.push(this.months(c,"")),f.push(this.monthsShort(c,""));for(
|
||||
// Sorting makes sure if one month (or abbr) is a prefix of another it
|
||||
// will match the longer piece.
|
||||
d.sort(a),e.sort(a),f.sort(a),b=0;12>b;b++)d[b]=_(d[b]),e[b]=_(e[b]);for(b=0;24>b;b++)f[b]=_(f[b]);this._monthsRegex=new RegExp("^("+f.join("|")+")","i"),this._monthsShortRegex=this._monthsRegex,this._monthsStrictRegex=new RegExp("^("+e.join("|")+")","i"),this._monthsShortStrictRegex=new RegExp("^("+d.join("|")+")","i")}
|
||||
// HELPERS
|
||||
function oa(a){return pa(a)?366:365}function pa(a){return a%4===0&&a%100!==0||a%400===0}function qa(){return pa(this.year())}function ra(a,b,c,d,e,f,g){
|
||||
//can't just apply() to create a date:
|
||||
//http://stackoverflow.com/questions/181348/instantiating-a-javascript-object-by-calling-prototype-constructor-apply
|
||||
var h=new Date(a,b,c,d,e,f,g);
|
||||
//the date constructor remaps years 0-99 to 1900-1999
|
||||
return 100>a&&a>=0&&isFinite(h.getFullYear())&&h.setFullYear(a),h}function sa(a){var b=new Date(Date.UTC.apply(null,arguments));
|
||||
//the Date.UTC function remaps years 0-99 to 1900-1999
|
||||
return 100>a&&a>=0&&isFinite(b.getUTCFullYear())&&b.setUTCFullYear(a),b}
|
||||
// start-of-first-week - start-of-year
|
||||
function ta(a,b,c){var// first-week day -- which january is always in the first week (4 for iso, 1 for other)
|
||||
d=7+b-c,
|
||||
// first-week day local weekday -- which local weekday is fwd
|
||||
e=(7+sa(a,0,d).getUTCDay()-b)%7;return-e+d-1}
|
||||
//http://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
|
||||
function ua(a,b,c,d,e){var f,g,h=(7+c-d)%7,i=ta(a,d,e),j=1+7*(b-1)+h+i;return 0>=j?(f=a-1,g=oa(f)+j):j>oa(a)?(f=a+1,g=j-oa(a)):(f=a,g=j),{year:f,dayOfYear:g}}function va(a,b,c){var d,e,f=ta(a.year(),b,c),g=Math.floor((a.dayOfYear()-f-1)/7)+1;return 1>g?(e=a.year()-1,d=g+wa(e,b,c)):g>wa(a.year(),b,c)?(d=g-wa(a.year(),b,c),e=a.year()+1):(e=a.year(),d=g),{week:d,year:e}}function wa(a,b,c){var d=ta(a,b,c),e=ta(a+1,b,c);return(oa(a)-d+e)/7}
|
||||
// HELPERS
|
||||
// LOCALES
|
||||
function xa(a){return va(a,this._week.dow,this._week.doy).week}function ya(){return this._week.dow}function za(){return this._week.doy}
|
||||
// MOMENTS
|
||||
function Aa(a){var b=this.localeData().week(this);return null==a?b:this.add(7*(a-b),"d")}function Ba(a){var b=va(this,1,4).week;return null==a?b:this.add(7*(a-b),"d")}
|
||||
// HELPERS
|
||||
function Ca(a,b){return"string"!=typeof a?a:isNaN(a)?(a=b.weekdaysParse(a),"number"==typeof a?a:null):parseInt(a,10)}function Da(a,b){return"string"==typeof a?b.weekdaysParse(a)%7||7:isNaN(a)?null:a}function Ea(a,b){return a?c(this._weekdays)?this._weekdays[a.day()]:this._weekdays[this._weekdays.isFormat.test(b)?"format":"standalone"][a.day()]:this._weekdays}function Fa(a){return a?this._weekdaysShort[a.day()]:this._weekdaysShort}function Ga(a){return a?this._weekdaysMin[a.day()]:this._weekdaysMin}function Ha(a,b,c){var d,e,f,g=a.toLocaleLowerCase();if(!this._weekdaysParse)for(this._weekdaysParse=[],this._shortWeekdaysParse=[],this._minWeekdaysParse=[],d=0;7>d;++d)f=j([2e3,1]).day(d),this._minWeekdaysParse[d]=this.weekdaysMin(f,"").toLocaleLowerCase(),this._shortWeekdaysParse[d]=this.weekdaysShort(f,"").toLocaleLowerCase(),this._weekdaysParse[d]=this.weekdays(f,"").toLocaleLowerCase();return c?"dddd"===b?(e=sd.call(this._weekdaysParse,g),-1!==e?e:null):"ddd"===b?(e=sd.call(this._shortWeekdaysParse,g),-1!==e?e:null):(e=sd.call(this._minWeekdaysParse,g),-1!==e?e:null):"dddd"===b?(e=sd.call(this._weekdaysParse,g),-1!==e?e:(e=sd.call(this._shortWeekdaysParse,g),-1!==e?e:(e=sd.call(this._minWeekdaysParse,g),-1!==e?e:null))):"ddd"===b?(e=sd.call(this._shortWeekdaysParse,g),-1!==e?e:(e=sd.call(this._weekdaysParse,g),-1!==e?e:(e=sd.call(this._minWeekdaysParse,g),-1!==e?e:null))):(e=sd.call(this._minWeekdaysParse,g),-1!==e?e:(e=sd.call(this._weekdaysParse,g),-1!==e?e:(e=sd.call(this._shortWeekdaysParse,g),-1!==e?e:null)))}function Ia(a,b,c){var d,e,f;if(this._weekdaysParseExact)return Ha.call(this,a,b,c);for(this._weekdaysParse||(this._weekdaysParse=[],this._minWeekdaysParse=[],this._shortWeekdaysParse=[],this._fullWeekdaysParse=[]),d=0;7>d;d++){
|
||||
// test the regex
|
||||
if(e=j([2e3,1]).day(d),c&&!this._fullWeekdaysParse[d]&&(this._fullWeekdaysParse[d]=new RegExp("^"+this.weekdays(e,"").replace(".",".?")+"$","i"),this._shortWeekdaysParse[d]=new RegExp("^"+this.weekdaysShort(e,"").replace(".",".?")+"$","i"),this._minWeekdaysParse[d]=new RegExp("^"+this.weekdaysMin(e,"").replace(".",".?")+"$","i")),this._weekdaysParse[d]||(f="^"+this.weekdays(e,"")+"|^"+this.weekdaysShort(e,"")+"|^"+this.weekdaysMin(e,""),this._weekdaysParse[d]=new RegExp(f.replace(".",""),"i")),c&&"dddd"===b&&this._fullWeekdaysParse[d].test(a))return d;if(c&&"ddd"===b&&this._shortWeekdaysParse[d].test(a))return d;if(c&&"dd"===b&&this._minWeekdaysParse[d].test(a))return d;if(!c&&this._weekdaysParse[d].test(a))return d}}
|
||||
// MOMENTS
|
||||
function Ja(a){if(!this.isValid())return null!=a?this:NaN;var b=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=a?(a=Ca(a,this.localeData()),this.add(a-b,"d")):b}function Ka(a){if(!this.isValid())return null!=a?this:NaN;var b=(this.day()+7-this.localeData()._week.dow)%7;return null==a?b:this.add(a-b,"d")}function La(a){if(!this.isValid())return null!=a?this:NaN;
|
||||
// behaves the same as moment#day except
|
||||
// as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)
|
||||
// as a setter, sunday should belong to the previous week.
|
||||
if(null!=a){var b=Da(a,this.localeData());return this.day(this.day()%7?b:b-7)}return this.day()||7}function Ma(a){return this._weekdaysParseExact?(h(this,"_weekdaysRegex")||Pa.call(this),a?this._weekdaysStrictRegex:this._weekdaysRegex):(h(this,"_weekdaysRegex")||(this._weekdaysRegex=pe),this._weekdaysStrictRegex&&a?this._weekdaysStrictRegex:this._weekdaysRegex)}function Na(a){return this._weekdaysParseExact?(h(this,"_weekdaysRegex")||Pa.call(this),a?this._weekdaysShortStrictRegex:this._weekdaysShortRegex):(h(this,"_weekdaysShortRegex")||(this._weekdaysShortRegex=qe),this._weekdaysShortStrictRegex&&a?this._weekdaysShortStrictRegex:this._weekdaysShortRegex)}function Oa(a){return this._weekdaysParseExact?(h(this,"_weekdaysRegex")||Pa.call(this),a?this._weekdaysMinStrictRegex:this._weekdaysMinRegex):(h(this,"_weekdaysMinRegex")||(this._weekdaysMinRegex=re),this._weekdaysMinStrictRegex&&a?this._weekdaysMinStrictRegex:this._weekdaysMinRegex)}function Pa(){function a(a,b){return b.length-a.length}var b,c,d,e,f,g=[],h=[],i=[],k=[];for(b=0;7>b;b++)c=j([2e3,1]).day(b),d=this.weekdaysMin(c,""),e=this.weekdaysShort(c,""),f=this.weekdays(c,""),g.push(d),h.push(e),i.push(f),k.push(d),k.push(e),k.push(f);for(
|
||||
// Sorting makes sure if one weekday (or abbr) is a prefix of another it
|
||||
// will match the longer piece.
|
||||
g.sort(a),h.sort(a),i.sort(a),k.sort(a),b=0;7>b;b++)h[b]=_(h[b]),i[b]=_(i[b]),k[b]=_(k[b]);this._weekdaysRegex=new RegExp("^("+k.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+i.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+h.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+g.join("|")+")","i")}
|
||||
// FORMATTING
|
||||
function Qa(){return this.hours()%12||12}function Ra(){return this.hours()||24}function Sa(a,b){T(a,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),b)})}
|
||||
// PARSING
|
||||
function Ta(a,b){return b._meridiemParse}
|
||||
// LOCALES
|
||||
function Ua(a){
|
||||
// IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays
|
||||
// Using charAt should be more compatible.
|
||||
return"p"===(a+"").toLowerCase().charAt(0)}function Va(a,b,c){return a>11?c?"pm":"PM":c?"am":"AM"}function Wa(a){return a?a.toLowerCase().replace("_","-"):a}
|
||||
// pick the locale from the array
|
||||
// try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
|
||||
// substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
|
||||
function Xa(a){for(var b,c,d,e,f=0;f<a.length;){for(e=Wa(a[f]).split("-"),b=e.length,c=Wa(a[f+1]),c=c?c.split("-"):null;b>0;){if(d=Ya(e.slice(0,b).join("-")))return d;if(c&&c.length>=b&&u(e,c,!0)>=b-1)
|
||||
//the next array item is better than a shallower substring of this one
|
||||
break;b--}f++}return null}function Ya(a){var b=null;
|
||||
// TODO: Find a better way to register and load all the locales in Node
|
||||
if(!we[a]&&"undefined"!=typeof module&&module&&module.exports)try{b=se._abbr,require("./locale/"+a),
|
||||
// because defineLocale currently also sets the global locale, we
|
||||
// want to undo that for lazy loaded locales
|
||||
Za(b)}catch(c){}return we[a]}
|
||||
// This function will load locale and then set the global locale. If
|
||||
// no arguments are passed in, it will simply return the current global
|
||||
// locale key.
|
||||
function Za(a,b){var c;
|
||||
// moment.duration._locale = moment._locale = data;
|
||||
return a&&(c=o(b)?ab(a):$a(a,b),c&&(se=c)),se._abbr}function $a(a,b){if(null!==b){var c=ve;
|
||||
// treat as if there is no base config
|
||||
// backwards compat for now: also set the locale
|
||||
return b.abbr=a,null!=we[a]?(x("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),c=we[a]._config):null!=b.parentLocale&&(null!=we[b.parentLocale]?c=we[b.parentLocale]._config:x("parentLocaleUndefined","specified parentLocale is not defined yet. See http://momentjs.com/guides/#/warnings/parent-locale/")),we[a]=new B(A(c,b)),Za(a),we[a]}
|
||||
// useful for testing
|
||||
return delete we[a],null}function _a(a,b){if(null!=b){var c,d=ve;
|
||||
// MERGE
|
||||
null!=we[a]&&(d=we[a]._config),b=A(d,b),c=new B(b),c.parentLocale=we[a],we[a]=c,
|
||||
// backwards compat for now: also set the locale
|
||||
Za(a)}else
|
||||
// pass null for config to unupdate, useful for tests
|
||||
null!=we[a]&&(null!=we[a].parentLocale?we[a]=we[a].parentLocale:null!=we[a]&&delete we[a]);return we[a]}
|
||||
// returns locale data
|
||||
function ab(a){var b;if(a&&a._locale&&a._locale._abbr&&(a=a._locale._abbr),!a)return se;if(!c(a)){if(b=Ya(a))return b;a=[a]}return Xa(a)}function bb(){return rd(we)}function cb(a){var b,c=a._a;return c&&-2===l(a).overflow&&(b=c[Zd]<0||c[Zd]>11?Zd:c[$d]<1||c[$d]>da(c[Yd],c[Zd])?$d:c[_d]<0||c[_d]>24||24===c[_d]&&(0!==c[ae]||0!==c[be]||0!==c[ce])?_d:c[ae]<0||c[ae]>59?ae:c[be]<0||c[be]>59?be:c[ce]<0||c[ce]>999?ce:-1,l(a)._overflowDayOfYear&&(Yd>b||b>$d)&&(b=$d),l(a)._overflowWeeks&&-1===b&&(b=de),l(a)._overflowWeekday&&-1===b&&(b=ee),l(a).overflow=b),a}
|
||||
// date from iso format
|
||||
function db(a){var b,c,d,e,f,g,h=a._i,i=xe.exec(h)||ye.exec(h);if(i){for(l(a).iso=!0,b=0,c=Ae.length;c>b;b++)if(Ae[b][1].exec(i[1])){e=Ae[b][0],d=Ae[b][2]!==!1;break}if(null==e)return void(a._isValid=!1);if(i[3]){for(b=0,c=Be.length;c>b;b++)if(Be[b][1].exec(i[3])){
|
||||
// match[2] should be 'T' or space
|
||||
f=(i[2]||" ")+Be[b][0];break}if(null==f)return void(a._isValid=!1)}if(!d&&null!=f)return void(a._isValid=!1);if(i[4]){if(!ze.exec(i[4]))return void(a._isValid=!1);g="Z"}a._f=e+(f||"")+(g||""),jb(a)}else a._isValid=!1}
|
||||
// date from iso format or fallback
|
||||
function eb(b){var c=Ce.exec(b._i);return null!==c?void(b._d=new Date(+c[1])):(db(b),void(b._isValid===!1&&(delete b._isValid,a.createFromInputFallback(b))))}
|
||||
// Pick the first defined of two or three arguments.
|
||||
function fb(a,b,c){return null!=a?a:null!=b?b:c}function gb(b){
|
||||
// hooks is actually the exported moment object
|
||||
var c=new Date(a.now());return b._useUTC?[c.getUTCFullYear(),c.getUTCMonth(),c.getUTCDate()]:[c.getFullYear(),c.getMonth(),c.getDate()]}
|
||||
// convert an array to a date.
|
||||
// the array should mirror the parameters below
|
||||
// note: all values past the year are optional and will default to the lowest possible value.
|
||||
// [year, month, day , hour, minute, second, millisecond]
|
||||
function hb(a){var b,c,d,e,f=[];if(!a._d){
|
||||
// Default to current date.
|
||||
// * if no year, month, day of month are given, default to today
|
||||
// * if day of month is given, default month and year
|
||||
// * if month is given, default only year
|
||||
// * if year is given, don't default anything
|
||||
for(d=gb(a),a._w&&null==a._a[$d]&&null==a._a[Zd]&&ib(a),a._dayOfYear&&(e=fb(a._a[Yd],d[Yd]),a._dayOfYear>oa(e)&&(l(a)._overflowDayOfYear=!0),c=sa(e,0,a._dayOfYear),a._a[Zd]=c.getUTCMonth(),a._a[$d]=c.getUTCDate()),b=0;3>b&&null==a._a[b];++b)a._a[b]=f[b]=d[b];
|
||||
// Zero out whatever was not defaulted, including time
|
||||
for(;7>b;b++)a._a[b]=f[b]=null==a._a[b]?2===b?1:0:a._a[b];
|
||||
// Check for 24:00:00.000
|
||||
24===a._a[_d]&&0===a._a[ae]&&0===a._a[be]&&0===a._a[ce]&&(a._nextDay=!0,a._a[_d]=0),a._d=(a._useUTC?sa:ra).apply(null,f),
|
||||
// Apply timezone offset from input. The actual utcOffset can be changed
|
||||
// with parseZone.
|
||||
null!=a._tzm&&a._d.setUTCMinutes(a._d.getUTCMinutes()-a._tzm),a._nextDay&&(a._a[_d]=24)}}function ib(a){var b,c,d,e,f,g,h,i;b=a._w,null!=b.GG||null!=b.W||null!=b.E?(f=1,g=4,c=fb(b.GG,a._a[Yd],va(rb(),1,4).year),d=fb(b.W,1),e=fb(b.E,1),(1>e||e>7)&&(i=!0)):(f=a._locale._week.dow,g=a._locale._week.doy,c=fb(b.gg,a._a[Yd],va(rb(),f,g).year),d=fb(b.w,1),null!=b.d?(e=b.d,(0>e||e>6)&&(i=!0)):null!=b.e?(e=b.e+f,(b.e<0||b.e>6)&&(i=!0)):e=f),1>d||d>wa(c,f,g)?l(a)._overflowWeeks=!0:null!=i?l(a)._overflowWeekday=!0:(h=ua(c,d,e,f,g),a._a[Yd]=h.year,a._dayOfYear=h.dayOfYear)}
|
||||
// date from string and format string
|
||||
function jb(b){
|
||||
// TODO: Move this to another part of the creation flow to prevent circular deps
|
||||
if(b._f===a.ISO_8601)return void db(b);b._a=[],l(b).empty=!0;
|
||||
// This array is used to make a Date, either with `new Date` or `Date.UTC`
|
||||
var c,d,e,f,g,h=""+b._i,i=h.length,j=0;for(e=X(b._f,b._locale).match(Bd)||[],c=0;c<e.length;c++)f=e[c],d=(h.match(Z(f,b))||[])[0],d&&(g=h.substr(0,h.indexOf(d)),g.length>0&&l(b).unusedInput.push(g),h=h.slice(h.indexOf(d)+d.length),j+=d.length),Ed[f]?(d?l(b).empty=!1:l(b).unusedTokens.push(f),ca(f,d,b)):b._strict&&!d&&l(b).unusedTokens.push(f);
|
||||
// add remaining unparsed input length to the string
|
||||
l(b).charsLeftOver=i-j,h.length>0&&l(b).unusedInput.push(h),
|
||||
// clear _12h flag if hour is <= 12
|
||||
b._a[_d]<=12&&l(b).bigHour===!0&&b._a[_d]>0&&(l(b).bigHour=void 0),l(b).parsedDateParts=b._a.slice(0),l(b).meridiem=b._meridiem,
|
||||
// handle meridiem
|
||||
b._a[_d]=kb(b._locale,b._a[_d],b._meridiem),hb(b),cb(b)}function kb(a,b,c){var d;
|
||||
// Fallback
|
||||
return null==c?b:null!=a.meridiemHour?a.meridiemHour(b,c):null!=a.isPM?(d=a.isPM(c),d&&12>b&&(b+=12),d||12!==b||(b=0),b):b}
|
||||
// date from string and array of format strings
|
||||
function lb(a){var b,c,d,e,f;if(0===a._f.length)return l(a).invalidFormat=!0,void(a._d=new Date(NaN));for(e=0;e<a._f.length;e++)f=0,b=p({},a),null!=a._useUTC&&(b._useUTC=a._useUTC),b._f=a._f[e],jb(b),m(b)&&(f+=l(b).charsLeftOver,f+=10*l(b).unusedTokens.length,l(b).score=f,(null==d||d>f)&&(d=f,c=b));i(a,c||b)}function mb(a){if(!a._d){var b=K(a._i);a._a=g([b.year,b.month,b.day||b.date,b.hour,b.minute,b.second,b.millisecond],function(a){return a&&parseInt(a,10)}),hb(a)}}function nb(a){var b=new q(cb(ob(a)));
|
||||
// Adding is smart enough around DST
|
||||
return b._nextDay&&(b.add(1,"d"),b._nextDay=void 0),b}function ob(a){var b=a._i,d=a._f;return a._locale=a._locale||ab(a._l),null===b||void 0===d&&""===b?n({nullInput:!0}):("string"==typeof b&&(a._i=b=a._locale.preparse(b)),r(b)?new q(cb(b)):(c(d)?lb(a):f(b)?a._d=b:d?jb(a):pb(a),m(a)||(a._d=null),a))}function pb(b){var d=b._i;void 0===d?b._d=new Date(a.now()):f(d)?b._d=new Date(d.valueOf()):"string"==typeof d?eb(b):c(d)?(b._a=g(d.slice(0),function(a){return parseInt(a,10)}),hb(b)):"object"==typeof d?mb(b):"number"==typeof d?
|
||||
// from milliseconds
|
||||
b._d=new Date(d):a.createFromInputFallback(b)}function qb(a,b,f,g,h){var i={};
|
||||
// object construction must be done this way.
|
||||
// https://github.com/moment/moment/issues/1423
|
||||
return"boolean"==typeof f&&(g=f,f=void 0),(d(a)&&e(a)||c(a)&&0===a.length)&&(a=void 0),i._isAMomentObject=!0,i._useUTC=i._isUTC=h,i._l=f,i._i=a,i._f=b,i._strict=g,nb(i)}function rb(a,b,c,d){return qb(a,b,c,d,!1)}
|
||||
// Pick a moment m from moments so that m[fn](other) is true for all
|
||||
// other. This relies on the function fn to be transitive.
|
||||
//
|
||||
// moments should either be an array of moment objects or an array, whose
|
||||
// first element is an array of moment objects.
|
||||
function sb(a,b){var d,e;if(1===b.length&&c(b[0])&&(b=b[0]),!b.length)return rb();for(d=b[0],e=1;e<b.length;++e)b[e].isValid()&&!b[e][a](d)||(d=b[e]);return d}
|
||||
// TODO: Use [].sort instead?
|
||||
function tb(){var a=[].slice.call(arguments,0);return sb("isBefore",a)}function ub(){var a=[].slice.call(arguments,0);return sb("isAfter",a)}function vb(a){var b=K(a),c=b.year||0,d=b.quarter||0,e=b.month||0,f=b.week||0,g=b.day||0,h=b.hour||0,i=b.minute||0,j=b.second||0,k=b.millisecond||0;
|
||||
// representation for dateAddRemove
|
||||
this._milliseconds=+k+1e3*j+// 1000
|
||||
6e4*i+// 1000 * 60
|
||||
1e3*h*60*60,//using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978
|
||||
// Because of dateAddRemove treats 24 hours as different from a
|
||||
// day when working around DST, we need to store them separately
|
||||
this._days=+g+7*f,
|
||||
// It is impossible translate months into days without knowing
|
||||
// which months you are are talking about, so we have to store
|
||||
// it separately.
|
||||
this._months=+e+3*d+12*c,this._data={},this._locale=ab(),this._bubble()}function wb(a){return a instanceof vb}function xb(a){return 0>a?-1*Math.round(-1*a):Math.round(a)}
|
||||
// FORMATTING
|
||||
function yb(a,b){T(a,0,0,function(){var a=this.utcOffset(),c="+";return 0>a&&(a=-a,c="-"),c+S(~~(a/60),2)+b+S(~~a%60,2)})}function zb(a,b){var c=(b||"").match(a)||[],d=c[c.length-1]||[],e=(d+"").match(Ge)||["-",0,0],f=+(60*e[1])+t(e[2]);return"+"===e[0]?f:-f}
|
||||
// Return a moment from input, that is local/utc/zone equivalent to model.
|
||||
function Ab(b,c){var d,e;
|
||||
// Use low-level api, because this fn is low-level api.
|
||||
return c._isUTC?(d=c.clone(),e=(r(b)||f(b)?b.valueOf():rb(b).valueOf())-d.valueOf(),d._d.setTime(d._d.valueOf()+e),a.updateOffset(d,!1),d):rb(b).local()}function Bb(a){
|
||||
// On Firefox.24 Date#getTimezoneOffset returns a floating point.
|
||||
// https://github.com/moment/moment/pull/1871
|
||||
return 15*-Math.round(a._d.getTimezoneOffset()/15)}
|
||||
// MOMENTS
|
||||
// keepLocalTime = true means only change the timezone, without
|
||||
// affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]-->
|
||||
// 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset
|
||||
// +0200, so we adjust the time as needed, to be valid.
|
||||
//
|
||||
// Keeping the time actually adds/subtracts (one hour)
|
||||
// from the actual represented time. That is why we call updateOffset
|
||||
// a second time. In case it wants us to change the offset again
|
||||
// _changeInProgress == true case, then we have to adjust, because
|
||||
// there is no such time in the given timezone.
|
||||
function Cb(b,c){var d,e=this._offset||0;return this.isValid()?null!=b?("string"==typeof b?b=zb(Td,b):Math.abs(b)<16&&(b=60*b),!this._isUTC&&c&&(d=Bb(this)),this._offset=b,this._isUTC=!0,null!=d&&this.add(d,"m"),e!==b&&(!c||this._changeInProgress?Sb(this,Nb(b-e,"m"),1,!1):this._changeInProgress||(this._changeInProgress=!0,a.updateOffset(this,!0),this._changeInProgress=null)),this):this._isUTC?e:Bb(this):null!=b?this:NaN}function Db(a,b){return null!=a?("string"!=typeof a&&(a=-a),this.utcOffset(a,b),this):-this.utcOffset()}function Eb(a){return this.utcOffset(0,a)}function Fb(a){return this._isUTC&&(this.utcOffset(0,a),this._isUTC=!1,a&&this.subtract(Bb(this),"m")),this}function Gb(){if(this._tzm)this.utcOffset(this._tzm);else if("string"==typeof this._i){var a=zb(Sd,this._i);0===a?this.utcOffset(0,!0):this.utcOffset(zb(Sd,this._i))}return this}function Hb(a){return this.isValid()?(a=a?rb(a).utcOffset():0,(this.utcOffset()-a)%60===0):!1}function Ib(){return this.utcOffset()>this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()}function Jb(){if(!o(this._isDSTShifted))return this._isDSTShifted;var a={};if(p(a,this),a=ob(a),a._a){var b=a._isUTC?j(a._a):rb(a._a);this._isDSTShifted=this.isValid()&&u(a._a,b.toArray())>0}else this._isDSTShifted=!1;return this._isDSTShifted}function Kb(){return this.isValid()?!this._isUTC:!1}function Lb(){return this.isValid()?this._isUTC:!1}function Mb(){return this.isValid()?this._isUTC&&0===this._offset:!1}function Nb(a,b){var c,d,e,f=a,
|
||||
// matching against regexp is expensive, do it on demand
|
||||
g=null;// checks for null or undefined
|
||||
return wb(a)?f={ms:a._milliseconds,d:a._days,M:a._months}:"number"==typeof a?(f={},b?f[b]=a:f.milliseconds=a):(g=He.exec(a))?(c="-"===g[1]?-1:1,f={y:0,d:t(g[$d])*c,h:t(g[_d])*c,m:t(g[ae])*c,s:t(g[be])*c,ms:t(xb(1e3*g[ce]))*c}):(g=Ie.exec(a))?(c="-"===g[1]?-1:1,f={y:Ob(g[2],c),M:Ob(g[3],c),w:Ob(g[4],c),d:Ob(g[5],c),h:Ob(g[6],c),m:Ob(g[7],c),s:Ob(g[8],c)}):null==f?f={}:"object"==typeof f&&("from"in f||"to"in f)&&(e=Qb(rb(f.from),rb(f.to)),f={},f.ms=e.milliseconds,f.M=e.months),d=new vb(f),wb(a)&&h(a,"_locale")&&(d._locale=a._locale),d}function Ob(a,b){
|
||||
// We'd normally use ~~inp for this, but unfortunately it also
|
||||
// converts floats to ints.
|
||||
// inp may be undefined, so careful calling replace on it.
|
||||
var c=a&&parseFloat(a.replace(",","."));
|
||||
// apply sign while we're at it
|
||||
return(isNaN(c)?0:c)*b}function Pb(a,b){var c={milliseconds:0,months:0};return c.months=b.month()-a.month()+12*(b.year()-a.year()),a.clone().add(c.months,"M").isAfter(b)&&--c.months,c.milliseconds=+b-+a.clone().add(c.months,"M"),c}function Qb(a,b){var c;return a.isValid()&&b.isValid()?(b=Ab(b,a),a.isBefore(b)?c=Pb(a,b):(c=Pb(b,a),c.milliseconds=-c.milliseconds,c.months=-c.months),c):{milliseconds:0,months:0}}
|
||||
// TODO: remove 'name' arg after deprecation is removed
|
||||
function Rb(a,b){return function(c,d){var e,f;
|
||||
//invert the arguments, but complain about it
|
||||
return null===d||isNaN(+d)||(x(b,"moment()."+b+"(period, number) is deprecated. Please use moment()."+b+"(number, period). See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info."),f=c,c=d,d=f),c="string"==typeof c?+c:c,e=Nb(c,d),Sb(this,e,a),this}}function Sb(b,c,d,e){var f=c._milliseconds,g=xb(c._days),h=xb(c._months);b.isValid()&&(e=null==e?!0:e,f&&b._d.setTime(b._d.valueOf()+f*d),g&&P(b,"Date",O(b,"Date")+g*d),h&&ia(b,O(b,"Month")+h*d),e&&a.updateOffset(b,g||h))}function Tb(a,b){var c=a.diff(b,"days",!0);return-6>c?"sameElse":-1>c?"lastWeek":0>c?"lastDay":1>c?"sameDay":2>c?"nextDay":7>c?"nextWeek":"sameElse"}function Ub(b,c){
|
||||
// We want to compare the start of today, vs this.
|
||||
// Getting start-of-today depends on whether we're local/utc/offset or not.
|
||||
var d=b||rb(),e=Ab(d,this).startOf("day"),f=a.calendarFormat(this,e)||"sameElse",g=c&&(y(c[f])?c[f].call(this,d):c[f]);return this.format(g||this.localeData().calendar(f,this,rb(d)))}function Vb(){return new q(this)}function Wb(a,b){var c=r(a)?a:rb(a);return this.isValid()&&c.isValid()?(b=J(o(b)?"millisecond":b),"millisecond"===b?this.valueOf()>c.valueOf():c.valueOf()<this.clone().startOf(b).valueOf()):!1}function Xb(a,b){var c=r(a)?a:rb(a);return this.isValid()&&c.isValid()?(b=J(o(b)?"millisecond":b),"millisecond"===b?this.valueOf()<c.valueOf():this.clone().endOf(b).valueOf()<c.valueOf()):!1}function Yb(a,b,c,d){return d=d||"()",("("===d[0]?this.isAfter(a,c):!this.isBefore(a,c))&&(")"===d[1]?this.isBefore(b,c):!this.isAfter(b,c))}function Zb(a,b){var c,d=r(a)?a:rb(a);return this.isValid()&&d.isValid()?(b=J(b||"millisecond"),"millisecond"===b?this.valueOf()===d.valueOf():(c=d.valueOf(),this.clone().startOf(b).valueOf()<=c&&c<=this.clone().endOf(b).valueOf())):!1}function $b(a,b){return this.isSame(a,b)||this.isAfter(a,b)}function _b(a,b){return this.isSame(a,b)||this.isBefore(a,b)}function ac(a,b,c){var d,e,f,g;// 1000
|
||||
// 1000 * 60
|
||||
// 1000 * 60 * 60
|
||||
// 1000 * 60 * 60 * 24, negate dst
|
||||
// 1000 * 60 * 60 * 24 * 7, negate dst
|
||||
return this.isValid()?(d=Ab(a,this),d.isValid()?(e=6e4*(d.utcOffset()-this.utcOffset()),b=J(b),"year"===b||"month"===b||"quarter"===b?(g=bc(this,d),"quarter"===b?g/=3:"year"===b&&(g/=12)):(f=this-d,g="second"===b?f/1e3:"minute"===b?f/6e4:"hour"===b?f/36e5:"day"===b?(f-e)/864e5:"week"===b?(f-e)/6048e5:f),c?g:s(g)):NaN):NaN}function bc(a,b){
|
||||
// difference in months
|
||||
var c,d,e=12*(b.year()-a.year())+(b.month()-a.month()),
|
||||
// b is in (anchor - 1 month, anchor + 1 month)
|
||||
f=a.clone().add(e,"months");
|
||||
//check for negative zero, return zero if negative zero
|
||||
// linear across the month
|
||||
// linear across the month
|
||||
return 0>b-f?(c=a.clone().add(e-1,"months"),d=(b-f)/(f-c)):(c=a.clone().add(e+1,"months"),d=(b-f)/(c-f)),-(e+d)||0}function cc(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")}function dc(){var a=this.clone().utc();return 0<a.year()&&a.year()<=9999?y(Date.prototype.toISOString)?this.toDate().toISOString():W(a,"YYYY-MM-DD[T]HH:mm:ss.SSS[Z]"):W(a,"YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]")}function ec(b){b||(b=this.isUtc()?a.defaultFormatUtc:a.defaultFormat);var c=W(this,b);return this.localeData().postformat(c)}function fc(a,b){return this.isValid()&&(r(a)&&a.isValid()||rb(a).isValid())?Nb({to:this,from:a}).locale(this.locale()).humanize(!b):this.localeData().invalidDate()}function gc(a){return this.from(rb(),a)}function hc(a,b){return this.isValid()&&(r(a)&&a.isValid()||rb(a).isValid())?Nb({from:this,to:a}).locale(this.locale()).humanize(!b):this.localeData().invalidDate()}function ic(a){return this.to(rb(),a)}
|
||||
// If passed a locale key, it will set the locale for this
|
||||
// instance. Otherwise, it will return the locale configuration
|
||||
// variables for this instance.
|
||||
function jc(a){var b;return void 0===a?this._locale._abbr:(b=ab(a),null!=b&&(this._locale=b),this)}function kc(){return this._locale}function lc(a){
|
||||
// the following switch intentionally omits break keywords
|
||||
// to utilize falling through the cases.
|
||||
switch(a=J(a)){case"year":this.month(0);/* falls through */
|
||||
case"quarter":case"month":this.date(1);/* falls through */
|
||||
case"week":case"isoWeek":case"day":case"date":this.hours(0);/* falls through */
|
||||
case"hour":this.minutes(0);/* falls through */
|
||||
case"minute":this.seconds(0);/* falls through */
|
||||
case"second":this.milliseconds(0)}
|
||||
// weeks are a special case
|
||||
// quarters are also special
|
||||
return"week"===a&&this.weekday(0),"isoWeek"===a&&this.isoWeekday(1),"quarter"===a&&this.month(3*Math.floor(this.month()/3)),this}function mc(a){
|
||||
// 'date' is an alias for 'day', so it should be considered as such.
|
||||
return a=J(a),void 0===a||"millisecond"===a?this:("date"===a&&(a="day"),this.startOf(a).add(1,"isoWeek"===a?"week":a).subtract(1,"ms"))}function nc(){return this._d.valueOf()-6e4*(this._offset||0)}function oc(){return Math.floor(this.valueOf()/1e3)}function pc(){return new Date(this.valueOf())}function qc(){var a=this;return[a.year(),a.month(),a.date(),a.hour(),a.minute(),a.second(),a.millisecond()]}function rc(){var a=this;return{years:a.year(),months:a.month(),date:a.date(),hours:a.hours(),minutes:a.minutes(),seconds:a.seconds(),milliseconds:a.milliseconds()}}function sc(){
|
||||
// new Date(NaN).toJSON() === null
|
||||
return this.isValid()?this.toISOString():null}function tc(){return m(this)}function uc(){return i({},l(this))}function vc(){return l(this).overflow}function wc(){return{input:this._i,format:this._f,locale:this._locale,isUTC:this._isUTC,strict:this._strict}}function xc(a,b){T(0,[a,a.length],0,b)}
|
||||
// MOMENTS
|
||||
function yc(a){return Cc.call(this,a,this.week(),this.weekday(),this.localeData()._week.dow,this.localeData()._week.doy)}function zc(a){return Cc.call(this,a,this.isoWeek(),this.isoWeekday(),1,4)}function Ac(){return wa(this.year(),1,4)}function Bc(){var a=this.localeData()._week;return wa(this.year(),a.dow,a.doy)}function Cc(a,b,c,d,e){var f;return null==a?va(this,d,e).year:(f=wa(a,d,e),b>f&&(b=f),Dc.call(this,a,b,c,d,e))}function Dc(a,b,c,d,e){var f=ua(a,b,c,d,e),g=sa(f.year,0,f.dayOfYear);return this.year(g.getUTCFullYear()),this.month(g.getUTCMonth()),this.date(g.getUTCDate()),this}
|
||||
// MOMENTS
|
||||
function Ec(a){return null==a?Math.ceil((this.month()+1)/3):this.month(3*(a-1)+this.month()%3)}
|
||||
// HELPERS
|
||||
// MOMENTS
|
||||
function Fc(a){var b=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return null==a?b:this.add(a-b,"d")}function Gc(a,b){b[ce]=t(1e3*("0."+a))}
|
||||
// MOMENTS
|
||||
function Hc(){return this._isUTC?"UTC":""}function Ic(){return this._isUTC?"Coordinated Universal Time":""}function Jc(a){return rb(1e3*a)}function Kc(){return rb.apply(null,arguments).parseZone()}function Lc(a){return a}function Mc(a,b,c,d){var e=ab(),f=j().set(d,b);return e[c](f,a)}function Nc(a,b,c){if("number"==typeof a&&(b=a,a=void 0),a=a||"",null!=b)return Mc(a,b,c,"month");var d,e=[];for(d=0;12>d;d++)e[d]=Mc(a,d,c,"month");return e}
|
||||
// ()
|
||||
// (5)
|
||||
// (fmt, 5)
|
||||
// (fmt)
|
||||
// (true)
|
||||
// (true, 5)
|
||||
// (true, fmt, 5)
|
||||
// (true, fmt)
|
||||
function Oc(a,b,c,d){"boolean"==typeof a?("number"==typeof b&&(c=b,b=void 0),b=b||""):(b=a,c=b,a=!1,"number"==typeof b&&(c=b,b=void 0),b=b||"");var e=ab(),f=a?e._week.dow:0;if(null!=c)return Mc(b,(c+f)%7,d,"day");var g,h=[];for(g=0;7>g;g++)h[g]=Mc(b,(g+f)%7,d,"day");return h}function Pc(a,b){return Nc(a,b,"months")}function Qc(a,b){return Nc(a,b,"monthsShort")}function Rc(a,b,c){return Oc(a,b,c,"weekdays")}function Sc(a,b,c){return Oc(a,b,c,"weekdaysShort")}function Tc(a,b,c){return Oc(a,b,c,"weekdaysMin")}function Uc(){var a=this._data;return this._milliseconds=Ue(this._milliseconds),this._days=Ue(this._days),this._months=Ue(this._months),a.milliseconds=Ue(a.milliseconds),a.seconds=Ue(a.seconds),a.minutes=Ue(a.minutes),a.hours=Ue(a.hours),a.months=Ue(a.months),a.years=Ue(a.years),this}function Vc(a,b,c,d){var e=Nb(b,c);return a._milliseconds+=d*e._milliseconds,a._days+=d*e._days,a._months+=d*e._months,a._bubble()}
|
||||
// supports only 2.0-style add(1, 's') or add(duration)
|
||||
function Wc(a,b){return Vc(this,a,b,1)}
|
||||
// supports only 2.0-style subtract(1, 's') or subtract(duration)
|
||||
function Xc(a,b){return Vc(this,a,b,-1)}function Yc(a){return 0>a?Math.floor(a):Math.ceil(a)}function Zc(){var a,b,c,d,e,f=this._milliseconds,g=this._days,h=this._months,i=this._data;
|
||||
// if we have a mix of positive and negative values, bubble down first
|
||||
// check: https://github.com/moment/moment/issues/2166
|
||||
// The following code bubbles up values, see the tests for
|
||||
// examples of what that means.
|
||||
// convert days to months
|
||||
// 12 months -> 1 year
|
||||
return f>=0&&g>=0&&h>=0||0>=f&&0>=g&&0>=h||(f+=864e5*Yc(_c(h)+g),g=0,h=0),i.milliseconds=f%1e3,a=s(f/1e3),i.seconds=a%60,b=s(a/60),i.minutes=b%60,c=s(b/60),i.hours=c%24,g+=s(c/24),e=s($c(g)),h+=e,g-=Yc(_c(e)),d=s(h/12),h%=12,i.days=g,i.months=h,i.years=d,this}function $c(a){
|
||||
// 400 years have 146097 days (taking into account leap year rules)
|
||||
// 400 years have 12 months === 4800
|
||||
return 4800*a/146097}function _c(a){
|
||||
// the reverse of daysToMonths
|
||||
return 146097*a/4800}function ad(a){var b,c,d=this._milliseconds;if(a=J(a),"month"===a||"year"===a)return b=this._days+d/864e5,c=this._months+$c(b),"month"===a?c:c/12;switch(b=this._days+Math.round(_c(this._months)),a){case"week":return b/7+d/6048e5;case"day":return b+d/864e5;case"hour":return 24*b+d/36e5;case"minute":return 1440*b+d/6e4;case"second":return 86400*b+d/1e3;
|
||||
// Math.floor prevents floating point math errors here
|
||||
case"millisecond":return Math.floor(864e5*b)+d;default:throw new Error("Unknown unit "+a)}}
|
||||
// TODO: Use this.as('ms')?
|
||||
function bd(){return this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*t(this._months/12)}function cd(a){return function(){return this.as(a)}}function dd(a){return a=J(a),this[a+"s"]()}function ed(a){return function(){return this._data[a]}}function fd(){return s(this.days()/7)}
|
||||
// helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize
|
||||
function gd(a,b,c,d,e){return e.relativeTime(b||1,!!c,a,d)}function hd(a,b,c){var d=Nb(a).abs(),e=jf(d.as("s")),f=jf(d.as("m")),g=jf(d.as("h")),h=jf(d.as("d")),i=jf(d.as("M")),j=jf(d.as("y")),k=e<kf.s&&["s",e]||1>=f&&["m"]||f<kf.m&&["mm",f]||1>=g&&["h"]||g<kf.h&&["hh",g]||1>=h&&["d"]||h<kf.d&&["dd",h]||1>=i&&["M"]||i<kf.M&&["MM",i]||1>=j&&["y"]||["yy",j];return k[2]=b,k[3]=+a>0,k[4]=c,gd.apply(null,k)}
|
||||
// This function allows you to set the rounding function for relative time strings
|
||||
function id(a){return void 0===a?jf:"function"==typeof a?(jf=a,!0):!1}
|
||||
// This function allows you to set a threshold for relative time strings
|
||||
function jd(a,b){return void 0===kf[a]?!1:void 0===b?kf[a]:(kf[a]=b,!0)}function kd(a){var b=this.localeData(),c=hd(this,!a,b);return a&&(c=b.pastFuture(+this,c)),b.postformat(c)}function ld(){
|
||||
// for ISO strings we do not use the normal bubbling rules:
|
||||
// * milliseconds bubble up until they become hours
|
||||
// * days do not bubble at all
|
||||
// * months bubble up until they become years
|
||||
// This is because there is no context-free conversion between hours and days
|
||||
// (think of clock changes)
|
||||
// and also not between days and months (28-31 days per month)
|
||||
var a,b,c,d=lf(this._milliseconds)/1e3,e=lf(this._days),f=lf(this._months);a=s(d/60),b=s(a/60),d%=60,a%=60,c=s(f/12),f%=12;
|
||||
// inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js
|
||||
var g=c,h=f,i=e,j=b,k=a,l=d,m=this.asSeconds();return m?(0>m?"-":"")+"P"+(g?g+"Y":"")+(h?h+"M":"")+(i?i+"D":"")+(j||k||l?"T":"")+(j?j+"H":"")+(k?k+"M":"")+(l?l+"S":""):"P0D"}var md,nd;nd=Array.prototype.some?Array.prototype.some:function(a){for(var b=Object(this),c=b.length>>>0,d=0;c>d;d++)if(d in b&&a.call(this,b[d],d,b))return!0;return!1};
|
||||
// Plugins that add properties should also add the key here (null value),
|
||||
// so we can properly clone ourselves.
|
||||
var od=a.momentProperties=[],pd=!1,qd={};a.suppressDeprecationWarnings=!1,a.deprecationHandler=null;var rd;rd=Object.keys?Object.keys:function(a){var b,c=[];for(b in a)h(a,b)&&c.push(b);return c};var sd,td={sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},ud={LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},vd="Invalid date",wd="%d",xd=/\d{1,2}/,yd={future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},zd={},Ad={},Bd=/(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g,Cd=/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,Dd={},Ed={},Fd=/\d/,Gd=/\d\d/,Hd=/\d{3}/,Id=/\d{4}/,Jd=/[+-]?\d{6}/,Kd=/\d\d?/,Ld=/\d\d\d\d?/,Md=/\d\d\d\d\d\d?/,Nd=/\d{1,3}/,Od=/\d{1,4}/,Pd=/[+-]?\d{1,6}/,Qd=/\d+/,Rd=/[+-]?\d+/,Sd=/Z|[+-]\d\d:?\d\d/gi,Td=/Z|[+-]\d\d(?::?\d\d)?/gi,Ud=/[+-]?\d+(\.\d{1,3})?/,Vd=/[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i,Wd={},Xd={},Yd=0,Zd=1,$d=2,_d=3,ae=4,be=5,ce=6,de=7,ee=8;sd=Array.prototype.indexOf?Array.prototype.indexOf:function(a){
|
||||
// I know
|
||||
var b;for(b=0;b<this.length;++b)if(this[b]===a)return b;return-1},T("M",["MM",2],"Mo",function(){return this.month()+1}),T("MMM",0,0,function(a){return this.localeData().monthsShort(this,a)}),T("MMMM",0,0,function(a){return this.localeData().months(this,a)}),I("month","M"),L("month",8),Y("M",Kd),Y("MM",Kd,Gd),Y("MMM",function(a,b){return b.monthsShortRegex(a)}),Y("MMMM",function(a,b){return b.monthsRegex(a)}),aa(["M","MM"],function(a,b){b[Zd]=t(a)-1}),aa(["MMM","MMMM"],function(a,b,c,d){var e=c._locale.monthsParse(a,d,c._strict);null!=e?b[Zd]=e:l(c).invalidMonth=a});
|
||||
// LOCALES
|
||||
var fe=/D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/,ge="January_February_March_April_May_June_July_August_September_October_November_December".split("_"),he="Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),ie=Vd,je=Vd;
|
||||
// FORMATTING
|
||||
T("Y",0,0,function(){var a=this.year();return 9999>=a?""+a:"+"+a}),T(0,["YY",2],0,function(){return this.year()%100}),T(0,["YYYY",4],0,"year"),T(0,["YYYYY",5],0,"year"),T(0,["YYYYYY",6,!0],0,"year"),
|
||||
// ALIASES
|
||||
I("year","y"),
|
||||
// PRIORITIES
|
||||
L("year",1),
|
||||
// PARSING
|
||||
Y("Y",Rd),Y("YY",Kd,Gd),Y("YYYY",Od,Id),Y("YYYYY",Pd,Jd),Y("YYYYYY",Pd,Jd),aa(["YYYYY","YYYYYY"],Yd),aa("YYYY",function(b,c){c[Yd]=2===b.length?a.parseTwoDigitYear(b):t(b)}),aa("YY",function(b,c){c[Yd]=a.parseTwoDigitYear(b)}),aa("Y",function(a,b){b[Yd]=parseInt(a,10)}),
|
||||
// HOOKS
|
||||
a.parseTwoDigitYear=function(a){return t(a)+(t(a)>68?1900:2e3)};
|
||||
// MOMENTS
|
||||
var ke=N("FullYear",!0);
|
||||
// FORMATTING
|
||||
T("w",["ww",2],"wo","week"),T("W",["WW",2],"Wo","isoWeek"),
|
||||
// ALIASES
|
||||
I("week","w"),I("isoWeek","W"),
|
||||
// PRIORITIES
|
||||
L("week",5),L("isoWeek",5),
|
||||
// PARSING
|
||||
Y("w",Kd),Y("ww",Kd,Gd),Y("W",Kd),Y("WW",Kd,Gd),ba(["w","ww","W","WW"],function(a,b,c,d){b[d.substr(0,1)]=t(a)});var le={dow:0,// Sunday is the first day of the week.
|
||||
doy:6};
|
||||
// FORMATTING
|
||||
T("d",0,"do","day"),T("dd",0,0,function(a){return this.localeData().weekdaysMin(this,a)}),T("ddd",0,0,function(a){return this.localeData().weekdaysShort(this,a)}),T("dddd",0,0,function(a){return this.localeData().weekdays(this,a)}),T("e",0,0,"weekday"),T("E",0,0,"isoWeekday"),
|
||||
// ALIASES
|
||||
I("day","d"),I("weekday","e"),I("isoWeekday","E"),
|
||||
// PRIORITY
|
||||
L("day",11),L("weekday",11),L("isoWeekday",11),
|
||||
// PARSING
|
||||
Y("d",Kd),Y("e",Kd),Y("E",Kd),Y("dd",function(a,b){return b.weekdaysMinRegex(a)}),Y("ddd",function(a,b){return b.weekdaysShortRegex(a)}),Y("dddd",function(a,b){return b.weekdaysRegex(a)}),ba(["dd","ddd","dddd"],function(a,b,c,d){var e=c._locale.weekdaysParse(a,d,c._strict);
|
||||
// if we didn't get a weekday name, mark the date as invalid
|
||||
null!=e?b.d=e:l(c).invalidWeekday=a}),ba(["d","e","E"],function(a,b,c,d){b[d]=t(a)});
|
||||
// LOCALES
|
||||
var me="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),ne="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),oe="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),pe=Vd,qe=Vd,re=Vd;T("H",["HH",2],0,"hour"),T("h",["hh",2],0,Qa),T("k",["kk",2],0,Ra),T("hmm",0,0,function(){return""+Qa.apply(this)+S(this.minutes(),2)}),T("hmmss",0,0,function(){return""+Qa.apply(this)+S(this.minutes(),2)+S(this.seconds(),2)}),T("Hmm",0,0,function(){return""+this.hours()+S(this.minutes(),2)}),T("Hmmss",0,0,function(){return""+this.hours()+S(this.minutes(),2)+S(this.seconds(),2)}),Sa("a",!0),Sa("A",!1),
|
||||
// ALIASES
|
||||
I("hour","h"),
|
||||
// PRIORITY
|
||||
L("hour",13),Y("a",Ta),Y("A",Ta),Y("H",Kd),Y("h",Kd),Y("HH",Kd,Gd),Y("hh",Kd,Gd),Y("hmm",Ld),Y("hmmss",Md),Y("Hmm",Ld),Y("Hmmss",Md),aa(["H","HH"],_d),aa(["a","A"],function(a,b,c){c._isPm=c._locale.isPM(a),c._meridiem=a}),aa(["h","hh"],function(a,b,c){b[_d]=t(a),l(c).bigHour=!0}),aa("hmm",function(a,b,c){var d=a.length-2;b[_d]=t(a.substr(0,d)),b[ae]=t(a.substr(d)),l(c).bigHour=!0}),aa("hmmss",function(a,b,c){var d=a.length-4,e=a.length-2;b[_d]=t(a.substr(0,d)),b[ae]=t(a.substr(d,2)),b[be]=t(a.substr(e)),l(c).bigHour=!0}),aa("Hmm",function(a,b,c){var d=a.length-2;b[_d]=t(a.substr(0,d)),b[ae]=t(a.substr(d))}),aa("Hmmss",function(a,b,c){var d=a.length-4,e=a.length-2;b[_d]=t(a.substr(0,d)),b[ae]=t(a.substr(d,2)),b[be]=t(a.substr(e))});var se,te=/[ap]\.?m?\.?/i,ue=N("Hours",!0),ve={calendar:td,longDateFormat:ud,invalidDate:vd,ordinal:wd,ordinalParse:xd,relativeTime:yd,months:ge,monthsShort:he,week:le,weekdays:me,weekdaysMin:oe,weekdaysShort:ne,meridiemParse:te},we={},xe=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?/,ye=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?/,ze=/Z|[+-]\d\d(?::?\d\d)?/,Ae=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],
|
||||
// YYYYMM is NOT allowed by the standard
|
||||
["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],Be=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],Ce=/^\/?Date\((\-?\d+)/i;a.createFromInputFallback=w("value provided is not in a recognized ISO format. moment construction falls back to js Date(), which is not reliable across all browsers and versions. Non ISO date formats are discouraged and will be removed in an upcoming major release. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.",function(a){a._d=new Date(a._i+(a._useUTC?" UTC":""))}),
|
||||
// constant that refers to the ISO standard
|
||||
a.ISO_8601=function(){};var De=w("moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/",function(){var a=rb.apply(null,arguments);return this.isValid()&&a.isValid()?this>a?this:a:n()}),Ee=w("moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/",function(){var a=rb.apply(null,arguments);return this.isValid()&&a.isValid()?a>this?this:a:n()}),Fe=function(){return Date.now?Date.now():+new Date};yb("Z",":"),yb("ZZ",""),
|
||||
// PARSING
|
||||
Y("Z",Td),Y("ZZ",Td),aa(["Z","ZZ"],function(a,b,c){c._useUTC=!0,c._tzm=zb(Td,a)});
|
||||
// HELPERS
|
||||
// timezone chunker
|
||||
// '+10:00' > ['10', '00']
|
||||
// '-1530' > ['-15', '30']
|
||||
var Ge=/([\+\-]|\d\d)/gi;
|
||||
// HOOKS
|
||||
// This function will be called whenever a moment is mutated.
|
||||
// It is intended to keep the offset in sync with the timezone.
|
||||
a.updateOffset=function(){};
|
||||
// ASP.NET json date format regex
|
||||
var He=/^(\-)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/,Ie=/^(-)?P(?:(-?[0-9,.]*)Y)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)W)?(?:(-?[0-9,.]*)D)?(?:T(?:(-?[0-9,.]*)H)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)S)?)?$/;Nb.fn=vb.prototype;var Je=Rb(1,"add"),Ke=Rb(-1,"subtract");a.defaultFormat="YYYY-MM-DDTHH:mm:ssZ",a.defaultFormatUtc="YYYY-MM-DDTHH:mm:ss[Z]";var Le=w("moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.",function(a){return void 0===a?this.localeData():this.locale(a)});
|
||||
// FORMATTING
|
||||
T(0,["gg",2],0,function(){return this.weekYear()%100}),T(0,["GG",2],0,function(){return this.isoWeekYear()%100}),xc("gggg","weekYear"),xc("ggggg","weekYear"),xc("GGGG","isoWeekYear"),xc("GGGGG","isoWeekYear"),
|
||||
// ALIASES
|
||||
I("weekYear","gg"),I("isoWeekYear","GG"),
|
||||
// PRIORITY
|
||||
L("weekYear",1),L("isoWeekYear",1),
|
||||
// PARSING
|
||||
Y("G",Rd),Y("g",Rd),Y("GG",Kd,Gd),Y("gg",Kd,Gd),Y("GGGG",Od,Id),Y("gggg",Od,Id),Y("GGGGG",Pd,Jd),Y("ggggg",Pd,Jd),ba(["gggg","ggggg","GGGG","GGGGG"],function(a,b,c,d){b[d.substr(0,2)]=t(a)}),ba(["gg","GG"],function(b,c,d,e){c[e]=a.parseTwoDigitYear(b)}),
|
||||
// FORMATTING
|
||||
T("Q",0,"Qo","quarter"),
|
||||
// ALIASES
|
||||
I("quarter","Q"),
|
||||
// PRIORITY
|
||||
L("quarter",7),
|
||||
// PARSING
|
||||
Y("Q",Fd),aa("Q",function(a,b){b[Zd]=3*(t(a)-1)}),
|
||||
// FORMATTING
|
||||
T("D",["DD",2],"Do","date"),
|
||||
// ALIASES
|
||||
I("date","D"),
|
||||
// PRIOROITY
|
||||
L("date",9),
|
||||
// PARSING
|
||||
Y("D",Kd),Y("DD",Kd,Gd),Y("Do",function(a,b){return a?b._ordinalParse:b._ordinalParseLenient}),aa(["D","DD"],$d),aa("Do",function(a,b){b[$d]=t(a.match(Kd)[0],10)});
|
||||
// MOMENTS
|
||||
var Me=N("Date",!0);
|
||||
// FORMATTING
|
||||
T("DDD",["DDDD",3],"DDDo","dayOfYear"),
|
||||
// ALIASES
|
||||
I("dayOfYear","DDD"),
|
||||
// PRIORITY
|
||||
L("dayOfYear",4),
|
||||
// PARSING
|
||||
Y("DDD",Nd),Y("DDDD",Hd),aa(["DDD","DDDD"],function(a,b,c){c._dayOfYear=t(a)}),
|
||||
// FORMATTING
|
||||
T("m",["mm",2],0,"minute"),
|
||||
// ALIASES
|
||||
I("minute","m"),
|
||||
// PRIORITY
|
||||
L("minute",14),
|
||||
// PARSING
|
||||
Y("m",Kd),Y("mm",Kd,Gd),aa(["m","mm"],ae);
|
||||
// MOMENTS
|
||||
var Ne=N("Minutes",!1);
|
||||
// FORMATTING
|
||||
T("s",["ss",2],0,"second"),
|
||||
// ALIASES
|
||||
I("second","s"),
|
||||
// PRIORITY
|
||||
L("second",15),
|
||||
// PARSING
|
||||
Y("s",Kd),Y("ss",Kd,Gd),aa(["s","ss"],be);
|
||||
// MOMENTS
|
||||
var Oe=N("Seconds",!1);
|
||||
// FORMATTING
|
||||
T("S",0,0,function(){return~~(this.millisecond()/100)}),T(0,["SS",2],0,function(){return~~(this.millisecond()/10)}),T(0,["SSS",3],0,"millisecond"),T(0,["SSSS",4],0,function(){return 10*this.millisecond()}),T(0,["SSSSS",5],0,function(){return 100*this.millisecond()}),T(0,["SSSSSS",6],0,function(){return 1e3*this.millisecond()}),T(0,["SSSSSSS",7],0,function(){return 1e4*this.millisecond()}),T(0,["SSSSSSSS",8],0,function(){return 1e5*this.millisecond()}),T(0,["SSSSSSSSS",9],0,function(){return 1e6*this.millisecond()}),
|
||||
// ALIASES
|
||||
I("millisecond","ms"),
|
||||
// PRIORITY
|
||||
L("millisecond",16),
|
||||
// PARSING
|
||||
Y("S",Nd,Fd),Y("SS",Nd,Gd),Y("SSS",Nd,Hd);var Pe;for(Pe="SSSS";Pe.length<=9;Pe+="S")Y(Pe,Qd);for(Pe="S";Pe.length<=9;Pe+="S")aa(Pe,Gc);
|
||||
// MOMENTS
|
||||
var Qe=N("Milliseconds",!1);
|
||||
// FORMATTING
|
||||
T("z",0,0,"zoneAbbr"),T("zz",0,0,"zoneName");var Re=q.prototype;Re.add=Je,Re.calendar=Ub,Re.clone=Vb,Re.diff=ac,Re.endOf=mc,Re.format=ec,Re.from=fc,Re.fromNow=gc,Re.to=hc,Re.toNow=ic,Re.get=Q,Re.invalidAt=vc,Re.isAfter=Wb,Re.isBefore=Xb,Re.isBetween=Yb,Re.isSame=Zb,Re.isSameOrAfter=$b,Re.isSameOrBefore=_b,Re.isValid=tc,Re.lang=Le,Re.locale=jc,Re.localeData=kc,Re.max=Ee,Re.min=De,Re.parsingFlags=uc,Re.set=R,Re.startOf=lc,Re.subtract=Ke,Re.toArray=qc,Re.toObject=rc,Re.toDate=pc,Re.toISOString=dc,Re.toJSON=sc,Re.toString=cc,Re.unix=oc,Re.valueOf=nc,Re.creationData=wc,
|
||||
// Year
|
||||
Re.year=ke,Re.isLeapYear=qa,
|
||||
// Week Year
|
||||
Re.weekYear=yc,Re.isoWeekYear=zc,
|
||||
// Quarter
|
||||
Re.quarter=Re.quarters=Ec,
|
||||
// Month
|
||||
Re.month=ja,Re.daysInMonth=ka,
|
||||
// Week
|
||||
Re.week=Re.weeks=Aa,Re.isoWeek=Re.isoWeeks=Ba,Re.weeksInYear=Bc,Re.isoWeeksInYear=Ac,
|
||||
// Day
|
||||
Re.date=Me,Re.day=Re.days=Ja,Re.weekday=Ka,Re.isoWeekday=La,Re.dayOfYear=Fc,
|
||||
// Hour
|
||||
Re.hour=Re.hours=ue,
|
||||
// Minute
|
||||
Re.minute=Re.minutes=Ne,
|
||||
// Second
|
||||
Re.second=Re.seconds=Oe,
|
||||
// Millisecond
|
||||
Re.millisecond=Re.milliseconds=Qe,
|
||||
// Offset
|
||||
Re.utcOffset=Cb,Re.utc=Eb,Re.local=Fb,Re.parseZone=Gb,Re.hasAlignedHourOffset=Hb,Re.isDST=Ib,Re.isLocal=Kb,Re.isUtcOffset=Lb,Re.isUtc=Mb,Re.isUTC=Mb,
|
||||
// Timezone
|
||||
Re.zoneAbbr=Hc,Re.zoneName=Ic,
|
||||
// Deprecations
|
||||
Re.dates=w("dates accessor is deprecated. Use date instead.",Me),Re.months=w("months accessor is deprecated. Use month instead",ja),Re.years=w("years accessor is deprecated. Use year instead",ke),Re.zone=w("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",Db),Re.isDSTShifted=w("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",Jb);var Se=Re,Te=B.prototype;Te.calendar=C,Te.longDateFormat=D,Te.invalidDate=E,Te.ordinal=F,Te.preparse=Lc,Te.postformat=Lc,Te.relativeTime=G,Te.pastFuture=H,Te.set=z,
|
||||
// Month
|
||||
Te.months=ea,Te.monthsShort=fa,Te.monthsParse=ha,Te.monthsRegex=ma,Te.monthsShortRegex=la,
|
||||
// Week
|
||||
Te.week=xa,Te.firstDayOfYear=za,Te.firstDayOfWeek=ya,
|
||||
// Day of Week
|
||||
Te.weekdays=Ea,Te.weekdaysMin=Ga,Te.weekdaysShort=Fa,Te.weekdaysParse=Ia,Te.weekdaysRegex=Ma,Te.weekdaysShortRegex=Na,Te.weekdaysMinRegex=Oa,
|
||||
// Hours
|
||||
Te.isPM=Ua,Te.meridiem=Va,Za("en",{ordinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(a){var b=a%10,c=1===t(a%100/10)?"th":1===b?"st":2===b?"nd":3===b?"rd":"th";return a+c}}),
|
||||
// Side effect imports
|
||||
a.lang=w("moment.lang is deprecated. Use moment.locale instead.",Za),a.langData=w("moment.langData is deprecated. Use moment.localeData instead.",ab);var Ue=Math.abs,Ve=cd("ms"),We=cd("s"),Xe=cd("m"),Ye=cd("h"),Ze=cd("d"),$e=cd("w"),_e=cd("M"),af=cd("y"),bf=ed("milliseconds"),cf=ed("seconds"),df=ed("minutes"),ef=ed("hours"),ff=ed("days"),gf=ed("months"),hf=ed("years"),jf=Math.round,kf={s:45,// seconds to minute
|
||||
m:45,// minutes to hour
|
||||
h:22,// hours to day
|
||||
d:26,// days to month
|
||||
M:11},lf=Math.abs,mf=vb.prototype;mf.abs=Uc,mf.add=Wc,mf.subtract=Xc,mf.as=ad,mf.asMilliseconds=Ve,mf.asSeconds=We,mf.asMinutes=Xe,mf.asHours=Ye,mf.asDays=Ze,mf.asWeeks=$e,mf.asMonths=_e,mf.asYears=af,mf.valueOf=bd,mf._bubble=Zc,mf.get=dd,mf.milliseconds=bf,mf.seconds=cf,mf.minutes=df,mf.hours=ef,mf.days=ff,mf.weeks=fd,mf.months=gf,mf.years=hf,mf.humanize=kd,mf.toISOString=ld,mf.toString=ld,mf.toJSON=ld,mf.locale=jc,mf.localeData=kc,
|
||||
// Deprecations
|
||||
mf.toIsoString=w("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",ld),mf.lang=Le,
|
||||
// Side effect imports
|
||||
// FORMATTING
|
||||
T("X",0,0,"unix"),T("x",0,0,"valueOf"),
|
||||
// PARSING
|
||||
Y("x",Rd),Y("X",Ud),aa("X",function(a,b,c){c._d=new Date(1e3*parseFloat(a,10))}),aa("x",function(a,b,c){c._d=new Date(t(a))}),
|
||||
// Side effect imports
|
||||
a.version="2.15.1",b(rb),a.fn=Se,a.min=tb,a.max=ub,a.now=Fe,a.utc=j,a.unix=Jc,a.months=Pc,a.isDate=f,a.locale=Za,a.invalid=n,a.duration=Nb,a.isMoment=r,a.weekdays=Rc,a.parseZone=Kc,a.localeData=ab,a.isDuration=wb,a.monthsShort=Qc,a.weekdaysMin=Tc,a.defineLocale=$a,a.updateLocale=_a,a.locales=bb,a.weekdaysShort=Sc,a.normalizeUnits=J,a.relativeTimeRounding=id,a.relativeTimeThreshold=jd,a.calendarFormat=Tb,a.prototype=Se;var nf=a;return nf});
|
||||
1
common/static/js/vendor/requirejs/require.js
vendored
1
common/static/js/vendor/requirejs/require.js
vendored
@@ -1 +0,0 @@
|
||||
../../../../../node_modules/requirejs/require.js
|
||||
6279
common/static/js/vendor/sinon-1.17.0.js
vendored
6279
common/static/js/vendor/sinon-1.17.0.js
vendored
@@ -1,6279 +0,0 @@
|
||||
/**
|
||||
* Sinon.JS 1.17.0, 2015/09/22
|
||||
*
|
||||
* @author Christian Johansen (christian@cjohansen.no)
|
||||
* @author Contributors: https://github.com/cjohansen/Sinon.JS/blob/master/AUTHORS
|
||||
*
|
||||
* (The BSD License)
|
||||
*
|
||||
* Copyright (c) 2010-2014, Christian Johansen, christian@cjohansen.no
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* * Neither the name of Christian Johansen nor the names of his contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
(function (root, factory) {
|
||||
'use strict';
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
define('sinon', [], function () {
|
||||
return (root.sinon = factory());
|
||||
});
|
||||
} else if (typeof exports === 'object') {
|
||||
module.exports = factory();
|
||||
} else {
|
||||
root.sinon = factory();
|
||||
}
|
||||
}(this, function () {
|
||||
'use strict';
|
||||
var samsam, formatio, lolex;
|
||||
(function () {
|
||||
function define(mod, deps, fn) {
|
||||
if (mod == "samsam") {
|
||||
samsam = deps();
|
||||
} else if (typeof deps === "function" && mod.length === 0) {
|
||||
lolex = deps();
|
||||
} else if (typeof fn === "function") {
|
||||
formatio = fn(samsam);
|
||||
}
|
||||
}
|
||||
define.amd = {};
|
||||
((typeof define === "function" && define.amd && function (m) { define("samsam", m); }) ||
|
||||
(typeof module === "object" &&
|
||||
function (m) { module.exports = m(); }) || // Node
|
||||
function (m) { this.samsam = m(); } // Browser globals
|
||||
)(function () {
|
||||
var o = Object.prototype;
|
||||
var div = typeof document !== "undefined" && document.createElement("div");
|
||||
|
||||
function isNaN(value) {
|
||||
// Unlike global isNaN, this avoids type coercion
|
||||
// typeof check avoids IE host object issues, hat tip to
|
||||
// lodash
|
||||
var val = value; // JsLint thinks value !== value is "weird"
|
||||
return typeof value === "number" && value !== val;
|
||||
}
|
||||
|
||||
function getClass(value) {
|
||||
// Returns the internal [[Class]] by calling Object.prototype.toString
|
||||
// with the provided value as this. Return value is a string, naming the
|
||||
// internal class, e.g. "Array"
|
||||
return o.toString.call(value).split(/[ \]]/)[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* @name samsam.isArguments
|
||||
* @param Object object
|
||||
*
|
||||
* Returns ``true`` if ``object`` is an ``arguments`` object,
|
||||
* ``false`` otherwise.
|
||||
*/
|
||||
function isArguments(object) {
|
||||
if (getClass(object) === 'Arguments') { return true; }
|
||||
if (typeof object !== "object" || typeof object.length !== "number" ||
|
||||
getClass(object) === "Array") {
|
||||
return false;
|
||||
}
|
||||
if (typeof object.callee == "function") { return true; }
|
||||
try {
|
||||
object[object.length] = 6;
|
||||
delete object[object.length];
|
||||
} catch (e) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name samsam.isElement
|
||||
* @param Object object
|
||||
*
|
||||
* Returns ``true`` if ``object`` is a DOM element node. Unlike
|
||||
* Underscore.js/lodash, this function will return ``false`` if ``object``
|
||||
* is an *element-like* object, i.e. a regular object with a ``nodeType``
|
||||
* property that holds the value ``1``.
|
||||
*/
|
||||
function isElement(object) {
|
||||
if (!object || object.nodeType !== 1 || !div) { return false; }
|
||||
try {
|
||||
object.appendChild(div);
|
||||
object.removeChild(div);
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name samsam.keys
|
||||
* @param Object object
|
||||
*
|
||||
* Return an array of own property names.
|
||||
*/
|
||||
function keys(object) {
|
||||
var ks = [], prop;
|
||||
for (prop in object) {
|
||||
if (o.hasOwnProperty.call(object, prop)) { ks.push(prop); }
|
||||
}
|
||||
return ks;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name samsam.isDate
|
||||
* @param Object value
|
||||
*
|
||||
* Returns true if the object is a ``Date``, or *date-like*. Duck typing
|
||||
* of date objects work by checking that the object has a ``getTime``
|
||||
* function whose return value equals the return value from the object's
|
||||
* ``valueOf``.
|
||||
*/
|
||||
function isDate(value) {
|
||||
return typeof value.getTime == "function" &&
|
||||
value.getTime() == value.valueOf();
|
||||
}
|
||||
|
||||
/**
|
||||
* @name samsam.isNegZero
|
||||
* @param Object value
|
||||
*
|
||||
* Returns ``true`` if ``value`` is ``-0``.
|
||||
*/
|
||||
function isNegZero(value) {
|
||||
return value === 0 && 1 / value === -Infinity;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name samsam.equal
|
||||
* @param Object obj1
|
||||
* @param Object obj2
|
||||
*
|
||||
* Returns ``true`` if two objects are strictly equal. Compared to
|
||||
* ``===`` there are two exceptions:
|
||||
*
|
||||
* - NaN is considered equal to NaN
|
||||
* - -0 and +0 are not considered equal
|
||||
*/
|
||||
function identical(obj1, obj2) {
|
||||
if (obj1 === obj2 || (isNaN(obj1) && isNaN(obj2))) {
|
||||
return obj1 !== 0 || isNegZero(obj1) === isNegZero(obj2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @name samsam.deepEqual
|
||||
* @param Object obj1
|
||||
* @param Object obj2
|
||||
*
|
||||
* Deep equal comparison. Two values are "deep equal" if:
|
||||
*
|
||||
* - They are equal, according to samsam.identical
|
||||
* - They are both date objects representing the same time
|
||||
* - They are both arrays containing elements that are all deepEqual
|
||||
* - They are objects with the same set of properties, and each property
|
||||
* in ``obj1`` is deepEqual to the corresponding property in ``obj2``
|
||||
*
|
||||
* Supports cyclic objects.
|
||||
*/
|
||||
function deepEqualCyclic(obj1, obj2) {
|
||||
|
||||
// used for cyclic comparison
|
||||
// contain already visited objects
|
||||
var objects1 = [],
|
||||
objects2 = [],
|
||||
// contain pathes (position in the object structure)
|
||||
// of the already visited objects
|
||||
// indexes same as in objects arrays
|
||||
paths1 = [],
|
||||
paths2 = [],
|
||||
// contains combinations of already compared objects
|
||||
// in the manner: { "$1['ref']$2['ref']": true }
|
||||
compared = {};
|
||||
|
||||
/**
|
||||
* used to check, if the value of a property is an object
|
||||
* (cyclic logic is only needed for objects)
|
||||
* only needed for cyclic logic
|
||||
*/
|
||||
function isObject(value) {
|
||||
|
||||
if (typeof value === 'object' && value !== null &&
|
||||
!(value instanceof Boolean) &&
|
||||
!(value instanceof Date) &&
|
||||
!(value instanceof Number) &&
|
||||
!(value instanceof RegExp) &&
|
||||
!(value instanceof String)) {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the index of the given object in the
|
||||
* given objects array, -1 if not contained
|
||||
* only needed for cyclic logic
|
||||
*/
|
||||
function getIndex(objects, obj) {
|
||||
|
||||
var i;
|
||||
for (i = 0; i < objects.length; i++) {
|
||||
if (objects[i] === obj) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
// does the recursion for the deep equal check
|
||||
return (function deepEqual(obj1, obj2, path1, path2) {
|
||||
var type1 = typeof obj1;
|
||||
var type2 = typeof obj2;
|
||||
|
||||
// == null also matches undefined
|
||||
if (obj1 === obj2 ||
|
||||
isNaN(obj1) || isNaN(obj2) ||
|
||||
obj1 == null || obj2 == null ||
|
||||
type1 !== "object" || type2 !== "object") {
|
||||
|
||||
return identical(obj1, obj2);
|
||||
}
|
||||
|
||||
// Elements are only equal if identical(expected, actual)
|
||||
if (isElement(obj1) || isElement(obj2)) { return false; }
|
||||
|
||||
var isDate1 = isDate(obj1), isDate2 = isDate(obj2);
|
||||
if (isDate1 || isDate2) {
|
||||
if (!isDate1 || !isDate2 || obj1.getTime() !== obj2.getTime()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (obj1 instanceof RegExp && obj2 instanceof RegExp) {
|
||||
if (obj1.toString() !== obj2.toString()) { return false; }
|
||||
}
|
||||
|
||||
var class1 = getClass(obj1);
|
||||
var class2 = getClass(obj2);
|
||||
var keys1 = keys(obj1);
|
||||
var keys2 = keys(obj2);
|
||||
|
||||
if (isArguments(obj1) || isArguments(obj2)) {
|
||||
if (obj1.length !== obj2.length) { return false; }
|
||||
} else {
|
||||
if (type1 !== type2 || class1 !== class2 ||
|
||||
keys1.length !== keys2.length) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
var key, i, l,
|
||||
// following vars are used for the cyclic logic
|
||||
value1, value2,
|
||||
isObject1, isObject2,
|
||||
index1, index2,
|
||||
newPath1, newPath2;
|
||||
|
||||
for (i = 0, l = keys1.length; i < l; i++) {
|
||||
key = keys1[i];
|
||||
if (!o.hasOwnProperty.call(obj2, key)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Start of the cyclic logic
|
||||
|
||||
value1 = obj1[key];
|
||||
value2 = obj2[key];
|
||||
|
||||
isObject1 = isObject(value1);
|
||||
isObject2 = isObject(value2);
|
||||
|
||||
// determine, if the objects were already visited
|
||||
// (it's faster to check for isObject first, than to
|
||||
// get -1 from getIndex for non objects)
|
||||
index1 = isObject1 ? getIndex(objects1, value1) : -1;
|
||||
index2 = isObject2 ? getIndex(objects2, value2) : -1;
|
||||
|
||||
// determine the new pathes of the objects
|
||||
// - for non cyclic objects the current path will be extended
|
||||
// by current property name
|
||||
// - for cyclic objects the stored path is taken
|
||||
newPath1 = index1 !== -1
|
||||
? paths1[index1]
|
||||
: path1 + '[' + JSON.stringify(key) + ']';
|
||||
newPath2 = index2 !== -1
|
||||
? paths2[index2]
|
||||
: path2 + '[' + JSON.stringify(key) + ']';
|
||||
|
||||
// stop recursion if current objects are already compared
|
||||
if (compared[newPath1 + newPath2]) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// remember the current objects and their pathes
|
||||
if (index1 === -1 && isObject1) {
|
||||
objects1.push(value1);
|
||||
paths1.push(newPath1);
|
||||
}
|
||||
if (index2 === -1 && isObject2) {
|
||||
objects2.push(value2);
|
||||
paths2.push(newPath2);
|
||||
}
|
||||
|
||||
// remember that the current objects are already compared
|
||||
if (isObject1 && isObject2) {
|
||||
compared[newPath1 + newPath2] = true;
|
||||
}
|
||||
|
||||
// End of cyclic logic
|
||||
|
||||
// neither value1 nor value2 is a cycle
|
||||
// continue with next level
|
||||
if (!deepEqual(value1, value2, newPath1, newPath2)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}(obj1, obj2, '$1', '$2'));
|
||||
}
|
||||
|
||||
var match;
|
||||
|
||||
function arrayContains(array, subset) {
|
||||
if (subset.length === 0) { return true; }
|
||||
var i, l, j, k;
|
||||
for (i = 0, l = array.length; i < l; ++i) {
|
||||
if (match(array[i], subset[0])) {
|
||||
for (j = 0, k = subset.length; j < k; ++j) {
|
||||
if (!match(array[i + j], subset[j])) { return false; }
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name samsam.match
|
||||
* @param Object object
|
||||
* @param Object matcher
|
||||
*
|
||||
* Compare arbitrary value ``object`` with matcher.
|
||||
*/
|
||||
match = function match(object, matcher) {
|
||||
if (matcher && typeof matcher.test === "function") {
|
||||
return matcher.test(object);
|
||||
}
|
||||
|
||||
if (typeof matcher === "function") {
|
||||
return matcher(object) === true;
|
||||
}
|
||||
|
||||
if (typeof matcher === "string") {
|
||||
matcher = matcher.toLowerCase();
|
||||
var notNull = typeof object === "string" || !!object;
|
||||
return notNull &&
|
||||
(String(object)).toLowerCase().indexOf(matcher) >= 0;
|
||||
}
|
||||
|
||||
if (typeof matcher === "number") {
|
||||
return matcher === object;
|
||||
}
|
||||
|
||||
if (typeof matcher === "boolean") {
|
||||
return matcher === object;
|
||||
}
|
||||
|
||||
if (typeof(matcher) === "undefined") {
|
||||
return typeof(object) === "undefined";
|
||||
}
|
||||
|
||||
if (matcher === null) {
|
||||
return object === null;
|
||||
}
|
||||
|
||||
if (getClass(object) === "Array" && getClass(matcher) === "Array") {
|
||||
return arrayContains(object, matcher);
|
||||
}
|
||||
|
||||
if (matcher && typeof matcher === "object") {
|
||||
if (matcher === object) {
|
||||
return true;
|
||||
}
|
||||
var prop;
|
||||
for (prop in matcher) {
|
||||
var value = object[prop];
|
||||
if (typeof value === "undefined" &&
|
||||
typeof object.getAttribute === "function") {
|
||||
value = object.getAttribute(prop);
|
||||
}
|
||||
if (matcher[prop] === null || typeof matcher[prop] === 'undefined') {
|
||||
if (value !== matcher[prop]) {
|
||||
return false;
|
||||
}
|
||||
} else if (typeof value === "undefined" || !match(value, matcher[prop])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
throw new Error("Matcher was not a string, a number, a " +
|
||||
"function, a boolean or an object");
|
||||
};
|
||||
|
||||
return {
|
||||
isArguments: isArguments,
|
||||
isElement: isElement,
|
||||
isDate: isDate,
|
||||
isNegZero: isNegZero,
|
||||
identical: identical,
|
||||
deepEqual: deepEqualCyclic,
|
||||
match: match,
|
||||
keys: keys
|
||||
};
|
||||
});
|
||||
((typeof define === "function" && define.amd && function (m) {
|
||||
define("formatio", ["samsam"], m);
|
||||
}) || (typeof module === "object" && function (m) {
|
||||
module.exports = m(require("samsam"));
|
||||
}) || function (m) { this.formatio = m(this.samsam); }
|
||||
)(function (samsam) {
|
||||
|
||||
var formatio = {
|
||||
excludeConstructors: ["Object", /^.$/],
|
||||
quoteStrings: true,
|
||||
limitChildrenCount: 0
|
||||
};
|
||||
|
||||
var hasOwn = Object.prototype.hasOwnProperty;
|
||||
|
||||
var specialObjects = [];
|
||||
if (typeof global !== "undefined") {
|
||||
specialObjects.push({ object: global, value: "[object global]" });
|
||||
}
|
||||
if (typeof document !== "undefined") {
|
||||
specialObjects.push({
|
||||
object: document,
|
||||
value: "[object HTMLDocument]"
|
||||
});
|
||||
}
|
||||
if (typeof window !== "undefined") {
|
||||
specialObjects.push({ object: window, value: "[object Window]" });
|
||||
}
|
||||
|
||||
function functionName(func) {
|
||||
if (!func) { return ""; }
|
||||
if (func.displayName) { return func.displayName; }
|
||||
if (func.name) { return func.name; }
|
||||
var matches = func.toString().match(/function\s+([^\(]+)/m);
|
||||
return (matches && matches[1]) || "";
|
||||
}
|
||||
|
||||
function constructorName(f, object) {
|
||||
var name = functionName(object && object.constructor);
|
||||
var excludes = f.excludeConstructors ||
|
||||
formatio.excludeConstructors || [];
|
||||
|
||||
var i, l;
|
||||
for (i = 0, l = excludes.length; i < l; ++i) {
|
||||
if (typeof excludes[i] === "string" && excludes[i] === name) {
|
||||
return "";
|
||||
} else if (excludes[i].test && excludes[i].test(name)) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
function isCircular(object, objects) {
|
||||
if (typeof object !== "object") { return false; }
|
||||
var i, l;
|
||||
for (i = 0, l = objects.length; i < l; ++i) {
|
||||
if (objects[i] === object) { return true; }
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function ascii(f, object, processed, indent) {
|
||||
if (typeof object === "string") {
|
||||
var qs = f.quoteStrings;
|
||||
var quote = typeof qs !== "boolean" || qs;
|
||||
return processed || quote ? '"' + object + '"' : object;
|
||||
}
|
||||
|
||||
if (typeof object === "function" && !(object instanceof RegExp)) {
|
||||
return ascii.func(object);
|
||||
}
|
||||
|
||||
processed = processed || [];
|
||||
|
||||
if (isCircular(object, processed)) { return "[Circular]"; }
|
||||
|
||||
if (Object.prototype.toString.call(object) === "[object Array]") {
|
||||
return ascii.array.call(f, object, processed);
|
||||
}
|
||||
|
||||
if (!object) { return String((1/object) === -Infinity ? "-0" : object); }
|
||||
if (samsam.isElement(object)) { return ascii.element(object); }
|
||||
|
||||
if (typeof object.toString === "function" &&
|
||||
object.toString !== Object.prototype.toString) {
|
||||
return object.toString();
|
||||
}
|
||||
|
||||
var i, l;
|
||||
for (i = 0, l = specialObjects.length; i < l; i++) {
|
||||
if (object === specialObjects[i].object) {
|
||||
return specialObjects[i].value;
|
||||
}
|
||||
}
|
||||
|
||||
return ascii.object.call(f, object, processed, indent);
|
||||
}
|
||||
|
||||
ascii.func = function (func) {
|
||||
return "function " + functionName(func) + "() {}";
|
||||
};
|
||||
|
||||
ascii.array = function (array, processed) {
|
||||
processed = processed || [];
|
||||
processed.push(array);
|
||||
var pieces = [];
|
||||
var i, l;
|
||||
l = (this.limitChildrenCount > 0) ?
|
||||
Math.min(this.limitChildrenCount, array.length) : array.length;
|
||||
|
||||
for (i = 0; i < l; ++i) {
|
||||
pieces.push(ascii(this, array[i], processed));
|
||||
}
|
||||
|
||||
if(l < array.length)
|
||||
pieces.push("[... " + (array.length - l) + " more elements]");
|
||||
|
||||
return "[" + pieces.join(", ") + "]";
|
||||
};
|
||||
|
||||
ascii.object = function (object, processed, indent) {
|
||||
processed = processed || [];
|
||||
processed.push(object);
|
||||
indent = indent || 0;
|
||||
var pieces = [], properties = samsam.keys(object).sort();
|
||||
var length = 3;
|
||||
var prop, str, obj, i, k, l;
|
||||
l = (this.limitChildrenCount > 0) ?
|
||||
Math.min(this.limitChildrenCount, properties.length) : properties.length;
|
||||
|
||||
for (i = 0; i < l; ++i) {
|
||||
prop = properties[i];
|
||||
obj = object[prop];
|
||||
|
||||
if (isCircular(obj, processed)) {
|
||||
str = "[Circular]";
|
||||
} else {
|
||||
str = ascii(this, obj, processed, indent + 2);
|
||||
}
|
||||
|
||||
str = (/\s/.test(prop) ? '"' + prop + '"' : prop) + ": " + str;
|
||||
length += str.length;
|
||||
pieces.push(str);
|
||||
}
|
||||
|
||||
var cons = constructorName(this, object);
|
||||
var prefix = cons ? "[" + cons + "] " : "";
|
||||
var is = "";
|
||||
for (i = 0, k = indent; i < k; ++i) { is += " "; }
|
||||
|
||||
if(l < properties.length)
|
||||
pieces.push("[... " + (properties.length - l) + " more elements]");
|
||||
|
||||
if (length + indent > 80) {
|
||||
return prefix + "{\n " + is + pieces.join(",\n " + is) + "\n" +
|
||||
is + "}";
|
||||
}
|
||||
return prefix + "{ " + pieces.join(", ") + " }";
|
||||
};
|
||||
|
||||
ascii.element = function (element) {
|
||||
var tagName = element.tagName.toLowerCase();
|
||||
var attrs = element.attributes, attr, pairs = [], attrName, i, l, val;
|
||||
|
||||
for (i = 0, l = attrs.length; i < l; ++i) {
|
||||
attr = attrs.item(i);
|
||||
attrName = attr.nodeName.toLowerCase().replace("html:", "");
|
||||
val = attr.nodeValue;
|
||||
if (attrName !== "contenteditable" || val !== "inherit") {
|
||||
if (!!val) { pairs.push(attrName + "=\"" + val + "\""); }
|
||||
}
|
||||
}
|
||||
|
||||
var formatted = "<" + tagName + (pairs.length > 0 ? " " : "");
|
||||
var content = element.innerHTML;
|
||||
|
||||
if (content.length > 20) {
|
||||
content = content.substr(0, 20) + "[...]";
|
||||
}
|
||||
|
||||
var res = formatted + pairs.join(" ") + ">" + content +
|
||||
"</" + tagName + ">";
|
||||
|
||||
return res.replace(/ contentEditable="inherit"/, "");
|
||||
};
|
||||
|
||||
function Formatio(options) {
|
||||
for (var opt in options) {
|
||||
this[opt] = options[opt];
|
||||
}
|
||||
}
|
||||
|
||||
Formatio.prototype = {
|
||||
functionName: functionName,
|
||||
|
||||
configure: function (options) {
|
||||
return new Formatio(options);
|
||||
},
|
||||
|
||||
constructorName: function (object) {
|
||||
return constructorName(this, object);
|
||||
},
|
||||
|
||||
ascii: function (object, processed, indent) {
|
||||
return ascii(this, object, processed, indent);
|
||||
}
|
||||
};
|
||||
|
||||
return Formatio.prototype;
|
||||
});
|
||||
!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.lolex=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
|
||||
(function (global){
|
||||
/*jslint eqeqeq: false, plusplus: false, evil: true, onevar: false, browser: true, forin: false*/
|
||||
/*global global*/
|
||||
/**
|
||||
* @author Christian Johansen (christian@cjohansen.no) and contributors
|
||||
* @license BSD
|
||||
*
|
||||
* Copyright (c) 2010-2014 Christian Johansen
|
||||
*/
|
||||
|
||||
// node expects setTimeout/setInterval to return a fn object w/ .ref()/.unref()
|
||||
// browsers, a number.
|
||||
// see https://github.com/cjohansen/Sinon.JS/pull/436
|
||||
var timeoutResult = setTimeout(function() {}, 0);
|
||||
var addTimerReturnsObject = typeof timeoutResult === "object";
|
||||
clearTimeout(timeoutResult);
|
||||
|
||||
var NativeDate = Date;
|
||||
var id = 1;
|
||||
|
||||
/**
|
||||
* Parse strings like "01:10:00" (meaning 1 hour, 10 minutes, 0 seconds) into
|
||||
* number of milliseconds. This is used to support human-readable strings passed
|
||||
* to clock.tick()
|
||||
*/
|
||||
function parseTime(str) {
|
||||
if (!str) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
var strings = str.split(":");
|
||||
var l = strings.length, i = l;
|
||||
var ms = 0, parsed;
|
||||
|
||||
if (l > 3 || !/^(\d\d:){0,2}\d\d?$/.test(str)) {
|
||||
throw new Error("tick only understands numbers and 'h:m:s'");
|
||||
}
|
||||
|
||||
while (i--) {
|
||||
parsed = parseInt(strings[i], 10);
|
||||
|
||||
if (parsed >= 60) {
|
||||
throw new Error("Invalid time " + str);
|
||||
}
|
||||
|
||||
ms += parsed * Math.pow(60, (l - i - 1));
|
||||
}
|
||||
|
||||
return ms * 1000;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to grok the `now` parameter to createClock.
|
||||
*/
|
||||
function getEpoch(epoch) {
|
||||
if (!epoch) { return 0; }
|
||||
if (typeof epoch.getTime === "function") { return epoch.getTime(); }
|
||||
if (typeof epoch === "number") { return epoch; }
|
||||
throw new TypeError("now should be milliseconds since UNIX epoch");
|
||||
}
|
||||
|
||||
function inRange(from, to, timer) {
|
||||
return timer && timer.callAt >= from && timer.callAt <= to;
|
||||
}
|
||||
|
||||
function mirrorDateProperties(target, source) {
|
||||
if (source.now) {
|
||||
target.now = function now() {
|
||||
return target.clock.now;
|
||||
};
|
||||
} else {
|
||||
delete target.now;
|
||||
}
|
||||
|
||||
if (source.toSource) {
|
||||
target.toSource = function toSource() {
|
||||
return source.toSource();
|
||||
};
|
||||
} else {
|
||||
delete target.toSource;
|
||||
}
|
||||
|
||||
target.toString = function toString() {
|
||||
return source.toString();
|
||||
};
|
||||
|
||||
target.prototype = source.prototype;
|
||||
target.parse = source.parse;
|
||||
target.UTC = source.UTC;
|
||||
target.prototype.toUTCString = source.prototype.toUTCString;
|
||||
|
||||
for (var prop in source) {
|
||||
if (source.hasOwnProperty(prop)) {
|
||||
target[prop] = source[prop];
|
||||
}
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
function createDate() {
|
||||
function ClockDate(year, month, date, hour, minute, second, ms) {
|
||||
// Defensive and verbose to avoid potential harm in passing
|
||||
// explicit undefined when user does not pass argument
|
||||
switch (arguments.length) {
|
||||
case 0:
|
||||
return new NativeDate(ClockDate.clock.now);
|
||||
case 1:
|
||||
return new NativeDate(year);
|
||||
case 2:
|
||||
return new NativeDate(year, month);
|
||||
case 3:
|
||||
return new NativeDate(year, month, date);
|
||||
case 4:
|
||||
return new NativeDate(year, month, date, hour);
|
||||
case 5:
|
||||
return new NativeDate(year, month, date, hour, minute);
|
||||
case 6:
|
||||
return new NativeDate(year, month, date, hour, minute, second);
|
||||
default:
|
||||
return new NativeDate(year, month, date, hour, minute, second, ms);
|
||||
}
|
||||
}
|
||||
|
||||
return mirrorDateProperties(ClockDate, NativeDate);
|
||||
}
|
||||
|
||||
function addTimer(clock, timer) {
|
||||
if (typeof timer.func === "undefined") {
|
||||
throw new Error("Callback must be provided to timer calls");
|
||||
}
|
||||
|
||||
if (!clock.timers) {
|
||||
clock.timers = {};
|
||||
}
|
||||
|
||||
timer.id = id++;
|
||||
timer.createdAt = clock.now;
|
||||
timer.callAt = clock.now + (timer.delay || 0);
|
||||
|
||||
clock.timers[timer.id] = timer;
|
||||
|
||||
if (addTimerReturnsObject) {
|
||||
return {
|
||||
id: timer.id,
|
||||
ref: function() {},
|
||||
unref: function() {}
|
||||
};
|
||||
}
|
||||
else {
|
||||
return timer.id;
|
||||
}
|
||||
}
|
||||
|
||||
function firstTimerInRange(clock, from, to) {
|
||||
var timers = clock.timers, timer = null;
|
||||
|
||||
for (var id in timers) {
|
||||
if (!inRange(from, to, timers[id])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!timer || ~compareTimers(timer, timers[id])) {
|
||||
timer = timers[id];
|
||||
}
|
||||
}
|
||||
|
||||
return timer;
|
||||
}
|
||||
|
||||
function compareTimers(a, b) {
|
||||
// Sort first by absolute timing
|
||||
if (a.callAt < b.callAt) {
|
||||
return -1;
|
||||
}
|
||||
if (a.callAt > b.callAt) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Sort next by immediate, immediate timers take precedence
|
||||
if (a.immediate && !b.immediate) {
|
||||
return -1;
|
||||
}
|
||||
if (!a.immediate && b.immediate) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Sort next by creation time, earlier-created timers take precedence
|
||||
if (a.createdAt < b.createdAt) {
|
||||
return -1;
|
||||
}
|
||||
if (a.createdAt > b.createdAt) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Sort next by id, lower-id timers take precedence
|
||||
if (a.id < b.id) {
|
||||
return -1;
|
||||
}
|
||||
if (a.id > b.id) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// As timer ids are unique, no fallback `0` is necessary
|
||||
}
|
||||
|
||||
function callTimer(clock, timer) {
|
||||
if (typeof timer.interval == "number") {
|
||||
clock.timers[timer.id].callAt += timer.interval;
|
||||
} else {
|
||||
delete clock.timers[timer.id];
|
||||
}
|
||||
|
||||
try {
|
||||
if (typeof timer.func == "function") {
|
||||
timer.func.apply(null, timer.args);
|
||||
} else {
|
||||
eval(timer.func);
|
||||
}
|
||||
} catch (e) {
|
||||
var exception = e;
|
||||
}
|
||||
|
||||
if (!clock.timers[timer.id]) {
|
||||
if (exception) {
|
||||
throw exception;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (exception) {
|
||||
throw exception;
|
||||
}
|
||||
}
|
||||
|
||||
function uninstall(clock, target) {
|
||||
var method;
|
||||
|
||||
for (var i = 0, l = clock.methods.length; i < l; i++) {
|
||||
method = clock.methods[i];
|
||||
|
||||
if (target[method].hadOwnProperty) {
|
||||
target[method] = clock["_" + method];
|
||||
} else {
|
||||
try {
|
||||
delete target[method];
|
||||
} catch (e) {}
|
||||
}
|
||||
}
|
||||
|
||||
// Prevent multiple executions which will completely remove these props
|
||||
clock.methods = [];
|
||||
}
|
||||
|
||||
function hijackMethod(target, method, clock) {
|
||||
clock[method].hadOwnProperty = Object.prototype.hasOwnProperty.call(target, method);
|
||||
clock["_" + method] = target[method];
|
||||
|
||||
if (method == "Date") {
|
||||
var date = mirrorDateProperties(clock[method], target[method]);
|
||||
target[method] = date;
|
||||
} else {
|
||||
target[method] = function () {
|
||||
return clock[method].apply(clock, arguments);
|
||||
};
|
||||
|
||||
for (var prop in clock[method]) {
|
||||
if (clock[method].hasOwnProperty(prop)) {
|
||||
target[method][prop] = clock[method][prop];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
target[method].clock = clock;
|
||||
}
|
||||
|
||||
var timers = {
|
||||
setTimeout: setTimeout,
|
||||
clearTimeout: clearTimeout,
|
||||
setImmediate: (typeof setImmediate !== "undefined" ? setImmediate : undefined),
|
||||
clearImmediate: (typeof clearImmediate !== "undefined" ? clearImmediate: undefined),
|
||||
setInterval: setInterval,
|
||||
clearInterval: clearInterval,
|
||||
Date: Date
|
||||
};
|
||||
|
||||
var keys = Object.keys || function (obj) {
|
||||
var ks = [];
|
||||
for (var key in obj) {
|
||||
ks.push(key);
|
||||
}
|
||||
return ks;
|
||||
};
|
||||
|
||||
exports.timers = timers;
|
||||
|
||||
var createClock = exports.createClock = function (now) {
|
||||
var clock = {
|
||||
now: getEpoch(now),
|
||||
timeouts: {},
|
||||
Date: createDate()
|
||||
};
|
||||
|
||||
clock.Date.clock = clock;
|
||||
|
||||
clock.setTimeout = function setTimeout(func, timeout) {
|
||||
return addTimer(clock, {
|
||||
func: func,
|
||||
args: Array.prototype.slice.call(arguments, 2),
|
||||
delay: timeout
|
||||
});
|
||||
};
|
||||
|
||||
clock.clearTimeout = function clearTimeout(timerId) {
|
||||
if (!timerId) {
|
||||
// null appears to be allowed in most browsers, and appears to be
|
||||
// relied upon by some libraries, like Bootstrap carousel
|
||||
return;
|
||||
}
|
||||
if (!clock.timers) {
|
||||
clock.timers = [];
|
||||
}
|
||||
// in Node, timerId is an object with .ref()/.unref(), and
|
||||
// its .id field is the actual timer id.
|
||||
if (typeof timerId === "object") {
|
||||
timerId = timerId.id
|
||||
}
|
||||
if (timerId in clock.timers) {
|
||||
delete clock.timers[timerId];
|
||||
}
|
||||
};
|
||||
|
||||
clock.setInterval = function setInterval(func, timeout) {
|
||||
return addTimer(clock, {
|
||||
func: func,
|
||||
args: Array.prototype.slice.call(arguments, 2),
|
||||
delay: timeout,
|
||||
interval: timeout
|
||||
});
|
||||
};
|
||||
|
||||
clock.clearInterval = function clearInterval(timerId) {
|
||||
clock.clearTimeout(timerId);
|
||||
};
|
||||
|
||||
clock.setImmediate = function setImmediate(func) {
|
||||
return addTimer(clock, {
|
||||
func: func,
|
||||
args: Array.prototype.slice.call(arguments, 1),
|
||||
immediate: true
|
||||
});
|
||||
};
|
||||
|
||||
clock.clearImmediate = function clearImmediate(timerId) {
|
||||
clock.clearTimeout(timerId);
|
||||
};
|
||||
|
||||
clock.tick = function tick(ms) {
|
||||
ms = typeof ms == "number" ? ms : parseTime(ms);
|
||||
var tickFrom = clock.now, tickTo = clock.now + ms, previous = clock.now;
|
||||
var timer = firstTimerInRange(clock, tickFrom, tickTo);
|
||||
|
||||
var firstException;
|
||||
while (timer && tickFrom <= tickTo) {
|
||||
if (clock.timers[timer.id]) {
|
||||
tickFrom = clock.now = timer.callAt;
|
||||
try {
|
||||
callTimer(clock, timer);
|
||||
} catch (e) {
|
||||
firstException = firstException || e;
|
||||
}
|
||||
}
|
||||
|
||||
timer = firstTimerInRange(clock, previous, tickTo);
|
||||
previous = tickFrom;
|
||||
}
|
||||
|
||||
clock.now = tickTo;
|
||||
|
||||
if (firstException) {
|
||||
throw firstException;
|
||||
}
|
||||
|
||||
return clock.now;
|
||||
};
|
||||
|
||||
clock.reset = function reset() {
|
||||
clock.timers = {};
|
||||
};
|
||||
|
||||
return clock;
|
||||
};
|
||||
|
||||
exports.install = function install(target, now, toFake) {
|
||||
if (typeof target === "number") {
|
||||
toFake = now;
|
||||
now = target;
|
||||
target = null;
|
||||
}
|
||||
|
||||
if (!target) {
|
||||
target = global;
|
||||
}
|
||||
|
||||
var clock = createClock(now);
|
||||
|
||||
clock.uninstall = function () {
|
||||
uninstall(clock, target);
|
||||
};
|
||||
|
||||
clock.methods = toFake || [];
|
||||
|
||||
if (clock.methods.length === 0) {
|
||||
clock.methods = keys(timers);
|
||||
}
|
||||
|
||||
for (var i = 0, l = clock.methods.length; i < l; i++) {
|
||||
hijackMethod(target, clock.methods[i], clock);
|
||||
}
|
||||
|
||||
return clock;
|
||||
};
|
||||
|
||||
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
||||
},{}]},{},[1])(1)
|
||||
});
|
||||
})();
|
||||
var define;
|
||||
/**
|
||||
* Sinon core utilities. For internal use only.
|
||||
*
|
||||
* @author Christian Johansen (christian@cjohansen.no)
|
||||
* @license BSD
|
||||
*
|
||||
* Copyright (c) 2010-2013 Christian Johansen
|
||||
*/
|
||||
var sinon = (function () {
|
||||
"use strict";
|
||||
// eslint-disable-line no-unused-vars
|
||||
|
||||
var sinonModule;
|
||||
var isNode = typeof module !== "undefined" && module.exports && typeof require === "function";
|
||||
var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
|
||||
|
||||
function loadDependencies(require, exports, module) {
|
||||
sinonModule = module.exports = require("./sinon/util/core");
|
||||
require("./sinon/extend");
|
||||
require("./sinon/walk");
|
||||
require("./sinon/typeOf");
|
||||
require("./sinon/times_in_words");
|
||||
require("./sinon/spy");
|
||||
require("./sinon/call");
|
||||
require("./sinon/behavior");
|
||||
require("./sinon/stub");
|
||||
require("./sinon/mock");
|
||||
require("./sinon/collection");
|
||||
require("./sinon/assert");
|
||||
require("./sinon/sandbox");
|
||||
require("./sinon/test");
|
||||
require("./sinon/test_case");
|
||||
require("./sinon/match");
|
||||
require("./sinon/format");
|
||||
require("./sinon/log_error");
|
||||
}
|
||||
|
||||
if (isAMD) {
|
||||
define(loadDependencies);
|
||||
} else if (isNode) {
|
||||
loadDependencies(require, module.exports, module);
|
||||
sinonModule = module.exports;
|
||||
} else {
|
||||
sinonModule = {};
|
||||
}
|
||||
|
||||
return sinonModule;
|
||||
}());
|
||||
|
||||
/**
|
||||
* @depend ../../sinon.js
|
||||
*/
|
||||
/**
|
||||
* Sinon core utilities. For internal use only.
|
||||
*
|
||||
* @author Christian Johansen (christian@cjohansen.no)
|
||||
* @license BSD
|
||||
*
|
||||
* Copyright (c) 2010-2013 Christian Johansen
|
||||
*/
|
||||
(function (sinonGlobal) {
|
||||
|
||||
var div = typeof document !== "undefined" && document.createElement("div");
|
||||
var hasOwn = Object.prototype.hasOwnProperty;
|
||||
|
||||
function isDOMNode(obj) {
|
||||
var success = false;
|
||||
|
||||
try {
|
||||
obj.appendChild(div);
|
||||
success = div.parentNode === obj;
|
||||
} catch (e) {
|
||||
return false;
|
||||
} finally {
|
||||
try {
|
||||
obj.removeChild(div);
|
||||
} catch (e) {
|
||||
// Remove failed, not much we can do about that
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
function isElement(obj) {
|
||||
return div && obj && obj.nodeType === 1 && isDOMNode(obj);
|
||||
}
|
||||
|
||||
function isFunction(obj) {
|
||||
return typeof obj === "function" || !!(obj && obj.constructor && obj.call && obj.apply);
|
||||
}
|
||||
|
||||
function isReallyNaN(val) {
|
||||
return typeof val === "number" && isNaN(val);
|
||||
}
|
||||
|
||||
function mirrorProperties(target, source) {
|
||||
for (var prop in source) {
|
||||
if (!hasOwn.call(target, prop)) {
|
||||
target[prop] = source[prop];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function isRestorable(obj) {
|
||||
return typeof obj === "function" && typeof obj.restore === "function" && obj.restore.sinon;
|
||||
}
|
||||
|
||||
// Cheap way to detect if we have ES5 support.
|
||||
var hasES5Support = "keys" in Object;
|
||||
|
||||
function makeApi(sinon) {
|
||||
sinon.wrapMethod = function wrapMethod(object, property, method) {
|
||||
if (!object) {
|
||||
throw new TypeError("Should wrap property of object");
|
||||
}
|
||||
|
||||
if (typeof method !== "function" && typeof method !== "object") {
|
||||
throw new TypeError("Method wrapper should be a function or a property descriptor");
|
||||
}
|
||||
|
||||
function checkWrappedMethod(wrappedMethod) {
|
||||
var error;
|
||||
|
||||
if (!isFunction(wrappedMethod)) {
|
||||
error = new TypeError("Attempted to wrap " + (typeof wrappedMethod) + " property " +
|
||||
property + " as function");
|
||||
} else if (wrappedMethod.restore && wrappedMethod.restore.sinon) {
|
||||
error = new TypeError("Attempted to wrap " + property + " which is already wrapped");
|
||||
} else if (wrappedMethod.calledBefore) {
|
||||
var verb = wrappedMethod.returns ? "stubbed" : "spied on";
|
||||
error = new TypeError("Attempted to wrap " + property + " which is already " + verb);
|
||||
}
|
||||
|
||||
if (error) {
|
||||
if (wrappedMethod && wrappedMethod.stackTrace) {
|
||||
error.stack += "\n--------------\n" + wrappedMethod.stackTrace;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
var error, wrappedMethod, i;
|
||||
|
||||
// IE 8 does not support hasOwnProperty on the window object and Firefox has a problem
|
||||
// when using hasOwn.call on objects from other frames.
|
||||
var owned = object.hasOwnProperty ? object.hasOwnProperty(property) : hasOwn.call(object, property);
|
||||
|
||||
if (hasES5Support) {
|
||||
var methodDesc = (typeof method === "function") ? {value: method} : method;
|
||||
var wrappedMethodDesc = sinon.getPropertyDescriptor(object, property);
|
||||
|
||||
if (!wrappedMethodDesc) {
|
||||
error = new TypeError("Attempted to wrap " + (typeof wrappedMethod) + " property " +
|
||||
property + " as function");
|
||||
} else if (wrappedMethodDesc.restore && wrappedMethodDesc.restore.sinon) {
|
||||
error = new TypeError("Attempted to wrap " + property + " which is already wrapped");
|
||||
}
|
||||
if (error) {
|
||||
if (wrappedMethodDesc && wrappedMethodDesc.stackTrace) {
|
||||
error.stack += "\n--------------\n" + wrappedMethodDesc.stackTrace;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
|
||||
var types = sinon.objectKeys(methodDesc);
|
||||
for (i = 0; i < types.length; i++) {
|
||||
wrappedMethod = wrappedMethodDesc[types[i]];
|
||||
checkWrappedMethod(wrappedMethod);
|
||||
}
|
||||
|
||||
mirrorProperties(methodDesc, wrappedMethodDesc);
|
||||
for (i = 0; i < types.length; i++) {
|
||||
mirrorProperties(methodDesc[types[i]], wrappedMethodDesc[types[i]]);
|
||||
}
|
||||
Object.defineProperty(object, property, methodDesc);
|
||||
} else {
|
||||
wrappedMethod = object[property];
|
||||
checkWrappedMethod(wrappedMethod);
|
||||
object[property] = method;
|
||||
method.displayName = property;
|
||||
}
|
||||
|
||||
method.displayName = property;
|
||||
|
||||
// Set up a stack trace which can be used later to find what line of
|
||||
// code the original method was created on.
|
||||
method.stackTrace = (new Error("Stack Trace for original")).stack;
|
||||
|
||||
method.restore = function () {
|
||||
// For prototype properties try to reset by delete first.
|
||||
// If this fails (ex: localStorage on mobile safari) then force a reset
|
||||
// via direct assignment.
|
||||
if (!owned) {
|
||||
// In some cases `delete` may throw an error
|
||||
try {
|
||||
delete object[property];
|
||||
} catch (e) {} // eslint-disable-line no-empty
|
||||
// For native code functions `delete` fails without throwing an error
|
||||
// on Chrome < 43, PhantomJS, etc.
|
||||
} else if (hasES5Support) {
|
||||
Object.defineProperty(object, property, wrappedMethodDesc);
|
||||
}
|
||||
|
||||
// Use strict equality comparison to check failures then force a reset
|
||||
// via direct assignment.
|
||||
if (object[property] === method) {
|
||||
object[property] = wrappedMethod;
|
||||
}
|
||||
};
|
||||
|
||||
method.restore.sinon = true;
|
||||
|
||||
if (!hasES5Support) {
|
||||
mirrorProperties(method, wrappedMethod);
|
||||
}
|
||||
|
||||
return method;
|
||||
};
|
||||
|
||||
sinon.create = function create(proto) {
|
||||
var F = function () {};
|
||||
F.prototype = proto;
|
||||
return new F();
|
||||
};
|
||||
|
||||
sinon.deepEqual = function deepEqual(a, b) {
|
||||
if (sinon.match && sinon.match.isMatcher(a)) {
|
||||
return a.test(b);
|
||||
}
|
||||
|
||||
if (typeof a !== "object" || typeof b !== "object") {
|
||||
return isReallyNaN(a) && isReallyNaN(b) || a === b;
|
||||
}
|
||||
|
||||
if (isElement(a) || isElement(b)) {
|
||||
return a === b;
|
||||
}
|
||||
|
||||
if (a === b) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((a === null && b !== null) || (a !== null && b === null)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (a instanceof RegExp && b instanceof RegExp) {
|
||||
return (a.source === b.source) && (a.global === b.global) &&
|
||||
(a.ignoreCase === b.ignoreCase) && (a.multiline === b.multiline);
|
||||
}
|
||||
|
||||
var aString = Object.prototype.toString.call(a);
|
||||
if (aString !== Object.prototype.toString.call(b)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (aString === "[object Date]") {
|
||||
return a.valueOf() === b.valueOf();
|
||||
}
|
||||
|
||||
var prop;
|
||||
var aLength = 0;
|
||||
var bLength = 0;
|
||||
|
||||
if (aString === "[object Array]" && a.length !== b.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (prop in a) {
|
||||
if (a.hasOwnProperty(prop)) {
|
||||
aLength += 1;
|
||||
|
||||
if (!(prop in b)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!deepEqual(a[prop], b[prop])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (prop in b) {
|
||||
if (b.hasOwnProperty(prop)) {
|
||||
bLength += 1;
|
||||
}
|
||||
}
|
||||
|
||||
return aLength === bLength;
|
||||
};
|
||||
|
||||
sinon.functionName = function functionName(func) {
|
||||
var name = func.displayName || func.name;
|
||||
|
||||
// Use function decomposition as a last resort to get function
|
||||
// name. Does not rely on function decomposition to work - if it
|
||||
// doesn't debugging will be slightly less informative
|
||||
// (i.e. toString will say 'spy' rather than 'myFunc').
|
||||
if (!name) {
|
||||
var matches = func.toString().match(/function ([^\s\(]+)/);
|
||||
name = matches && matches[1];
|
||||
}
|
||||
|
||||
return name;
|
||||
};
|
||||
|
||||
sinon.functionToString = function toString() {
|
||||
if (this.getCall && this.callCount) {
|
||||
var thisValue,
|
||||
prop;
|
||||
var i = this.callCount;
|
||||
|
||||
while (i--) {
|
||||
thisValue = this.getCall(i).thisValue;
|
||||
|
||||
for (prop in thisValue) {
|
||||
if (thisValue[prop] === this) {
|
||||
return prop;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return this.displayName || "sinon fake";
|
||||
};
|
||||
|
||||
sinon.objectKeys = function objectKeys(obj) {
|
||||
if (obj !== Object(obj)) {
|
||||
throw new TypeError("sinon.objectKeys called on a non-object");
|
||||
}
|
||||
|
||||
var keys = [];
|
||||
var key;
|
||||
for (key in obj) {
|
||||
if (hasOwn.call(obj, key)) {
|
||||
keys.push(key);
|
||||
}
|
||||
}
|
||||
|
||||
return keys;
|
||||
};
|
||||
|
||||
sinon.getPropertyDescriptor = function getPropertyDescriptor(object, property) {
|
||||
var proto = object;
|
||||
var descriptor;
|
||||
|
||||
while (proto && !(descriptor = Object.getOwnPropertyDescriptor(proto, property))) {
|
||||
proto = Object.getPrototypeOf(proto);
|
||||
}
|
||||
return descriptor;
|
||||
};
|
||||
|
||||
sinon.getConfig = function (custom) {
|
||||
var config = {};
|
||||
custom = custom || {};
|
||||
var defaults = sinon.defaultConfig;
|
||||
|
||||
for (var prop in defaults) {
|
||||
if (defaults.hasOwnProperty(prop)) {
|
||||
config[prop] = custom.hasOwnProperty(prop) ? custom[prop] : defaults[prop];
|
||||
}
|
||||
}
|
||||
|
||||
return config;
|
||||
};
|
||||
|
||||
sinon.defaultConfig = {
|
||||
injectIntoThis: true,
|
||||
injectInto: null,
|
||||
properties: ["spy", "stub", "mock", "clock", "server", "requests"],
|
||||
useFakeTimers: true,
|
||||
useFakeServer: true
|
||||
};
|
||||
|
||||
sinon.timesInWords = function timesInWords(count) {
|
||||
return count === 1 && "once" ||
|
||||
count === 2 && "twice" ||
|
||||
count === 3 && "thrice" ||
|
||||
(count || 0) + " times";
|
||||
};
|
||||
|
||||
sinon.calledInOrder = function (spies) {
|
||||
for (var i = 1, l = spies.length; i < l; i++) {
|
||||
if (!spies[i - 1].calledBefore(spies[i]) || !spies[i].called) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
sinon.orderByFirstCall = function (spies) {
|
||||
return spies.sort(function (a, b) {
|
||||
// uuid, won't ever be equal
|
||||
var aCall = a.getCall(0);
|
||||
var bCall = b.getCall(0);
|
||||
var aId = aCall && aCall.callId || -1;
|
||||
var bId = bCall && bCall.callId || -1;
|
||||
|
||||
return aId < bId ? -1 : 1;
|
||||
});
|
||||
};
|
||||
|
||||
sinon.createStubInstance = function (constructor) {
|
||||
if (typeof constructor !== "function") {
|
||||
throw new TypeError("The constructor should be a function.");
|
||||
}
|
||||
return sinon.stub(sinon.create(constructor.prototype));
|
||||
};
|
||||
|
||||
sinon.restore = function (object) {
|
||||
if (object !== null && typeof object === "object") {
|
||||
for (var prop in object) {
|
||||
if (isRestorable(object[prop])) {
|
||||
object[prop].restore();
|
||||
}
|
||||
}
|
||||
} else if (isRestorable(object)) {
|
||||
object.restore();
|
||||
}
|
||||
};
|
||||
|
||||
return sinon;
|
||||
}
|
||||
|
||||
var isNode = typeof module !== "undefined" && module.exports && typeof require === "function";
|
||||
var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
|
||||
|
||||
function loadDependencies(require, exports) {
|
||||
makeApi(exports);
|
||||
}
|
||||
|
||||
if (isAMD) {
|
||||
define(loadDependencies);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isNode) {
|
||||
loadDependencies(require, module.exports, module);
|
||||
return;
|
||||
}
|
||||
|
||||
if (sinonGlobal) {
|
||||
makeApi(sinonGlobal);
|
||||
}
|
||||
}(
|
||||
typeof sinon === "object" && sinon // eslint-disable-line no-undef
|
||||
));
|
||||
|
||||
/**
|
||||
* @depend util/core.js
|
||||
*/
|
||||
(function (sinonGlobal) {
|
||||
|
||||
function makeApi(sinon) {
|
||||
|
||||
// Adapted from https://developer.mozilla.org/en/docs/ECMAScript_DontEnum_attribute#JScript_DontEnum_Bug
|
||||
var hasDontEnumBug = (function () {
|
||||
var obj = {
|
||||
constructor: function () {
|
||||
return "0";
|
||||
},
|
||||
toString: function () {
|
||||
return "1";
|
||||
},
|
||||
valueOf: function () {
|
||||
return "2";
|
||||
},
|
||||
toLocaleString: function () {
|
||||
return "3";
|
||||
},
|
||||
prototype: function () {
|
||||
return "4";
|
||||
},
|
||||
isPrototypeOf: function () {
|
||||
return "5";
|
||||
},
|
||||
propertyIsEnumerable: function () {
|
||||
return "6";
|
||||
},
|
||||
hasOwnProperty: function () {
|
||||
return "7";
|
||||
},
|
||||
length: function () {
|
||||
return "8";
|
||||
},
|
||||
unique: function () {
|
||||
return "9";
|
||||
}
|
||||
};
|
||||
|
||||
var result = [];
|
||||
for (var prop in obj) {
|
||||
if (obj.hasOwnProperty(prop)) {
|
||||
result.push(obj[prop]());
|
||||
}
|
||||
}
|
||||
return result.join("") !== "0123456789";
|
||||
})();
|
||||
|
||||
/* Public: Extend target in place with all (own) properties from sources in-order. Thus, last source will
|
||||
* override properties in previous sources.
|
||||
*
|
||||
* target - The Object to extend
|
||||
* sources - Objects to copy properties from.
|
||||
*
|
||||
* Returns the extended target
|
||||
*/
|
||||
function extend(target /*, sources */) {
|
||||
var sources = Array.prototype.slice.call(arguments, 1);
|
||||
var source, i, prop;
|
||||
|
||||
for (i = 0; i < sources.length; i++) {
|
||||
source = sources[i];
|
||||
|
||||
for (prop in source) {
|
||||
if (source.hasOwnProperty(prop)) {
|
||||
target[prop] = source[prop];
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure we copy (own) toString method even when in JScript with DontEnum bug
|
||||
// See https://developer.mozilla.org/en/docs/ECMAScript_DontEnum_attribute#JScript_DontEnum_Bug
|
||||
if (hasDontEnumBug && source.hasOwnProperty("toString") && source.toString !== target.toString) {
|
||||
target.toString = source.toString;
|
||||
}
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
sinon.extend = extend;
|
||||
return sinon.extend;
|
||||
}
|
||||
|
||||
function loadDependencies(require, exports, module) {
|
||||
var sinon = require("./util/core");
|
||||
module.exports = makeApi(sinon);
|
||||
}
|
||||
|
||||
var isNode = typeof module !== "undefined" && module.exports && typeof require === "function";
|
||||
var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
|
||||
|
||||
if (isAMD) {
|
||||
define(loadDependencies);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isNode) {
|
||||
loadDependencies(require, module.exports, module);
|
||||
return;
|
||||
}
|
||||
|
||||
if (sinonGlobal) {
|
||||
makeApi(sinonGlobal);
|
||||
}
|
||||
}(
|
||||
typeof sinon === "object" && sinon // eslint-disable-line no-undef
|
||||
));
|
||||
|
||||
/**
|
||||
* @depend util/core.js
|
||||
*/
|
||||
(function (sinonGlobal) {
|
||||
|
||||
function makeApi(sinon) {
|
||||
|
||||
function timesInWords(count) {
|
||||
switch (count) {
|
||||
case 1:
|
||||
return "once";
|
||||
case 2:
|
||||
return "twice";
|
||||
case 3:
|
||||
return "thrice";
|
||||
default:
|
||||
return (count || 0) + " times";
|
||||
}
|
||||
}
|
||||
|
||||
sinon.timesInWords = timesInWords;
|
||||
return sinon.timesInWords;
|
||||
}
|
||||
|
||||
function loadDependencies(require, exports, module) {
|
||||
var core = require("./util/core");
|
||||
module.exports = makeApi(core);
|
||||
}
|
||||
|
||||
var isNode = typeof module !== "undefined" && module.exports && typeof require === "function";
|
||||
var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
|
||||
|
||||
if (isAMD) {
|
||||
define(loadDependencies);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isNode) {
|
||||
loadDependencies(require, module.exports, module);
|
||||
return;
|
||||
}
|
||||
|
||||
if (sinonGlobal) {
|
||||
makeApi(sinonGlobal);
|
||||
}
|
||||
}(
|
||||
typeof sinon === "object" && sinon // eslint-disable-line no-undef
|
||||
));
|
||||
|
||||
/**
|
||||
* @depend util/core.js
|
||||
*/
|
||||
/**
|
||||
* Format functions
|
||||
*
|
||||
* @author Christian Johansen (christian@cjohansen.no)
|
||||
* @license BSD
|
||||
*
|
||||
* Copyright (c) 2010-2014 Christian Johansen
|
||||
*/
|
||||
(function (sinonGlobal) {
|
||||
|
||||
function makeApi(sinon) {
|
||||
function typeOf(value) {
|
||||
if (value === null) {
|
||||
return "null";
|
||||
} else if (value === undefined) {
|
||||
return "undefined";
|
||||
}
|
||||
var string = Object.prototype.toString.call(value);
|
||||
return string.substring(8, string.length - 1).toLowerCase();
|
||||
}
|
||||
|
||||
sinon.typeOf = typeOf;
|
||||
return sinon.typeOf;
|
||||
}
|
||||
|
||||
function loadDependencies(require, exports, module) {
|
||||
var core = require("./util/core");
|
||||
module.exports = makeApi(core);
|
||||
}
|
||||
|
||||
var isNode = typeof module !== "undefined" && module.exports && typeof require === "function";
|
||||
var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
|
||||
|
||||
if (isAMD) {
|
||||
define(loadDependencies);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isNode) {
|
||||
loadDependencies(require, module.exports, module);
|
||||
return;
|
||||
}
|
||||
|
||||
if (sinonGlobal) {
|
||||
makeApi(sinonGlobal);
|
||||
}
|
||||
}(
|
||||
typeof sinon === "object" && sinon // eslint-disable-line no-undef
|
||||
));
|
||||
|
||||
/**
|
||||
* @depend util/core.js
|
||||
* @depend typeOf.js
|
||||
*/
|
||||
/*jslint eqeqeq: false, onevar: false, plusplus: false*/
|
||||
/*global module, require, sinon*/
|
||||
/**
|
||||
* Match functions
|
||||
*
|
||||
* @author Maximilian Antoni (mail@maxantoni.de)
|
||||
* @license BSD
|
||||
*
|
||||
* Copyright (c) 2012 Maximilian Antoni
|
||||
*/
|
||||
(function (sinonGlobal) {
|
||||
|
||||
function makeApi(sinon) {
|
||||
function assertType(value, type, name) {
|
||||
var actual = sinon.typeOf(value);
|
||||
if (actual !== type) {
|
||||
throw new TypeError("Expected type of " + name + " to be " +
|
||||
type + ", but was " + actual);
|
||||
}
|
||||
}
|
||||
|
||||
var matcher = {
|
||||
toString: function () {
|
||||
return this.message;
|
||||
}
|
||||
};
|
||||
|
||||
function isMatcher(object) {
|
||||
return matcher.isPrototypeOf(object);
|
||||
}
|
||||
|
||||
function matchObject(expectation, actual) {
|
||||
if (actual === null || actual === undefined) {
|
||||
return false;
|
||||
}
|
||||
for (var key in expectation) {
|
||||
if (expectation.hasOwnProperty(key)) {
|
||||
var exp = expectation[key];
|
||||
var act = actual[key];
|
||||
if (isMatcher(exp)) {
|
||||
if (!exp.test(act)) {
|
||||
return false;
|
||||
}
|
||||
} else if (sinon.typeOf(exp) === "object") {
|
||||
if (!matchObject(exp, act)) {
|
||||
return false;
|
||||
}
|
||||
} else if (!sinon.deepEqual(exp, act)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function match(expectation, message) {
|
||||
var m = sinon.create(matcher);
|
||||
var type = sinon.typeOf(expectation);
|
||||
switch (type) {
|
||||
case "object":
|
||||
if (typeof expectation.test === "function") {
|
||||
m.test = function (actual) {
|
||||
return expectation.test(actual) === true;
|
||||
};
|
||||
m.message = "match(" + sinon.functionName(expectation.test) + ")";
|
||||
return m;
|
||||
}
|
||||
var str = [];
|
||||
for (var key in expectation) {
|
||||
if (expectation.hasOwnProperty(key)) {
|
||||
str.push(key + ": " + expectation[key]);
|
||||
}
|
||||
}
|
||||
m.test = function (actual) {
|
||||
return matchObject(expectation, actual);
|
||||
};
|
||||
m.message = "match(" + str.join(", ") + ")";
|
||||
break;
|
||||
case "number":
|
||||
m.test = function (actual) {
|
||||
// we need type coercion here
|
||||
return expectation == actual; // eslint-disable-line eqeqeq
|
||||
};
|
||||
break;
|
||||
case "string":
|
||||
m.test = function (actual) {
|
||||
if (typeof actual !== "string") {
|
||||
return false;
|
||||
}
|
||||
return actual.indexOf(expectation) !== -1;
|
||||
};
|
||||
m.message = "match(\"" + expectation + "\")";
|
||||
break;
|
||||
case "regexp":
|
||||
m.test = function (actual) {
|
||||
if (typeof actual !== "string") {
|
||||
return false;
|
||||
}
|
||||
return expectation.test(actual);
|
||||
};
|
||||
break;
|
||||
case "function":
|
||||
m.test = expectation;
|
||||
if (message) {
|
||||
m.message = message;
|
||||
} else {
|
||||
m.message = "match(" + sinon.functionName(expectation) + ")";
|
||||
}
|
||||
break;
|
||||
default:
|
||||
m.test = function (actual) {
|
||||
return sinon.deepEqual(expectation, actual);
|
||||
};
|
||||
}
|
||||
if (!m.message) {
|
||||
m.message = "match(" + expectation + ")";
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
matcher.or = function (m2) {
|
||||
if (!arguments.length) {
|
||||
throw new TypeError("Matcher expected");
|
||||
} else if (!isMatcher(m2)) {
|
||||
m2 = match(m2);
|
||||
}
|
||||
var m1 = this;
|
||||
var or = sinon.create(matcher);
|
||||
or.test = function (actual) {
|
||||
return m1.test(actual) || m2.test(actual);
|
||||
};
|
||||
or.message = m1.message + ".or(" + m2.message + ")";
|
||||
return or;
|
||||
};
|
||||
|
||||
matcher.and = function (m2) {
|
||||
if (!arguments.length) {
|
||||
throw new TypeError("Matcher expected");
|
||||
} else if (!isMatcher(m2)) {
|
||||
m2 = match(m2);
|
||||
}
|
||||
var m1 = this;
|
||||
var and = sinon.create(matcher);
|
||||
and.test = function (actual) {
|
||||
return m1.test(actual) && m2.test(actual);
|
||||
};
|
||||
and.message = m1.message + ".and(" + m2.message + ")";
|
||||
return and;
|
||||
};
|
||||
|
||||
match.isMatcher = isMatcher;
|
||||
|
||||
match.any = match(function () {
|
||||
return true;
|
||||
}, "any");
|
||||
|
||||
match.defined = match(function (actual) {
|
||||
return actual !== null && actual !== undefined;
|
||||
}, "defined");
|
||||
|
||||
match.truthy = match(function (actual) {
|
||||
return !!actual;
|
||||
}, "truthy");
|
||||
|
||||
match.falsy = match(function (actual) {
|
||||
return !actual;
|
||||
}, "falsy");
|
||||
|
||||
match.same = function (expectation) {
|
||||
return match(function (actual) {
|
||||
return expectation === actual;
|
||||
}, "same(" + expectation + ")");
|
||||
};
|
||||
|
||||
match.typeOf = function (type) {
|
||||
assertType(type, "string", "type");
|
||||
return match(function (actual) {
|
||||
return sinon.typeOf(actual) === type;
|
||||
}, "typeOf(\"" + type + "\")");
|
||||
};
|
||||
|
||||
match.instanceOf = function (type) {
|
||||
assertType(type, "function", "type");
|
||||
return match(function (actual) {
|
||||
return actual instanceof type;
|
||||
}, "instanceOf(" + sinon.functionName(type) + ")");
|
||||
};
|
||||
|
||||
function createPropertyMatcher(propertyTest, messagePrefix) {
|
||||
return function (property, value) {
|
||||
assertType(property, "string", "property");
|
||||
var onlyProperty = arguments.length === 1;
|
||||
var message = messagePrefix + "(\"" + property + "\"";
|
||||
if (!onlyProperty) {
|
||||
message += ", " + value;
|
||||
}
|
||||
message += ")";
|
||||
return match(function (actual) {
|
||||
if (actual === undefined || actual === null ||
|
||||
!propertyTest(actual, property)) {
|
||||
return false;
|
||||
}
|
||||
return onlyProperty || sinon.deepEqual(value, actual[property]);
|
||||
}, message);
|
||||
};
|
||||
}
|
||||
|
||||
match.has = createPropertyMatcher(function (actual, property) {
|
||||
if (typeof actual === "object") {
|
||||
return property in actual;
|
||||
}
|
||||
return actual[property] !== undefined;
|
||||
}, "has");
|
||||
|
||||
match.hasOwn = createPropertyMatcher(function (actual, property) {
|
||||
return actual.hasOwnProperty(property);
|
||||
}, "hasOwn");
|
||||
|
||||
match.bool = match.typeOf("boolean");
|
||||
match.number = match.typeOf("number");
|
||||
match.string = match.typeOf("string");
|
||||
match.object = match.typeOf("object");
|
||||
match.func = match.typeOf("function");
|
||||
match.array = match.typeOf("array");
|
||||
match.regexp = match.typeOf("regexp");
|
||||
match.date = match.typeOf("date");
|
||||
|
||||
sinon.match = match;
|
||||
return match;
|
||||
}
|
||||
|
||||
var isNode = typeof module !== "undefined" && module.exports && typeof require === "function";
|
||||
var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
|
||||
|
||||
function loadDependencies(require, exports, module) {
|
||||
var sinon = require("./util/core");
|
||||
require("./typeOf");
|
||||
module.exports = makeApi(sinon);
|
||||
}
|
||||
|
||||
if (isAMD) {
|
||||
define(loadDependencies);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isNode) {
|
||||
loadDependencies(require, module.exports, module);
|
||||
return;
|
||||
}
|
||||
|
||||
if (sinonGlobal) {
|
||||
makeApi(sinonGlobal);
|
||||
}
|
||||
}(
|
||||
typeof sinon === "object" && sinon // eslint-disable-line no-undef
|
||||
));
|
||||
|
||||
/**
|
||||
* @depend util/core.js
|
||||
*/
|
||||
/**
|
||||
* Format functions
|
||||
*
|
||||
* @author Christian Johansen (christian@cjohansen.no)
|
||||
* @license BSD
|
||||
*
|
||||
* Copyright (c) 2010-2014 Christian Johansen
|
||||
*/
|
||||
(function (sinonGlobal, formatio) {
|
||||
|
||||
function makeApi(sinon) {
|
||||
function valueFormatter(value) {
|
||||
return "" + value;
|
||||
}
|
||||
|
||||
function getFormatioFormatter() {
|
||||
var formatter = formatio.configure({
|
||||
quoteStrings: false,
|
||||
limitChildrenCount: 250
|
||||
});
|
||||
|
||||
function format() {
|
||||
return formatter.ascii.apply(formatter, arguments);
|
||||
}
|
||||
|
||||
return format;
|
||||
}
|
||||
|
||||
function getNodeFormatter() {
|
||||
try {
|
||||
var util = require("util");
|
||||
} catch (e) {
|
||||
/* Node, but no util module - would be very old, but better safe than sorry */
|
||||
}
|
||||
|
||||
function format(v) {
|
||||
var isObjectWithNativeToString = typeof v === "object" && v.toString === Object.prototype.toString;
|
||||
return isObjectWithNativeToString ? util.inspect(v) : v;
|
||||
}
|
||||
|
||||
return util ? format : valueFormatter;
|
||||
}
|
||||
|
||||
var isNode = typeof module !== "undefined" && module.exports && typeof require === "function";
|
||||
var formatter;
|
||||
|
||||
if (isNode) {
|
||||
try {
|
||||
formatio = require("formatio");
|
||||
}
|
||||
catch (e) {} // eslint-disable-line no-empty
|
||||
}
|
||||
|
||||
if (formatio) {
|
||||
formatter = getFormatioFormatter();
|
||||
} else if (isNode) {
|
||||
formatter = getNodeFormatter();
|
||||
} else {
|
||||
formatter = valueFormatter;
|
||||
}
|
||||
|
||||
sinon.format = formatter;
|
||||
return sinon.format;
|
||||
}
|
||||
|
||||
function loadDependencies(require, exports, module) {
|
||||
var sinon = require("./util/core");
|
||||
module.exports = makeApi(sinon);
|
||||
}
|
||||
|
||||
var isNode = typeof module !== "undefined" && module.exports && typeof require === "function";
|
||||
var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
|
||||
|
||||
if (isAMD) {
|
||||
define(loadDependencies);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isNode) {
|
||||
loadDependencies(require, module.exports, module);
|
||||
return;
|
||||
}
|
||||
|
||||
if (sinonGlobal) {
|
||||
makeApi(sinonGlobal);
|
||||
}
|
||||
}(
|
||||
typeof sinon === "object" && sinon, // eslint-disable-line no-undef
|
||||
typeof formatio === "object" && formatio // eslint-disable-line no-undef
|
||||
));
|
||||
|
||||
/**
|
||||
* @depend util/core.js
|
||||
* @depend match.js
|
||||
* @depend format.js
|
||||
*/
|
||||
/**
|
||||
* Spy calls
|
||||
*
|
||||
* @author Christian Johansen (christian@cjohansen.no)
|
||||
* @author Maximilian Antoni (mail@maxantoni.de)
|
||||
* @license BSD
|
||||
*
|
||||
* Copyright (c) 2010-2013 Christian Johansen
|
||||
* Copyright (c) 2013 Maximilian Antoni
|
||||
*/
|
||||
(function (sinonGlobal) {
|
||||
|
||||
var slice = Array.prototype.slice;
|
||||
|
||||
function makeApi(sinon) {
|
||||
function throwYieldError(proxy, text, args) {
|
||||
var msg = sinon.functionName(proxy) + text;
|
||||
if (args.length) {
|
||||
msg += " Received [" + slice.call(args).join(", ") + "]";
|
||||
}
|
||||
throw new Error(msg);
|
||||
}
|
||||
|
||||
var callProto = {
|
||||
calledOn: function calledOn(thisValue) {
|
||||
if (sinon.match && sinon.match.isMatcher(thisValue)) {
|
||||
return thisValue.test(this.thisValue);
|
||||
}
|
||||
return this.thisValue === thisValue;
|
||||
},
|
||||
|
||||
calledWith: function calledWith() {
|
||||
var l = arguments.length;
|
||||
if (l > this.args.length) {
|
||||
return false;
|
||||
}
|
||||
for (var i = 0; i < l; i += 1) {
|
||||
if (!sinon.deepEqual(arguments[i], this.args[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
calledWithMatch: function calledWithMatch() {
|
||||
var l = arguments.length;
|
||||
if (l > this.args.length) {
|
||||
return false;
|
||||
}
|
||||
for (var i = 0; i < l; i += 1) {
|
||||
var actual = this.args[i];
|
||||
var expectation = arguments[i];
|
||||
if (!sinon.match || !sinon.match(expectation).test(actual)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
calledWithExactly: function calledWithExactly() {
|
||||
return arguments.length === this.args.length &&
|
||||
this.calledWith.apply(this, arguments);
|
||||
},
|
||||
|
||||
notCalledWith: function notCalledWith() {
|
||||
return !this.calledWith.apply(this, arguments);
|
||||
},
|
||||
|
||||
notCalledWithMatch: function notCalledWithMatch() {
|
||||
return !this.calledWithMatch.apply(this, arguments);
|
||||
},
|
||||
|
||||
returned: function returned(value) {
|
||||
return sinon.deepEqual(value, this.returnValue);
|
||||
},
|
||||
|
||||
threw: function threw(error) {
|
||||
if (typeof error === "undefined" || !this.exception) {
|
||||
return !!this.exception;
|
||||
}
|
||||
|
||||
return this.exception === error || this.exception.name === error;
|
||||
},
|
||||
|
||||
calledWithNew: function calledWithNew() {
|
||||
return this.proxy.prototype && this.thisValue instanceof this.proxy;
|
||||
},
|
||||
|
||||
calledBefore: function (other) {
|
||||
return this.callId < other.callId;
|
||||
},
|
||||
|
||||
calledAfter: function (other) {
|
||||
return this.callId > other.callId;
|
||||
},
|
||||
|
||||
callArg: function (pos) {
|
||||
this.args[pos]();
|
||||
},
|
||||
|
||||
callArgOn: function (pos, thisValue) {
|
||||
this.args[pos].apply(thisValue);
|
||||
},
|
||||
|
||||
callArgWith: function (pos) {
|
||||
this.callArgOnWith.apply(this, [pos, null].concat(slice.call(arguments, 1)));
|
||||
},
|
||||
|
||||
callArgOnWith: function (pos, thisValue) {
|
||||
var args = slice.call(arguments, 2);
|
||||
this.args[pos].apply(thisValue, args);
|
||||
},
|
||||
|
||||
"yield": function () {
|
||||
this.yieldOn.apply(this, [null].concat(slice.call(arguments, 0)));
|
||||
},
|
||||
|
||||
yieldOn: function (thisValue) {
|
||||
var args = this.args;
|
||||
for (var i = 0, l = args.length; i < l; ++i) {
|
||||
if (typeof args[i] === "function") {
|
||||
args[i].apply(thisValue, slice.call(arguments, 1));
|
||||
return;
|
||||
}
|
||||
}
|
||||
throwYieldError(this.proxy, " cannot yield since no callback was passed.", args);
|
||||
},
|
||||
|
||||
yieldTo: function (prop) {
|
||||
this.yieldToOn.apply(this, [prop, null].concat(slice.call(arguments, 1)));
|
||||
},
|
||||
|
||||
yieldToOn: function (prop, thisValue) {
|
||||
var args = this.args;
|
||||
for (var i = 0, l = args.length; i < l; ++i) {
|
||||
if (args[i] && typeof args[i][prop] === "function") {
|
||||
args[i][prop].apply(thisValue, slice.call(arguments, 2));
|
||||
return;
|
||||
}
|
||||
}
|
||||
throwYieldError(this.proxy, " cannot yield to '" + prop +
|
||||
"' since no callback was passed.", args);
|
||||
},
|
||||
|
||||
getStackFrames: function () {
|
||||
// Omit the error message and the two top stack frames in sinon itself:
|
||||
return this.stack && this.stack.split("\n").slice(3);
|
||||
},
|
||||
|
||||
toString: function () {
|
||||
var callStr = this.proxy.toString() + "(";
|
||||
var args = [];
|
||||
|
||||
for (var i = 0, l = this.args.length; i < l; ++i) {
|
||||
args.push(sinon.format(this.args[i]));
|
||||
}
|
||||
|
||||
callStr = callStr + args.join(", ") + ")";
|
||||
|
||||
if (typeof this.returnValue !== "undefined") {
|
||||
callStr += " => " + sinon.format(this.returnValue);
|
||||
}
|
||||
|
||||
if (this.exception) {
|
||||
callStr += " !" + this.exception.name;
|
||||
|
||||
if (this.exception.message) {
|
||||
callStr += "(" + this.exception.message + ")";
|
||||
}
|
||||
}
|
||||
if (this.stack) {
|
||||
callStr += this.getStackFrames()[0].replace(/^\s*(?:at\s+|@)?/, " at ");
|
||||
|
||||
}
|
||||
|
||||
return callStr;
|
||||
}
|
||||
};
|
||||
|
||||
callProto.invokeCallback = callProto.yield;
|
||||
|
||||
function createSpyCall(spy, thisValue, args, returnValue, exception, id, stack) {
|
||||
if (typeof id !== "number") {
|
||||
throw new TypeError("Call id is not a number");
|
||||
}
|
||||
var proxyCall = sinon.create(callProto);
|
||||
proxyCall.proxy = spy;
|
||||
proxyCall.thisValue = thisValue;
|
||||
proxyCall.args = args;
|
||||
proxyCall.returnValue = returnValue;
|
||||
proxyCall.exception = exception;
|
||||
proxyCall.callId = id;
|
||||
proxyCall.stack = stack;
|
||||
|
||||
return proxyCall;
|
||||
}
|
||||
createSpyCall.toString = callProto.toString; // used by mocks
|
||||
|
||||
sinon.spyCall = createSpyCall;
|
||||
return createSpyCall;
|
||||
}
|
||||
|
||||
var isNode = typeof module !== "undefined" && module.exports && typeof require === "function";
|
||||
var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
|
||||
|
||||
function loadDependencies(require, exports, module) {
|
||||
var sinon = require("./util/core");
|
||||
require("./match");
|
||||
require("./format");
|
||||
module.exports = makeApi(sinon);
|
||||
}
|
||||
|
||||
if (isAMD) {
|
||||
define(loadDependencies);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isNode) {
|
||||
loadDependencies(require, module.exports, module);
|
||||
return;
|
||||
}
|
||||
|
||||
if (sinonGlobal) {
|
||||
makeApi(sinonGlobal);
|
||||
}
|
||||
}(
|
||||
typeof sinon === "object" && sinon // eslint-disable-line no-undef
|
||||
));
|
||||
|
||||
/**
|
||||
* @depend times_in_words.js
|
||||
* @depend util/core.js
|
||||
* @depend extend.js
|
||||
* @depend call.js
|
||||
* @depend format.js
|
||||
*/
|
||||
/**
|
||||
* Spy functions
|
||||
*
|
||||
* @author Christian Johansen (christian@cjohansen.no)
|
||||
* @license BSD
|
||||
*
|
||||
* Copyright (c) 2010-2013 Christian Johansen
|
||||
*/
|
||||
(function (sinonGlobal) {
|
||||
|
||||
function makeApi(sinon) {
|
||||
var push = Array.prototype.push;
|
||||
var slice = Array.prototype.slice;
|
||||
var callId = 0;
|
||||
|
||||
function spy(object, property, types) {
|
||||
if (!property && typeof object === "function") {
|
||||
return spy.create(object);
|
||||
}
|
||||
|
||||
if (!object && !property) {
|
||||
return spy.create(function () { });
|
||||
}
|
||||
|
||||
if (types) {
|
||||
var methodDesc = sinon.getPropertyDescriptor(object, property);
|
||||
for (var i = 0; i < types.length; i++) {
|
||||
methodDesc[types[i]] = spy.create(methodDesc[types[i]]);
|
||||
}
|
||||
return sinon.wrapMethod(object, property, methodDesc);
|
||||
}
|
||||
|
||||
return sinon.wrapMethod(object, property, spy.create(object[property]));
|
||||
}
|
||||
|
||||
function matchingFake(fakes, args, strict) {
|
||||
if (!fakes) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
for (var i = 0, l = fakes.length; i < l; i++) {
|
||||
if (fakes[i].matches(args, strict)) {
|
||||
return fakes[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function incrementCallCount() {
|
||||
this.called = true;
|
||||
this.callCount += 1;
|
||||
this.notCalled = false;
|
||||
this.calledOnce = this.callCount === 1;
|
||||
this.calledTwice = this.callCount === 2;
|
||||
this.calledThrice = this.callCount === 3;
|
||||
}
|
||||
|
||||
function createCallProperties() {
|
||||
this.firstCall = this.getCall(0);
|
||||
this.secondCall = this.getCall(1);
|
||||
this.thirdCall = this.getCall(2);
|
||||
this.lastCall = this.getCall(this.callCount - 1);
|
||||
}
|
||||
|
||||
var vars = "a,b,c,d,e,f,g,h,i,j,k,l";
|
||||
function createProxy(func, proxyLength) {
|
||||
// Retain the function length:
|
||||
var p;
|
||||
if (proxyLength) {
|
||||
eval("p = (function proxy(" + vars.substring(0, proxyLength * 2 - 1) + // eslint-disable-line no-eval
|
||||
") { return p.invoke(func, this, slice.call(arguments)); });");
|
||||
} else {
|
||||
p = function proxy() {
|
||||
return p.invoke(func, this, slice.call(arguments));
|
||||
};
|
||||
}
|
||||
p.isSinonProxy = true;
|
||||
return p;
|
||||
}
|
||||
|
||||
var uuid = 0;
|
||||
|
||||
// Public API
|
||||
var spyApi = {
|
||||
reset: function () {
|
||||
if (this.invoking) {
|
||||
var err = new Error("Cannot reset Sinon function while invoking it. " +
|
||||
"Move the call to .reset outside of the callback.");
|
||||
err.name = "InvalidResetException";
|
||||
throw err;
|
||||
}
|
||||
|
||||
this.called = false;
|
||||
this.notCalled = true;
|
||||
this.calledOnce = false;
|
||||
this.calledTwice = false;
|
||||
this.calledThrice = false;
|
||||
this.callCount = 0;
|
||||
this.firstCall = null;
|
||||
this.secondCall = null;
|
||||
this.thirdCall = null;
|
||||
this.lastCall = null;
|
||||
this.args = [];
|
||||
this.returnValues = [];
|
||||
this.thisValues = [];
|
||||
this.exceptions = [];
|
||||
this.callIds = [];
|
||||
this.stacks = [];
|
||||
if (this.fakes) {
|
||||
for (var i = 0; i < this.fakes.length; i++) {
|
||||
this.fakes[i].reset();
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
create: function create(func, spyLength) {
|
||||
var name;
|
||||
|
||||
if (typeof func !== "function") {
|
||||
func = function () { };
|
||||
} else {
|
||||
name = sinon.functionName(func);
|
||||
}
|
||||
|
||||
if (!spyLength) {
|
||||
spyLength = func.length;
|
||||
}
|
||||
|
||||
var proxy = createProxy(func, spyLength);
|
||||
|
||||
sinon.extend(proxy, spy);
|
||||
delete proxy.create;
|
||||
sinon.extend(proxy, func);
|
||||
|
||||
proxy.reset();
|
||||
proxy.prototype = func.prototype;
|
||||
proxy.displayName = name || "spy";
|
||||
proxy.toString = sinon.functionToString;
|
||||
proxy.instantiateFake = sinon.spy.create;
|
||||
proxy.id = "spy#" + uuid++;
|
||||
|
||||
return proxy;
|
||||
},
|
||||
|
||||
invoke: function invoke(func, thisValue, args) {
|
||||
var matching = matchingFake(this.fakes, args);
|
||||
var exception, returnValue;
|
||||
|
||||
incrementCallCount.call(this);
|
||||
push.call(this.thisValues, thisValue);
|
||||
push.call(this.args, args);
|
||||
push.call(this.callIds, callId++);
|
||||
|
||||
// Make call properties available from within the spied function:
|
||||
createCallProperties.call(this);
|
||||
|
||||
try {
|
||||
this.invoking = true;
|
||||
|
||||
if (matching) {
|
||||
returnValue = matching.invoke(func, thisValue, args);
|
||||
} else {
|
||||
returnValue = (this.func || func).apply(thisValue, args);
|
||||
}
|
||||
|
||||
var thisCall = this.getCall(this.callCount - 1);
|
||||
if (thisCall.calledWithNew() && typeof returnValue !== "object") {
|
||||
returnValue = thisValue;
|
||||
}
|
||||
} catch (e) {
|
||||
exception = e;
|
||||
} finally {
|
||||
delete this.invoking;
|
||||
}
|
||||
|
||||
push.call(this.exceptions, exception);
|
||||
push.call(this.returnValues, returnValue);
|
||||
push.call(this.stacks, new Error().stack);
|
||||
|
||||
// Make return value and exception available in the calls:
|
||||
createCallProperties.call(this);
|
||||
|
||||
if (exception !== undefined) {
|
||||
throw exception;
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
},
|
||||
|
||||
named: function named(name) {
|
||||
this.displayName = name;
|
||||
return this;
|
||||
},
|
||||
|
||||
getCall: function getCall(i) {
|
||||
if (i < 0 || i >= this.callCount) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return sinon.spyCall(this, this.thisValues[i], this.args[i],
|
||||
this.returnValues[i], this.exceptions[i],
|
||||
this.callIds[i], this.stacks[i]);
|
||||
},
|
||||
|
||||
getCalls: function () {
|
||||
var calls = [];
|
||||
var i;
|
||||
|
||||
for (i = 0; i < this.callCount; i++) {
|
||||
calls.push(this.getCall(i));
|
||||
}
|
||||
|
||||
return calls;
|
||||
},
|
||||
|
||||
calledBefore: function calledBefore(spyFn) {
|
||||
if (!this.called) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!spyFn.called) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return this.callIds[0] < spyFn.callIds[spyFn.callIds.length - 1];
|
||||
},
|
||||
|
||||
calledAfter: function calledAfter(spyFn) {
|
||||
if (!this.called || !spyFn.called) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.callIds[this.callCount - 1] > spyFn.callIds[spyFn.callCount - 1];
|
||||
},
|
||||
|
||||
withArgs: function () {
|
||||
var args = slice.call(arguments);
|
||||
|
||||
if (this.fakes) {
|
||||
var match = matchingFake(this.fakes, args, true);
|
||||
|
||||
if (match) {
|
||||
return match;
|
||||
}
|
||||
} else {
|
||||
this.fakes = [];
|
||||
}
|
||||
|
||||
var original = this;
|
||||
var fake = this.instantiateFake();
|
||||
fake.matchingAguments = args;
|
||||
fake.parent = this;
|
||||
push.call(this.fakes, fake);
|
||||
|
||||
fake.withArgs = function () {
|
||||
return original.withArgs.apply(original, arguments);
|
||||
};
|
||||
|
||||
for (var i = 0; i < this.args.length; i++) {
|
||||
if (fake.matches(this.args[i])) {
|
||||
incrementCallCount.call(fake);
|
||||
push.call(fake.thisValues, this.thisValues[i]);
|
||||
push.call(fake.args, this.args[i]);
|
||||
push.call(fake.returnValues, this.returnValues[i]);
|
||||
push.call(fake.exceptions, this.exceptions[i]);
|
||||
push.call(fake.callIds, this.callIds[i]);
|
||||
}
|
||||
}
|
||||
createCallProperties.call(fake);
|
||||
|
||||
return fake;
|
||||
},
|
||||
|
||||
matches: function (args, strict) {
|
||||
var margs = this.matchingAguments;
|
||||
|
||||
if (margs.length <= args.length &&
|
||||
sinon.deepEqual(margs, args.slice(0, margs.length))) {
|
||||
return !strict || margs.length === args.length;
|
||||
}
|
||||
},
|
||||
|
||||
printf: function (format) {
|
||||
var spyInstance = this;
|
||||
var args = slice.call(arguments, 1);
|
||||
var formatter;
|
||||
|
||||
return (format || "").replace(/%(.)/g, function (match, specifyer) {
|
||||
formatter = spyApi.formatters[specifyer];
|
||||
|
||||
if (typeof formatter === "function") {
|
||||
return formatter.call(null, spyInstance, args);
|
||||
} else if (!isNaN(parseInt(specifyer, 10))) {
|
||||
return sinon.format(args[specifyer - 1]);
|
||||
}
|
||||
|
||||
return "%" + specifyer;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function delegateToCalls(method, matchAny, actual, notCalled) {
|
||||
spyApi[method] = function () {
|
||||
if (!this.called) {
|
||||
if (notCalled) {
|
||||
return notCalled.apply(this, arguments);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
var currentCall;
|
||||
var matches = 0;
|
||||
|
||||
for (var i = 0, l = this.callCount; i < l; i += 1) {
|
||||
currentCall = this.getCall(i);
|
||||
|
||||
if (currentCall[actual || method].apply(currentCall, arguments)) {
|
||||
matches += 1;
|
||||
|
||||
if (matchAny) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return matches === this.callCount;
|
||||
};
|
||||
}
|
||||
|
||||
delegateToCalls("calledOn", true);
|
||||
delegateToCalls("alwaysCalledOn", false, "calledOn");
|
||||
delegateToCalls("calledWith", true);
|
||||
delegateToCalls("calledWithMatch", true);
|
||||
delegateToCalls("alwaysCalledWith", false, "calledWith");
|
||||
delegateToCalls("alwaysCalledWithMatch", false, "calledWithMatch");
|
||||
delegateToCalls("calledWithExactly", true);
|
||||
delegateToCalls("alwaysCalledWithExactly", false, "calledWithExactly");
|
||||
delegateToCalls("neverCalledWith", false, "notCalledWith", function () {
|
||||
return true;
|
||||
});
|
||||
delegateToCalls("neverCalledWithMatch", false, "notCalledWithMatch", function () {
|
||||
return true;
|
||||
});
|
||||
delegateToCalls("threw", true);
|
||||
delegateToCalls("alwaysThrew", false, "threw");
|
||||
delegateToCalls("returned", true);
|
||||
delegateToCalls("alwaysReturned", false, "returned");
|
||||
delegateToCalls("calledWithNew", true);
|
||||
delegateToCalls("alwaysCalledWithNew", false, "calledWithNew");
|
||||
delegateToCalls("callArg", false, "callArgWith", function () {
|
||||
throw new Error(this.toString() + " cannot call arg since it was not yet invoked.");
|
||||
});
|
||||
spyApi.callArgWith = spyApi.callArg;
|
||||
delegateToCalls("callArgOn", false, "callArgOnWith", function () {
|
||||
throw new Error(this.toString() + " cannot call arg since it was not yet invoked.");
|
||||
});
|
||||
spyApi.callArgOnWith = spyApi.callArgOn;
|
||||
delegateToCalls("yield", false, "yield", function () {
|
||||
throw new Error(this.toString() + " cannot yield since it was not yet invoked.");
|
||||
});
|
||||
// "invokeCallback" is an alias for "yield" since "yield" is invalid in strict mode.
|
||||
spyApi.invokeCallback = spyApi.yield;
|
||||
delegateToCalls("yieldOn", false, "yieldOn", function () {
|
||||
throw new Error(this.toString() + " cannot yield since it was not yet invoked.");
|
||||
});
|
||||
delegateToCalls("yieldTo", false, "yieldTo", function (property) {
|
||||
throw new Error(this.toString() + " cannot yield to '" + property +
|
||||
"' since it was not yet invoked.");
|
||||
});
|
||||
delegateToCalls("yieldToOn", false, "yieldToOn", function (property) {
|
||||
throw new Error(this.toString() + " cannot yield to '" + property +
|
||||
"' since it was not yet invoked.");
|
||||
});
|
||||
|
||||
spyApi.formatters = {
|
||||
c: function (spyInstance) {
|
||||
return sinon.timesInWords(spyInstance.callCount);
|
||||
},
|
||||
|
||||
n: function (spyInstance) {
|
||||
return spyInstance.toString();
|
||||
},
|
||||
|
||||
C: function (spyInstance) {
|
||||
var calls = [];
|
||||
|
||||
for (var i = 0, l = spyInstance.callCount; i < l; ++i) {
|
||||
var stringifiedCall = " " + spyInstance.getCall(i).toString();
|
||||
if (/\n/.test(calls[i - 1])) {
|
||||
stringifiedCall = "\n" + stringifiedCall;
|
||||
}
|
||||
push.call(calls, stringifiedCall);
|
||||
}
|
||||
|
||||
return calls.length > 0 ? "\n" + calls.join("\n") : "";
|
||||
},
|
||||
|
||||
t: function (spyInstance) {
|
||||
var objects = [];
|
||||
|
||||
for (var i = 0, l = spyInstance.callCount; i < l; ++i) {
|
||||
push.call(objects, sinon.format(spyInstance.thisValues[i]));
|
||||
}
|
||||
|
||||
return objects.join(", ");
|
||||
},
|
||||
|
||||
"*": function (spyInstance, args) {
|
||||
var formatted = [];
|
||||
|
||||
for (var i = 0, l = args.length; i < l; ++i) {
|
||||
push.call(formatted, sinon.format(args[i]));
|
||||
}
|
||||
|
||||
return formatted.join(", ");
|
||||
}
|
||||
};
|
||||
|
||||
sinon.extend(spy, spyApi);
|
||||
|
||||
spy.spyCall = sinon.spyCall;
|
||||
sinon.spy = spy;
|
||||
|
||||
return spy;
|
||||
}
|
||||
|
||||
var isNode = typeof module !== "undefined" && module.exports && typeof require === "function";
|
||||
var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
|
||||
|
||||
function loadDependencies(require, exports, module) {
|
||||
var core = require("./util/core");
|
||||
require("./call");
|
||||
require("./extend");
|
||||
require("./times_in_words");
|
||||
require("./format");
|
||||
module.exports = makeApi(core);
|
||||
}
|
||||
|
||||
if (isAMD) {
|
||||
define(loadDependencies);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isNode) {
|
||||
loadDependencies(require, module.exports, module);
|
||||
return;
|
||||
}
|
||||
|
||||
if (sinonGlobal) {
|
||||
makeApi(sinonGlobal);
|
||||
}
|
||||
}(
|
||||
typeof sinon === "object" && sinon // eslint-disable-line no-undef
|
||||
));
|
||||
|
||||
/**
|
||||
* @depend util/core.js
|
||||
* @depend extend.js
|
||||
*/
|
||||
/**
|
||||
* Stub behavior
|
||||
*
|
||||
* @author Christian Johansen (christian@cjohansen.no)
|
||||
* @author Tim Fischbach (mail@timfischbach.de)
|
||||
* @license BSD
|
||||
*
|
||||
* Copyright (c) 2010-2013 Christian Johansen
|
||||
*/
|
||||
(function (sinonGlobal) {
|
||||
|
||||
var slice = Array.prototype.slice;
|
||||
var join = Array.prototype.join;
|
||||
var useLeftMostCallback = -1;
|
||||
var useRightMostCallback = -2;
|
||||
|
||||
var nextTick = (function () {
|
||||
if (typeof process === "object" && typeof process.nextTick === "function") {
|
||||
return process.nextTick;
|
||||
}
|
||||
|
||||
if (typeof setImmediate === "function") {
|
||||
return setImmediate;
|
||||
}
|
||||
|
||||
return function (callback) {
|
||||
setTimeout(callback, 0);
|
||||
};
|
||||
})();
|
||||
|
||||
function throwsException(error, message) {
|
||||
if (typeof error === "string") {
|
||||
this.exception = new Error(message || "");
|
||||
this.exception.name = error;
|
||||
} else if (!error) {
|
||||
this.exception = new Error("Error");
|
||||
} else {
|
||||
this.exception = error;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
function getCallback(behavior, args) {
|
||||
var callArgAt = behavior.callArgAt;
|
||||
|
||||
if (callArgAt >= 0) {
|
||||
return args[callArgAt];
|
||||
}
|
||||
|
||||
var argumentList;
|
||||
|
||||
if (callArgAt === useLeftMostCallback) {
|
||||
argumentList = args;
|
||||
}
|
||||
|
||||
if (callArgAt === useRightMostCallback) {
|
||||
argumentList = slice.call(args).reverse();
|
||||
}
|
||||
|
||||
var callArgProp = behavior.callArgProp;
|
||||
|
||||
for (var i = 0, l = argumentList.length; i < l; ++i) {
|
||||
if (!callArgProp && typeof argumentList[i] === "function") {
|
||||
return argumentList[i];
|
||||
}
|
||||
|
||||
if (callArgProp && argumentList[i] &&
|
||||
typeof argumentList[i][callArgProp] === "function") {
|
||||
return argumentList[i][callArgProp];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function makeApi(sinon) {
|
||||
function getCallbackError(behavior, func, args) {
|
||||
if (behavior.callArgAt < 0) {
|
||||
var msg;
|
||||
|
||||
if (behavior.callArgProp) {
|
||||
msg = sinon.functionName(behavior.stub) +
|
||||
" expected to yield to '" + behavior.callArgProp +
|
||||
"', but no object with such a property was passed.";
|
||||
} else {
|
||||
msg = sinon.functionName(behavior.stub) +
|
||||
" expected to yield, but no callback was passed.";
|
||||
}
|
||||
|
||||
if (args.length > 0) {
|
||||
msg += " Received [" + join.call(args, ", ") + "]";
|
||||
}
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
return "argument at index " + behavior.callArgAt + " is not a function: " + func;
|
||||
}
|
||||
|
||||
function callCallback(behavior, args) {
|
||||
if (typeof behavior.callArgAt === "number") {
|
||||
var func = getCallback(behavior, args);
|
||||
|
||||
if (typeof func !== "function") {
|
||||
throw new TypeError(getCallbackError(behavior, func, args));
|
||||
}
|
||||
|
||||
if (behavior.callbackAsync) {
|
||||
nextTick(function () {
|
||||
func.apply(behavior.callbackContext, behavior.callbackArguments);
|
||||
});
|
||||
} else {
|
||||
func.apply(behavior.callbackContext, behavior.callbackArguments);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var proto = {
|
||||
create: function create(stub) {
|
||||
var behavior = sinon.extend({}, sinon.behavior);
|
||||
delete behavior.create;
|
||||
behavior.stub = stub;
|
||||
|
||||
return behavior;
|
||||
},
|
||||
|
||||
isPresent: function isPresent() {
|
||||
return (typeof this.callArgAt === "number" ||
|
||||
this.exception ||
|
||||
typeof this.returnArgAt === "number" ||
|
||||
this.returnThis ||
|
||||
this.returnValueDefined);
|
||||
},
|
||||
|
||||
invoke: function invoke(context, args) {
|
||||
callCallback(this, args);
|
||||
|
||||
if (this.exception) {
|
||||
throw this.exception;
|
||||
} else if (typeof this.returnArgAt === "number") {
|
||||
return args[this.returnArgAt];
|
||||
} else if (this.returnThis) {
|
||||
return context;
|
||||
}
|
||||
|
||||
return this.returnValue;
|
||||
},
|
||||
|
||||
onCall: function onCall(index) {
|
||||
return this.stub.onCall(index);
|
||||
},
|
||||
|
||||
onFirstCall: function onFirstCall() {
|
||||
return this.stub.onFirstCall();
|
||||
},
|
||||
|
||||
onSecondCall: function onSecondCall() {
|
||||
return this.stub.onSecondCall();
|
||||
},
|
||||
|
||||
onThirdCall: function onThirdCall() {
|
||||
return this.stub.onThirdCall();
|
||||
},
|
||||
|
||||
withArgs: function withArgs(/* arguments */) {
|
||||
throw new Error(
|
||||
"Defining a stub by invoking \"stub.onCall(...).withArgs(...)\" " +
|
||||
"is not supported. Use \"stub.withArgs(...).onCall(...)\" " +
|
||||
"to define sequential behavior for calls with certain arguments."
|
||||
);
|
||||
},
|
||||
|
||||
callsArg: function callsArg(pos) {
|
||||
if (typeof pos !== "number") {
|
||||
throw new TypeError("argument index is not number");
|
||||
}
|
||||
|
||||
this.callArgAt = pos;
|
||||
this.callbackArguments = [];
|
||||
this.callbackContext = undefined;
|
||||
this.callArgProp = undefined;
|
||||
this.callbackAsync = false;
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
callsArgOn: function callsArgOn(pos, context) {
|
||||
if (typeof pos !== "number") {
|
||||
throw new TypeError("argument index is not number");
|
||||
}
|
||||
if (typeof context !== "object") {
|
||||
throw new TypeError("argument context is not an object");
|
||||
}
|
||||
|
||||
this.callArgAt = pos;
|
||||
this.callbackArguments = [];
|
||||
this.callbackContext = context;
|
||||
this.callArgProp = undefined;
|
||||
this.callbackAsync = false;
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
callsArgWith: function callsArgWith(pos) {
|
||||
if (typeof pos !== "number") {
|
||||
throw new TypeError("argument index is not number");
|
||||
}
|
||||
|
||||
this.callArgAt = pos;
|
||||
this.callbackArguments = slice.call(arguments, 1);
|
||||
this.callbackContext = undefined;
|
||||
this.callArgProp = undefined;
|
||||
this.callbackAsync = false;
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
callsArgOnWith: function callsArgWith(pos, context) {
|
||||
if (typeof pos !== "number") {
|
||||
throw new TypeError("argument index is not number");
|
||||
}
|
||||
if (typeof context !== "object") {
|
||||
throw new TypeError("argument context is not an object");
|
||||
}
|
||||
|
||||
this.callArgAt = pos;
|
||||
this.callbackArguments = slice.call(arguments, 2);
|
||||
this.callbackContext = context;
|
||||
this.callArgProp = undefined;
|
||||
this.callbackAsync = false;
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
yields: function () {
|
||||
this.callArgAt = useLeftMostCallback;
|
||||
this.callbackArguments = slice.call(arguments, 0);
|
||||
this.callbackContext = undefined;
|
||||
this.callArgProp = undefined;
|
||||
this.callbackAsync = false;
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
yieldsRight: function () {
|
||||
this.callArgAt = useRightMostCallback;
|
||||
this.callbackArguments = slice.call(arguments, 0);
|
||||
this.callbackContext = undefined;
|
||||
this.callArgProp = undefined;
|
||||
this.callbackAsync = false;
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
yieldsOn: function (context) {
|
||||
if (typeof context !== "object") {
|
||||
throw new TypeError("argument context is not an object");
|
||||
}
|
||||
|
||||
this.callArgAt = useLeftMostCallback;
|
||||
this.callbackArguments = slice.call(arguments, 1);
|
||||
this.callbackContext = context;
|
||||
this.callArgProp = undefined;
|
||||
this.callbackAsync = false;
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
yieldsTo: function (prop) {
|
||||
this.callArgAt = useLeftMostCallback;
|
||||
this.callbackArguments = slice.call(arguments, 1);
|
||||
this.callbackContext = undefined;
|
||||
this.callArgProp = prop;
|
||||
this.callbackAsync = false;
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
yieldsToOn: function (prop, context) {
|
||||
if (typeof context !== "object") {
|
||||
throw new TypeError("argument context is not an object");
|
||||
}
|
||||
|
||||
this.callArgAt = useLeftMostCallback;
|
||||
this.callbackArguments = slice.call(arguments, 2);
|
||||
this.callbackContext = context;
|
||||
this.callArgProp = prop;
|
||||
this.callbackAsync = false;
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
throws: throwsException,
|
||||
throwsException: throwsException,
|
||||
|
||||
returns: function returns(value) {
|
||||
this.returnValue = value;
|
||||
this.returnValueDefined = true;
|
||||
this.exception = undefined;
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
returnsArg: function returnsArg(pos) {
|
||||
if (typeof pos !== "number") {
|
||||
throw new TypeError("argument index is not number");
|
||||
}
|
||||
|
||||
this.returnArgAt = pos;
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
returnsThis: function returnsThis() {
|
||||
this.returnThis = true;
|
||||
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
function createAsyncVersion(syncFnName) {
|
||||
return function () {
|
||||
var result = this[syncFnName].apply(this, arguments);
|
||||
this.callbackAsync = true;
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
// create asynchronous versions of callsArg* and yields* methods
|
||||
for (var method in proto) {
|
||||
// need to avoid creating anotherasync versions of the newly added async methods
|
||||
if (proto.hasOwnProperty(method) && method.match(/^(callsArg|yields)/) && !method.match(/Async/)) {
|
||||
proto[method + "Async"] = createAsyncVersion(method);
|
||||
}
|
||||
}
|
||||
|
||||
sinon.behavior = proto;
|
||||
return proto;
|
||||
}
|
||||
|
||||
var isNode = typeof module !== "undefined" && module.exports && typeof require === "function";
|
||||
var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
|
||||
|
||||
function loadDependencies(require, exports, module) {
|
||||
var sinon = require("./util/core");
|
||||
require("./extend");
|
||||
module.exports = makeApi(sinon);
|
||||
}
|
||||
|
||||
if (isAMD) {
|
||||
define(loadDependencies);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isNode) {
|
||||
loadDependencies(require, module.exports, module);
|
||||
return;
|
||||
}
|
||||
|
||||
if (sinonGlobal) {
|
||||
makeApi(sinonGlobal);
|
||||
}
|
||||
}(
|
||||
typeof sinon === "object" && sinon // eslint-disable-line no-undef
|
||||
));
|
||||
|
||||
/**
|
||||
* @depend util/core.js
|
||||
*/
|
||||
(function (sinonGlobal) {
|
||||
|
||||
function makeApi(sinon) {
|
||||
/* Public: walks the prototype chain of an object and iterates over every own property
|
||||
* name encountered. The iterator is called in the same fashion that Array.prototype.forEach
|
||||
* works, where it is passed the value, key, and own object as the 1st, 2nd, and 3rd positional
|
||||
* argument, respectively. In cases where Object.getOwnPropertyNames is not available, walk will
|
||||
* default to using a simple for..in loop.
|
||||
*
|
||||
* obj - The object to walk the prototype chain for.
|
||||
* iterator - The function to be called on each pass of the walk.
|
||||
* context - (Optional) When given, the iterator will be called with this object as the receiver.
|
||||
*/
|
||||
function walk(obj, iterator, context) {
|
||||
var proto, prop;
|
||||
|
||||
if (typeof Object.getOwnPropertyNames !== "function") {
|
||||
// We explicitly want to enumerate through all of the prototype's properties
|
||||
// in this case, therefore we deliberately leave out an own property check.
|
||||
/* eslint-disable guard-for-in */
|
||||
for (prop in obj) {
|
||||
iterator.call(context, obj[prop], prop, obj);
|
||||
}
|
||||
/* eslint-enable guard-for-in */
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Object.getOwnPropertyNames(obj).forEach(function (k) {
|
||||
iterator.call(context, obj[k], k, obj);
|
||||
});
|
||||
|
||||
proto = Object.getPrototypeOf(obj);
|
||||
if (proto) {
|
||||
walk(proto, iterator, context);
|
||||
}
|
||||
}
|
||||
|
||||
sinon.walk = walk;
|
||||
return sinon.walk;
|
||||
}
|
||||
|
||||
function loadDependencies(require, exports, module) {
|
||||
var sinon = require("./util/core");
|
||||
module.exports = makeApi(sinon);
|
||||
}
|
||||
|
||||
var isNode = typeof module !== "undefined" && module.exports && typeof require === "function";
|
||||
var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
|
||||
|
||||
if (isAMD) {
|
||||
define(loadDependencies);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isNode) {
|
||||
loadDependencies(require, module.exports, module);
|
||||
return;
|
||||
}
|
||||
|
||||
if (sinonGlobal) {
|
||||
makeApi(sinonGlobal);
|
||||
}
|
||||
}(
|
||||
typeof sinon === "object" && sinon // eslint-disable-line no-undef
|
||||
));
|
||||
|
||||
/**
|
||||
* @depend util/core.js
|
||||
* @depend extend.js
|
||||
* @depend spy.js
|
||||
* @depend behavior.js
|
||||
* @depend walk.js
|
||||
*/
|
||||
/**
|
||||
* Stub functions
|
||||
*
|
||||
* @author Christian Johansen (christian@cjohansen.no)
|
||||
* @license BSD
|
||||
*
|
||||
* Copyright (c) 2010-2013 Christian Johansen
|
||||
*/
|
||||
(function (sinonGlobal) {
|
||||
|
||||
function makeApi(sinon) {
|
||||
function stub(object, property, func) {
|
||||
if (!!func && typeof func !== "function" && typeof func !== "object") {
|
||||
throw new TypeError("Custom stub should be a function or a property descriptor");
|
||||
}
|
||||
|
||||
var wrapper;
|
||||
|
||||
if (func) {
|
||||
if (typeof func === "function") {
|
||||
wrapper = sinon.spy && sinon.spy.create ? sinon.spy.create(func) : func;
|
||||
} else {
|
||||
wrapper = func;
|
||||
if (sinon.spy && sinon.spy.create) {
|
||||
var types = sinon.objectKeys(wrapper);
|
||||
for (var i = 0; i < types.length; i++) {
|
||||
wrapper[types[i]] = sinon.spy.create(wrapper[types[i]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
var stubLength = 0;
|
||||
if (typeof object === "object" && typeof object[property] === "function") {
|
||||
stubLength = object[property].length;
|
||||
}
|
||||
wrapper = stub.create(stubLength);
|
||||
}
|
||||
|
||||
if (!object && typeof property === "undefined") {
|
||||
return sinon.stub.create();
|
||||
}
|
||||
|
||||
if (typeof property === "undefined" && typeof object === "object") {
|
||||
sinon.walk(object || {}, function (value, prop, propOwner) {
|
||||
// we don't want to stub things like toString(), valueOf(), etc. so we only stub if the object
|
||||
// is not Object.prototype
|
||||
if (
|
||||
propOwner !== Object.prototype &&
|
||||
typeof sinon.getPropertyDescriptor(propOwner, prop).value === "function"
|
||||
) {
|
||||
stub(object, prop);
|
||||
}
|
||||
});
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
return sinon.wrapMethod(object, property, wrapper);
|
||||
}
|
||||
|
||||
|
||||
/*eslint-disable no-use-before-define*/
|
||||
function getParentBehaviour(stubInstance) {
|
||||
return (stubInstance.parent && getCurrentBehavior(stubInstance.parent));
|
||||
}
|
||||
|
||||
function getDefaultBehavior(stubInstance) {
|
||||
return stubInstance.defaultBehavior ||
|
||||
getParentBehaviour(stubInstance) ||
|
||||
sinon.behavior.create(stubInstance);
|
||||
}
|
||||
|
||||
function getCurrentBehavior(stubInstance) {
|
||||
var behavior = stubInstance.behaviors[stubInstance.callCount - 1];
|
||||
return behavior && behavior.isPresent() ? behavior : getDefaultBehavior(stubInstance);
|
||||
}
|
||||
/*eslint-enable no-use-before-define*/
|
||||
|
||||
var uuid = 0;
|
||||
|
||||
var proto = {
|
||||
create: function create(stubLength) {
|
||||
var functionStub = function () {
|
||||
return getCurrentBehavior(functionStub).invoke(this, arguments);
|
||||
};
|
||||
|
||||
functionStub.id = "stub#" + uuid++;
|
||||
var orig = functionStub;
|
||||
functionStub = sinon.spy.create(functionStub, stubLength);
|
||||
functionStub.func = orig;
|
||||
|
||||
sinon.extend(functionStub, stub);
|
||||
functionStub.instantiateFake = sinon.stub.create;
|
||||
functionStub.displayName = "stub";
|
||||
functionStub.toString = sinon.functionToString;
|
||||
|
||||
functionStub.defaultBehavior = null;
|
||||
functionStub.behaviors = [];
|
||||
|
||||
return functionStub;
|
||||
},
|
||||
|
||||
resetBehavior: function () {
|
||||
var i;
|
||||
|
||||
this.defaultBehavior = null;
|
||||
this.behaviors = [];
|
||||
|
||||
delete this.returnValue;
|
||||
delete this.returnArgAt;
|
||||
this.returnThis = false;
|
||||
|
||||
if (this.fakes) {
|
||||
for (i = 0; i < this.fakes.length; i++) {
|
||||
this.fakes[i].resetBehavior();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
onCall: function onCall(index) {
|
||||
if (!this.behaviors[index]) {
|
||||
this.behaviors[index] = sinon.behavior.create(this);
|
||||
}
|
||||
|
||||
return this.behaviors[index];
|
||||
},
|
||||
|
||||
onFirstCall: function onFirstCall() {
|
||||
return this.onCall(0);
|
||||
},
|
||||
|
||||
onSecondCall: function onSecondCall() {
|
||||
return this.onCall(1);
|
||||
},
|
||||
|
||||
onThirdCall: function onThirdCall() {
|
||||
return this.onCall(2);
|
||||
}
|
||||
};
|
||||
|
||||
function createBehavior(behaviorMethod) {
|
||||
return function () {
|
||||
this.defaultBehavior = this.defaultBehavior || sinon.behavior.create(this);
|
||||
this.defaultBehavior[behaviorMethod].apply(this.defaultBehavior, arguments);
|
||||
return this;
|
||||
};
|
||||
}
|
||||
|
||||
for (var method in sinon.behavior) {
|
||||
if (sinon.behavior.hasOwnProperty(method) &&
|
||||
!proto.hasOwnProperty(method) &&
|
||||
method !== "create" &&
|
||||
method !== "withArgs" &&
|
||||
method !== "invoke") {
|
||||
proto[method] = createBehavior(method);
|
||||
}
|
||||
}
|
||||
|
||||
sinon.extend(stub, proto);
|
||||
sinon.stub = stub;
|
||||
|
||||
return stub;
|
||||
}
|
||||
|
||||
var isNode = typeof module !== "undefined" && module.exports && typeof require === "function";
|
||||
var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
|
||||
|
||||
function loadDependencies(require, exports, module) {
|
||||
var core = require("./util/core");
|
||||
require("./behavior");
|
||||
require("./spy");
|
||||
require("./extend");
|
||||
module.exports = makeApi(core);
|
||||
}
|
||||
|
||||
if (isAMD) {
|
||||
define(loadDependencies);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isNode) {
|
||||
loadDependencies(require, module.exports, module);
|
||||
return;
|
||||
}
|
||||
|
||||
if (sinonGlobal) {
|
||||
makeApi(sinonGlobal);
|
||||
}
|
||||
}(
|
||||
typeof sinon === "object" && sinon // eslint-disable-line no-undef
|
||||
));
|
||||
|
||||
/**
|
||||
* @depend times_in_words.js
|
||||
* @depend util/core.js
|
||||
* @depend call.js
|
||||
* @depend extend.js
|
||||
* @depend match.js
|
||||
* @depend spy.js
|
||||
* @depend stub.js
|
||||
* @depend format.js
|
||||
*/
|
||||
/**
|
||||
* Mock functions.
|
||||
*
|
||||
* @author Christian Johansen (christian@cjohansen.no)
|
||||
* @license BSD
|
||||
*
|
||||
* Copyright (c) 2010-2013 Christian Johansen
|
||||
*/
|
||||
(function (sinonGlobal) {
|
||||
|
||||
function makeApi(sinon) {
|
||||
var push = [].push;
|
||||
var match = sinon.match;
|
||||
|
||||
function mock(object) {
|
||||
// if (typeof console !== undefined && console.warn) {
|
||||
// console.warn("mock will be removed from Sinon.JS v2.0");
|
||||
// }
|
||||
|
||||
if (!object) {
|
||||
return sinon.expectation.create("Anonymous mock");
|
||||
}
|
||||
|
||||
return mock.create(object);
|
||||
}
|
||||
|
||||
function each(collection, callback) {
|
||||
if (!collection) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = 0, l = collection.length; i < l; i += 1) {
|
||||
callback(collection[i]);
|
||||
}
|
||||
}
|
||||
|
||||
function arrayEquals(arr1, arr2, compareLength) {
|
||||
if (compareLength && (arr1.length !== arr2.length)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var i = 0, l = arr1.length; i < l; i++) {
|
||||
if (!sinon.deepEqual(arr1[i], arr2[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
sinon.extend(mock, {
|
||||
create: function create(object) {
|
||||
if (!object) {
|
||||
throw new TypeError("object is null");
|
||||
}
|
||||
|
||||
var mockObject = sinon.extend({}, mock);
|
||||
mockObject.object = object;
|
||||
delete mockObject.create;
|
||||
|
||||
return mockObject;
|
||||
},
|
||||
|
||||
expects: function expects(method) {
|
||||
if (!method) {
|
||||
throw new TypeError("method is falsy");
|
||||
}
|
||||
|
||||
if (!this.expectations) {
|
||||
this.expectations = {};
|
||||
this.proxies = [];
|
||||
}
|
||||
|
||||
if (!this.expectations[method]) {
|
||||
this.expectations[method] = [];
|
||||
var mockObject = this;
|
||||
|
||||
sinon.wrapMethod(this.object, method, function () {
|
||||
return mockObject.invokeMethod(method, this, arguments);
|
||||
});
|
||||
|
||||
push.call(this.proxies, method);
|
||||
}
|
||||
|
||||
var expectation = sinon.expectation.create(method);
|
||||
push.call(this.expectations[method], expectation);
|
||||
|
||||
return expectation;
|
||||
},
|
||||
|
||||
restore: function restore() {
|
||||
var object = this.object;
|
||||
|
||||
each(this.proxies, function (proxy) {
|
||||
if (typeof object[proxy].restore === "function") {
|
||||
object[proxy].restore();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
verify: function verify() {
|
||||
var expectations = this.expectations || {};
|
||||
var messages = [];
|
||||
var met = [];
|
||||
|
||||
each(this.proxies, function (proxy) {
|
||||
each(expectations[proxy], function (expectation) {
|
||||
if (!expectation.met()) {
|
||||
push.call(messages, expectation.toString());
|
||||
} else {
|
||||
push.call(met, expectation.toString());
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
this.restore();
|
||||
|
||||
if (messages.length > 0) {
|
||||
sinon.expectation.fail(messages.concat(met).join("\n"));
|
||||
} else if (met.length > 0) {
|
||||
sinon.expectation.pass(messages.concat(met).join("\n"));
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
invokeMethod: function invokeMethod(method, thisValue, args) {
|
||||
var expectations = this.expectations && this.expectations[method] ? this.expectations[method] : [];
|
||||
var expectationsWithMatchingArgs = [];
|
||||
var currentArgs = args || [];
|
||||
var i, available;
|
||||
|
||||
for (i = 0; i < expectations.length; i += 1) {
|
||||
var expectedArgs = expectations[i].expectedArguments || [];
|
||||
if (arrayEquals(expectedArgs, currentArgs, expectations[i].expectsExactArgCount)) {
|
||||
expectationsWithMatchingArgs.push(expectations[i]);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < expectationsWithMatchingArgs.length; i += 1) {
|
||||
if (!expectationsWithMatchingArgs[i].met() &&
|
||||
expectationsWithMatchingArgs[i].allowsCall(thisValue, args)) {
|
||||
return expectationsWithMatchingArgs[i].apply(thisValue, args);
|
||||
}
|
||||
}
|
||||
|
||||
var messages = [];
|
||||
var exhausted = 0;
|
||||
|
||||
for (i = 0; i < expectationsWithMatchingArgs.length; i += 1) {
|
||||
if (expectationsWithMatchingArgs[i].allowsCall(thisValue, args)) {
|
||||
available = available || expectationsWithMatchingArgs[i];
|
||||
} else {
|
||||
exhausted += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (available && exhausted === 0) {
|
||||
return available.apply(thisValue, args);
|
||||
}
|
||||
|
||||
for (i = 0; i < expectations.length; i += 1) {
|
||||
push.call(messages, " " + expectations[i].toString());
|
||||
}
|
||||
|
||||
messages.unshift("Unexpected call: " + sinon.spyCall.toString.call({
|
||||
proxy: method,
|
||||
args: args
|
||||
}));
|
||||
|
||||
sinon.expectation.fail(messages.join("\n"));
|
||||
}
|
||||
});
|
||||
|
||||
var times = sinon.timesInWords;
|
||||
var slice = Array.prototype.slice;
|
||||
|
||||
function callCountInWords(callCount) {
|
||||
if (callCount === 0) {
|
||||
return "never called";
|
||||
}
|
||||
|
||||
return "called " + times(callCount);
|
||||
}
|
||||
|
||||
function expectedCallCountInWords(expectation) {
|
||||
var min = expectation.minCalls;
|
||||
var max = expectation.maxCalls;
|
||||
|
||||
if (typeof min === "number" && typeof max === "number") {
|
||||
var str = times(min);
|
||||
|
||||
if (min !== max) {
|
||||
str = "at least " + str + " and at most " + times(max);
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
if (typeof min === "number") {
|
||||
return "at least " + times(min);
|
||||
}
|
||||
|
||||
return "at most " + times(max);
|
||||
}
|
||||
|
||||
function receivedMinCalls(expectation) {
|
||||
var hasMinLimit = typeof expectation.minCalls === "number";
|
||||
return !hasMinLimit || expectation.callCount >= expectation.minCalls;
|
||||
}
|
||||
|
||||
function receivedMaxCalls(expectation) {
|
||||
if (typeof expectation.maxCalls !== "number") {
|
||||
return false;
|
||||
}
|
||||
|
||||
return expectation.callCount === expectation.maxCalls;
|
||||
}
|
||||
|
||||
function verifyMatcher(possibleMatcher, arg) {
|
||||
var isMatcher = match && match.isMatcher(possibleMatcher);
|
||||
|
||||
return isMatcher && possibleMatcher.test(arg) || true;
|
||||
}
|
||||
|
||||
sinon.expectation = {
|
||||
minCalls: 1,
|
||||
maxCalls: 1,
|
||||
|
||||
create: function create(methodName) {
|
||||
var expectation = sinon.extend(sinon.stub.create(), sinon.expectation);
|
||||
delete expectation.create;
|
||||
expectation.method = methodName;
|
||||
|
||||
return expectation;
|
||||
},
|
||||
|
||||
invoke: function invoke(func, thisValue, args) {
|
||||
this.verifyCallAllowed(thisValue, args);
|
||||
|
||||
return sinon.spy.invoke.apply(this, arguments);
|
||||
},
|
||||
|
||||
atLeast: function atLeast(num) {
|
||||
if (typeof num !== "number") {
|
||||
throw new TypeError("'" + num + "' is not number");
|
||||
}
|
||||
|
||||
if (!this.limitsSet) {
|
||||
this.maxCalls = null;
|
||||
this.limitsSet = true;
|
||||
}
|
||||
|
||||
this.minCalls = num;
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
atMost: function atMost(num) {
|
||||
if (typeof num !== "number") {
|
||||
throw new TypeError("'" + num + "' is not number");
|
||||
}
|
||||
|
||||
if (!this.limitsSet) {
|
||||
this.minCalls = null;
|
||||
this.limitsSet = true;
|
||||
}
|
||||
|
||||
this.maxCalls = num;
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
never: function never() {
|
||||
return this.exactly(0);
|
||||
},
|
||||
|
||||
once: function once() {
|
||||
return this.exactly(1);
|
||||
},
|
||||
|
||||
twice: function twice() {
|
||||
return this.exactly(2);
|
||||
},
|
||||
|
||||
thrice: function thrice() {
|
||||
return this.exactly(3);
|
||||
},
|
||||
|
||||
exactly: function exactly(num) {
|
||||
if (typeof num !== "number") {
|
||||
throw new TypeError("'" + num + "' is not a number");
|
||||
}
|
||||
|
||||
this.atLeast(num);
|
||||
return this.atMost(num);
|
||||
},
|
||||
|
||||
met: function met() {
|
||||
return !this.failed && receivedMinCalls(this);
|
||||
},
|
||||
|
||||
verifyCallAllowed: function verifyCallAllowed(thisValue, args) {
|
||||
if (receivedMaxCalls(this)) {
|
||||
this.failed = true;
|
||||
sinon.expectation.fail(this.method + " already called " + times(this.maxCalls));
|
||||
}
|
||||
|
||||
if ("expectedThis" in this && this.expectedThis !== thisValue) {
|
||||
sinon.expectation.fail(this.method + " called with " + thisValue + " as thisValue, expected " +
|
||||
this.expectedThis);
|
||||
}
|
||||
|
||||
if (!("expectedArguments" in this)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!args) {
|
||||
sinon.expectation.fail(this.method + " received no arguments, expected " +
|
||||
sinon.format(this.expectedArguments));
|
||||
}
|
||||
|
||||
if (args.length < this.expectedArguments.length) {
|
||||
sinon.expectation.fail(this.method + " received too few arguments (" + sinon.format(args) +
|
||||
"), expected " + sinon.format(this.expectedArguments));
|
||||
}
|
||||
|
||||
if (this.expectsExactArgCount &&
|
||||
args.length !== this.expectedArguments.length) {
|
||||
sinon.expectation.fail(this.method + " received too many arguments (" + sinon.format(args) +
|
||||
"), expected " + sinon.format(this.expectedArguments));
|
||||
}
|
||||
|
||||
for (var i = 0, l = this.expectedArguments.length; i < l; i += 1) {
|
||||
|
||||
if (!verifyMatcher(this.expectedArguments[i], args[i])) {
|
||||
sinon.expectation.fail(this.method + " received wrong arguments " + sinon.format(args) +
|
||||
", didn't match " + this.expectedArguments.toString());
|
||||
}
|
||||
|
||||
if (!sinon.deepEqual(this.expectedArguments[i], args[i])) {
|
||||
sinon.expectation.fail(this.method + " received wrong arguments " + sinon.format(args) +
|
||||
", expected " + sinon.format(this.expectedArguments));
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
allowsCall: function allowsCall(thisValue, args) {
|
||||
if (this.met() && receivedMaxCalls(this)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ("expectedThis" in this && this.expectedThis !== thisValue) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!("expectedArguments" in this)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
args = args || [];
|
||||
|
||||
if (args.length < this.expectedArguments.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.expectsExactArgCount &&
|
||||
args.length !== this.expectedArguments.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var i = 0, l = this.expectedArguments.length; i < l; i += 1) {
|
||||
if (!verifyMatcher(this.expectedArguments[i], args[i])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!sinon.deepEqual(this.expectedArguments[i], args[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
withArgs: function withArgs() {
|
||||
this.expectedArguments = slice.call(arguments);
|
||||
return this;
|
||||
},
|
||||
|
||||
withExactArgs: function withExactArgs() {
|
||||
this.withArgs.apply(this, arguments);
|
||||
this.expectsExactArgCount = true;
|
||||
return this;
|
||||
},
|
||||
|
||||
on: function on(thisValue) {
|
||||
this.expectedThis = thisValue;
|
||||
return this;
|
||||
},
|
||||
|
||||
toString: function () {
|
||||
var args = (this.expectedArguments || []).slice();
|
||||
|
||||
if (!this.expectsExactArgCount) {
|
||||
push.call(args, "[...]");
|
||||
}
|
||||
|
||||
var callStr = sinon.spyCall.toString.call({
|
||||
proxy: this.method || "anonymous mock expectation",
|
||||
args: args
|
||||
});
|
||||
|
||||
var message = callStr.replace(", [...", "[, ...") + " " +
|
||||
expectedCallCountInWords(this);
|
||||
|
||||
if (this.met()) {
|
||||
return "Expectation met: " + message;
|
||||
}
|
||||
|
||||
return "Expected " + message + " (" +
|
||||
callCountInWords(this.callCount) + ")";
|
||||
},
|
||||
|
||||
verify: function verify() {
|
||||
if (!this.met()) {
|
||||
sinon.expectation.fail(this.toString());
|
||||
} else {
|
||||
sinon.expectation.pass(this.toString());
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
pass: function pass(message) {
|
||||
sinon.assert.pass(message);
|
||||
},
|
||||
|
||||
fail: function fail(message) {
|
||||
var exception = new Error(message);
|
||||
exception.name = "ExpectationError";
|
||||
|
||||
throw exception;
|
||||
}
|
||||
};
|
||||
|
||||
sinon.mock = mock;
|
||||
return mock;
|
||||
}
|
||||
|
||||
var isNode = typeof module !== "undefined" && module.exports && typeof require === "function";
|
||||
var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
|
||||
|
||||
function loadDependencies(require, exports, module) {
|
||||
var sinon = require("./util/core");
|
||||
require("./times_in_words");
|
||||
require("./call");
|
||||
require("./extend");
|
||||
require("./match");
|
||||
require("./spy");
|
||||
require("./stub");
|
||||
require("./format");
|
||||
|
||||
module.exports = makeApi(sinon);
|
||||
}
|
||||
|
||||
if (isAMD) {
|
||||
define(loadDependencies);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isNode) {
|
||||
loadDependencies(require, module.exports, module);
|
||||
return;
|
||||
}
|
||||
|
||||
if (sinonGlobal) {
|
||||
makeApi(sinonGlobal);
|
||||
}
|
||||
}(
|
||||
typeof sinon === "object" && sinon // eslint-disable-line no-undef
|
||||
));
|
||||
|
||||
/**
|
||||
* @depend util/core.js
|
||||
* @depend spy.js
|
||||
* @depend stub.js
|
||||
* @depend mock.js
|
||||
*/
|
||||
/**
|
||||
* Collections of stubs, spies and mocks.
|
||||
*
|
||||
* @author Christian Johansen (christian@cjohansen.no)
|
||||
* @license BSD
|
||||
*
|
||||
* Copyright (c) 2010-2013 Christian Johansen
|
||||
*/
|
||||
(function (sinonGlobal) {
|
||||
|
||||
var push = [].push;
|
||||
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
||||
|
||||
function getFakes(fakeCollection) {
|
||||
if (!fakeCollection.fakes) {
|
||||
fakeCollection.fakes = [];
|
||||
}
|
||||
|
||||
return fakeCollection.fakes;
|
||||
}
|
||||
|
||||
function each(fakeCollection, method) {
|
||||
var fakes = getFakes(fakeCollection);
|
||||
|
||||
for (var i = 0, l = fakes.length; i < l; i += 1) {
|
||||
if (typeof fakes[i][method] === "function") {
|
||||
fakes[i][method]();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function compact(fakeCollection) {
|
||||
var fakes = getFakes(fakeCollection);
|
||||
var i = 0;
|
||||
while (i < fakes.length) {
|
||||
fakes.splice(i, 1);
|
||||
}
|
||||
}
|
||||
|
||||
function makeApi(sinon) {
|
||||
var collection = {
|
||||
verify: function resolve() {
|
||||
each(this, "verify");
|
||||
},
|
||||
|
||||
restore: function restore() {
|
||||
each(this, "restore");
|
||||
compact(this);
|
||||
},
|
||||
|
||||
reset: function restore() {
|
||||
each(this, "reset");
|
||||
},
|
||||
|
||||
verifyAndRestore: function verifyAndRestore() {
|
||||
var exception;
|
||||
|
||||
try {
|
||||
this.verify();
|
||||
} catch (e) {
|
||||
exception = e;
|
||||
}
|
||||
|
||||
this.restore();
|
||||
|
||||
if (exception) {
|
||||
throw exception;
|
||||
}
|
||||
},
|
||||
|
||||
add: function add(fake) {
|
||||
push.call(getFakes(this), fake);
|
||||
return fake;
|
||||
},
|
||||
|
||||
spy: function spy() {
|
||||
return this.add(sinon.spy.apply(sinon, arguments));
|
||||
},
|
||||
|
||||
stub: function stub(object, property, value) {
|
||||
if (property) {
|
||||
var original = object[property];
|
||||
|
||||
if (typeof original !== "function") {
|
||||
if (!hasOwnProperty.call(object, property)) {
|
||||
throw new TypeError("Cannot stub non-existent own property " + property);
|
||||
}
|
||||
|
||||
object[property] = value;
|
||||
|
||||
return this.add({
|
||||
restore: function () {
|
||||
object[property] = original;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
if (!property && !!object && typeof object === "object") {
|
||||
var stubbedObj = sinon.stub.apply(sinon, arguments);
|
||||
|
||||
for (var prop in stubbedObj) {
|
||||
if (typeof stubbedObj[prop] === "function") {
|
||||
this.add(stubbedObj[prop]);
|
||||
}
|
||||
}
|
||||
|
||||
return stubbedObj;
|
||||
}
|
||||
|
||||
return this.add(sinon.stub.apply(sinon, arguments));
|
||||
},
|
||||
|
||||
mock: function mock() {
|
||||
return this.add(sinon.mock.apply(sinon, arguments));
|
||||
},
|
||||
|
||||
inject: function inject(obj) {
|
||||
var col = this;
|
||||
|
||||
obj.spy = function () {
|
||||
return col.spy.apply(col, arguments);
|
||||
};
|
||||
|
||||
obj.stub = function () {
|
||||
return col.stub.apply(col, arguments);
|
||||
};
|
||||
|
||||
obj.mock = function () {
|
||||
return col.mock.apply(col, arguments);
|
||||
};
|
||||
|
||||
return obj;
|
||||
}
|
||||
};
|
||||
|
||||
sinon.collection = collection;
|
||||
return collection;
|
||||
}
|
||||
|
||||
var isNode = typeof module !== "undefined" && module.exports && typeof require === "function";
|
||||
var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
|
||||
|
||||
function loadDependencies(require, exports, module) {
|
||||
var sinon = require("./util/core");
|
||||
require("./mock");
|
||||
require("./spy");
|
||||
require("./stub");
|
||||
module.exports = makeApi(sinon);
|
||||
}
|
||||
|
||||
if (isAMD) {
|
||||
define(loadDependencies);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isNode) {
|
||||
loadDependencies(require, module.exports, module);
|
||||
return;
|
||||
}
|
||||
|
||||
if (sinonGlobal) {
|
||||
makeApi(sinonGlobal);
|
||||
}
|
||||
}(
|
||||
typeof sinon === "object" && sinon // eslint-disable-line no-undef
|
||||
));
|
||||
|
||||
/**
|
||||
* Fake timer API
|
||||
* setTimeout
|
||||
* setInterval
|
||||
* clearTimeout
|
||||
* clearInterval
|
||||
* tick
|
||||
* reset
|
||||
* Date
|
||||
*
|
||||
* Inspired by jsUnitMockTimeOut from JsUnit
|
||||
*
|
||||
* @author Christian Johansen (christian@cjohansen.no)
|
||||
* @license BSD
|
||||
*
|
||||
* Copyright (c) 2010-2013 Christian Johansen
|
||||
*/
|
||||
(function () {
|
||||
|
||||
function makeApi(s, lol) {
|
||||
/*global lolex */
|
||||
var llx = typeof lolex !== "undefined" ? lolex : lol;
|
||||
|
||||
s.useFakeTimers = function () {
|
||||
var now;
|
||||
var methods = Array.prototype.slice.call(arguments);
|
||||
|
||||
if (typeof methods[0] === "string") {
|
||||
now = 0;
|
||||
} else {
|
||||
now = methods.shift();
|
||||
}
|
||||
|
||||
var clock = llx.install(now || 0, methods);
|
||||
clock.restore = clock.uninstall;
|
||||
return clock;
|
||||
};
|
||||
|
||||
s.clock = {
|
||||
create: function (now) {
|
||||
return llx.createClock(now);
|
||||
}
|
||||
};
|
||||
|
||||
s.timers = {
|
||||
setTimeout: setTimeout,
|
||||
clearTimeout: clearTimeout,
|
||||
setImmediate: (typeof setImmediate !== "undefined" ? setImmediate : undefined),
|
||||
clearImmediate: (typeof clearImmediate !== "undefined" ? clearImmediate : undefined),
|
||||
setInterval: setInterval,
|
||||
clearInterval: clearInterval,
|
||||
Date: Date
|
||||
};
|
||||
}
|
||||
|
||||
var isNode = typeof module !== "undefined" && module.exports && typeof require === "function";
|
||||
var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
|
||||
|
||||
function loadDependencies(require, epxorts, module, lolex) {
|
||||
var core = require("./core");
|
||||
makeApi(core, lolex);
|
||||
module.exports = core;
|
||||
}
|
||||
|
||||
if (isAMD) {
|
||||
define(loadDependencies);
|
||||
} else if (isNode) {
|
||||
loadDependencies(require, module.exports, module, require("lolex"));
|
||||
} else {
|
||||
makeApi(sinon); // eslint-disable-line no-undef
|
||||
}
|
||||
}());
|
||||
|
||||
/**
|
||||
* Minimal Event interface implementation
|
||||
*
|
||||
* Original implementation by Sven Fuchs: https://gist.github.com/995028
|
||||
* Modifications and tests by Christian Johansen.
|
||||
*
|
||||
* @author Sven Fuchs (svenfuchs@artweb-design.de)
|
||||
* @author Christian Johansen (christian@cjohansen.no)
|
||||
* @license BSD
|
||||
*
|
||||
* Copyright (c) 2011 Sven Fuchs, Christian Johansen
|
||||
*/
|
||||
if (typeof sinon === "undefined") {
|
||||
this.sinon = {};
|
||||
}
|
||||
|
||||
(function () {
|
||||
|
||||
var push = [].push;
|
||||
|
||||
function makeApi(sinon) {
|
||||
sinon.Event = function Event(type, bubbles, cancelable, target) {
|
||||
this.initEvent(type, bubbles, cancelable, target);
|
||||
};
|
||||
|
||||
sinon.Event.prototype = {
|
||||
initEvent: function (type, bubbles, cancelable, target) {
|
||||
this.type = type;
|
||||
this.bubbles = bubbles;
|
||||
this.cancelable = cancelable;
|
||||
this.target = target;
|
||||
},
|
||||
|
||||
stopPropagation: function () {},
|
||||
|
||||
preventDefault: function () {
|
||||
this.defaultPrevented = true;
|
||||
}
|
||||
};
|
||||
|
||||
sinon.ProgressEvent = function ProgressEvent(type, progressEventRaw, target) {
|
||||
this.initEvent(type, false, false, target);
|
||||
this.loaded = progressEventRaw.loaded || null;
|
||||
this.total = progressEventRaw.total || null;
|
||||
this.lengthComputable = !!progressEventRaw.total;
|
||||
};
|
||||
|
||||
sinon.ProgressEvent.prototype = new sinon.Event();
|
||||
|
||||
sinon.ProgressEvent.prototype.constructor = sinon.ProgressEvent;
|
||||
|
||||
sinon.CustomEvent = function CustomEvent(type, customData, target) {
|
||||
this.initEvent(type, false, false, target);
|
||||
this.detail = customData.detail || null;
|
||||
};
|
||||
|
||||
sinon.CustomEvent.prototype = new sinon.Event();
|
||||
|
||||
sinon.CustomEvent.prototype.constructor = sinon.CustomEvent;
|
||||
|
||||
sinon.EventTarget = {
|
||||
addEventListener: function addEventListener(event, listener) {
|
||||
this.eventListeners = this.eventListeners || {};
|
||||
this.eventListeners[event] = this.eventListeners[event] || [];
|
||||
push.call(this.eventListeners[event], listener);
|
||||
},
|
||||
|
||||
removeEventListener: function removeEventListener(event, listener) {
|
||||
var listeners = this.eventListeners && this.eventListeners[event] || [];
|
||||
|
||||
for (var i = 0, l = listeners.length; i < l; ++i) {
|
||||
if (listeners[i] === listener) {
|
||||
return listeners.splice(i, 1);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
dispatchEvent: function dispatchEvent(event) {
|
||||
var type = event.type;
|
||||
var listeners = this.eventListeners && this.eventListeners[type] || [];
|
||||
|
||||
for (var i = 0; i < listeners.length; i++) {
|
||||
if (typeof listeners[i] === "function") {
|
||||
listeners[i].call(this, event);
|
||||
} else {
|
||||
listeners[i].handleEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
return !!event.defaultPrevented;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
var isNode = typeof module !== "undefined" && module.exports && typeof require === "function";
|
||||
var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
|
||||
|
||||
function loadDependencies(require) {
|
||||
var sinon = require("./core");
|
||||
makeApi(sinon);
|
||||
}
|
||||
|
||||
if (isAMD) {
|
||||
define(loadDependencies);
|
||||
} else if (isNode) {
|
||||
loadDependencies(require);
|
||||
} else {
|
||||
makeApi(sinon); // eslint-disable-line no-undef
|
||||
}
|
||||
}());
|
||||
|
||||
/**
|
||||
* @depend util/core.js
|
||||
*/
|
||||
/**
|
||||
* Logs errors
|
||||
*
|
||||
* @author Christian Johansen (christian@cjohansen.no)
|
||||
* @license BSD
|
||||
*
|
||||
* Copyright (c) 2010-2014 Christian Johansen
|
||||
*/
|
||||
(function (sinonGlobal) {
|
||||
|
||||
// cache a reference to setTimeout, so that our reference won't be stubbed out
|
||||
// when using fake timers and errors will still get logged
|
||||
// https://github.com/cjohansen/Sinon.JS/issues/381
|
||||
var realSetTimeout = setTimeout;
|
||||
|
||||
function makeApi(sinon) {
|
||||
|
||||
function log() {}
|
||||
|
||||
function logError(label, err) {
|
||||
var msg = label + " threw exception: ";
|
||||
|
||||
function throwLoggedError() {
|
||||
err.message = msg + err.message;
|
||||
throw err;
|
||||
}
|
||||
|
||||
sinon.log(msg + "[" + err.name + "] " + err.message);
|
||||
|
||||
if (err.stack) {
|
||||
sinon.log(err.stack);
|
||||
}
|
||||
|
||||
if (logError.useImmediateExceptions) {
|
||||
throwLoggedError();
|
||||
} else {
|
||||
logError.setTimeout(throwLoggedError, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// When set to true, any errors logged will be thrown immediately;
|
||||
// If set to false, the errors will be thrown in separate execution frame.
|
||||
logError.useImmediateExceptions = false;
|
||||
|
||||
// wrap realSetTimeout with something we can stub in tests
|
||||
logError.setTimeout = function (func, timeout) {
|
||||
realSetTimeout(func, timeout);
|
||||
};
|
||||
|
||||
var exports = {};
|
||||
exports.log = sinon.log = log;
|
||||
exports.logError = sinon.logError = logError;
|
||||
|
||||
return exports;
|
||||
}
|
||||
|
||||
function loadDependencies(require, exports, module) {
|
||||
var sinon = require("./util/core");
|
||||
module.exports = makeApi(sinon);
|
||||
}
|
||||
|
||||
var isNode = typeof module !== "undefined" && module.exports && typeof require === "function";
|
||||
var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
|
||||
|
||||
if (isAMD) {
|
||||
define(loadDependencies);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isNode) {
|
||||
loadDependencies(require, module.exports, module);
|
||||
return;
|
||||
}
|
||||
|
||||
if (sinonGlobal) {
|
||||
makeApi(sinonGlobal);
|
||||
}
|
||||
}(
|
||||
typeof sinon === "object" && sinon // eslint-disable-line no-undef
|
||||
));
|
||||
|
||||
/**
|
||||
* @depend core.js
|
||||
* @depend ../extend.js
|
||||
* @depend event.js
|
||||
* @depend ../log_error.js
|
||||
*/
|
||||
/**
|
||||
* Fake XDomainRequest object
|
||||
*/
|
||||
if (typeof sinon === "undefined") {
|
||||
this.sinon = {};
|
||||
}
|
||||
|
||||
// wrapper for global
|
||||
(function (global) {
|
||||
|
||||
var xdr = { XDomainRequest: global.XDomainRequest };
|
||||
xdr.GlobalXDomainRequest = global.XDomainRequest;
|
||||
xdr.supportsXDR = typeof xdr.GlobalXDomainRequest !== "undefined";
|
||||
xdr.workingXDR = xdr.supportsXDR ? xdr.GlobalXDomainRequest : false;
|
||||
|
||||
function makeApi(sinon) {
|
||||
sinon.xdr = xdr;
|
||||
|
||||
function FakeXDomainRequest() {
|
||||
this.readyState = FakeXDomainRequest.UNSENT;
|
||||
this.requestBody = null;
|
||||
this.requestHeaders = {};
|
||||
this.status = 0;
|
||||
this.timeout = null;
|
||||
|
||||
if (typeof FakeXDomainRequest.onCreate === "function") {
|
||||
FakeXDomainRequest.onCreate(this);
|
||||
}
|
||||
}
|
||||
|
||||
function verifyState(x) {
|
||||
if (x.readyState !== FakeXDomainRequest.OPENED) {
|
||||
throw new Error("INVALID_STATE_ERR");
|
||||
}
|
||||
|
||||
if (x.sendFlag) {
|
||||
throw new Error("INVALID_STATE_ERR");
|
||||
}
|
||||
}
|
||||
|
||||
function verifyRequestSent(x) {
|
||||
if (x.readyState === FakeXDomainRequest.UNSENT) {
|
||||
throw new Error("Request not sent");
|
||||
}
|
||||
if (x.readyState === FakeXDomainRequest.DONE) {
|
||||
throw new Error("Request done");
|
||||
}
|
||||
}
|
||||
|
||||
function verifyResponseBodyType(body) {
|
||||
if (typeof body !== "string") {
|
||||
var error = new Error("Attempted to respond to fake XDomainRequest with " +
|
||||
body + ", which is not a string.");
|
||||
error.name = "InvalidBodyException";
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
sinon.extend(FakeXDomainRequest.prototype, sinon.EventTarget, {
|
||||
open: function open(method, url) {
|
||||
this.method = method;
|
||||
this.url = url;
|
||||
|
||||
this.responseText = null;
|
||||
this.sendFlag = false;
|
||||
|
||||
this.readyStateChange(FakeXDomainRequest.OPENED);
|
||||
},
|
||||
|
||||
readyStateChange: function readyStateChange(state) {
|
||||
this.readyState = state;
|
||||
var eventName = "";
|
||||
switch (this.readyState) {
|
||||
case FakeXDomainRequest.UNSENT:
|
||||
break;
|
||||
case FakeXDomainRequest.OPENED:
|
||||
break;
|
||||
case FakeXDomainRequest.LOADING:
|
||||
if (this.sendFlag) {
|
||||
//raise the progress event
|
||||
eventName = "onprogress";
|
||||
}
|
||||
break;
|
||||
case FakeXDomainRequest.DONE:
|
||||
if (this.isTimeout) {
|
||||
eventName = "ontimeout";
|
||||
} else if (this.errorFlag || (this.status < 200 || this.status > 299)) {
|
||||
eventName = "onerror";
|
||||
} else {
|
||||
eventName = "onload";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// raising event (if defined)
|
||||
if (eventName) {
|
||||
if (typeof this[eventName] === "function") {
|
||||
try {
|
||||
this[eventName]();
|
||||
} catch (e) {
|
||||
sinon.logError("Fake XHR " + eventName + " handler", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
send: function send(data) {
|
||||
verifyState(this);
|
||||
|
||||
if (!/^(get|head)$/i.test(this.method)) {
|
||||
this.requestBody = data;
|
||||
}
|
||||
this.requestHeaders["Content-Type"] = "text/plain;charset=utf-8";
|
||||
|
||||
this.errorFlag = false;
|
||||
this.sendFlag = true;
|
||||
this.readyStateChange(FakeXDomainRequest.OPENED);
|
||||
|
||||
if (typeof this.onSend === "function") {
|
||||
this.onSend(this);
|
||||
}
|
||||
},
|
||||
|
||||
abort: function abort() {
|
||||
this.aborted = true;
|
||||
this.responseText = null;
|
||||
this.errorFlag = true;
|
||||
|
||||
if (this.readyState > sinon.FakeXDomainRequest.UNSENT && this.sendFlag) {
|
||||
this.readyStateChange(sinon.FakeXDomainRequest.DONE);
|
||||
this.sendFlag = false;
|
||||
}
|
||||
},
|
||||
|
||||
setResponseBody: function setResponseBody(body) {
|
||||
verifyRequestSent(this);
|
||||
verifyResponseBodyType(body);
|
||||
|
||||
var chunkSize = this.chunkSize || 10;
|
||||
var index = 0;
|
||||
this.responseText = "";
|
||||
|
||||
do {
|
||||
this.readyStateChange(FakeXDomainRequest.LOADING);
|
||||
this.responseText += body.substring(index, index + chunkSize);
|
||||
index += chunkSize;
|
||||
} while (index < body.length);
|
||||
|
||||
this.readyStateChange(FakeXDomainRequest.DONE);
|
||||
},
|
||||
|
||||
respond: function respond(status, contentType, body) {
|
||||
// content-type ignored, since XDomainRequest does not carry this
|
||||
// we keep the same syntax for respond(...) as for FakeXMLHttpRequest to ease
|
||||
// test integration across browsers
|
||||
this.status = typeof status === "number" ? status : 200;
|
||||
this.setResponseBody(body || "");
|
||||
},
|
||||
|
||||
simulatetimeout: function simulatetimeout() {
|
||||
this.status = 0;
|
||||
this.isTimeout = true;
|
||||
// Access to this should actually throw an error
|
||||
this.responseText = undefined;
|
||||
this.readyStateChange(FakeXDomainRequest.DONE);
|
||||
}
|
||||
});
|
||||
|
||||
sinon.extend(FakeXDomainRequest, {
|
||||
UNSENT: 0,
|
||||
OPENED: 1,
|
||||
LOADING: 3,
|
||||
DONE: 4
|
||||
});
|
||||
|
||||
sinon.useFakeXDomainRequest = function useFakeXDomainRequest() {
|
||||
sinon.FakeXDomainRequest.restore = function restore(keepOnCreate) {
|
||||
if (xdr.supportsXDR) {
|
||||
global.XDomainRequest = xdr.GlobalXDomainRequest;
|
||||
}
|
||||
|
||||
delete sinon.FakeXDomainRequest.restore;
|
||||
|
||||
if (keepOnCreate !== true) {
|
||||
delete sinon.FakeXDomainRequest.onCreate;
|
||||
}
|
||||
};
|
||||
if (xdr.supportsXDR) {
|
||||
global.XDomainRequest = sinon.FakeXDomainRequest;
|
||||
}
|
||||
return sinon.FakeXDomainRequest;
|
||||
};
|
||||
|
||||
sinon.FakeXDomainRequest = FakeXDomainRequest;
|
||||
}
|
||||
|
||||
var isNode = typeof module !== "undefined" && module.exports && typeof require === "function";
|
||||
var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
|
||||
|
||||
function loadDependencies(require, exports, module) {
|
||||
var sinon = require("./core");
|
||||
require("../extend");
|
||||
require("./event");
|
||||
require("../log_error");
|
||||
makeApi(sinon);
|
||||
module.exports = sinon;
|
||||
}
|
||||
|
||||
if (isAMD) {
|
||||
define(loadDependencies);
|
||||
} else if (isNode) {
|
||||
loadDependencies(require, module.exports, module);
|
||||
} else {
|
||||
makeApi(sinon); // eslint-disable-line no-undef
|
||||
}
|
||||
})(typeof global !== "undefined" ? global : self);
|
||||
|
||||
/**
|
||||
* @depend core.js
|
||||
* @depend ../extend.js
|
||||
* @depend event.js
|
||||
* @depend ../log_error.js
|
||||
*/
|
||||
/**
|
||||
* Fake XMLHttpRequest object
|
||||
*
|
||||
* @author Christian Johansen (christian@cjohansen.no)
|
||||
* @license BSD
|
||||
*
|
||||
* Copyright (c) 2010-2013 Christian Johansen
|
||||
*/
|
||||
(function (sinonGlobal, global) {
|
||||
|
||||
function getWorkingXHR(globalScope) {
|
||||
var supportsXHR = typeof globalScope.XMLHttpRequest !== "undefined";
|
||||
if (supportsXHR) {
|
||||
return globalScope.XMLHttpRequest;
|
||||
}
|
||||
|
||||
var supportsActiveX = typeof globalScope.ActiveXObject !== "undefined";
|
||||
if (supportsActiveX) {
|
||||
return function () {
|
||||
return new globalScope.ActiveXObject("MSXML2.XMLHTTP.3.0");
|
||||
};
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
var supportsProgress = typeof ProgressEvent !== "undefined";
|
||||
var supportsCustomEvent = typeof CustomEvent !== "undefined";
|
||||
var supportsFormData = typeof FormData !== "undefined";
|
||||
var supportsArrayBuffer = typeof ArrayBuffer !== "undefined";
|
||||
var supportsBlob = typeof Blob === "function";
|
||||
var sinonXhr = { XMLHttpRequest: global.XMLHttpRequest };
|
||||
sinonXhr.GlobalXMLHttpRequest = global.XMLHttpRequest;
|
||||
sinonXhr.GlobalActiveXObject = global.ActiveXObject;
|
||||
sinonXhr.supportsActiveX = typeof sinonXhr.GlobalActiveXObject !== "undefined";
|
||||
sinonXhr.supportsXHR = typeof sinonXhr.GlobalXMLHttpRequest !== "undefined";
|
||||
sinonXhr.workingXHR = getWorkingXHR(global);
|
||||
sinonXhr.supportsCORS = sinonXhr.supportsXHR && "withCredentials" in (new sinonXhr.GlobalXMLHttpRequest());
|
||||
|
||||
var unsafeHeaders = {
|
||||
"Accept-Charset": true,
|
||||
"Accept-Encoding": true,
|
||||
Connection: true,
|
||||
"Content-Length": true,
|
||||
Cookie: true,
|
||||
Cookie2: true,
|
||||
"Content-Transfer-Encoding": true,
|
||||
Date: true,
|
||||
Expect: true,
|
||||
Host: true,
|
||||
"Keep-Alive": true,
|
||||
Referer: true,
|
||||
TE: true,
|
||||
Trailer: true,
|
||||
"Transfer-Encoding": true,
|
||||
Upgrade: true,
|
||||
"User-Agent": true,
|
||||
Via: true
|
||||
};
|
||||
|
||||
// An upload object is created for each
|
||||
// FakeXMLHttpRequest and allows upload
|
||||
// events to be simulated using uploadProgress
|
||||
// and uploadError.
|
||||
function UploadProgress() {
|
||||
this.eventListeners = {
|
||||
progress: [],
|
||||
load: [],
|
||||
abort: [],
|
||||
error: []
|
||||
};
|
||||
}
|
||||
|
||||
UploadProgress.prototype.addEventListener = function addEventListener(event, listener) {
|
||||
this.eventListeners[event].push(listener);
|
||||
};
|
||||
|
||||
UploadProgress.prototype.removeEventListener = function removeEventListener(event, listener) {
|
||||
var listeners = this.eventListeners[event] || [];
|
||||
|
||||
for (var i = 0, l = listeners.length; i < l; ++i) {
|
||||
if (listeners[i] === listener) {
|
||||
return listeners.splice(i, 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
UploadProgress.prototype.dispatchEvent = function dispatchEvent(event) {
|
||||
var listeners = this.eventListeners[event.type] || [];
|
||||
|
||||
for (var i = 0, listener; (listener = listeners[i]) != null; i++) {
|
||||
listener(event);
|
||||
}
|
||||
};
|
||||
|
||||
// Note that for FakeXMLHttpRequest to work pre ES5
|
||||
// we lose some of the alignment with the spec.
|
||||
// To ensure as close a match as possible,
|
||||
// set responseType before calling open, send or respond;
|
||||
function FakeXMLHttpRequest() {
|
||||
this.readyState = FakeXMLHttpRequest.UNSENT;
|
||||
this.requestHeaders = {};
|
||||
this.requestBody = null;
|
||||
this.status = 0;
|
||||
this.statusText = "";
|
||||
this.upload = new UploadProgress();
|
||||
this.responseType = "";
|
||||
this.response = "";
|
||||
if (sinonXhr.supportsCORS) {
|
||||
this.withCredentials = false;
|
||||
}
|
||||
|
||||
var xhr = this;
|
||||
var events = ["loadstart", "load", "abort", "loadend"];
|
||||
|
||||
function addEventListener(eventName) {
|
||||
xhr.addEventListener(eventName, function (event) {
|
||||
var listener = xhr["on" + eventName];
|
||||
|
||||
if (listener && typeof listener === "function") {
|
||||
listener.call(this, event);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
for (var i = events.length - 1; i >= 0; i--) {
|
||||
addEventListener(events[i]);
|
||||
}
|
||||
|
||||
if (typeof FakeXMLHttpRequest.onCreate === "function") {
|
||||
FakeXMLHttpRequest.onCreate(this);
|
||||
}
|
||||
}
|
||||
|
||||
function verifyState(xhr) {
|
||||
if (xhr.readyState !== FakeXMLHttpRequest.OPENED) {
|
||||
throw new Error("INVALID_STATE_ERR");
|
||||
}
|
||||
|
||||
if (xhr.sendFlag) {
|
||||
throw new Error("INVALID_STATE_ERR");
|
||||
}
|
||||
}
|
||||
|
||||
function getHeader(headers, header) {
|
||||
header = header.toLowerCase();
|
||||
|
||||
for (var h in headers) {
|
||||
if (h.toLowerCase() === header) {
|
||||
return h;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// filtering to enable a white-list version of Sinon FakeXhr,
|
||||
// where whitelisted requests are passed through to real XHR
|
||||
function each(collection, callback) {
|
||||
if (!collection) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = 0, l = collection.length; i < l; i += 1) {
|
||||
callback(collection[i]);
|
||||
}
|
||||
}
|
||||
function some(collection, callback) {
|
||||
for (var index = 0; index < collection.length; index++) {
|
||||
if (callback(collection[index]) === true) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// largest arity in XHR is 5 - XHR#open
|
||||
var apply = function (obj, method, args) {
|
||||
switch (args.length) {
|
||||
case 0: return obj[method]();
|
||||
case 1: return obj[method](args[0]);
|
||||
case 2: return obj[method](args[0], args[1]);
|
||||
case 3: return obj[method](args[0], args[1], args[2]);
|
||||
case 4: return obj[method](args[0], args[1], args[2], args[3]);
|
||||
case 5: return obj[method](args[0], args[1], args[2], args[3], args[4]);
|
||||
}
|
||||
};
|
||||
|
||||
FakeXMLHttpRequest.filters = [];
|
||||
FakeXMLHttpRequest.addFilter = function addFilter(fn) {
|
||||
this.filters.push(fn);
|
||||
};
|
||||
var IE6Re = /MSIE 6/;
|
||||
FakeXMLHttpRequest.defake = function defake(fakeXhr, xhrArgs) {
|
||||
var xhr = new sinonXhr.workingXHR(); // eslint-disable-line new-cap
|
||||
|
||||
each([
|
||||
"open",
|
||||
"setRequestHeader",
|
||||
"send",
|
||||
"abort",
|
||||
"getResponseHeader",
|
||||
"getAllResponseHeaders",
|
||||
"addEventListener",
|
||||
"overrideMimeType",
|
||||
"removeEventListener"
|
||||
], function (method) {
|
||||
fakeXhr[method] = function () {
|
||||
return apply(xhr, method, arguments);
|
||||
};
|
||||
});
|
||||
|
||||
var copyAttrs = function (args) {
|
||||
each(args, function (attr) {
|
||||
try {
|
||||
fakeXhr[attr] = xhr[attr];
|
||||
} catch (e) {
|
||||
if (!IE6Re.test(navigator.userAgent)) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
var stateChange = function stateChange() {
|
||||
fakeXhr.readyState = xhr.readyState;
|
||||
if (xhr.readyState >= FakeXMLHttpRequest.HEADERS_RECEIVED) {
|
||||
copyAttrs(["status", "statusText"]);
|
||||
}
|
||||
if (xhr.readyState >= FakeXMLHttpRequest.LOADING) {
|
||||
copyAttrs(["responseText", "response"]);
|
||||
}
|
||||
if (xhr.readyState === FakeXMLHttpRequest.DONE) {
|
||||
copyAttrs(["responseXML"]);
|
||||
}
|
||||
if (fakeXhr.onreadystatechange) {
|
||||
fakeXhr.onreadystatechange.call(fakeXhr, { target: fakeXhr });
|
||||
}
|
||||
};
|
||||
|
||||
if (xhr.addEventListener) {
|
||||
for (var event in fakeXhr.eventListeners) {
|
||||
if (fakeXhr.eventListeners.hasOwnProperty(event)) {
|
||||
|
||||
/*eslint-disable no-loop-func*/
|
||||
each(fakeXhr.eventListeners[event], function (handler) {
|
||||
xhr.addEventListener(event, handler);
|
||||
});
|
||||
/*eslint-enable no-loop-func*/
|
||||
}
|
||||
}
|
||||
xhr.addEventListener("readystatechange", stateChange);
|
||||
} else {
|
||||
xhr.onreadystatechange = stateChange;
|
||||
}
|
||||
apply(xhr, "open", xhrArgs);
|
||||
};
|
||||
FakeXMLHttpRequest.useFilters = false;
|
||||
|
||||
function verifyRequestOpened(xhr) {
|
||||
if (xhr.readyState !== FakeXMLHttpRequest.OPENED) {
|
||||
throw new Error("INVALID_STATE_ERR - " + xhr.readyState);
|
||||
}
|
||||
}
|
||||
|
||||
function verifyRequestSent(xhr) {
|
||||
if (xhr.readyState === FakeXMLHttpRequest.DONE) {
|
||||
throw new Error("Request done");
|
||||
}
|
||||
}
|
||||
|
||||
function verifyHeadersReceived(xhr) {
|
||||
if (xhr.async && xhr.readyState !== FakeXMLHttpRequest.HEADERS_RECEIVED) {
|
||||
throw new Error("No headers received");
|
||||
}
|
||||
}
|
||||
|
||||
function verifyResponseBodyType(body) {
|
||||
if (typeof body !== "string") {
|
||||
var error = new Error("Attempted to respond to fake XMLHttpRequest with " +
|
||||
body + ", which is not a string.");
|
||||
error.name = "InvalidBodyException";
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
function convertToArrayBuffer(body) {
|
||||
var buffer = new ArrayBuffer(body.length);
|
||||
var view = new Uint8Array(buffer);
|
||||
for (var i = 0; i < body.length; i++) {
|
||||
var charCode = body.charCodeAt(i);
|
||||
if (charCode >= 256) {
|
||||
throw new TypeError("arraybuffer or blob responseTypes require binary string, " +
|
||||
"invalid character " + body[i] + " found.");
|
||||
}
|
||||
view[i] = charCode;
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
function isXmlContentType(contentType) {
|
||||
return !contentType || /(text\/xml)|(application\/xml)|(\+xml)/.test(contentType);
|
||||
}
|
||||
|
||||
function convertResponseBody(responseType, contentType, body) {
|
||||
if (responseType === "" || responseType === "text") {
|
||||
return body;
|
||||
} else if (supportsArrayBuffer && responseType === "arraybuffer") {
|
||||
return convertToArrayBuffer(body);
|
||||
} else if (responseType === "json") {
|
||||
try {
|
||||
return JSON.parse(body);
|
||||
} catch (e) {
|
||||
// Return parsing failure as null
|
||||
return null;
|
||||
}
|
||||
} else if (supportsBlob && responseType === "blob") {
|
||||
var blobOptions = {};
|
||||
if (contentType) {
|
||||
blobOptions.type = contentType;
|
||||
}
|
||||
return new Blob([convertToArrayBuffer(body)], blobOptions);
|
||||
} else if (responseType === "document") {
|
||||
if (isXmlContentType(contentType)) {
|
||||
return FakeXMLHttpRequest.parseXML(body);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
throw new Error("Invalid responseType " + responseType);
|
||||
}
|
||||
|
||||
function clearResponse(xhr) {
|
||||
if (xhr.responseType === "" || xhr.responseType === "text") {
|
||||
xhr.response = xhr.responseText = "";
|
||||
} else {
|
||||
xhr.response = xhr.responseText = null;
|
||||
}
|
||||
xhr.responseXML = null;
|
||||
}
|
||||
|
||||
FakeXMLHttpRequest.parseXML = function parseXML(text) {
|
||||
// Treat empty string as parsing failure
|
||||
if (text !== "") {
|
||||
try {
|
||||
if (typeof DOMParser !== "undefined") {
|
||||
var parser = new DOMParser();
|
||||
return parser.parseFromString(text, "text/xml");
|
||||
}
|
||||
var xmlDoc = new window.ActiveXObject("Microsoft.XMLDOM");
|
||||
xmlDoc.async = "false";
|
||||
xmlDoc.loadXML(text);
|
||||
return xmlDoc;
|
||||
} catch (e) {
|
||||
// Unable to parse XML - no biggie
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
FakeXMLHttpRequest.statusCodes = {
|
||||
100: "Continue",
|
||||
101: "Switching Protocols",
|
||||
200: "OK",
|
||||
201: "Created",
|
||||
202: "Accepted",
|
||||
203: "Non-Authoritative Information",
|
||||
204: "No Content",
|
||||
205: "Reset Content",
|
||||
206: "Partial Content",
|
||||
207: "Multi-Status",
|
||||
300: "Multiple Choice",
|
||||
301: "Moved Permanently",
|
||||
302: "Found",
|
||||
303: "See Other",
|
||||
304: "Not Modified",
|
||||
305: "Use Proxy",
|
||||
307: "Temporary Redirect",
|
||||
400: "Bad Request",
|
||||
401: "Unauthorized",
|
||||
402: "Payment Required",
|
||||
403: "Forbidden",
|
||||
404: "Not Found",
|
||||
405: "Method Not Allowed",
|
||||
406: "Not Acceptable",
|
||||
407: "Proxy Authentication Required",
|
||||
408: "Request Timeout",
|
||||
409: "Conflict",
|
||||
410: "Gone",
|
||||
411: "Length Required",
|
||||
412: "Precondition Failed",
|
||||
413: "Request Entity Too Large",
|
||||
414: "Request-URI Too Long",
|
||||
415: "Unsupported Media Type",
|
||||
416: "Requested Range Not Satisfiable",
|
||||
417: "Expectation Failed",
|
||||
422: "Unprocessable Entity",
|
||||
500: "Internal Server Error",
|
||||
501: "Not Implemented",
|
||||
502: "Bad Gateway",
|
||||
503: "Service Unavailable",
|
||||
504: "Gateway Timeout",
|
||||
505: "HTTP Version Not Supported"
|
||||
};
|
||||
|
||||
function makeApi(sinon) {
|
||||
sinon.xhr = sinonXhr;
|
||||
|
||||
sinon.extend(FakeXMLHttpRequest.prototype, sinon.EventTarget, {
|
||||
async: true,
|
||||
|
||||
open: function open(method, url, async, username, password) {
|
||||
this.method = method;
|
||||
this.url = url;
|
||||
this.async = typeof async === "boolean" ? async : true;
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
clearResponse(this);
|
||||
this.requestHeaders = {};
|
||||
this.sendFlag = false;
|
||||
|
||||
if (FakeXMLHttpRequest.useFilters === true) {
|
||||
var xhrArgs = arguments;
|
||||
var defake = some(FakeXMLHttpRequest.filters, function (filter) {
|
||||
return filter.apply(this, xhrArgs);
|
||||
});
|
||||
if (defake) {
|
||||
return FakeXMLHttpRequest.defake(this, arguments);
|
||||
}
|
||||
}
|
||||
this.readyStateChange(FakeXMLHttpRequest.OPENED);
|
||||
},
|
||||
|
||||
readyStateChange: function readyStateChange(state) {
|
||||
this.readyState = state;
|
||||
|
||||
var readyStateChangeEvent = new sinon.Event("readystatechange", false, false, this);
|
||||
|
||||
if (typeof this.onreadystatechange === "function") {
|
||||
try {
|
||||
this.onreadystatechange(readyStateChangeEvent);
|
||||
} catch (e) {
|
||||
sinon.logError("Fake XHR onreadystatechange handler", e);
|
||||
}
|
||||
}
|
||||
|
||||
switch (this.readyState) {
|
||||
case FakeXMLHttpRequest.DONE:
|
||||
if (supportsProgress) {
|
||||
this.upload.dispatchEvent(new sinon.ProgressEvent("progress", {loaded: 100, total: 100}));
|
||||
this.dispatchEvent(new sinon.ProgressEvent("progress", {loaded: 100, total: 100}));
|
||||
}
|
||||
this.upload.dispatchEvent(new sinon.Event("load", false, false, this));
|
||||
this.dispatchEvent(new sinon.Event("load", false, false, this));
|
||||
this.dispatchEvent(new sinon.Event("loadend", false, false, this));
|
||||
break;
|
||||
}
|
||||
|
||||
this.dispatchEvent(readyStateChangeEvent);
|
||||
},
|
||||
|
||||
setRequestHeader: function setRequestHeader(header, value) {
|
||||
verifyState(this);
|
||||
|
||||
if (unsafeHeaders[header] || /^(Sec-|Proxy-)/.test(header)) {
|
||||
throw new Error("Refused to set unsafe header \"" + header + "\"");
|
||||
}
|
||||
|
||||
if (this.requestHeaders[header]) {
|
||||
this.requestHeaders[header] += "," + value;
|
||||
} else {
|
||||
this.requestHeaders[header] = value;
|
||||
}
|
||||
},
|
||||
|
||||
// Helps testing
|
||||
setResponseHeaders: function setResponseHeaders(headers) {
|
||||
verifyRequestOpened(this);
|
||||
this.responseHeaders = {};
|
||||
|
||||
for (var header in headers) {
|
||||
if (headers.hasOwnProperty(header)) {
|
||||
this.responseHeaders[header] = headers[header];
|
||||
}
|
||||
}
|
||||
|
||||
if (this.async) {
|
||||
this.readyStateChange(FakeXMLHttpRequest.HEADERS_RECEIVED);
|
||||
} else {
|
||||
this.readyState = FakeXMLHttpRequest.HEADERS_RECEIVED;
|
||||
}
|
||||
},
|
||||
|
||||
// Currently treats ALL data as a DOMString (i.e. no Document)
|
||||
send: function send(data) {
|
||||
verifyState(this);
|
||||
|
||||
if (!/^(get|head)$/i.test(this.method)) {
|
||||
var contentType = getHeader(this.requestHeaders, "Content-Type");
|
||||
if (this.requestHeaders[contentType]) {
|
||||
var value = this.requestHeaders[contentType].split(";");
|
||||
this.requestHeaders[contentType] = value[0] + ";charset=utf-8";
|
||||
} else if (supportsFormData && !(data instanceof FormData)) {
|
||||
this.requestHeaders["Content-Type"] = "text/plain;charset=utf-8";
|
||||
}
|
||||
|
||||
this.requestBody = data;
|
||||
}
|
||||
|
||||
this.errorFlag = false;
|
||||
this.sendFlag = this.async;
|
||||
clearResponse(this);
|
||||
this.readyStateChange(FakeXMLHttpRequest.OPENED);
|
||||
|
||||
if (typeof this.onSend === "function") {
|
||||
this.onSend(this);
|
||||
}
|
||||
|
||||
this.dispatchEvent(new sinon.Event("loadstart", false, false, this));
|
||||
},
|
||||
|
||||
abort: function abort() {
|
||||
this.aborted = true;
|
||||
clearResponse(this);
|
||||
this.errorFlag = true;
|
||||
this.requestHeaders = {};
|
||||
this.responseHeaders = {};
|
||||
|
||||
if (this.readyState > FakeXMLHttpRequest.UNSENT && this.sendFlag) {
|
||||
this.readyStateChange(FakeXMLHttpRequest.DONE);
|
||||
this.sendFlag = false;
|
||||
}
|
||||
|
||||
this.readyState = FakeXMLHttpRequest.UNSENT;
|
||||
|
||||
this.dispatchEvent(new sinon.Event("abort", false, false, this));
|
||||
|
||||
this.upload.dispatchEvent(new sinon.Event("abort", false, false, this));
|
||||
|
||||
if (typeof this.onerror === "function") {
|
||||
this.onerror();
|
||||
}
|
||||
},
|
||||
|
||||
getResponseHeader: function getResponseHeader(header) {
|
||||
if (this.readyState < FakeXMLHttpRequest.HEADERS_RECEIVED) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (/^Set-Cookie2?$/i.test(header)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
header = getHeader(this.responseHeaders, header);
|
||||
|
||||
return this.responseHeaders[header] || null;
|
||||
},
|
||||
|
||||
getAllResponseHeaders: function getAllResponseHeaders() {
|
||||
if (this.readyState < FakeXMLHttpRequest.HEADERS_RECEIVED) {
|
||||
return "";
|
||||
}
|
||||
|
||||
var headers = "";
|
||||
|
||||
for (var header in this.responseHeaders) {
|
||||
if (this.responseHeaders.hasOwnProperty(header) &&
|
||||
!/^Set-Cookie2?$/i.test(header)) {
|
||||
headers += header + ": " + this.responseHeaders[header] + "\r\n";
|
||||
}
|
||||
}
|
||||
|
||||
return headers;
|
||||
},
|
||||
|
||||
setResponseBody: function setResponseBody(body) {
|
||||
verifyRequestSent(this);
|
||||
verifyHeadersReceived(this);
|
||||
verifyResponseBodyType(body);
|
||||
var contentType = this.getResponseHeader("Content-Type");
|
||||
|
||||
var isTextResponse = this.responseType === "" || this.responseType === "text";
|
||||
clearResponse(this);
|
||||
if (this.async) {
|
||||
var chunkSize = this.chunkSize || 10;
|
||||
var index = 0;
|
||||
|
||||
do {
|
||||
this.readyStateChange(FakeXMLHttpRequest.LOADING);
|
||||
|
||||
if (isTextResponse) {
|
||||
this.responseText = this.response += body.substring(index, index + chunkSize);
|
||||
}
|
||||
index += chunkSize;
|
||||
} while (index < body.length);
|
||||
}
|
||||
|
||||
this.response = convertResponseBody(this.responseType, contentType, body);
|
||||
if (isTextResponse) {
|
||||
this.responseText = this.response;
|
||||
}
|
||||
|
||||
if (this.responseType === "document") {
|
||||
this.responseXML = this.response;
|
||||
} else if (this.responseType === "" && isXmlContentType(contentType)) {
|
||||
this.responseXML = FakeXMLHttpRequest.parseXML(this.responseText);
|
||||
}
|
||||
this.readyStateChange(FakeXMLHttpRequest.DONE);
|
||||
},
|
||||
|
||||
respond: function respond(status, headers, body) {
|
||||
this.status = typeof status === "number" ? status : 200;
|
||||
this.statusText = FakeXMLHttpRequest.statusCodes[this.status];
|
||||
this.setResponseHeaders(headers || {});
|
||||
this.setResponseBody(body || "");
|
||||
},
|
||||
|
||||
uploadProgress: function uploadProgress(progressEventRaw) {
|
||||
if (supportsProgress) {
|
||||
this.upload.dispatchEvent(new sinon.ProgressEvent("progress", progressEventRaw));
|
||||
}
|
||||
},
|
||||
|
||||
downloadProgress: function downloadProgress(progressEventRaw) {
|
||||
if (supportsProgress) {
|
||||
this.dispatchEvent(new sinon.ProgressEvent("progress", progressEventRaw));
|
||||
}
|
||||
},
|
||||
|
||||
uploadError: function uploadError(error) {
|
||||
if (supportsCustomEvent) {
|
||||
this.upload.dispatchEvent(new sinon.CustomEvent("error", {detail: error}));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
sinon.extend(FakeXMLHttpRequest, {
|
||||
UNSENT: 0,
|
||||
OPENED: 1,
|
||||
HEADERS_RECEIVED: 2,
|
||||
LOADING: 3,
|
||||
DONE: 4
|
||||
});
|
||||
|
||||
sinon.useFakeXMLHttpRequest = function () {
|
||||
FakeXMLHttpRequest.restore = function restore(keepOnCreate) {
|
||||
if (sinonXhr.supportsXHR) {
|
||||
global.XMLHttpRequest = sinonXhr.GlobalXMLHttpRequest;
|
||||
}
|
||||
|
||||
if (sinonXhr.supportsActiveX) {
|
||||
global.ActiveXObject = sinonXhr.GlobalActiveXObject;
|
||||
}
|
||||
|
||||
delete FakeXMLHttpRequest.restore;
|
||||
|
||||
if (keepOnCreate !== true) {
|
||||
delete FakeXMLHttpRequest.onCreate;
|
||||
}
|
||||
};
|
||||
if (sinonXhr.supportsXHR) {
|
||||
global.XMLHttpRequest = FakeXMLHttpRequest;
|
||||
}
|
||||
|
||||
if (sinonXhr.supportsActiveX) {
|
||||
global.ActiveXObject = function ActiveXObject(objId) {
|
||||
if (objId === "Microsoft.XMLHTTP" || /^Msxml2\.XMLHTTP/i.test(objId)) {
|
||||
|
||||
return new FakeXMLHttpRequest();
|
||||
}
|
||||
|
||||
return new sinonXhr.GlobalActiveXObject(objId);
|
||||
};
|
||||
}
|
||||
|
||||
return FakeXMLHttpRequest;
|
||||
};
|
||||
|
||||
sinon.FakeXMLHttpRequest = FakeXMLHttpRequest;
|
||||
}
|
||||
|
||||
var isNode = typeof module !== "undefined" && module.exports && typeof require === "function";
|
||||
var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
|
||||
|
||||
function loadDependencies(require, exports, module) {
|
||||
var sinon = require("./core");
|
||||
require("../extend");
|
||||
require("./event");
|
||||
require("../log_error");
|
||||
makeApi(sinon);
|
||||
module.exports = sinon;
|
||||
}
|
||||
|
||||
if (isAMD) {
|
||||
define(loadDependencies);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isNode) {
|
||||
loadDependencies(require, module.exports, module);
|
||||
return;
|
||||
}
|
||||
|
||||
if (sinonGlobal) {
|
||||
makeApi(sinonGlobal);
|
||||
}
|
||||
}(
|
||||
typeof sinon === "object" && sinon, // eslint-disable-line no-undef
|
||||
typeof global !== "undefined" ? global : self
|
||||
));
|
||||
|
||||
/**
|
||||
* @depend fake_xdomain_request.js
|
||||
* @depend fake_xml_http_request.js
|
||||
* @depend ../format.js
|
||||
* @depend ../log_error.js
|
||||
*/
|
||||
/**
|
||||
* The Sinon "server" mimics a web server that receives requests from
|
||||
* sinon.FakeXMLHttpRequest and provides an API to respond to those requests,
|
||||
* both synchronously and asynchronously. To respond synchronuously, canned
|
||||
* answers have to be provided upfront.
|
||||
*
|
||||
* @author Christian Johansen (christian@cjohansen.no)
|
||||
* @license BSD
|
||||
*
|
||||
* Copyright (c) 2010-2013 Christian Johansen
|
||||
*/
|
||||
(function () {
|
||||
|
||||
var push = [].push;
|
||||
|
||||
function responseArray(handler) {
|
||||
var response = handler;
|
||||
|
||||
if (Object.prototype.toString.call(handler) !== "[object Array]") {
|
||||
response = [200, {}, handler];
|
||||
}
|
||||
|
||||
if (typeof response[2] !== "string") {
|
||||
throw new TypeError("Fake server response body should be string, but was " +
|
||||
typeof response[2]);
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
var wloc = typeof window !== "undefined" ? window.location : {};
|
||||
var rCurrLoc = new RegExp("^" + wloc.protocol + "//" + wloc.host);
|
||||
|
||||
function matchOne(response, reqMethod, reqUrl) {
|
||||
var rmeth = response.method;
|
||||
var matchMethod = !rmeth || rmeth.toLowerCase() === reqMethod.toLowerCase();
|
||||
var url = response.url;
|
||||
var matchUrl = !url || url === reqUrl || (typeof url.test === "function" && url.test(reqUrl));
|
||||
|
||||
return matchMethod && matchUrl;
|
||||
}
|
||||
|
||||
function match(response, request) {
|
||||
var requestUrl = request.url;
|
||||
|
||||
if (!/^https?:\/\//.test(requestUrl) || rCurrLoc.test(requestUrl)) {
|
||||
requestUrl = requestUrl.replace(rCurrLoc, "");
|
||||
}
|
||||
|
||||
if (matchOne(response, this.getHTTPMethod(request), requestUrl)) {
|
||||
if (typeof response.response === "function") {
|
||||
var ru = response.url;
|
||||
var args = [request].concat(ru && typeof ru.exec === "function" ? ru.exec(requestUrl).slice(1) : []);
|
||||
return response.response.apply(response, args);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function makeApi(sinon) {
|
||||
sinon.fakeServer = {
|
||||
create: function (config) {
|
||||
var server = sinon.create(this);
|
||||
server.configure(config);
|
||||
if (!sinon.xhr.supportsCORS) {
|
||||
this.xhr = sinon.useFakeXDomainRequest();
|
||||
} else {
|
||||
this.xhr = sinon.useFakeXMLHttpRequest();
|
||||
}
|
||||
server.requests = [];
|
||||
|
||||
this.xhr.onCreate = function (xhrObj) {
|
||||
server.addRequest(xhrObj);
|
||||
};
|
||||
|
||||
return server;
|
||||
},
|
||||
configure: function (config) {
|
||||
var whitelist = {
|
||||
"autoRespond": true,
|
||||
"autoRespondAfter": true,
|
||||
"respondImmediately": true,
|
||||
"fakeHTTPMethods": true
|
||||
};
|
||||
var setting;
|
||||
|
||||
config = config || {};
|
||||
for (setting in config) {
|
||||
if (whitelist.hasOwnProperty(setting) && config.hasOwnProperty(setting)) {
|
||||
this[setting] = config[setting];
|
||||
}
|
||||
}
|
||||
},
|
||||
addRequest: function addRequest(xhrObj) {
|
||||
var server = this;
|
||||
push.call(this.requests, xhrObj);
|
||||
|
||||
xhrObj.onSend = function () {
|
||||
server.handleRequest(this);
|
||||
|
||||
if (server.respondImmediately) {
|
||||
server.respond();
|
||||
} else if (server.autoRespond && !server.responding) {
|
||||
setTimeout(function () {
|
||||
server.responding = false;
|
||||
server.respond();
|
||||
}, server.autoRespondAfter || 10);
|
||||
|
||||
server.responding = true;
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
getHTTPMethod: function getHTTPMethod(request) {
|
||||
if (this.fakeHTTPMethods && /post/i.test(request.method)) {
|
||||
var matches = (request.requestBody || "").match(/_method=([^\b;]+)/);
|
||||
return matches ? matches[1] : request.method;
|
||||
}
|
||||
|
||||
return request.method;
|
||||
},
|
||||
|
||||
handleRequest: function handleRequest(xhr) {
|
||||
if (xhr.async) {
|
||||
if (!this.queue) {
|
||||
this.queue = [];
|
||||
}
|
||||
|
||||
push.call(this.queue, xhr);
|
||||
} else {
|
||||
this.processRequest(xhr);
|
||||
}
|
||||
},
|
||||
|
||||
log: function log(response, request) {
|
||||
var str;
|
||||
|
||||
str = "Request:\n" + sinon.format(request) + "\n\n";
|
||||
str += "Response:\n" + sinon.format(response) + "\n\n";
|
||||
|
||||
sinon.log(str);
|
||||
},
|
||||
|
||||
respondWith: function respondWith(method, url, body) {
|
||||
if (arguments.length === 1 && typeof method !== "function") {
|
||||
this.response = responseArray(method);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.responses) {
|
||||
this.responses = [];
|
||||
}
|
||||
|
||||
if (arguments.length === 1) {
|
||||
body = method;
|
||||
url = method = null;
|
||||
}
|
||||
|
||||
if (arguments.length === 2) {
|
||||
body = url;
|
||||
url = method;
|
||||
method = null;
|
||||
}
|
||||
|
||||
push.call(this.responses, {
|
||||
method: method,
|
||||
url: url,
|
||||
response: typeof body === "function" ? body : responseArray(body)
|
||||
});
|
||||
},
|
||||
|
||||
respond: function respond() {
|
||||
if (arguments.length > 0) {
|
||||
this.respondWith.apply(this, arguments);
|
||||
}
|
||||
|
||||
var queue = this.queue || [];
|
||||
var requests = queue.splice(0, queue.length);
|
||||
|
||||
for (var i = 0; i < requests.length; i++) {
|
||||
this.processRequest(requests[i]);
|
||||
}
|
||||
},
|
||||
|
||||
processRequest: function processRequest(request) {
|
||||
try {
|
||||
if (request.aborted) {
|
||||
return;
|
||||
}
|
||||
|
||||
var response = this.response || [404, {}, ""];
|
||||
|
||||
if (this.responses) {
|
||||
for (var l = this.responses.length, i = l - 1; i >= 0; i--) {
|
||||
if (match.call(this, this.responses[i], request)) {
|
||||
response = this.responses[i].response;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (request.readyState !== 4) {
|
||||
this.log(response, request);
|
||||
|
||||
request.respond(response[0], response[1], response[2]);
|
||||
}
|
||||
} catch (e) {
|
||||
sinon.logError("Fake server request processing", e);
|
||||
}
|
||||
},
|
||||
|
||||
restore: function restore() {
|
||||
return this.xhr.restore && this.xhr.restore.apply(this.xhr, arguments);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
var isNode = typeof module !== "undefined" && module.exports && typeof require === "function";
|
||||
var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
|
||||
|
||||
function loadDependencies(require, exports, module) {
|
||||
var sinon = require("./core");
|
||||
require("./fake_xdomain_request");
|
||||
require("./fake_xml_http_request");
|
||||
require("../format");
|
||||
makeApi(sinon);
|
||||
module.exports = sinon;
|
||||
}
|
||||
|
||||
if (isAMD) {
|
||||
define(loadDependencies);
|
||||
} else if (isNode) {
|
||||
loadDependencies(require, module.exports, module);
|
||||
} else {
|
||||
makeApi(sinon); // eslint-disable-line no-undef
|
||||
}
|
||||
}());
|
||||
|
||||
/**
|
||||
* @depend fake_server.js
|
||||
* @depend fake_timers.js
|
||||
*/
|
||||
/**
|
||||
* Add-on for sinon.fakeServer that automatically handles a fake timer along with
|
||||
* the FakeXMLHttpRequest. The direct inspiration for this add-on is jQuery
|
||||
* 1.3.x, which does not use xhr object's onreadystatehandler at all - instead,
|
||||
* it polls the object for completion with setInterval. Dispite the direct
|
||||
* motivation, there is nothing jQuery-specific in this file, so it can be used
|
||||
* in any environment where the ajax implementation depends on setInterval or
|
||||
* setTimeout.
|
||||
*
|
||||
* @author Christian Johansen (christian@cjohansen.no)
|
||||
* @license BSD
|
||||
*
|
||||
* Copyright (c) 2010-2013 Christian Johansen
|
||||
*/
|
||||
(function () {
|
||||
|
||||
function makeApi(sinon) {
|
||||
function Server() {}
|
||||
Server.prototype = sinon.fakeServer;
|
||||
|
||||
sinon.fakeServerWithClock = new Server();
|
||||
|
||||
sinon.fakeServerWithClock.addRequest = function addRequest(xhr) {
|
||||
if (xhr.async) {
|
||||
if (typeof setTimeout.clock === "object") {
|
||||
this.clock = setTimeout.clock;
|
||||
} else {
|
||||
this.clock = sinon.useFakeTimers();
|
||||
this.resetClock = true;
|
||||
}
|
||||
|
||||
if (!this.longestTimeout) {
|
||||
var clockSetTimeout = this.clock.setTimeout;
|
||||
var clockSetInterval = this.clock.setInterval;
|
||||
var server = this;
|
||||
|
||||
this.clock.setTimeout = function (fn, timeout) {
|
||||
server.longestTimeout = Math.max(timeout, server.longestTimeout || 0);
|
||||
|
||||
return clockSetTimeout.apply(this, arguments);
|
||||
};
|
||||
|
||||
this.clock.setInterval = function (fn, timeout) {
|
||||
server.longestTimeout = Math.max(timeout, server.longestTimeout || 0);
|
||||
|
||||
return clockSetInterval.apply(this, arguments);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return sinon.fakeServer.addRequest.call(this, xhr);
|
||||
};
|
||||
|
||||
sinon.fakeServerWithClock.respond = function respond() {
|
||||
var returnVal = sinon.fakeServer.respond.apply(this, arguments);
|
||||
|
||||
if (this.clock) {
|
||||
this.clock.tick(this.longestTimeout || 0);
|
||||
this.longestTimeout = 0;
|
||||
|
||||
if (this.resetClock) {
|
||||
this.clock.restore();
|
||||
this.resetClock = false;
|
||||
}
|
||||
}
|
||||
|
||||
return returnVal;
|
||||
};
|
||||
|
||||
sinon.fakeServerWithClock.restore = function restore() {
|
||||
if (this.clock) {
|
||||
this.clock.restore();
|
||||
}
|
||||
|
||||
return sinon.fakeServer.restore.apply(this, arguments);
|
||||
};
|
||||
}
|
||||
|
||||
var isNode = typeof module !== "undefined" && module.exports && typeof require === "function";
|
||||
var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
|
||||
|
||||
function loadDependencies(require) {
|
||||
var sinon = require("./core");
|
||||
require("./fake_server");
|
||||
require("./fake_timers");
|
||||
makeApi(sinon);
|
||||
}
|
||||
|
||||
if (isAMD) {
|
||||
define(loadDependencies);
|
||||
} else if (isNode) {
|
||||
loadDependencies(require);
|
||||
} else {
|
||||
makeApi(sinon); // eslint-disable-line no-undef
|
||||
}
|
||||
}());
|
||||
|
||||
/**
|
||||
* @depend util/core.js
|
||||
* @depend extend.js
|
||||
* @depend collection.js
|
||||
* @depend util/fake_timers.js
|
||||
* @depend util/fake_server_with_clock.js
|
||||
*/
|
||||
/**
|
||||
* Manages fake collections as well as fake utilities such as Sinon's
|
||||
* timers and fake XHR implementation in one convenient object.
|
||||
*
|
||||
* @author Christian Johansen (christian@cjohansen.no)
|
||||
* @license BSD
|
||||
*
|
||||
* Copyright (c) 2010-2013 Christian Johansen
|
||||
*/
|
||||
(function (sinonGlobal) {
|
||||
|
||||
function makeApi(sinon) {
|
||||
var push = [].push;
|
||||
|
||||
function exposeValue(sandbox, config, key, value) {
|
||||
if (!value) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (config.injectInto && !(key in config.injectInto)) {
|
||||
config.injectInto[key] = value;
|
||||
sandbox.injectedKeys.push(key);
|
||||
} else {
|
||||
push.call(sandbox.args, value);
|
||||
}
|
||||
}
|
||||
|
||||
function prepareSandboxFromConfig(config) {
|
||||
var sandbox = sinon.create(sinon.sandbox);
|
||||
|
||||
if (config.useFakeServer) {
|
||||
if (typeof config.useFakeServer === "object") {
|
||||
sandbox.serverPrototype = config.useFakeServer;
|
||||
}
|
||||
|
||||
sandbox.useFakeServer();
|
||||
}
|
||||
|
||||
if (config.useFakeTimers) {
|
||||
if (typeof config.useFakeTimers === "object") {
|
||||
sandbox.useFakeTimers.apply(sandbox, config.useFakeTimers);
|
||||
} else {
|
||||
sandbox.useFakeTimers();
|
||||
}
|
||||
}
|
||||
|
||||
return sandbox;
|
||||
}
|
||||
|
||||
sinon.sandbox = sinon.extend(sinon.create(sinon.collection), {
|
||||
useFakeTimers: function useFakeTimers() {
|
||||
this.clock = sinon.useFakeTimers.apply(sinon, arguments);
|
||||
|
||||
return this.add(this.clock);
|
||||
},
|
||||
|
||||
serverPrototype: sinon.fakeServer,
|
||||
|
||||
useFakeServer: function useFakeServer() {
|
||||
var proto = this.serverPrototype || sinon.fakeServer;
|
||||
|
||||
if (!proto || !proto.create) {
|
||||
return null;
|
||||
}
|
||||
|
||||
this.server = proto.create();
|
||||
return this.add(this.server);
|
||||
},
|
||||
|
||||
inject: function (obj) {
|
||||
sinon.collection.inject.call(this, obj);
|
||||
|
||||
if (this.clock) {
|
||||
obj.clock = this.clock;
|
||||
}
|
||||
|
||||
if (this.server) {
|
||||
obj.server = this.server;
|
||||
obj.requests = this.server.requests;
|
||||
}
|
||||
|
||||
obj.match = sinon.match;
|
||||
|
||||
return obj;
|
||||
},
|
||||
|
||||
restore: function () {
|
||||
sinon.collection.restore.apply(this, arguments);
|
||||
this.restoreContext();
|
||||
},
|
||||
|
||||
restoreContext: function () {
|
||||
if (this.injectedKeys) {
|
||||
for (var i = 0, j = this.injectedKeys.length; i < j; i++) {
|
||||
delete this.injectInto[this.injectedKeys[i]];
|
||||
}
|
||||
this.injectedKeys = [];
|
||||
}
|
||||
},
|
||||
|
||||
create: function (config) {
|
||||
if (!config) {
|
||||
return sinon.create(sinon.sandbox);
|
||||
}
|
||||
|
||||
var sandbox = prepareSandboxFromConfig(config);
|
||||
sandbox.args = sandbox.args || [];
|
||||
sandbox.injectedKeys = [];
|
||||
sandbox.injectInto = config.injectInto;
|
||||
var prop,
|
||||
value;
|
||||
var exposed = sandbox.inject({});
|
||||
|
||||
if (config.properties) {
|
||||
for (var i = 0, l = config.properties.length; i < l; i++) {
|
||||
prop = config.properties[i];
|
||||
value = exposed[prop] || prop === "sandbox" && sandbox;
|
||||
exposeValue(sandbox, config, prop, value);
|
||||
}
|
||||
} else {
|
||||
exposeValue(sandbox, config, "sandbox", value);
|
||||
}
|
||||
|
||||
return sandbox;
|
||||
},
|
||||
|
||||
match: sinon.match
|
||||
});
|
||||
|
||||
sinon.sandbox.useFakeXMLHttpRequest = sinon.sandbox.useFakeServer;
|
||||
|
||||
return sinon.sandbox;
|
||||
}
|
||||
|
||||
var isNode = typeof module !== "undefined" && module.exports && typeof require === "function";
|
||||
var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
|
||||
|
||||
function loadDependencies(require, exports, module) {
|
||||
var sinon = require("./util/core");
|
||||
require("./extend");
|
||||
require("./util/fake_server_with_clock");
|
||||
require("./util/fake_timers");
|
||||
require("./collection");
|
||||
module.exports = makeApi(sinon);
|
||||
}
|
||||
|
||||
if (isAMD) {
|
||||
define(loadDependencies);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isNode) {
|
||||
loadDependencies(require, module.exports, module);
|
||||
return;
|
||||
}
|
||||
|
||||
if (sinonGlobal) {
|
||||
makeApi(sinonGlobal);
|
||||
}
|
||||
}(
|
||||
typeof sinon === "object" && sinon // eslint-disable-line no-undef
|
||||
));
|
||||
|
||||
/**
|
||||
* @depend util/core.js
|
||||
* @depend sandbox.js
|
||||
*/
|
||||
/**
|
||||
* Test function, sandboxes fakes
|
||||
*
|
||||
* @author Christian Johansen (christian@cjohansen.no)
|
||||
* @license BSD
|
||||
*
|
||||
* Copyright (c) 2010-2013 Christian Johansen
|
||||
*/
|
||||
(function (sinonGlobal) {
|
||||
|
||||
function makeApi(sinon) {
|
||||
var slice = Array.prototype.slice;
|
||||
|
||||
function test(callback) {
|
||||
var type = typeof callback;
|
||||
|
||||
if (type !== "function") {
|
||||
throw new TypeError("sinon.test needs to wrap a test function, got " + type);
|
||||
}
|
||||
|
||||
function sinonSandboxedTest() {
|
||||
var config = sinon.getConfig(sinon.config);
|
||||
config.injectInto = config.injectIntoThis && this || config.injectInto;
|
||||
var sandbox = sinon.sandbox.create(config);
|
||||
var args = slice.call(arguments);
|
||||
var oldDone = args.length && args[args.length - 1];
|
||||
var exception, result;
|
||||
|
||||
if (typeof oldDone === "function") {
|
||||
args[args.length - 1] = function sinonDone(res) {
|
||||
if (res) {
|
||||
sandbox.restore();
|
||||
} else {
|
||||
sandbox.verifyAndRestore();
|
||||
}
|
||||
oldDone(res);
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
result = callback.apply(this, args.concat(sandbox.args));
|
||||
} catch (e) {
|
||||
exception = e;
|
||||
}
|
||||
|
||||
if (typeof oldDone !== "function") {
|
||||
if (typeof exception !== "undefined") {
|
||||
sandbox.restore();
|
||||
throw exception;
|
||||
} else {
|
||||
sandbox.verifyAndRestore();
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
if (callback.length) {
|
||||
return function sinonAsyncSandboxedTest(done) { // eslint-disable-line no-unused-vars
|
||||
return sinonSandboxedTest.apply(this, arguments);
|
||||
};
|
||||
}
|
||||
|
||||
return sinonSandboxedTest;
|
||||
}
|
||||
|
||||
test.config = {
|
||||
injectIntoThis: true,
|
||||
injectInto: null,
|
||||
properties: ["spy", "stub", "mock", "clock", "server", "requests"],
|
||||
useFakeTimers: true,
|
||||
useFakeServer: true
|
||||
};
|
||||
|
||||
sinon.test = test;
|
||||
return test;
|
||||
}
|
||||
|
||||
var isNode = typeof module !== "undefined" && module.exports && typeof require === "function";
|
||||
var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
|
||||
|
||||
function loadDependencies(require, exports, module) {
|
||||
var core = require("./util/core");
|
||||
require("./sandbox");
|
||||
module.exports = makeApi(core);
|
||||
}
|
||||
|
||||
if (isAMD) {
|
||||
define(loadDependencies);
|
||||
} else if (isNode) {
|
||||
loadDependencies(require, module.exports, module);
|
||||
} else if (sinonGlobal) {
|
||||
makeApi(sinonGlobal);
|
||||
}
|
||||
}(typeof sinon === "object" && sinon || null)); // eslint-disable-line no-undef
|
||||
|
||||
/**
|
||||
* @depend util/core.js
|
||||
* @depend test.js
|
||||
*/
|
||||
/**
|
||||
* Test case, sandboxes all test functions
|
||||
*
|
||||
* @author Christian Johansen (christian@cjohansen.no)
|
||||
* @license BSD
|
||||
*
|
||||
* Copyright (c) 2010-2013 Christian Johansen
|
||||
*/
|
||||
(function (sinonGlobal) {
|
||||
|
||||
function createTest(property, setUp, tearDown) {
|
||||
return function () {
|
||||
if (setUp) {
|
||||
setUp.apply(this, arguments);
|
||||
}
|
||||
|
||||
var exception, result;
|
||||
|
||||
try {
|
||||
result = property.apply(this, arguments);
|
||||
} catch (e) {
|
||||
exception = e;
|
||||
}
|
||||
|
||||
if (tearDown) {
|
||||
tearDown.apply(this, arguments);
|
||||
}
|
||||
|
||||
if (exception) {
|
||||
throw exception;
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
function makeApi(sinon) {
|
||||
function testCase(tests, prefix) {
|
||||
if (!tests || typeof tests !== "object") {
|
||||
throw new TypeError("sinon.testCase needs an object with test functions");
|
||||
}
|
||||
|
||||
prefix = prefix || "test";
|
||||
var rPrefix = new RegExp("^" + prefix);
|
||||
var methods = {};
|
||||
var setUp = tests.setUp;
|
||||
var tearDown = tests.tearDown;
|
||||
var testName,
|
||||
property,
|
||||
method;
|
||||
|
||||
for (testName in tests) {
|
||||
if (tests.hasOwnProperty(testName) && !/^(setUp|tearDown)$/.test(testName)) {
|
||||
property = tests[testName];
|
||||
|
||||
if (typeof property === "function" && rPrefix.test(testName)) {
|
||||
method = property;
|
||||
|
||||
if (setUp || tearDown) {
|
||||
method = createTest(property, setUp, tearDown);
|
||||
}
|
||||
|
||||
methods[testName] = sinon.test(method);
|
||||
} else {
|
||||
methods[testName] = tests[testName];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return methods;
|
||||
}
|
||||
|
||||
sinon.testCase = testCase;
|
||||
return testCase;
|
||||
}
|
||||
|
||||
var isNode = typeof module !== "undefined" && module.exports && typeof require === "function";
|
||||
var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
|
||||
|
||||
function loadDependencies(require, exports, module) {
|
||||
var core = require("./util/core");
|
||||
require("./test");
|
||||
module.exports = makeApi(core);
|
||||
}
|
||||
|
||||
if (isAMD) {
|
||||
define(loadDependencies);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isNode) {
|
||||
loadDependencies(require, module.exports, module);
|
||||
return;
|
||||
}
|
||||
|
||||
if (sinonGlobal) {
|
||||
makeApi(sinonGlobal);
|
||||
}
|
||||
}(
|
||||
typeof sinon === "object" && sinon // eslint-disable-line no-undef
|
||||
));
|
||||
|
||||
/**
|
||||
* @depend times_in_words.js
|
||||
* @depend util/core.js
|
||||
* @depend match.js
|
||||
* @depend format.js
|
||||
*/
|
||||
/**
|
||||
* Assertions matching the test spy retrieval interface.
|
||||
*
|
||||
* @author Christian Johansen (christian@cjohansen.no)
|
||||
* @license BSD
|
||||
*
|
||||
* Copyright (c) 2010-2013 Christian Johansen
|
||||
*/
|
||||
(function (sinonGlobal, global) {
|
||||
|
||||
var slice = Array.prototype.slice;
|
||||
|
||||
function makeApi(sinon) {
|
||||
var assert;
|
||||
|
||||
function verifyIsStub() {
|
||||
var method;
|
||||
|
||||
for (var i = 0, l = arguments.length; i < l; ++i) {
|
||||
method = arguments[i];
|
||||
|
||||
if (!method) {
|
||||
assert.fail("fake is not a spy");
|
||||
}
|
||||
|
||||
if (method.proxy && method.proxy.isSinonProxy) {
|
||||
verifyIsStub(method.proxy);
|
||||
} else {
|
||||
if (typeof method !== "function") {
|
||||
assert.fail(method + " is not a function");
|
||||
}
|
||||
|
||||
if (typeof method.getCall !== "function") {
|
||||
assert.fail(method + " is not stubbed");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function failAssertion(object, msg) {
|
||||
object = object || global;
|
||||
var failMethod = object.fail || assert.fail;
|
||||
failMethod.call(object, msg);
|
||||
}
|
||||
|
||||
function mirrorPropAsAssertion(name, method, message) {
|
||||
if (arguments.length === 2) {
|
||||
message = method;
|
||||
method = name;
|
||||
}
|
||||
|
||||
assert[name] = function (fake) {
|
||||
verifyIsStub(fake);
|
||||
|
||||
var args = slice.call(arguments, 1);
|
||||
var failed = false;
|
||||
|
||||
if (typeof method === "function") {
|
||||
failed = !method(fake);
|
||||
} else {
|
||||
failed = typeof fake[method] === "function" ?
|
||||
!fake[method].apply(fake, args) : !fake[method];
|
||||
}
|
||||
|
||||
if (failed) {
|
||||
failAssertion(this, (fake.printf || fake.proxy.printf).apply(fake, [message].concat(args)));
|
||||
} else {
|
||||
assert.pass(name);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function exposedName(prefix, prop) {
|
||||
return !prefix || /^fail/.test(prop) ? prop :
|
||||
prefix + prop.slice(0, 1).toUpperCase() + prop.slice(1);
|
||||
}
|
||||
|
||||
assert = {
|
||||
failException: "AssertError",
|
||||
|
||||
fail: function fail(message) {
|
||||
var error = new Error(message);
|
||||
error.name = this.failException || assert.failException;
|
||||
|
||||
throw error;
|
||||
},
|
||||
|
||||
pass: function pass() {},
|
||||
|
||||
callOrder: function assertCallOrder() {
|
||||
verifyIsStub.apply(null, arguments);
|
||||
var expected = "";
|
||||
var actual = "";
|
||||
|
||||
if (!sinon.calledInOrder(arguments)) {
|
||||
try {
|
||||
expected = [].join.call(arguments, ", ");
|
||||
var calls = slice.call(arguments);
|
||||
var i = calls.length;
|
||||
while (i) {
|
||||
if (!calls[--i].called) {
|
||||
calls.splice(i, 1);
|
||||
}
|
||||
}
|
||||
actual = sinon.orderByFirstCall(calls).join(", ");
|
||||
} catch (e) {
|
||||
// If this fails, we'll just fall back to the blank string
|
||||
}
|
||||
|
||||
failAssertion(this, "expected " + expected + " to be " +
|
||||
"called in order but were called as " + actual);
|
||||
} else {
|
||||
assert.pass("callOrder");
|
||||
}
|
||||
},
|
||||
|
||||
callCount: function assertCallCount(method, count) {
|
||||
verifyIsStub(method);
|
||||
|
||||
if (method.callCount !== count) {
|
||||
var msg = "expected %n to be called " + sinon.timesInWords(count) +
|
||||
" but was called %c%C";
|
||||
failAssertion(this, method.printf(msg));
|
||||
} else {
|
||||
assert.pass("callCount");
|
||||
}
|
||||
},
|
||||
|
||||
expose: function expose(target, options) {
|
||||
if (!target) {
|
||||
throw new TypeError("target is null or undefined");
|
||||
}
|
||||
|
||||
var o = options || {};
|
||||
var prefix = typeof o.prefix === "undefined" && "assert" || o.prefix;
|
||||
var includeFail = typeof o.includeFail === "undefined" || !!o.includeFail;
|
||||
|
||||
for (var method in this) {
|
||||
if (method !== "expose" && (includeFail || !/^(fail)/.test(method))) {
|
||||
target[exposedName(prefix, method)] = this[method];
|
||||
}
|
||||
}
|
||||
|
||||
return target;
|
||||
},
|
||||
|
||||
match: function match(actual, expectation) {
|
||||
var matcher = sinon.match(expectation);
|
||||
if (matcher.test(actual)) {
|
||||
assert.pass("match");
|
||||
} else {
|
||||
var formatted = [
|
||||
"expected value to match",
|
||||
" expected = " + sinon.format(expectation),
|
||||
" actual = " + sinon.format(actual)
|
||||
];
|
||||
|
||||
failAssertion(this, formatted.join("\n"));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
mirrorPropAsAssertion("called", "expected %n to have been called at least once but was never called");
|
||||
mirrorPropAsAssertion("notCalled", function (spy) {
|
||||
return !spy.called;
|
||||
}, "expected %n to not have been called but was called %c%C");
|
||||
mirrorPropAsAssertion("calledOnce", "expected %n to be called once but was called %c%C");
|
||||
mirrorPropAsAssertion("calledTwice", "expected %n to be called twice but was called %c%C");
|
||||
mirrorPropAsAssertion("calledThrice", "expected %n to be called thrice but was called %c%C");
|
||||
mirrorPropAsAssertion("calledOn", "expected %n to be called with %1 as this but was called with %t");
|
||||
mirrorPropAsAssertion(
|
||||
"alwaysCalledOn",
|
||||
"expected %n to always be called with %1 as this but was called with %t"
|
||||
);
|
||||
mirrorPropAsAssertion("calledWithNew", "expected %n to be called with new");
|
||||
mirrorPropAsAssertion("alwaysCalledWithNew", "expected %n to always be called with new");
|
||||
mirrorPropAsAssertion("calledWith", "expected %n to be called with arguments %*%C");
|
||||
mirrorPropAsAssertion("calledWithMatch", "expected %n to be called with match %*%C");
|
||||
mirrorPropAsAssertion("alwaysCalledWith", "expected %n to always be called with arguments %*%C");
|
||||
mirrorPropAsAssertion("alwaysCalledWithMatch", "expected %n to always be called with match %*%C");
|
||||
mirrorPropAsAssertion("calledWithExactly", "expected %n to be called with exact arguments %*%C");
|
||||
mirrorPropAsAssertion("alwaysCalledWithExactly", "expected %n to always be called with exact arguments %*%C");
|
||||
mirrorPropAsAssertion("neverCalledWith", "expected %n to never be called with arguments %*%C");
|
||||
mirrorPropAsAssertion("neverCalledWithMatch", "expected %n to never be called with match %*%C");
|
||||
mirrorPropAsAssertion("threw", "%n did not throw exception%C");
|
||||
mirrorPropAsAssertion("alwaysThrew", "%n did not always throw exception%C");
|
||||
|
||||
sinon.assert = assert;
|
||||
return assert;
|
||||
}
|
||||
|
||||
var isNode = typeof module !== "undefined" && module.exports && typeof require === "function";
|
||||
var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;
|
||||
|
||||
function loadDependencies(require, exports, module) {
|
||||
var sinon = require("./util/core");
|
||||
require("./match");
|
||||
require("./format");
|
||||
module.exports = makeApi(sinon);
|
||||
}
|
||||
|
||||
if (isAMD) {
|
||||
define(loadDependencies);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isNode) {
|
||||
loadDependencies(require, module.exports, module);
|
||||
return;
|
||||
}
|
||||
|
||||
if (sinonGlobal) {
|
||||
makeApi(sinonGlobal);
|
||||
}
|
||||
}(
|
||||
typeof sinon === "object" && sinon, // eslint-disable-line no-undef
|
||||
typeof global !== "undefined" ? global : self
|
||||
));
|
||||
|
||||
return sinon;
|
||||
}));
|
||||
@@ -1275,7 +1275,7 @@ base_vendor_js = [
|
||||
'edx-ui-toolkit/js/utils/html-utils.js',
|
||||
|
||||
# Finally load RequireJS and dependent vendor libraries
|
||||
'js/vendor/requirejs/require.js',
|
||||
'common/js/vendor/require.js',
|
||||
'js/RequireJS-namespace-undefine.js',
|
||||
'js/vendor/URI.min.js',
|
||||
'common/js/vendor/backbone.js'
|
||||
@@ -1690,7 +1690,7 @@ REQUIRE_BASE_URL = "./"
|
||||
REQUIRE_BUILD_PROFILE = "lms/js/build.js"
|
||||
|
||||
# The name of the require.js script used by your project, relative to REQUIRE_BASE_URL.
|
||||
REQUIRE_JS = "js/vendor/requirejs/require.js"
|
||||
REQUIRE_JS = "common/js/vendor/require.js"
|
||||
|
||||
# A dictionary of standalone modules to build with almond.js.
|
||||
REQUIRE_STANDALONE_MODULES = {}
|
||||
|
||||
@@ -13,7 +13,7 @@ var options = {
|
||||
|
||||
// Avoid adding files to this list. Use RequireJS.
|
||||
libraryFilesToInclude: [
|
||||
{pattern: 'xmodule_js/common_static/js/vendor/requirejs/require.js', included: true},
|
||||
{pattern: 'common/js/vendor/require.js', included: true},
|
||||
{pattern: 'js/RequireJS-namespace-undefine.js', included: true},
|
||||
|
||||
{pattern: 'common/js/vendor/jquery.js', included: true},
|
||||
@@ -22,8 +22,6 @@ var options = {
|
||||
{pattern: 'xmodule_js/common_static/js/vendor/slick.core.js', included: true},
|
||||
{pattern: 'xmodule_js/common_static/js/vendor/slick.grid.js', included: true},
|
||||
|
||||
{pattern: 'xmodule_js/common_static/js/vendor/requirejs/require.js', included: true},
|
||||
|
||||
{pattern: 'xmodule_js/common_static/coffee/src/ajax_prefix.js', included: true},
|
||||
{pattern: 'common/js/vendor/jquery.js', included: true},
|
||||
{pattern: 'common/js/vendor/jquery-migrate.js', included: true},
|
||||
|
||||
@@ -1,13 +1,18 @@
|
||||
/* globals _, requirejs */
|
||||
/* eslint-disable quote-props */
|
||||
|
||||
(function(require, define) {
|
||||
'use strict';
|
||||
|
||||
var defineDependency;
|
||||
|
||||
// We do not wish to bundle common libraries (that may also be used by non-RequireJS code on the page
|
||||
// into the optimized files. Therefore load these libraries through script tags and explicitly define them.
|
||||
// Note that when the optimizer executes this code, window will not be defined.
|
||||
if (window) {
|
||||
var defineDependency = function(globalName, name, noShim) {
|
||||
var getGlobalValue = function(name) {
|
||||
var globalNamePath = name.split('.'),
|
||||
defineDependency = function(globalName, name, noShim) {
|
||||
var getGlobalValue = function() {
|
||||
var globalNamePath = globalName.split('.'),
|
||||
result = window,
|
||||
i;
|
||||
for (i = 0; i < globalNamePath.length; i++) {
|
||||
@@ -15,16 +20,14 @@
|
||||
}
|
||||
return result;
|
||||
},
|
||||
globalValue = getGlobalValue(globalName);
|
||||
globalValue = getGlobalValue();
|
||||
if (globalValue) {
|
||||
if (noShim) {
|
||||
define(name, {});
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
define(name, [], function() { return globalValue; });
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
console.error('Expected library to be included on page, but not found on window object: ' + name);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
/* globals requirejs, requireSerial, MathJax */
|
||||
/* eslint-disable quote-props */
|
||||
|
||||
(function(requirejs) {
|
||||
'use strict';
|
||||
|
||||
var i, specHelpers, testFiles;
|
||||
|
||||
// TODO: how can we share the vast majority of this config that is in common with CMS?
|
||||
requirejs.config({
|
||||
baseUrl: '/base/',
|
||||
@@ -24,7 +29,7 @@
|
||||
'jquery.cookie': 'xmodule_js/common_static/js/vendor/jquery.cookie',
|
||||
'jquery.qtip': 'xmodule_js/common_static/js/vendor/jquery.qtip.min',
|
||||
'jquery.fileupload': 'xmodule_js/common_static/js/vendor/jQuery-File-Upload/js/jquery.fileupload',
|
||||
'jquery.iframe-transport': 'xmodule_js/common_static/js/vendor/jQuery-File-Upload/js/jquery.iframe-transport',
|
||||
'jquery.iframe-transport': 'xmodule_js/common_static/js/vendor/jQuery-File-Upload/js/jquery.iframe-transport', // eslint-disable-line max-len
|
||||
'jquery.inputnumber': 'xmodule_js/common_static/js/vendor/html5-input-polyfills/number-polyfill',
|
||||
'jquery.immediateDescendents': 'xmodule_js/common_static/coffee/src/jquery.immediateDescendents',
|
||||
'jquery.simulate': 'xmodule_js/common_static/js/vendor/jquery.simulate',
|
||||
@@ -47,8 +52,8 @@
|
||||
'xmodule': 'xmodule_js/src/xmodule',
|
||||
'utility': 'xmodule_js/common_static/js/src/utility',
|
||||
'accessibility': 'xmodule_js/common_static/js/src/accessibility_tools',
|
||||
'sinon': 'xmodule_js/common_static/js/vendor/sinon-1.17.0',
|
||||
'squire': 'xmodule_js/common_static/js/vendor/Squire',
|
||||
'sinon': 'common/js/vendor/sinon',
|
||||
'squire': 'common/js/vendor/Squire',
|
||||
'jasmine-imagediff': 'xmodule_js/common_static/js/vendor/jasmine-imagediff',
|
||||
'domReady': 'xmodule_js/common_static/js/vendor/domReady',
|
||||
mathjax: '//cdn.mathjax.org/mathjax/2.7-latest/MathJax.js?config=TeX-MML-AM_SVG&delayStartupUntil=configured', // eslint-disable-line max-len
|
||||
@@ -672,7 +677,7 @@
|
||||
}
|
||||
});
|
||||
|
||||
var testFiles = [
|
||||
testFiles = [
|
||||
'discussion/js/spec/discussion_board_factory_spec.js',
|
||||
'discussion/js/spec/discussion_profile_page_factory_spec.js',
|
||||
'discussion/js/spec/discussion_board_view_spec.js',
|
||||
@@ -804,11 +809,11 @@
|
||||
'teams/js/spec/views/topics_spec.js'
|
||||
];
|
||||
|
||||
for (var i = 0; i < testFiles.length; i++) {
|
||||
for (i = 0; i < testFiles.length; i++) {
|
||||
testFiles[i] = '/base/' + testFiles[i];
|
||||
}
|
||||
|
||||
var specHelpers = [
|
||||
specHelpers = [
|
||||
'common/js/spec_helpers/jasmine-extensions',
|
||||
'common/js/spec_helpers/jasmine-stealth',
|
||||
'common/js/spec_helpers/jasmine-waituntil'
|
||||
@@ -818,6 +823,6 @@
|
||||
// spec files one by one, otherwise some end up getting nested under others.
|
||||
window.requireSerial(specHelpers.concat(testFiles), function() {
|
||||
// start test run, once Require.js is done
|
||||
window.__karma__.start();
|
||||
window.__karma__.start(); // eslint-disable-line no-underscore-dangle
|
||||
});
|
||||
}).call(this, requirejs);
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
requirejs.config({
|
||||
baseUrl: '/base/',
|
||||
paths: {
|
||||
moment: 'xmodule_js/common_static/js/vendor/moment-with-locales',
|
||||
moment: 'xmodule_js/common_static/common/js/vendor/moment-with-locales',
|
||||
'draggabilly': 'xmodule_js/common_static/js/vendor/draggabilly',
|
||||
'edx-ui-toolkit': 'edx-ui-toolkit'
|
||||
},
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"jquery-migrate": "^1.4.1",
|
||||
"jquery.scrollto": "~2.1.2",
|
||||
"picturefill": "~3.0.2",
|
||||
"requirejs": "~2.1.22",
|
||||
"requirejs": "~2.3.2",
|
||||
"uglify-js": "2.7.0",
|
||||
"underscore": "~1.8.3",
|
||||
"underscore.string": "~3.3.4"
|
||||
@@ -34,6 +34,7 @@
|
||||
"karma-spec-reporter": "^0.0.20",
|
||||
"pa11y": "4.0.1",
|
||||
"pa11y-reporter-json-oldnode": "1.0.0",
|
||||
"plato": "1.2.2"
|
||||
"plato": "1.2.2",
|
||||
"squirejs": "^0.1.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ from functools import wraps
|
||||
from threading import Timer
|
||||
import argparse
|
||||
import glob
|
||||
import os
|
||||
import traceback
|
||||
|
||||
from paver import tasks
|
||||
@@ -46,17 +47,25 @@ COMMON_LOOKUP_PATHS = [
|
||||
# A list of NPM installed libraries that should be copied into the common
|
||||
# static directory.
|
||||
NPM_INSTALLED_LIBRARIES = [
|
||||
'jquery/dist/jquery.js',
|
||||
'jquery-migrate/dist/jquery-migrate.js',
|
||||
'jquery.scrollto/jquery.scrollTo.js',
|
||||
'underscore/underscore.js',
|
||||
'underscore.string/dist/underscore.string.js',
|
||||
'picturefill/dist/picturefill.js',
|
||||
'backbone-validation/dist/backbone-validation-min.js',
|
||||
'backbone/backbone.js',
|
||||
'edx-ui-toolkit/node_modules/backbone.paginator/lib/backbone.paginator.js',
|
||||
'backbone-validation/dist/backbone-validation-min.js',
|
||||
'edx-ui-toolkit/node_modules/moment-timezone/builds/moment-timezone-with-data.js',
|
||||
'edx-ui-toolkit/node_modules/moment/min/moment-with-locales.js',
|
||||
'jquery-migrate/dist/jquery-migrate.js',
|
||||
'jquery.scrollto/jquery.scrollTo.js',
|
||||
'jquery/dist/jquery.js',
|
||||
'picturefill/dist/picturefill.js',
|
||||
'requirejs/require.js',
|
||||
'underscore.string/dist/underscore.string.js',
|
||||
'underscore/underscore.js',
|
||||
]
|
||||
|
||||
# A list of NPM installed developer libraries that should be copied into the common
|
||||
# static directory only in development mode.
|
||||
NPM_INSTALLED_DEVELOPER_LIBRARIES = [
|
||||
'edx-ui-toolkit/node_modules/sinon/pkg/sinon.js',
|
||||
'squirejs/src/Squire.js',
|
||||
]
|
||||
|
||||
# Directory to install static vendor files
|
||||
@@ -597,6 +606,19 @@ def process_npm_assets():
|
||||
"""
|
||||
Process vendor libraries installed via NPM.
|
||||
"""
|
||||
def copy_vendor_library(library, skip_if_missing=False):
|
||||
"""
|
||||
Copies a vendor library to the shared vendor directory.
|
||||
"""
|
||||
library_path = 'node_modules/{library}'.format(library=library)
|
||||
if os.path.exists(library_path):
|
||||
sh('/bin/cp -rf {library_path} {vendor_dir}'.format(
|
||||
library_path=library_path,
|
||||
vendor_dir=NPM_VENDOR_DIRECTORY,
|
||||
))
|
||||
elif not skip_if_missing:
|
||||
raise Exception('Missing vendor file {library_path}'.format(library_path=library_path))
|
||||
|
||||
# Skip processing of the libraries if this is just a dry run
|
||||
if tasks.environment.dry_run:
|
||||
tasks.environment.info("install npm_assets")
|
||||
@@ -606,11 +628,14 @@ def process_npm_assets():
|
||||
NPM_VENDOR_DIRECTORY.mkdir_p()
|
||||
|
||||
# Copy each file to the vendor directory, overwriting any existing file.
|
||||
print("Copying vendor files into static directory")
|
||||
for library in NPM_INSTALLED_LIBRARIES:
|
||||
sh('/bin/cp -rf node_modules/{library} {vendor_dir}'.format(
|
||||
library=library,
|
||||
vendor_dir=NPM_VENDOR_DIRECTORY,
|
||||
))
|
||||
copy_vendor_library(library)
|
||||
|
||||
# Copy over each developer library too if they have been installed
|
||||
print("Copying developer vendor files into static directory")
|
||||
for library in NPM_INSTALLED_DEVELOPER_LIBRARIES:
|
||||
copy_vendor_library(library, skip_if_missing=True)
|
||||
|
||||
|
||||
def process_xmodule_assets():
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
"version": "0.0.1",
|
||||
"dependencies": {
|
||||
"annotator": "1.2.6",
|
||||
"backbone": "1.0.0",
|
||||
"backbone.paginator": "0.8.1",
|
||||
"backbone-relational": "0.9.0",
|
||||
"codemirror": "3.21.0",
|
||||
"date": "1.0",
|
||||
@@ -12,18 +10,12 @@
|
||||
"draggabilly": "1.2.4",
|
||||
"jquery-form": "3.18.0",
|
||||
"jquery-watch": "2.0",
|
||||
"moment": "2.10.6",
|
||||
"mustache": "0.5.1",
|
||||
"rangeslider": "1.0",
|
||||
"requirejs-text": "2.0.14",
|
||||
"slickgrid": "2.1",
|
||||
"timeago": "0.11.4",
|
||||
"tinymce": "4.0.20",
|
||||
"urijs": "1.11.2",
|
||||
"url": "1.8.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"sinon": "1.17.0",
|
||||
"squire": "1.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user