| (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.FakeTimers = 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<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){ |
| "use strict"; |
| |
| var every = require("./prototypes/array").every; |
| |
| function hasCallsLeft(callMap, spy) { |
| if (callMap[spy.id] === undefined) { |
| callMap[spy.id] = 0; |
| } |
| |
| return callMap[spy.id] < spy.callCount; |
| } |
| |
| function checkAdjacentCalls(callMap, spy, index, spies) { |
| var calledBeforeNext = true; |
| |
| if (index !== spies.length - 1) { |
| calledBeforeNext = spy.calledBefore(spies[index + 1]); |
| } |
| |
| if (hasCallsLeft(callMap, spy) && calledBeforeNext) { |
| callMap[spy.id] += 1; |
| return true; |
| } |
| |
| return false; |
| } |
| |
| module.exports = function calledInOrder(spies) { |
| var callMap = {}; |
| // eslint-disable-next-line no-underscore-dangle |
| var _spies = arguments.length > 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 <[email protected]> |
| * 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){ |
| if (typeof Object.create === 'function') { |
| // implementation from standard node.js 'util' module |
| module.exports = function inherits(ctor, superCtor) { |
| ctor.super_ = superCtor |
| ctor.prototype = Object.create(superCtor.prototype, { |
| constructor: { |
| value: ctor, |
| enumerable: false, |
| writable: true, |
| configurable: true |
| } |
| }); |
| }; |
| } else { |
| // old school shim for old browsers |
| module.exports = function inherits(ctor, superCtor) { |
| ctor.super_ = superCtor |
| var TempCtor = function () {} |
| TempCtor.prototype = superCtor.prototype |
| ctor.prototype = new TempCtor() |
| ctor.prototype.constructor = ctor |
| } |
| } |
| |
| },{}],21:[function(require,module,exports){ |
| module.exports = function isBuffer(arg) { |
| return arg && typeof arg === 'object' |
| && typeof arg.copy === 'function' |
| && typeof arg.fill === 'function' |
| && typeof arg.readUInt8 === 'function'; |
| } |
| },{}],22:[function(require,module,exports){ |
| // Copyright Joyent, Inc. and other Node contributors. |
| // |
| // Permission is hereby granted, free of charge, to any person obtaining a |
| // copy of this software and associated documentation files (the |
| // "Software"), to deal in the Software without restriction, including |
| // without limitation the rights to use, copy, modify, merge, publish, |
| // distribute, sublicense, and/or sell copies of the Software, and to permit |
| // persons to whom the Software is furnished to do so, subject to the |
| // following conditions: |
| // |
| // The above copyright notice and this permission notice shall be included |
| // in all copies or substantial portions of the Software. |
| // |
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
| // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
| // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN |
| // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
| // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR |
| // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE |
| // USE OR OTHER DEALINGS IN THE SOFTWARE. |
| |
| var formatRegExp = /%[sdj%]/g; |
| exports.format = function(f) { |
| if (!isString(f)) { |
| var objects = []; |
| for (var i = 0; i < arguments.length; i++) { |
| objects.push(inspect(arguments[i])); |
| } |
| return objects.join(' '); |
| } |
| |
| var i = 1; |
| var args = arguments; |
| var len = args.length; |
| var str = String(f).replace(formatRegExp, function(x) { |
| if (x === '%%') return '%'; |
| if (i >= len) return x; |
| switch (x) { |
| case '%s': return String(args[i++]); |
| case '%d': return Number(args[i++]); |
| case '%j': |
| try { |
| return JSON.stringify(args[i++]); |
| } catch (_) { |
| return '[Circular]'; |
| } |
| default: |
| return x; |
| } |
| }); |
| for (var x = args[i]; i < len; x = args[++i]) { |
| if (isNull(x) || !isObject(x)) { |
| str += ' ' + x; |
| } else { |
| str += ' ' + inspect(x); |
| } |
| } |
| return str; |
| }; |
| |
| |
| // Mark that a method should not be used. |
| // Returns a modified function which warns once by default. |
| // If --no-deprecation is set, then it is a no-op. |
| exports.deprecate = function(fn, msg) { |
| // Allow for deprecating things in the process of starting up. |
| if (isUndefined(global.process)) { |
| return function() { |
| return exports.deprecate(fn, msg).apply(this, arguments); |
| }; |
| } |
| |
| if (process.noDeprecation === true) { |
| return fn; |
| } |
| |
| var warned = false; |
| function deprecated() { |
| if (!warned) { |
| if (process.throwDeprecation) { |
| throw new Error(msg); |
| } else if (process.traceDeprecation) { |
| console.trace(msg); |
| } else { |
| console.error(msg); |
| } |
| warned = true; |
| } |
| return fn.apply(this, arguments); |
| } |
| |
| return deprecated; |
| }; |
| |
| |
| var debugs = {}; |
| var debugEnviron; |
| exports.debuglog = function(set) { |
| if (isUndefined(debugEnviron)) |
| debugEnviron = process.env.NODE_DEBUG || ''; |
| set = set.toUpperCase(); |
| if (!debugs[set]) { |
| if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) { |
| var pid = process.pid; |
| debugs[set] = function() { |
| var msg = exports.format.apply(exports, arguments); |
| console.error('%s %d: %s', set, pid, msg); |
| }; |
| } else { |
| debugs[set] = function() {}; |
| } |
| } |
| return debugs[set]; |
| }; |
| |
| |
| /** |
| * Echos the value of a value. Trys to print the value out |
| * in the best way possible given the different types. |
| * |
| * @param {Object} obj The object to print out. |
| * @param {Object} opts Optional options object that alters the output. |
| */ |
| /* legacy: obj, showHidden, depth, colors*/ |
| function inspect(obj, opts) { |
| // default options |
| var ctx = { |
| seen: [], |
| stylize: stylizeNoColor |
| }; |
| // legacy... |
| if (arguments.length >= 3) ctx.depth = arguments[2]; |
| if (arguments.length >= 4) ctx.colors = arguments[3]; |
| if (isBoolean(opts)) { |
| // legacy... |
| ctx.showHidden = opts; |
| } else if (opts) { |
| // got an "options" object |
| exports._extend(ctx, opts); |
| } |
| // set default options |
| if (isUndefined(ctx.showHidden)) ctx.showHidden = false; |
| if (isUndefined(ctx.depth)) ctx.depth = 2; |
| if (isUndefined(ctx.colors)) ctx.colors = false; |
| if (isUndefined(ctx.customInspect)) ctx.customInspect = true; |
| if (ctx.colors) ctx.stylize = stylizeWithColor; |
| return formatValue(ctx, obj, ctx.depth); |
| } |
| exports.inspect = inspect; |
| |
| |
| // http://en.wikipedia.org/wiki/ANSI_escape_code#graphics |
| inspect.colors = { |
| 'bold' : [1, 22], |
| 'italic' : [3, 23], |
| 'underline' : [4, 24], |
| 'inverse' : [7, 27], |
| 'white' : [37, 39], |
| 'grey' : [90, 39], |
| 'black' : [30, 39], |
| 'blue' : [34, 39], |
| 'cyan' : [36, 39], |
| 'green' : [32, 39], |
| 'magenta' : [35, 39], |
| 'red' : [31, 39], |
| 'yellow' : [33, 39] |
| }; |
| |
| // Don't use 'blue' not visible on cmd.exe |
| inspect.styles = { |
| 'special': 'cyan', |
| 'number': 'yellow', |
| 'boolean': 'yellow', |
| 'undefined': 'grey', |
| 'null': 'bold', |
| 'string': 'green', |
| 'date': 'magenta', |
| // "name": intentionally not styling |
| 'regexp': 'red' |
| }; |
| |
| |
| function stylizeWithColor(str, styleType) { |
| var style = inspect.styles[styleType]; |
| |
| if (style) { |
| return '\u001b[' + inspect.colors[style][0] + 'm' + str + |
| '\u001b[' + inspect.colors[style][1] + 'm'; |
| } else { |
| return str; |
| } |
| } |
| |
| |
| function stylizeNoColor(str, styleType) { |
| return str; |
| } |
| |
| |
| function arrayToHash(array) { |
| var hash = {}; |
| |
| array.forEach(function(val, idx) { |
| hash[val] = true; |
| }); |
| |
| return hash; |
| } |
| |
| |
| function formatValue(ctx, value, recurseTimes) { |
| // Provide a hook for user-specified inspect functions. |
| // Check that value is an object with an inspect function on it |
| if (ctx.customInspect && |
| value && |
| isFunction(value.inspect) && |
| // Filter out the util module, it's inspect function is special |
| value.inspect !== exports.inspect && |
| // Also filter out any prototype objects using the circular check. |
| !(value.constructor && value.constructor.prototype === value)) { |
| var ret = value.inspect(recurseTimes, ctx); |
| if (!isString(ret)) { |
| ret = formatValue(ctx, ret, recurseTimes); |
| } |
| return ret; |
| } |
| |
| // Primitive types cannot have properties |
| var primitive = formatPrimitive(ctx, value); |
| if (primitive) { |
| return primitive; |
| } |
| |
| // Look up the keys of the object. |
| var keys = Object.keys(value); |
| var visibleKeys = arrayToHash(keys); |
| |
| if (ctx.showHidden) { |
| keys = Object.getOwnPropertyNames(value); |
| } |
| |
| // IE doesn't make error fields non-enumerable |
| // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx |
| if (isError(value) |
| && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) { |
| return formatError(value); |
| } |
| |
| // Some type of object without properties can be shortcutted. |
| if (keys.length === 0) { |
| if (isFunction(value)) { |
| var name = value.name ? ': ' + value.name : ''; |
| return ctx.stylize('[Function' + name + ']', 'special'); |
| } |
| if (isRegExp(value)) { |
| return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); |
| } |
| if (isDate(value)) { |
| return ctx.stylize(Date.prototype.toString.call(value), 'date'); |
| } |
| if (isError(value)) { |
| return formatError(value); |
| } |
| } |
| |
| var base = '', array = false, braces = ['{', '}']; |
| |
| // Make Array say that they are Array |
| if (isArray(value)) { |
| array = true; |
| braces = ['[', ']']; |
| } |
| |
| // Make functions say that they are functions |
| if (isFunction(value)) { |
| var n = value.name ? ': ' + value.name : ''; |
| base = ' [Function' + n + ']'; |
| } |
| |
| // Make RegExps say that they are RegExps |
| if (isRegExp(value)) { |
| base = ' ' + RegExp.prototype.toString.call(value); |
| } |
| |
| // Make dates with properties first say the date |
| if (isDate(value)) { |
| base = ' ' + Date.prototype.toUTCString.call(value); |
| } |
| |
| // Make error with message first say the error |
| if (isError(value)) { |
| base = ' ' + formatError(value); |
| } |
| |
| if (keys.length === 0 && (!array || value.length == 0)) { |
| return braces[0] + base + braces[1]; |
| } |
| |
| if (recurseTimes < 0) { |
| if (isRegExp(value)) { |
| return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); |
| } else { |
| return ctx.stylize('[Object]', 'special'); |
| } |
| } |
| |
| ctx.seen.push(value); |
| |
| var output; |
| if (array) { |
| output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); |
| } else { |
| output = keys.map(function(key) { |
| return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); |
| }); |
| } |
| |
| ctx.seen.pop(); |
| |
| return reduceToSingleString(output, base, braces); |
| } |
| |
| |
| function formatPrimitive(ctx, value) { |
| if (isUndefined(value)) |
| return ctx.stylize('undefined', 'undefined'); |
| if (isString(value)) { |
| var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') |
| .replace(/'/g, "\\'") |
| .replace(/\\"/g, '"') + '\''; |
| return ctx.stylize(simple, 'string'); |
| } |
| if (isNumber(value)) |
| return ctx.stylize('' + value, 'number'); |
| if (isBoolean(value)) |
| return ctx.stylize('' + value, 'boolean'); |
| // For some reason typeof null is "object", so special case here. |
| if (isNull(value)) |
| return ctx.stylize('null', 'null'); |
| } |
| |
| |
| function formatError(value) { |
| return '[' + Error.prototype.toString.call(value) + ']'; |
| } |
| |
| |
| function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { |
| var output = []; |
| for (var i = 0, l = value.length; i < l; ++i) { |
| if (hasOwnProperty(value, String(i))) { |
| output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, |
| String(i), true)); |
| } else { |
| output.push(''); |
| } |
| } |
| keys.forEach(function(key) { |
| if (!key.match(/^\d+$/)) { |
| output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, |
| key, true)); |
| } |
| }); |
| return output; |
| } |
| |
| |
| function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { |
| var name, str, desc; |
| desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] }; |
| if (desc.get) { |
| if (desc.set) { |
| str = ctx.stylize('[Getter/Setter]', 'special'); |
| } else { |
| str = ctx.stylize('[Getter]', 'special'); |
| } |
| } else { |
| if (desc.set) { |
| str = ctx.stylize('[Setter]', 'special'); |
| } |
| } |
| if (!hasOwnProperty(visibleKeys, key)) { |
| name = '[' + key + ']'; |
| } |
| if (!str) { |
| if (ctx.seen.indexOf(desc.value) < 0) { |
| if (isNull(recurseTimes)) { |
| str = formatValue(ctx, desc.value, null); |
| } else { |
| str = formatValue(ctx, desc.value, recurseTimes - 1); |
| } |
| if (str.indexOf('\n') > -1) { |
| if (array) { |
| str = str.split('\n').map(function(line) { |
| return ' ' + line; |
| }).join('\n').substr(2); |
| } else { |
| str = '\n' + str.split('\n').map(function(line) { |
| return ' ' + line; |
| }).join('\n'); |
| } |
| } |
| } else { |
| str = ctx.stylize('[Circular]', 'special'); |
| } |
| } |
| if (isUndefined(name)) { |
| if (array && key.match(/^\d+$/)) { |
| return str; |
| } |
| name = JSON.stringify('' + key); |
| if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { |
| name = name.substr(1, name.length - 2); |
| name = ctx.stylize(name, 'name'); |
| } else { |
| name = name.replace(/'/g, "\\'") |
| .replace(/\\"/g, '"') |
| .replace(/(^"|"$)/g, "'"); |
| name = ctx.stylize(name, 'string'); |
| } |
| } |
| |
| return name + ': ' + str; |
| } |
| |
| |
| function reduceToSingleString(output, base, braces) { |
| var numLinesEst = 0; |
| var length = output.reduce(function(prev, cur) { |
| numLinesEst++; |
| if (cur.indexOf('\n') >= 0) numLinesEst++; |
| return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; |
| }, 0); |
| |
| if (length > 60) { |
| return braces[0] + |
| (base === '' ? '' : base + '\n ') + |
| ' ' + |
| output.join(',\n ') + |
| ' ' + |
| braces[1]; |
| } |
| |
| return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; |
| } |
| |
| |
| // NOTE: These type checking functions intentionally don't use `instanceof` |
| // because it is fragile and can be easily faked with `Object.create()`. |
| function isArray(ar) { |
| return Array.isArray(ar); |
| } |
| exports.isArray = isArray; |
| |
| function isBoolean(arg) { |
| return typeof arg === 'boolean'; |
| } |
| exports.isBoolean = isBoolean; |
| |
| function isNull(arg) { |
| return arg === null; |
| } |
| exports.isNull = isNull; |
| |
| function isNullOrUndefined(arg) { |
| return arg == null; |
| } |
| exports.isNullOrUndefined = isNullOrUndefined; |
| |
| function isNumber(arg) { |
| return typeof arg === 'number'; |
| } |
| exports.isNumber = isNumber; |
| |
| function isString(arg) { |
| return typeof arg === 'string'; |
| } |
| exports.isString = isString; |
| |
| function isSymbol(arg) { |
| return typeof arg === 'symbol'; |
| } |
| exports.isSymbol = isSymbol; |
| |
| function isUndefined(arg) { |
| return arg === void 0; |
| } |
| exports.isUndefined = isUndefined; |
| |
| function isRegExp(re) { |
| return isObject(re) && objectToString(re) === '[object RegExp]'; |
| } |
| exports.isRegExp = isRegExp; |
| |
| function isObject(arg) { |
| return typeof arg === 'object' && arg !== null; |
| } |
| exports.isObject = isObject; |
| |
| function isDate(d) { |
| return isObject(d) && objectToString(d) === '[object Date]'; |
| } |
| exports.isDate = isDate; |
| |
| function isError(e) { |
| return isObject(e) && |
| (objectToString(e) === '[object Error]' || e instanceof Error); |
| } |
| exports.isError = isError; |
| |
| function isFunction(arg) { |
| return typeof arg === 'function'; |
| } |
| exports.isFunction = isFunction; |
| |
| function isPrimitive(arg) { |
| return arg === null || |
| typeof arg === 'boolean' || |
| typeof arg === 'number' || |
| typeof arg === 'string' || |
| typeof arg === 'symbol' || // ES6 symbol |
| typeof arg === 'undefined'; |
| } |
| exports.isPrimitive = isPrimitive; |
| |
| exports.isBuffer = require('./support/isBuffer'); |
| |
| function objectToString(o) { |
| return Object.prototype.toString.call(o); |
| } |
| |
| |
| function pad(n) { |
| return n < 10 ? '0' + n.toString(10) : n.toString(10); |
| } |
| |
| |
| var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', |
| 'Oct', 'Nov', 'Dec']; |
| |
| // 26 Feb 16:19:34 |
| function timestamp() { |
| var d = new Date(); |
| var time = [pad(d.getHours()), |
| pad(d.getMinutes()), |
| pad(d.getSeconds())].join(':'); |
| return [d.getDate(), months[d.getMonth()], time].join(' '); |
| } |
| |
| |
| // log is just a thin wrapper to console.log that prepends a timestamp |
| exports.log = function() { |
| console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments)); |
| }; |
| |
| |
| /** |
| * Inherit the prototype methods from one constructor into another. |
| * |
| * The Function.prototype.inherits from lang.js rewritten as a standalone |
| * function (not on Function.prototype). NOTE: If this file is to be loaded |
| * during bootstrapping this function needs to be rewritten using some native |
| * functions as prototype setup using normal JavaScript does not work as |
| * expected during bootstrapping (see mirror.js in r114903). |
| * |
| * @param {function} ctor Constructor function which needs to inherit the |
| * prototype. |
| * @param {function} superCtor Constructor function to inherit prototype from. |
| */ |
| exports.inherits = require('inherits'); |
| |
| exports._extend = function(origin, add) { |
| // Don't do anything if add isn't an object |
| if (!add || !isObject(add)) return origin; |
| |
| var keys = Object.keys(add); |
| var i = keys.length; |
| while (i--) { |
| origin[keys[i]] = add[keys[i]]; |
| } |
| return origin; |
| }; |
| |
| function hasOwnProperty(obj, prop) { |
| return Object.prototype.hasOwnProperty.call(obj, prop); |
| } |
| |
| },{"./support/isBuffer":21,"inherits":20}],23:[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 utilPromisify = _global.process && require("util").promisify; |
| 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 |
| }); |
| }; |
| if (typeof _global.Promise !== "undefined" && utilPromisify) { |
| clock.setTimeout[ |
| utilPromisify.custom |
| ] = function promisifiedSetTimeout(timeout, arg) { |
| return new _global.Promise(function setTimeoutExecutor( |
| resolve |
| ) { |
| addTimer(clock, { |
| func: resolve, |
| args: [arg], |
| 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 |
| }); |
| }; |
| |
| if (typeof _global.Promise !== "undefined" && utilPromisify) { |
| clock.setImmediate[ |
| utilPromisify.custom |
| ] = function promisifiedSetImmediate(arg) { |
| return new _global.Promise(function setImmediateExecutor( |
| resolve |
| ) { |
| addTimer(clock, { |
| func: resolve, |
| args: [arg], |
| 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 FakeTimersNow() { |
| 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 FakeTimers to increment mocked time automatically (default false) |
| * @param config.advanceTimeDelta {Number} increment mocked time every <<advanceTimeDelta>> 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( |
| "FakeTimers.install called with " + |
| String(config) + |
| " install requires an object parameter" |
| ); |
| } |
| |
| // 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,"util":22}]},{},[23])(23) |
| }); |