(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.lolex = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i 1 ? arguments : spies; return every(_spies, checkAdjacentCalls.bind(null, callMap)); }; },{"./prototypes/array":9}],2:[function(require,module,exports){ "use strict"; var functionName = require("./function-name"); module.exports = function className(value) { return ( (value.constructor && value.constructor.name) || // The next branch is for IE11 support only: // Because the name property is not set on the prototype // of the Function object, we finally try to grab the // name from its definition. This will never be reached // in node, so we are not able to test this properly. // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name (typeof value.constructor === "function" && /* istanbul ignore next */ functionName(value.constructor)) || null ); }; },{"./function-name":5}],3:[function(require,module,exports){ /* eslint-disable no-console */ "use strict"; // wrap returns a function that will invoke the supplied function and print a deprecation warning to the console each // time it is called. exports.wrap = function(func, msg) { var wrapped = function() { exports.printWarning(msg); return func.apply(this, arguments); }; if (func.prototype) { wrapped.prototype = func.prototype; } return wrapped; }; // defaultMsg returns a string which can be supplied to `wrap()` to notify the user that a particular part of the // sinon API has been deprecated. exports.defaultMsg = function(packageName, funcName) { return ( packageName + "." + funcName + " is deprecated and will be removed from the public API in a future version of " + packageName + "." ); }; exports.printWarning = function(msg) { // Watch out for IE7 and below! :( /* istanbul ignore next */ if (typeof console !== "undefined") { if (console.info) { console.info(msg); } else { console.log(msg); } } }; },{}],4:[function(require,module,exports){ "use strict"; // This is an `every` implementation that works for all iterables module.exports = function every(obj, fn) { var pass = true; try { /* eslint-disable-next-line local-rules/no-prototype-methods */ obj.forEach(function() { if (!fn.apply(this, arguments)) { // Throwing an error is the only way to break `forEach` throw new Error(); } }); } catch (e) { pass = false; } return pass; }; },{}],5:[function(require,module,exports){ "use strict"; module.exports = function functionName(func) { if (!func) { return ""; } return ( 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'). (String(func).match(/function ([^\s(]+)/) || [])[1] ); }; },{}],6:[function(require,module,exports){ "use strict"; var globalObject; /* istanbul ignore else */ if (typeof global !== "undefined") { // Node globalObject = global; } else if (typeof window !== "undefined") { // Browser globalObject = window; } else { // WebWorker globalObject = self; } module.exports = globalObject; },{}],7:[function(require,module,exports){ "use strict"; module.exports = { global: require("./global"), calledInOrder: require("./called-in-order"), className: require("./class-name"), deprecated: require("./deprecated"), every: require("./every"), functionName: require("./function-name"), orderByFirstCall: require("./order-by-first-call"), prototypes: require("./prototypes"), typeOf: require("./type-of"), valueToString: require("./value-to-string") }; },{"./called-in-order":1,"./class-name":2,"./deprecated":3,"./every":4,"./function-name":5,"./global":6,"./order-by-first-call":8,"./prototypes":12,"./type-of":17,"./value-to-string":18}],8:[function(require,module,exports){ "use strict"; var sort = require("./prototypes/array").sort; var slice = require("./prototypes/array").slice; function comparator(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; } module.exports = function orderByFirstCall(spies) { return sort(slice(spies), comparator); }; },{"./prototypes/array":9}],9:[function(require,module,exports){ "use strict"; var copyPrototype = require("./copy-prototype"); module.exports = copyPrototype(Array.prototype); },{"./copy-prototype":10}],10:[function(require,module,exports){ "use strict"; var call = Function.call; module.exports = function copyPrototypeMethods(prototype) { /* eslint-disable local-rules/no-prototype-methods */ return Object.getOwnPropertyNames(prototype).reduce(function(result, name) { // ignore size because it throws from Map if ( name !== "size" && name !== "caller" && name !== "callee" && name !== "arguments" && typeof prototype[name] === "function" ) { result[name] = call.bind(prototype[name]); } return result; }, Object.create(null)); }; },{}],11:[function(require,module,exports){ "use strict"; var copyPrototype = require("./copy-prototype"); module.exports = copyPrototype(Function.prototype); },{"./copy-prototype":10}],12:[function(require,module,exports){ "use strict"; module.exports = { array: require("./array"), function: require("./function"), map: require("./map"), object: require("./object"), set: require("./set"), string: require("./string") }; },{"./array":9,"./function":11,"./map":13,"./object":14,"./set":15,"./string":16}],13:[function(require,module,exports){ "use strict"; var copyPrototype = require("./copy-prototype"); module.exports = copyPrototype(Map.prototype); },{"./copy-prototype":10}],14:[function(require,module,exports){ "use strict"; var copyPrototype = require("./copy-prototype"); module.exports = copyPrototype(Object.prototype); },{"./copy-prototype":10}],15:[function(require,module,exports){ "use strict"; var copyPrototype = require("./copy-prototype"); module.exports = copyPrototype(Set.prototype); },{"./copy-prototype":10}],16:[function(require,module,exports){ "use strict"; var copyPrototype = require("./copy-prototype"); module.exports = copyPrototype(String.prototype); },{"./copy-prototype":10}],17:[function(require,module,exports){ "use strict"; var type = require("type-detect"); module.exports = function typeOf(value) { return type(value).toLowerCase(); }; },{"type-detect":19}],18:[function(require,module,exports){ "use strict"; function valueToString(value) { if (value && value.toString) { /* eslint-disable-next-line local-rules/no-prototype-methods */ return value.toString(); } return String(value); } module.exports = valueToString; },{}],19:[function(require,module,exports){ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global.typeDetect = factory()); }(this, (function () { 'use strict'; /* ! * type-detect * Copyright(c) 2013 jake luer * MIT Licensed */ var promiseExists = typeof Promise === 'function'; /* eslint-disable no-undef */ var globalObject = typeof self === 'object' ? self : global; // eslint-disable-line id-blacklist var symbolExists = typeof Symbol !== 'undefined'; var mapExists = typeof Map !== 'undefined'; var setExists = typeof Set !== 'undefined'; var weakMapExists = typeof WeakMap !== 'undefined'; var weakSetExists = typeof WeakSet !== 'undefined'; var dataViewExists = typeof DataView !== 'undefined'; var symbolIteratorExists = symbolExists && typeof Symbol.iterator !== 'undefined'; var symbolToStringTagExists = symbolExists && typeof Symbol.toStringTag !== 'undefined'; var setEntriesExists = setExists && typeof Set.prototype.entries === 'function'; var mapEntriesExists = mapExists && typeof Map.prototype.entries === 'function'; var setIteratorPrototype = setEntriesExists && Object.getPrototypeOf(new Set().entries()); var mapIteratorPrototype = mapEntriesExists && Object.getPrototypeOf(new Map().entries()); var arrayIteratorExists = symbolIteratorExists && typeof Array.prototype[Symbol.iterator] === 'function'; var arrayIteratorPrototype = arrayIteratorExists && Object.getPrototypeOf([][Symbol.iterator]()); var stringIteratorExists = symbolIteratorExists && typeof String.prototype[Symbol.iterator] === 'function'; var stringIteratorPrototype = stringIteratorExists && Object.getPrototypeOf(''[Symbol.iterator]()); var toStringLeftSliceLength = 8; var toStringRightSliceLength = -1; /** * ### typeOf (obj) * * Uses `Object.prototype.toString` to determine the type of an object, * normalising behaviour across engine versions & well optimised. * * @param {Mixed} object * @return {String} object type * @api public */ function typeDetect(obj) { /* ! Speed optimisation * Pre: * string literal x 3,039,035 ops/sec ±1.62% (78 runs sampled) * boolean literal x 1,424,138 ops/sec ±4.54% (75 runs sampled) * number literal x 1,653,153 ops/sec ±1.91% (82 runs sampled) * undefined x 9,978,660 ops/sec ±1.92% (75 runs sampled) * function x 2,556,769 ops/sec ±1.73% (77 runs sampled) * Post: * string literal x 38,564,796 ops/sec ±1.15% (79 runs sampled) * boolean literal x 31,148,940 ops/sec ±1.10% (79 runs sampled) * number literal x 32,679,330 ops/sec ±1.90% (78 runs sampled) * undefined x 32,363,368 ops/sec ±1.07% (82 runs sampled) * function x 31,296,870 ops/sec ±0.96% (83 runs sampled) */ var typeofObj = typeof obj; if (typeofObj !== 'object') { return typeofObj; } /* ! Speed optimisation * Pre: * null x 28,645,765 ops/sec ±1.17% (82 runs sampled) * Post: * null x 36,428,962 ops/sec ±1.37% (84 runs sampled) */ if (obj === null) { return 'null'; } /* ! Spec Conformance * Test: `Object.prototype.toString.call(window)`` * - Node === "[object global]" * - Chrome === "[object global]" * - Firefox === "[object Window]" * - PhantomJS === "[object Window]" * - Safari === "[object Window]" * - IE 11 === "[object Window]" * - IE Edge === "[object Window]" * Test: `Object.prototype.toString.call(this)`` * - Chrome Worker === "[object global]" * - Firefox Worker === "[object DedicatedWorkerGlobalScope]" * - Safari Worker === "[object DedicatedWorkerGlobalScope]" * - IE 11 Worker === "[object WorkerGlobalScope]" * - IE Edge Worker === "[object WorkerGlobalScope]" */ if (obj === globalObject) { return 'global'; } /* ! Speed optimisation * Pre: * array literal x 2,888,352 ops/sec ±0.67% (82 runs sampled) * Post: * array literal x 22,479,650 ops/sec ±0.96% (81 runs sampled) */ if ( Array.isArray(obj) && (symbolToStringTagExists === false || !(Symbol.toStringTag in obj)) ) { return 'Array'; } // Not caching existence of `window` and related properties due to potential // for `window` to be unset before tests in quasi-browser environments. if (typeof window === 'object' && window !== null) { /* ! Spec Conformance * (https://html.spec.whatwg.org/multipage/browsers.html#location) * WhatWG HTML$7.7.3 - The `Location` interface * Test: `Object.prototype.toString.call(window.location)`` * - IE <=11 === "[object Object]" * - IE Edge <=13 === "[object Object]" */ if (typeof window.location === 'object' && obj === window.location) { return 'Location'; } /* ! Spec Conformance * (https://html.spec.whatwg.org/#document) * WhatWG HTML$3.1.1 - The `Document` object * Note: Most browsers currently adher to the W3C DOM Level 2 spec * (https://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-26809268) * which suggests that browsers should use HTMLTableCellElement for * both TD and TH elements. WhatWG separates these. * WhatWG HTML states: * > For historical reasons, Window objects must also have a * > writable, configurable, non-enumerable property named * > HTMLDocument whose value is the Document interface object. * Test: `Object.prototype.toString.call(document)`` * - Chrome === "[object HTMLDocument]" * - Firefox === "[object HTMLDocument]" * - Safari === "[object HTMLDocument]" * - IE <=10 === "[object Document]" * - IE 11 === "[object HTMLDocument]" * - IE Edge <=13 === "[object HTMLDocument]" */ if (typeof window.document === 'object' && obj === window.document) { return 'Document'; } if (typeof window.navigator === 'object') { /* ! Spec Conformance * (https://html.spec.whatwg.org/multipage/webappapis.html#mimetypearray) * WhatWG HTML$8.6.1.5 - Plugins - Interface MimeTypeArray * Test: `Object.prototype.toString.call(navigator.mimeTypes)`` * - IE <=10 === "[object MSMimeTypesCollection]" */ if (typeof window.navigator.mimeTypes === 'object' && obj === window.navigator.mimeTypes) { return 'MimeTypeArray'; } /* ! Spec Conformance * (https://html.spec.whatwg.org/multipage/webappapis.html#pluginarray) * WhatWG HTML$8.6.1.5 - Plugins - Interface PluginArray * Test: `Object.prototype.toString.call(navigator.plugins)`` * - IE <=10 === "[object MSPluginsCollection]" */ if (typeof window.navigator.plugins === 'object' && obj === window.navigator.plugins) { return 'PluginArray'; } } if ((typeof window.HTMLElement === 'function' || typeof window.HTMLElement === 'object') && obj instanceof window.HTMLElement) { /* ! Spec Conformance * (https://html.spec.whatwg.org/multipage/webappapis.html#pluginarray) * WhatWG HTML$4.4.4 - The `blockquote` element - Interface `HTMLQuoteElement` * Test: `Object.prototype.toString.call(document.createElement('blockquote'))`` * - IE <=10 === "[object HTMLBlockElement]" */ if (obj.tagName === 'BLOCKQUOTE') { return 'HTMLQuoteElement'; } /* ! Spec Conformance * (https://html.spec.whatwg.org/#htmltabledatacellelement) * WhatWG HTML$4.9.9 - The `td` element - Interface `HTMLTableDataCellElement` * Note: Most browsers currently adher to the W3C DOM Level 2 spec * (https://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-82915075) * which suggests that browsers should use HTMLTableCellElement for * both TD and TH elements. WhatWG separates these. * Test: Object.prototype.toString.call(document.createElement('td')) * - Chrome === "[object HTMLTableCellElement]" * - Firefox === "[object HTMLTableCellElement]" * - Safari === "[object HTMLTableCellElement]" */ if (obj.tagName === 'TD') { return 'HTMLTableDataCellElement'; } /* ! Spec Conformance * (https://html.spec.whatwg.org/#htmltableheadercellelement) * WhatWG HTML$4.9.9 - The `td` element - Interface `HTMLTableHeaderCellElement` * Note: Most browsers currently adher to the W3C DOM Level 2 spec * (https://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-82915075) * which suggests that browsers should use HTMLTableCellElement for * both TD and TH elements. WhatWG separates these. * Test: Object.prototype.toString.call(document.createElement('th')) * - Chrome === "[object HTMLTableCellElement]" * - Firefox === "[object HTMLTableCellElement]" * - Safari === "[object HTMLTableCellElement]" */ if (obj.tagName === 'TH') { return 'HTMLTableHeaderCellElement'; } } } /* ! Speed optimisation * Pre: * Float64Array x 625,644 ops/sec ±1.58% (80 runs sampled) * Float32Array x 1,279,852 ops/sec ±2.91% (77 runs sampled) * Uint32Array x 1,178,185 ops/sec ±1.95% (83 runs sampled) * Uint16Array x 1,008,380 ops/sec ±2.25% (80 runs sampled) * Uint8Array x 1,128,040 ops/sec ±2.11% (81 runs sampled) * Int32Array x 1,170,119 ops/sec ±2.88% (80 runs sampled) * Int16Array x 1,176,348 ops/sec ±5.79% (86 runs sampled) * Int8Array x 1,058,707 ops/sec ±4.94% (77 runs sampled) * Uint8ClampedArray x 1,110,633 ops/sec ±4.20% (80 runs sampled) * Post: * Float64Array x 7,105,671 ops/sec ±13.47% (64 runs sampled) * Float32Array x 5,887,912 ops/sec ±1.46% (82 runs sampled) * Uint32Array x 6,491,661 ops/sec ±1.76% (79 runs sampled) * Uint16Array x 6,559,795 ops/sec ±1.67% (82 runs sampled) * Uint8Array x 6,463,966 ops/sec ±1.43% (85 runs sampled) * Int32Array x 5,641,841 ops/sec ±3.49% (81 runs sampled) * Int16Array x 6,583,511 ops/sec ±1.98% (80 runs sampled) * Int8Array x 6,606,078 ops/sec ±1.74% (81 runs sampled) * Uint8ClampedArray x 6,602,224 ops/sec ±1.77% (83 runs sampled) */ var stringTag = (symbolToStringTagExists && obj[Symbol.toStringTag]); if (typeof stringTag === 'string') { return stringTag; } var objPrototype = Object.getPrototypeOf(obj); /* ! Speed optimisation * Pre: * regex literal x 1,772,385 ops/sec ±1.85% (77 runs sampled) * regex constructor x 2,143,634 ops/sec ±2.46% (78 runs sampled) * Post: * regex literal x 3,928,009 ops/sec ±0.65% (78 runs sampled) * regex constructor x 3,931,108 ops/sec ±0.58% (84 runs sampled) */ if (objPrototype === RegExp.prototype) { return 'RegExp'; } /* ! Speed optimisation * Pre: * date x 2,130,074 ops/sec ±4.42% (68 runs sampled) * Post: * date x 3,953,779 ops/sec ±1.35% (77 runs sampled) */ if (objPrototype === Date.prototype) { return 'Date'; } /* ! Spec Conformance * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-promise.prototype-@@tostringtag) * ES6$25.4.5.4 - Promise.prototype[@@toStringTag] should be "Promise": * Test: `Object.prototype.toString.call(Promise.resolve())`` * - Chrome <=47 === "[object Object]" * - Edge <=20 === "[object Object]" * - Firefox 29-Latest === "[object Promise]" * - Safari 7.1-Latest === "[object Promise]" */ if (promiseExists && objPrototype === Promise.prototype) { return 'Promise'; } /* ! Speed optimisation * Pre: * set x 2,222,186 ops/sec ±1.31% (82 runs sampled) * Post: * set x 4,545,879 ops/sec ±1.13% (83 runs sampled) */ if (setExists && objPrototype === Set.prototype) { return 'Set'; } /* ! Speed optimisation * Pre: * map x 2,396,842 ops/sec ±1.59% (81 runs sampled) * Post: * map x 4,183,945 ops/sec ±6.59% (82 runs sampled) */ if (mapExists && objPrototype === Map.prototype) { return 'Map'; } /* ! Speed optimisation * Pre: * weakset x 1,323,220 ops/sec ±2.17% (76 runs sampled) * Post: * weakset x 4,237,510 ops/sec ±2.01% (77 runs sampled) */ if (weakSetExists && objPrototype === WeakSet.prototype) { return 'WeakSet'; } /* ! Speed optimisation * Pre: * weakmap x 1,500,260 ops/sec ±2.02% (78 runs sampled) * Post: * weakmap x 3,881,384 ops/sec ±1.45% (82 runs sampled) */ if (weakMapExists && objPrototype === WeakMap.prototype) { return 'WeakMap'; } /* ! Spec Conformance * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-dataview.prototype-@@tostringtag) * ES6$24.2.4.21 - DataView.prototype[@@toStringTag] should be "DataView": * Test: `Object.prototype.toString.call(new DataView(new ArrayBuffer(1)))`` * - Edge <=13 === "[object Object]" */ if (dataViewExists && objPrototype === DataView.prototype) { return 'DataView'; } /* ! Spec Conformance * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%mapiteratorprototype%-@@tostringtag) * ES6$23.1.5.2.2 - %MapIteratorPrototype%[@@toStringTag] should be "Map Iterator": * Test: `Object.prototype.toString.call(new Map().entries())`` * - Edge <=13 === "[object Object]" */ if (mapExists && objPrototype === mapIteratorPrototype) { return 'Map Iterator'; } /* ! Spec Conformance * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%setiteratorprototype%-@@tostringtag) * ES6$23.2.5.2.2 - %SetIteratorPrototype%[@@toStringTag] should be "Set Iterator": * Test: `Object.prototype.toString.call(new Set().entries())`` * - Edge <=13 === "[object Object]" */ if (setExists && objPrototype === setIteratorPrototype) { return 'Set Iterator'; } /* ! Spec Conformance * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%arrayiteratorprototype%-@@tostringtag) * ES6$22.1.5.2.2 - %ArrayIteratorPrototype%[@@toStringTag] should be "Array Iterator": * Test: `Object.prototype.toString.call([][Symbol.iterator]())`` * - Edge <=13 === "[object Object]" */ if (arrayIteratorExists && objPrototype === arrayIteratorPrototype) { return 'Array Iterator'; } /* ! Spec Conformance * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%stringiteratorprototype%-@@tostringtag) * ES6$21.1.5.2.2 - %StringIteratorPrototype%[@@toStringTag] should be "String Iterator": * Test: `Object.prototype.toString.call(''[Symbol.iterator]())`` * - Edge <=13 === "[object Object]" */ if (stringIteratorExists && objPrototype === stringIteratorPrototype) { return 'String Iterator'; } /* ! Speed optimisation * Pre: * object from null x 2,424,320 ops/sec ±1.67% (76 runs sampled) * Post: * object from null x 5,838,000 ops/sec ±0.99% (84 runs sampled) */ if (objPrototype === null) { return 'Object'; } return Object .prototype .toString .call(obj) .slice(toStringLeftSliceLength, toStringRightSliceLength); } return typeDetect; }))); },{}],20:[function(require,module,exports){ "use strict"; var globalObject = require("@sinonjs/commons").global; // eslint-disable-next-line complexity function withGlobal(_global) { var userAgent = _global.navigator && _global.navigator.userAgent; var isRunningInIE = userAgent && userAgent.indexOf("MSIE ") > -1; var maxTimeout = Math.pow(2, 31) - 1; //see https://heycam.github.io/webidl/#abstract-opdef-converttoint var NOOP = function() { return undefined; }; var NOOP_ARRAY = function() { return []; }; var timeoutResult = _global.setTimeout(NOOP, 0); var addTimerReturnsObject = typeof timeoutResult === "object"; var hrtimePresent = _global.process && typeof _global.process.hrtime === "function"; var hrtimeBigintPresent = hrtimePresent && typeof _global.process.hrtime.bigint === "function"; var nextTickPresent = _global.process && typeof _global.process.nextTick === "function"; var performancePresent = _global.performance && typeof _global.performance.now === "function"; var hasPerformancePrototype = _global.Performance && (typeof _global.Performance).match(/^(function|object)$/); var queueMicrotaskPresent = _global.hasOwnProperty("queueMicrotask"); var requestAnimationFramePresent = _global.requestAnimationFrame && typeof _global.requestAnimationFrame === "function"; var cancelAnimationFramePresent = _global.cancelAnimationFrame && typeof _global.cancelAnimationFrame === "function"; var requestIdleCallbackPresent = _global.requestIdleCallback && typeof _global.requestIdleCallback === "function"; var cancelIdleCallbackPresent = _global.cancelIdleCallback && typeof _global.cancelIdleCallback === "function"; var setImmediatePresent = _global.setImmediate && typeof _global.setImmediate === "function"; // Make properties writable in IE, as per // http://www.adequatelygood.com/Replacing-setTimeout-Globally.html /* eslint-disable no-self-assign */ if (isRunningInIE) { _global.setTimeout = _global.setTimeout; _global.clearTimeout = _global.clearTimeout; _global.setInterval = _global.setInterval; _global.clearInterval = _global.clearInterval; _global.Date = _global.Date; } // setImmediate is not a standard function // avoid adding the prop to the window object if not present if (setImmediatePresent) { _global.setImmediate = _global.setImmediate; _global.clearImmediate = _global.clearImmediate; } /* eslint-enable no-self-assign */ _global.clearTimeout(timeoutResult); var NativeDate = _global.Date; var uniqueTimerId = 1; function isNumberFinite(num) { if (Number.isFinite) { return Number.isFinite(num); } if (typeof num !== "number") { return false; } return isFinite(num); } /** * 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; var i = l; var ms = 0; var parsed; if (l > 3 || !/^(\d\d:){0,2}\d\d?$/.test(str)) { throw new Error( "tick only understands numbers, 'm:s' and 'h:m:s'. Each part must be two digits" ); } 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; } /** * Get the decimal part of the millisecond value as nanoseconds * * @param {Number} msFloat the number of milliseconds * @returns {Number} an integer number of nanoseconds in the range [0,1e6) * * Example: nanoRemainer(123.456789) -> 456789 */ function nanoRemainder(msFloat) { var modulo = 1e6; var remainder = (msFloat * 1e6) % modulo; var positiveRemainder = remainder < 0 ? remainder + modulo : remainder; return Math.floor(positiveRemainder); } /** * Used to grok the `now` parameter to createClock. * @param epoch {Date|number} the system time */ 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) { var prop; for (prop in source) { if (source.hasOwnProperty(prop)) { target[prop] = source[prop]; } } // set special now implementation if (source.now) { target.now = function now() { return target.clock.now; }; } else { delete target.now; } // set special toSource implementation if (source.toSource) { target.toSource = function toSource() { return source.toSource(); }; } else { delete target.toSource; } // set special toString implementation 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; return target; } function createDate() { function ClockDate(year, month, date, hour, minute, second, ms) { // the Date constructor called as a function, ref Ecma-262 Edition 5.1, section 15.9.2. // This remains so in the 10th edition of 2019 as well. if (!(this instanceof ClockDate)) { return new NativeDate(ClockDate.clock.now).toString(); } // if Date is called as a constructor with 'new' keyword // 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 enqueueJob(clock, job) { // enqueues a microtick-deferred task - ecma262/#sec-enqueuejob if (!clock.jobs) { clock.jobs = []; } clock.jobs.push(job); } function runJobs(clock) { // runs all microtick-deferred tasks - ecma262/#sec-runjobs if (!clock.jobs) { return; } for (var i = 0; i < clock.jobs.length; i++) { var job = clock.jobs[i]; job.func.apply(null, job.args); if (clock.loopLimit && i > clock.loopLimit) { throw new Error( "Aborting after running " + clock.loopLimit + " timers, assuming an infinite loop!" ); } } clock.jobs = []; } function addTimer(clock, timer) { if (timer.func === undefined) { throw new Error("Callback must be provided to timer calls"); } timer.type = timer.immediate ? "Immediate" : "Timeout"; if (timer.hasOwnProperty("delay")) { if (!isNumberFinite(timer.delay)) { timer.delay = 0; } timer.delay = timer.delay > maxTimeout ? 1 : timer.delay; timer.delay = Math.max(0, timer.delay); } if (timer.hasOwnProperty("interval")) { timer.type = "Interval"; timer.interval = timer.interval > maxTimeout ? 1 : timer.interval; } if (timer.hasOwnProperty("animation")) { timer.type = "AnimationFrame"; timer.animation = true; } if (!clock.timers) { clock.timers = {}; } timer.id = uniqueTimerId++; timer.createdAt = clock.now; timer.callAt = clock.now + (parseInt(timer.delay) || (clock.duringTick ? 1 : 0)); clock.timers[timer.id] = timer; if (addTimerReturnsObject) { var res = { id: timer.id, ref: function() { return res; }, unref: function() { return res; }, refresh: function() { return res; } }; return res; } return timer.id; } /* eslint consistent-return: "off" */ 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 firstTimerInRange(clock, from, to) { var timers = clock.timers; var timer = null; var id, isInRange; for (id in timers) { if (timers.hasOwnProperty(id)) { isInRange = inRange(from, to, timers[id]); if ( isInRange && (!timer || compareTimers(timer, timers[id]) === 1) ) { timer = timers[id]; } } } return timer; } function firstTimer(clock) { var timers = clock.timers; var timer = null; var id; for (id in timers) { if (timers.hasOwnProperty(id)) { if (!timer || compareTimers(timer, timers[id]) === 1) { timer = timers[id]; } } } return timer; } function lastTimer(clock) { var timers = clock.timers; var timer = null; var id; for (id in timers) { if (timers.hasOwnProperty(id)) { if (!timer || compareTimers(timer, timers[id]) === -1) { timer = timers[id]; } } } return timer; } function callTimer(clock, timer) { if (typeof timer.interval === "number") { clock.timers[timer.id].callAt += timer.interval; } else { delete clock.timers[timer.id]; } if (typeof timer.func === "function") { timer.func.apply(null, timer.args); } else { /* eslint no-eval: "off" */ eval(timer.func); } } function clearTimer(clock, timerId, ttype) { 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. var id = typeof timerId === "object" ? timerId.id : timerId; if (clock.timers.hasOwnProperty(id)) { // check that the ID matches a timer of the correct type var timer = clock.timers[id]; if (timer.type === ttype) { delete clock.timers[id]; } else { var clear = ttype === "AnimationFrame" ? "cancelAnimationFrame" : "clear" + ttype; var schedule = timer.type === "AnimationFrame" ? "requestAnimationFrame" : "set" + timer.type; throw new Error( "Cannot clear timer: timer created with " + schedule + "() but cleared with " + clear + "()" ); } } } function uninstall(clock, target, config) { var method, i, l; var installedHrTime = "_hrtime"; var installedNextTick = "_nextTick"; for (i = 0, l = clock.methods.length; i < l; i++) { method = clock.methods[i]; if (method === "hrtime" && target.process) { target.process.hrtime = clock[installedHrTime]; } else if (method === "nextTick" && target.process) { target.process.nextTick = clock[installedNextTick]; } else if (method === "performance") { var originalPerfDescriptor = Object.getOwnPropertyDescriptor( clock, "_" + method ); if ( originalPerfDescriptor && originalPerfDescriptor.get && !originalPerfDescriptor.set ) { Object.defineProperty( target, method, originalPerfDescriptor ); } else if (originalPerfDescriptor.configurable) { target[method] = clock["_" + method]; } } else { if (target[method] && target[method].hadOwnProperty) { target[method] = clock["_" + method]; if ( method === "clearInterval" && config.shouldAdvanceTime === true ) { target[method](clock.attachedInterval); } } else { try { delete target[method]; } catch (ignore) { /* eslint no-empty: "off" */ } } } } // Prevent multiple executions which will completely remove these props clock.methods = []; // return pending timers, to enable checking what timers remained on uninstall if (!clock.timers) { return []; } return Object.keys(clock.timers).map(function mapper(key) { return clock.timers[key]; }); } function hijackMethod(target, method, clock) { var prop; 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 if (method === "performance") { var originalPerfDescriptor = Object.getOwnPropertyDescriptor( target, method ); // JSDOM has a read only performance field so we have to save/copy it differently if ( originalPerfDescriptor && originalPerfDescriptor.get && !originalPerfDescriptor.set ) { Object.defineProperty( clock, "_" + method, originalPerfDescriptor ); var perfDescriptor = Object.getOwnPropertyDescriptor( clock, method ); Object.defineProperty(target, method, perfDescriptor); } else { target[method] = clock[method]; } } else { target[method] = function() { return clock[method].apply(clock, arguments); }; for (prop in clock[method]) { if (clock[method].hasOwnProperty(prop)) { target[method][prop] = clock[method][prop]; } } } target[method].clock = clock; } function doIntervalTick(clock, advanceTimeDelta) { clock.tick(advanceTimeDelta); } var timers = { setTimeout: _global.setTimeout, clearTimeout: _global.clearTimeout, setInterval: _global.setInterval, clearInterval: _global.clearInterval, Date: _global.Date }; if (setImmediatePresent) { timers.setImmediate = _global.setImmediate; timers.clearImmediate = _global.clearImmediate; } if (hrtimePresent) { timers.hrtime = _global.process.hrtime; } if (nextTickPresent) { timers.nextTick = _global.process.nextTick; } if (performancePresent) { timers.performance = _global.performance; } if (requestAnimationFramePresent) { timers.requestAnimationFrame = _global.requestAnimationFrame; } if (queueMicrotaskPresent) { timers.queueMicrotask = true; } if (cancelAnimationFramePresent) { timers.cancelAnimationFrame = _global.cancelAnimationFrame; } if (requestIdleCallbackPresent) { timers.requestIdleCallback = _global.requestIdleCallback; } if (cancelIdleCallbackPresent) { timers.cancelIdleCallback = _global.cancelIdleCallback; } var keys = Object.keys || function(obj) { var ks = []; var key; for (key in obj) { if (obj.hasOwnProperty(key)) { ks.push(key); } } return ks; }; var originalSetTimeout = _global.setImmediate || _global.setTimeout; /** * @param start {Date|number} the system time - non-integer values are floored * @param loopLimit {number} maximum number of timers that will be run when calling runAll() */ function createClock(start, loopLimit) { // eslint-disable-next-line no-param-reassign start = Math.floor(getEpoch(start)); // eslint-disable-next-line no-param-reassign loopLimit = loopLimit || 1000; var nanos = 0; var adjustedSystemTime = [0, 0]; // [millis, nanoremainder] if (NativeDate === undefined) { throw new Error( "The global scope doesn't have a `Date` object" + " (see https://github.com/sinonjs/sinon/issues/1852#issuecomment-419622780)" ); } var clock = { now: start, timeouts: {}, Date: createDate(), loopLimit: loopLimit }; clock.Date.clock = clock; function getTimeToNextFrame() { return 16 - ((clock.now - start) % 16); } function hrtime(prev) { var millisSinceStart = clock.now - adjustedSystemTime[0] - start; var secsSinceStart = Math.floor(millisSinceStart / 1000); var remainderInNanos = (millisSinceStart - secsSinceStart * 1e3) * 1e6 + nanos - adjustedSystemTime[1]; if (Array.isArray(prev)) { if (prev[1] > 1e9) { throw new TypeError( "Number of nanoseconds can't exceed a billion" ); } var oldSecs = prev[0]; var nanoDiff = remainderInNanos - prev[1]; var secDiff = secsSinceStart - oldSecs; if (nanoDiff < 0) { nanoDiff += 1e9; secDiff -= 1; } return [secDiff, nanoDiff]; } return [secsSinceStart, remainderInNanos]; } if (hrtimeBigintPresent) { hrtime.bigint = function() { var parts = hrtime(); return BigInt(parts[0]) * BigInt(1e9) + BigInt(parts[1]); // eslint-disable-line }; } clock.requestIdleCallback = function requestIdleCallback( func, timeout ) { var timeToNextIdlePeriod = 0; if (clock.countTimers() > 0) { timeToNextIdlePeriod = 50; // const for now } var result = addTimer(clock, { func: func, args: Array.prototype.slice.call(arguments, 2), delay: typeof timeout === "undefined" ? timeToNextIdlePeriod : Math.min(timeout, timeToNextIdlePeriod) }); return result.id || result; }; clock.cancelIdleCallback = function cancelIdleCallback(timerId) { return clearTimer(clock, timerId, "Timeout"); }; 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) { return clearTimer(clock, timerId, "Timeout"); }; clock.nextTick = function nextTick(func) { return enqueueJob(clock, { func: func, args: Array.prototype.slice.call(arguments, 1) }); }; clock.queueMicrotask = function queueMicrotask(func) { return clock.nextTick(func); // explicitly drop additional arguments }; clock.setInterval = function setInterval(func, timeout) { // eslint-disable-next-line no-param-reassign timeout = parseInt(timeout, 10); return addTimer(clock, { func: func, args: Array.prototype.slice.call(arguments, 2), delay: timeout, interval: timeout }); }; clock.clearInterval = function clearInterval(timerId) { return clearTimer(clock, timerId, "Interval"); }; if (setImmediatePresent) { clock.setImmediate = function setImmediate(func) { return addTimer(clock, { func: func, args: Array.prototype.slice.call(arguments, 1), immediate: true }); }; clock.clearImmediate = function clearImmediate(timerId) { return clearTimer(clock, timerId, "Immediate"); }; } clock.countTimers = function countTimers() { return ( Object.keys(clock.timers || {}).length + (clock.jobs || []).length ); }; clock.requestAnimationFrame = function requestAnimationFrame(func) { var result = addTimer(clock, { func: func, delay: getTimeToNextFrame(), args: [clock.now + getTimeToNextFrame()], animation: true }); return result.id || result; }; clock.cancelAnimationFrame = function cancelAnimationFrame(timerId) { return clearTimer(clock, timerId, "AnimationFrame"); }; clock.runMicrotasks = function runMicrotasks() { runJobs(clock); }; function doTick(tickValue, isAsync, resolve, reject) { var msFloat = typeof tickValue === "number" ? tickValue : parseTime(tickValue); var ms = Math.floor(msFloat); var remainder = nanoRemainder(msFloat); var nanosTotal = nanos + remainder; var tickTo = clock.now + ms; if (msFloat < 0) { throw new TypeError("Negative ticks are not supported"); } // adjust for positive overflow if (nanosTotal >= 1e6) { tickTo += 1; nanosTotal -= 1e6; } nanos = nanosTotal; var tickFrom = clock.now; var previous = clock.now; var timer, firstException, oldNow, nextPromiseTick, compensationCheck, postTimerCall; clock.duringTick = true; // perform microtasks oldNow = clock.now; runJobs(clock); if (oldNow !== clock.now) { // compensate for any setSystemTime() call during microtask callback tickFrom += clock.now - oldNow; tickTo += clock.now - oldNow; } function doTickInner() { // perform each timer in the requested range timer = firstTimerInRange(clock, tickFrom, tickTo); // eslint-disable-next-line no-unmodified-loop-condition while (timer && tickFrom <= tickTo) { if (clock.timers[timer.id]) { tickFrom = timer.callAt; clock.now = timer.callAt; oldNow = clock.now; try { runJobs(clock); callTimer(clock, timer); } catch (e) { firstException = firstException || e; } if (isAsync) { // finish up after native setImmediate callback to allow // all native es6 promises to process their callbacks after // each timer fires. originalSetTimeout(nextPromiseTick); return; } compensationCheck(); } postTimerCall(); } // perform process.nextTick()s again oldNow = clock.now; runJobs(clock); if (oldNow !== clock.now) { // compensate for any setSystemTime() call during process.nextTick() callback tickFrom += clock.now - oldNow; tickTo += clock.now - oldNow; } clock.duringTick = false; // corner case: during runJobs new timers were scheduled which could be in the range [clock.now, tickTo] timer = firstTimerInRange(clock, tickFrom, tickTo); if (timer) { try { clock.tick(tickTo - clock.now); // do it all again - for the remainder of the requested range } catch (e) { firstException = firstException || e; } } else { // no timers remaining in the requested range: move the clock all the way to the end clock.now = tickTo; // update nanos nanos = nanosTotal; } if (firstException) { throw firstException; } if (isAsync) { resolve(clock.now); } else { return clock.now; } } nextPromiseTick = isAsync && function() { try { compensationCheck(); postTimerCall(); doTickInner(); } catch (e) { reject(e); } }; compensationCheck = function() { // compensate for any setSystemTime() call during timer callback if (oldNow !== clock.now) { tickFrom += clock.now - oldNow; tickTo += clock.now - oldNow; previous += clock.now - oldNow; } }; postTimerCall = function() { timer = firstTimerInRange(clock, previous, tickTo); previous = tickFrom; }; return doTickInner(); } /** * @param {tickValue} {String|Number} number of milliseconds or a human-readable value like "01:11:15" */ clock.tick = function tick(tickValue) { return doTick(tickValue, false); }; if (typeof _global.Promise !== "undefined") { clock.tickAsync = function tickAsync(ms) { return new _global.Promise(function(resolve, reject) { originalSetTimeout(function() { try { doTick(ms, true, resolve, reject); } catch (e) { reject(e); } }); }); }; } clock.next = function next() { runJobs(clock); var timer = firstTimer(clock); if (!timer) { return clock.now; } clock.duringTick = true; try { clock.now = timer.callAt; callTimer(clock, timer); runJobs(clock); return clock.now; } finally { clock.duringTick = false; } }; if (typeof _global.Promise !== "undefined") { clock.nextAsync = function nextAsync() { return new _global.Promise(function(resolve, reject) { originalSetTimeout(function() { try { var timer = firstTimer(clock); if (!timer) { resolve(clock.now); return; } var err; clock.duringTick = true; clock.now = timer.callAt; try { callTimer(clock, timer); } catch (e) { err = e; } clock.duringTick = false; originalSetTimeout(function() { if (err) { reject(err); } else { resolve(clock.now); } }); } catch (e) { reject(e); } }); }); }; } clock.runAll = function runAll() { var numTimers, i; runJobs(clock); for (i = 0; i < clock.loopLimit; i++) { if (!clock.timers) { return clock.now; } numTimers = keys(clock.timers).length; if (numTimers === 0) { return clock.now; } clock.next(); } throw new Error( "Aborting after running " + clock.loopLimit + " timers, assuming an infinite loop!" ); }; clock.runToFrame = function runToFrame() { return clock.tick(getTimeToNextFrame()); }; if (typeof _global.Promise !== "undefined") { clock.runAllAsync = function runAllAsync() { return new _global.Promise(function(resolve, reject) { var i = 0; function doRun() { originalSetTimeout(function() { try { var numTimers; if (i < clock.loopLimit) { if (!clock.timers) { resolve(clock.now); return; } numTimers = Object.keys(clock.timers) .length; if (numTimers === 0) { resolve(clock.now); return; } clock.next(); i++; doRun(); return; } reject( new Error( "Aborting after running " + clock.loopLimit + " timers, assuming an infinite loop!" ) ); } catch (e) { reject(e); } }); } doRun(); }); }; } clock.runToLast = function runToLast() { var timer = lastTimer(clock); if (!timer) { runJobs(clock); return clock.now; } return clock.tick(timer.callAt - clock.now); }; if (typeof _global.Promise !== "undefined") { clock.runToLastAsync = function runToLastAsync() { return new _global.Promise(function(resolve, reject) { originalSetTimeout(function() { try { var timer = lastTimer(clock); if (!timer) { resolve(clock.now); } resolve(clock.tickAsync(timer.callAt)); } catch (e) { reject(e); } }); }); }; } clock.reset = function reset() { nanos = 0; clock.timers = {}; clock.jobs = []; clock.now = start; }; clock.setSystemTime = function setSystemTime(systemTime) { // determine time difference var newNow = getEpoch(systemTime); var difference = newNow - clock.now; var id, timer; adjustedSystemTime[0] = adjustedSystemTime[0] + difference; adjustedSystemTime[1] = adjustedSystemTime[1] + nanos; // update 'system clock' clock.now = newNow; nanos = 0; // update timers and intervals to keep them stable for (id in clock.timers) { if (clock.timers.hasOwnProperty(id)) { timer = clock.timers[id]; timer.createdAt += difference; timer.callAt += difference; } } }; if (performancePresent) { clock.performance = Object.create(null); if (hasPerformancePrototype) { var proto = _global.Performance.prototype; Object.getOwnPropertyNames(proto).forEach(function(name) { if (name.indexOf("getEntries") === 0) { // match expected return type for getEntries functions clock.performance[name] = NOOP_ARRAY; } else { clock.performance[name] = NOOP; } }); } clock.performance.now = function lolexNow() { var hrt = hrtime(); var millis = hrt[0] * 1000 + hrt[1] / 1e6; return millis; }; } if (hrtimePresent) { clock.hrtime = hrtime; } return clock; } /** * @param config {Object} optional config * @param config.target {Object} the target to install timers in (default `window`) * @param config.now {number|Date} a number (in milliseconds) or a Date object (default epoch) * @param config.toFake {string[]} names of the methods that should be faked. * @param config.loopLimit {number} the maximum number of timers that will be run when calling runAll() * @param config.shouldAdvanceTime {Boolean} tells lolex to increment mocked time automatically (default false) * @param config.advanceTimeDelta {Number} increment mocked time every <> ms (default: 20ms) */ // eslint-disable-next-line complexity function install(config) { if ( arguments.length > 1 || config instanceof Date || Array.isArray(config) || typeof config === "number" ) { throw new TypeError( "lolex.install called with " + String(config) + " lolex 2.0+ requires an object parameter - see https://github.com/sinonjs/lolex" ); } // eslint-disable-next-line no-param-reassign config = typeof config !== "undefined" ? config : {}; config.shouldAdvanceTime = config.shouldAdvanceTime || false; config.advanceTimeDelta = config.advanceTimeDelta || 20; var i, l; var target = config.target || _global; var clock = createClock(config.now, config.loopLimit); clock.uninstall = function() { return uninstall(clock, target, config); }; clock.methods = config.toFake || []; if (clock.methods.length === 0) { // do not fake nextTick by default - GitHub#126 clock.methods = keys(timers).filter(function(key) { return key !== "nextTick" && key !== "queueMicrotask"; }); } for (i = 0, l = clock.methods.length; i < l; i++) { if (clock.methods[i] === "hrtime") { if ( target.process && typeof target.process.hrtime === "function" ) { hijackMethod(target.process, clock.methods[i], clock); } } else if (clock.methods[i] === "nextTick") { if ( target.process && typeof target.process.nextTick === "function" ) { hijackMethod(target.process, clock.methods[i], clock); } } else { if ( clock.methods[i] === "setInterval" && config.shouldAdvanceTime === true ) { var intervalTick = doIntervalTick.bind( null, clock, config.advanceTimeDelta ); var intervalId = target[clock.methods[i]]( intervalTick, config.advanceTimeDelta ); clock.attachedInterval = intervalId; } hijackMethod(target, clock.methods[i], clock); } } return clock; } return { timers: timers, createClock: createClock, install: install, withGlobal: withGlobal }; } var defaultImplementation = withGlobal(globalObject); exports.timers = defaultImplementation.timers; exports.createClock = defaultImplementation.createClock; exports.install = defaultImplementation.install; exports.withGlobal = withGlobal; },{"@sinonjs/commons":7}]},{},[20])(20) });