UNPKG

29.2 kBJavaScriptView Raw
1(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 e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
2(function (global){
3"use strict";
4
5function withGlobal(_global) {
6 var userAgent = _global.navigator && _global.navigator.userAgent;
7 var isRunningInIE = userAgent && userAgent.indexOf("MSIE ") > -1;
8 var maxTimeout = Math.pow(2, 31) - 1; //see https://heycam.github.io/webidl/#abstract-opdef-converttoint
9
10 // Make properties writable in IE, as per
11 // http://www.adequatelygood.com/Replacing-setTimeout-Globally.html
12 if (isRunningInIE) {
13 _global.setTimeout = _global.setTimeout;
14 _global.clearTimeout = _global.clearTimeout;
15 _global.setInterval = _global.setInterval;
16 _global.clearInterval = _global.clearInterval;
17 _global.Date = _global.Date;
18 }
19
20 // setImmediate is not a standard function
21 // avoid adding the prop to the window object if not present
22 if (_global.setImmediate !== undefined) {
23 _global.setImmediate = _global.setImmediate;
24 _global.clearImmediate = _global.clearImmediate;
25 }
26
27 // node expects setTimeout/setInterval to return a fn object w/ .ref()/.unref()
28 // browsers, a number.
29 // see https://github.com/cjohansen/Sinon.JS/pull/436
30
31 var NOOP = function () { return undefined; };
32 var timeoutResult = _global.setTimeout(NOOP, 0);
33 var addTimerReturnsObject = typeof timeoutResult === "object";
34 var hrtimePresent = (_global.process && typeof _global.process.hrtime === "function");
35 var nextTickPresent = (_global.process && typeof _global.process.nextTick === "function");
36 var performancePresent = (_global.performance && typeof _global.performance.now === "function");
37 var performanceConstructorExists = (_global.Performance && typeof _global.Performance === "function");
38 var requestAnimationFramePresent = (
39 _global.requestAnimationFrame && typeof _global.requestAnimationFrame === "function"
40 );
41 var cancelAnimationFramePresent = (
42 _global.cancelAnimationFrame && typeof _global.cancelAnimationFrame === "function"
43 );
44
45 _global.clearTimeout(timeoutResult);
46
47 var NativeDate = _global.Date;
48 var uniqueTimerId = 1;
49
50 function isNumberFinite(num) {
51 if (Number.isFinite) {
52 return Number.isFinite(num);
53 }
54
55 if (typeof num !== "number") {
56 return false;
57 }
58
59 return isFinite(num);
60 }
61
62 /**
63 * Parse strings like "01:10:00" (meaning 1 hour, 10 minutes, 0 seconds) into
64 * number of milliseconds. This is used to support human-readable strings passed
65 * to clock.tick()
66 */
67 function parseTime(str) {
68 if (!str) {
69 return 0;
70 }
71
72 var strings = str.split(":");
73 var l = strings.length;
74 var i = l;
75 var ms = 0;
76 var parsed;
77
78 if (l > 3 || !/^(\d\d:){0,2}\d\d?$/.test(str)) {
79 throw new Error("tick only understands numbers, 'm:s' and 'h:m:s'. Each part must be two digits");
80 }
81
82 while (i--) {
83 parsed = parseInt(strings[i], 10);
84
85 if (parsed >= 60) {
86 throw new Error("Invalid time " + str);
87 }
88
89 ms += parsed * Math.pow(60, (l - i - 1));
90 }
91
92 return ms * 1000;
93 }
94
95 /**
96 * Floor function that also works for negative numbers
97 */
98 function fixedFloor(n) {
99 return (n >= 0 ? Math.floor(n) : Math.ceil(n));
100 }
101
102 /**
103 * % operator that also works for negative numbers
104 */
105 function fixedModulo(n, m) {
106 return ((n % m) + m) % m;
107 }
108
109 /**
110 * Used to grok the `now` parameter to createClock.
111 * @param epoch {Date|number} the system time
112 */
113 function getEpoch(epoch) {
114 if (!epoch) { return 0; }
115 if (typeof epoch.getTime === "function") { return epoch.getTime(); }
116 if (typeof epoch === "number") { return epoch; }
117 throw new TypeError("now should be milliseconds since UNIX epoch");
118 }
119
120 function inRange(from, to, timer) {
121 return timer && timer.callAt >= from && timer.callAt <= to;
122 }
123
124 function mirrorDateProperties(target, source) {
125 var prop;
126 for (prop in source) {
127 if (source.hasOwnProperty(prop)) {
128 target[prop] = source[prop];
129 }
130 }
131
132 // set special now implementation
133 if (source.now) {
134 target.now = function now() {
135 return target.clock.now;
136 };
137 } else {
138 delete target.now;
139 }
140
141 // set special toSource implementation
142 if (source.toSource) {
143 target.toSource = function toSource() {
144 return source.toSource();
145 };
146 } else {
147 delete target.toSource;
148 }
149
150 // set special toString implementation
151 target.toString = function toString() {
152 return source.toString();
153 };
154
155 target.prototype = source.prototype;
156 target.parse = source.parse;
157 target.UTC = source.UTC;
158 target.prototype.toUTCString = source.prototype.toUTCString;
159
160 return target;
161 }
162
163 function createDate() {
164 function ClockDate(year, month, date, hour, minute, second, ms) {
165 // Defensive and verbose to avoid potential harm in passing
166 // explicit undefined when user does not pass argument
167 switch (arguments.length) {
168 case 0:
169 return new NativeDate(ClockDate.clock.now);
170 case 1:
171 return new NativeDate(year);
172 case 2:
173 return new NativeDate(year, month);
174 case 3:
175 return new NativeDate(year, month, date);
176 case 4:
177 return new NativeDate(year, month, date, hour);
178 case 5:
179 return new NativeDate(year, month, date, hour, minute);
180 case 6:
181 return new NativeDate(year, month, date, hour, minute, second);
182 default:
183 return new NativeDate(year, month, date, hour, minute, second, ms);
184 }
185 }
186
187 return mirrorDateProperties(ClockDate, NativeDate);
188 }
189
190
191 function enqueueJob(clock, job) {
192 // enqueues a microtick-deferred task - ecma262/#sec-enqueuejob
193 if (!clock.jobs) {
194 clock.jobs = [];
195 }
196 clock.jobs.push(job);
197 }
198
199 function runJobs(clock) {
200 // runs all microtick-deferred tasks - ecma262/#sec-runjobs
201 if (!clock.jobs) {
202 return;
203 }
204 for (var i = 0; i < clock.jobs.length; i++) {
205 var job = clock.jobs[i];
206 job.func.apply(null, job.args);
207 if (clock.loopLimit && i > clock.loopLimit) {
208 throw new Error("Aborting after running " + clock.loopLimit + " timers, assuming an infinite loop!");
209 }
210 }
211 clock.jobs = [];
212 }
213
214 function addTimer(clock, timer) {
215 if (timer.func === undefined) {
216 throw new Error("Callback must be provided to timer calls");
217 }
218
219 timer.type = timer.immediate ? "Immediate" : "Timeout";
220
221 if (timer.hasOwnProperty("delay")) {
222 if (!isNumberFinite(timer.delay)) {
223 timer.delay = 0;
224 }
225 timer.delay = timer.delay > maxTimeout ? 1 : timer.delay;
226 timer.delay = Math.max(0, timer.delay);
227 }
228
229 if (timer.hasOwnProperty("interval")) {
230 timer.type = "Interval";
231 timer.interval = timer.interval > maxTimeout ? 1 : timer.interval;
232 }
233
234 if (timer.hasOwnProperty("animation")) {
235 timer.type = "AnimationFrame";
236 timer.animation = true;
237 }
238
239 if (!clock.timers) {
240 clock.timers = {};
241 }
242
243 timer.id = uniqueTimerId++;
244 timer.createdAt = clock.now;
245 timer.callAt = clock.now + (parseInt(timer.delay) || (clock.duringTick ? 1 : 0));
246
247 clock.timers[timer.id] = timer;
248
249 if (addTimerReturnsObject) {
250 return {
251 id: timer.id,
252 ref: NOOP,
253 unref: NOOP
254 };
255 }
256
257 return timer.id;
258 }
259
260
261 /* eslint consistent-return: "off" */
262 function compareTimers(a, b) {
263 // Sort first by absolute timing
264 if (a.callAt < b.callAt) {
265 return -1;
266 }
267 if (a.callAt > b.callAt) {
268 return 1;
269 }
270
271 // Sort next by immediate, immediate timers take precedence
272 if (a.immediate && !b.immediate) {
273 return -1;
274 }
275 if (!a.immediate && b.immediate) {
276 return 1;
277 }
278
279 // Sort next by creation time, earlier-created timers take precedence
280 if (a.createdAt < b.createdAt) {
281 return -1;
282 }
283 if (a.createdAt > b.createdAt) {
284 return 1;
285 }
286
287 // Sort next by id, lower-id timers take precedence
288 if (a.id < b.id) {
289 return -1;
290 }
291 if (a.id > b.id) {
292 return 1;
293 }
294
295 // As timer ids are unique, no fallback `0` is necessary
296 }
297
298 function firstTimerInRange(clock, from, to) {
299 var timers = clock.timers;
300 var timer = null;
301 var id, isInRange;
302
303 for (id in timers) {
304 if (timers.hasOwnProperty(id)) {
305 isInRange = inRange(from, to, timers[id]);
306
307 if (isInRange && (!timer || compareTimers(timer, timers[id]) === 1)) {
308 timer = timers[id];
309 }
310 }
311 }
312
313 return timer;
314 }
315
316 function firstTimer(clock) {
317 var timers = clock.timers;
318 var timer = null;
319 var id;
320
321 for (id in timers) {
322 if (timers.hasOwnProperty(id)) {
323 if (!timer || compareTimers(timer, timers[id]) === 1) {
324 timer = timers[id];
325 }
326 }
327 }
328
329 return timer;
330 }
331
332 function lastTimer(clock) {
333 var timers = clock.timers;
334 var timer = null;
335 var id;
336
337 for (id in timers) {
338 if (timers.hasOwnProperty(id)) {
339 if (!timer || compareTimers(timer, timers[id]) === -1) {
340 timer = timers[id];
341 }
342 }
343 }
344
345 return timer;
346 }
347
348 function callTimer(clock, timer) {
349 if (typeof timer.interval === "number") {
350 clock.timers[timer.id].callAt += timer.interval;
351 } else {
352 delete clock.timers[timer.id];
353 }
354
355 if (typeof timer.func === "function") {
356 timer.func.apply(null, timer.args);
357 } else {
358 /* eslint no-eval: "off" */
359 eval(timer.func);
360 }
361 }
362
363 function clearTimer(clock, timerId, ttype) {
364 if (!timerId) {
365 // null appears to be allowed in most browsers, and appears to be
366 // relied upon by some libraries, like Bootstrap carousel
367 return;
368 }
369
370 if (!clock.timers) {
371 clock.timers = {};
372 }
373
374 // in Node, timerId is an object with .ref()/.unref(), and
375 // its .id field is the actual timer id.
376 if (typeof timerId === "object") {
377 timerId = timerId.id;
378 }
379
380 if (clock.timers.hasOwnProperty(timerId)) {
381 // check that the ID matches a timer of the correct type
382 var timer = clock.timers[timerId];
383 if (timer.type === ttype) {
384 delete clock.timers[timerId];
385 } else {
386 var clear = ttype === "AnimationFrame" ? "cancelAnimationFrame" : "clear" + ttype;
387 var schedule = timer.type === "AnimationFrame" ? "requestAnimationFrame" : "set" + timer.type;
388 throw new Error("Cannot clear timer: timer created with " + schedule
389 + "() but cleared with " + clear + "()");
390 }
391 }
392 }
393
394 function uninstall(clock, target, config) {
395 var method,
396 i,
397 l;
398 var installedHrTime = "_hrtime";
399 var installedNextTick = "_nextTick";
400
401 for (i = 0, l = clock.methods.length; i < l; i++) {
402 method = clock.methods[i];
403 if (method === "hrtime" && target.process) {
404 target.process.hrtime = clock[installedHrTime];
405 } else if (method === "nextTick" && target.process) {
406 target.process.nextTick = clock[installedNextTick];
407 } else if (method === "performance") {
408 Object.defineProperty(target, method, {
409 writeable: false,
410 value: clock["_" + method]
411 });
412 } else {
413 if (target[method] && target[method].hadOwnProperty) {
414 target[method] = clock["_" + method];
415 if (method === "clearInterval" && config.shouldAdvanceTime === true) {
416 target[method](clock.attachedInterval);
417 }
418 } else {
419 try {
420 delete target[method];
421 } catch (ignore) { /* eslint empty-block: "off" */ }
422 }
423 }
424 }
425
426 // Prevent multiple executions which will completely remove these props
427 clock.methods = [];
428
429 // return pending timers, to enable checking what timers remained on uninstall
430 if (!clock.timers) {
431 return [];
432 }
433 return Object.keys(clock.timers).map(function mapper(key) {
434 return clock.timers[key];
435 });
436 }
437
438 function hijackMethod(target, method, clock) {
439 var prop;
440 clock[method].hadOwnProperty = Object.prototype.hasOwnProperty.call(target, method);
441 clock["_" + method] = target[method];
442
443 if (method === "Date") {
444 var date = mirrorDateProperties(clock[method], target[method]);
445 target[method] = date;
446 } else if (method === "performance") {
447 Object.defineProperty(target, method, {
448 writeable: false,
449 value: clock[method]
450 });
451 } else {
452 target[method] = function () {
453 return clock[method].apply(clock, arguments);
454 };
455
456 for (prop in clock[method]) {
457 if (clock[method].hasOwnProperty(prop)) {
458 target[method][prop] = clock[method][prop];
459 }
460 }
461 }
462
463 target[method].clock = clock;
464 }
465
466 function doIntervalTick(clock, advanceTimeDelta) {
467 clock.tick(advanceTimeDelta);
468 }
469
470 var timers = {
471 setTimeout: _global.setTimeout,
472 clearTimeout: _global.clearTimeout,
473 setImmediate: _global.setImmediate,
474 clearImmediate: _global.clearImmediate,
475 setInterval: _global.setInterval,
476 clearInterval: _global.clearInterval,
477 Date: _global.Date
478 };
479
480 if (hrtimePresent) {
481 timers.hrtime = _global.process.hrtime;
482 }
483
484 if (nextTickPresent) {
485 timers.nextTick = _global.process.nextTick;
486 }
487
488 if (performancePresent) {
489 timers.performance = _global.performance;
490 }
491
492 if (requestAnimationFramePresent) {
493 timers.requestAnimationFrame = _global.requestAnimationFrame;
494 }
495
496 if (cancelAnimationFramePresent) {
497 timers.cancelAnimationFrame = _global.cancelAnimationFrame;
498 }
499
500 var keys = Object.keys || function (obj) {
501 var ks = [];
502 var key;
503
504 for (key in obj) {
505 if (obj.hasOwnProperty(key)) {
506 ks.push(key);
507 }
508 }
509
510 return ks;
511 };
512
513 /**
514 * @param start {Date|number} the system time
515 * @param loopLimit {number} maximum number of timers that will be run when calling runAll()
516 */
517 function createClock(start, loopLimit) {
518 start = start || 0;
519 loopLimit = loopLimit || 1000;
520
521 var clock = {
522 now: getEpoch(start),
523 hrNow: 0,
524 timeouts: {},
525 Date: createDate(),
526 loopLimit: loopLimit
527 };
528
529 clock.Date.clock = clock;
530
531 function getTimeToNextFrame() {
532 return 16 - ((clock.now - start) % 16);
533 }
534
535 clock.setTimeout = function setTimeout(func, timeout) {
536 return addTimer(clock, {
537 func: func,
538 args: Array.prototype.slice.call(arguments, 2),
539 delay: timeout
540 });
541 };
542
543 clock.clearTimeout = function clearTimeout(timerId) {
544 return clearTimer(clock, timerId, "Timeout");
545 };
546 clock.nextTick = function nextTick(func) {
547 return enqueueJob(clock, {
548 func: func,
549 args: Array.prototype.slice.call(arguments, 1)
550 });
551 };
552 clock.setInterval = function setInterval(func, timeout) {
553 return addTimer(clock, {
554 func: func,
555 args: Array.prototype.slice.call(arguments, 2),
556 delay: timeout,
557 interval: timeout
558 });
559 };
560
561 clock.clearInterval = function clearInterval(timerId) {
562 return clearTimer(clock, timerId, "Interval");
563 };
564
565 clock.setImmediate = function setImmediate(func) {
566 return addTimer(clock, {
567 func: func,
568 args: Array.prototype.slice.call(arguments, 1),
569 immediate: true
570 });
571 };
572
573 clock.clearImmediate = function clearImmediate(timerId) {
574 return clearTimer(clock, timerId, "Immediate");
575 };
576
577 clock.requestAnimationFrame = function requestAnimationFrame(func) {
578 var result = addTimer(clock, {
579 func: func,
580 delay: getTimeToNextFrame(),
581 args: [clock.now + getTimeToNextFrame()],
582 animation: true
583 });
584
585 return result.id || result;
586 };
587
588 clock.cancelAnimationFrame = function cancelAnimationFrame(timerId) {
589 return clearTimer(clock, timerId, "AnimationFrame");
590 };
591
592 function updateHrTime(newNow) {
593 clock.hrNow += (newNow - clock.now);
594 }
595
596 clock.runMicrotasks = function runMicrotasks() {
597 runJobs(clock);
598 };
599
600 clock.tick = function tick(ms) {
601 ms = typeof ms === "number" ? ms : parseTime(ms);
602 var tickFrom = clock.now;
603 var tickTo = clock.now + ms;
604 var previous = clock.now;
605 var timer, firstException, oldNow;
606
607 clock.duringTick = true;
608
609 // perform process.nextTick()s
610 oldNow = clock.now;
611 runJobs(clock);
612 if (oldNow !== clock.now) {
613 // compensate for any setSystemTime() call during process.nextTick() callback
614 tickFrom += clock.now - oldNow;
615 tickTo += clock.now - oldNow;
616 }
617
618 // perform each timer in the requested range
619 timer = firstTimerInRange(clock, tickFrom, tickTo);
620 while (timer && tickFrom <= tickTo) {
621 if (clock.timers[timer.id]) {
622 updateHrTime(timer.callAt);
623 tickFrom = timer.callAt;
624 clock.now = timer.callAt;
625 oldNow = clock.now;
626 try {
627 runJobs(clock);
628 callTimer(clock, timer);
629 } catch (e) {
630 firstException = firstException || e;
631 }
632
633 // compensate for any setSystemTime() call during timer callback
634 if (oldNow !== clock.now) {
635 tickFrom += clock.now - oldNow;
636 tickTo += clock.now - oldNow;
637 previous += clock.now - oldNow;
638 }
639 }
640
641 timer = firstTimerInRange(clock, previous, tickTo);
642 previous = tickFrom;
643 }
644
645 // perform process.nextTick()s again
646 oldNow = clock.now;
647 runJobs(clock);
648 if (oldNow !== clock.now) {
649 // compensate for any setSystemTime() call during process.nextTick() callback
650 tickFrom += clock.now - oldNow;
651 tickTo += clock.now - oldNow;
652 }
653 clock.duringTick = false;
654
655 // corner case: during runJobs, new timers were scheduled which could be in the range [clock.now, tickTo]
656 timer = firstTimerInRange(clock, tickFrom, tickTo);
657 if (timer) {
658 try {
659 clock.tick(tickTo - clock.now); // do it all again - for the remainder of the requested range
660 } catch (e) {
661 firstException = firstException || e;
662 }
663 } else {
664 // no timers remaining in the requested range: move the clock all the way to the end
665 updateHrTime(tickTo);
666 clock.now = tickTo;
667 }
668 if (firstException) {
669 throw firstException;
670 }
671 return clock.now;
672 };
673
674 clock.next = function next() {
675 runJobs(clock);
676 var timer = firstTimer(clock);
677 if (!timer) {
678 return clock.now;
679 }
680
681 clock.duringTick = true;
682 try {
683 updateHrTime(timer.callAt);
684 clock.now = timer.callAt;
685 callTimer(clock, timer);
686 runJobs(clock);
687 return clock.now;
688 } finally {
689 clock.duringTick = false;
690 }
691 };
692
693 clock.runAll = function runAll() {
694 var numTimers, i;
695 runJobs(clock);
696 for (i = 0; i < clock.loopLimit; i++) {
697 if (!clock.timers) {
698 return clock.now;
699 }
700
701 numTimers = keys(clock.timers).length;
702 if (numTimers === 0) {
703 return clock.now;
704 }
705
706 clock.next();
707 }
708
709 throw new Error("Aborting after running " + clock.loopLimit + " timers, assuming an infinite loop!");
710 };
711
712 clock.runToFrame = function runToFrame() {
713 return clock.tick(getTimeToNextFrame());
714 };
715
716 clock.runToLast = function runToLast() {
717 var timer = lastTimer(clock);
718 if (!timer) {
719 runJobs(clock);
720 return clock.now;
721 }
722
723 return clock.tick(timer.callAt);
724 };
725
726 clock.reset = function reset() {
727 clock.timers = {};
728 clock.jobs = [];
729 clock.now = getEpoch(start);
730 };
731
732 clock.setSystemTime = function setSystemTime(systemTime) {
733 // determine time difference
734 var newNow = getEpoch(systemTime);
735 var difference = newNow - clock.now;
736 var id, timer;
737
738 // update 'system clock'
739 clock.now = newNow;
740
741 // update timers and intervals to keep them stable
742 for (id in clock.timers) {
743 if (clock.timers.hasOwnProperty(id)) {
744 timer = clock.timers[id];
745 timer.createdAt += difference;
746 timer.callAt += difference;
747 }
748 }
749 };
750
751 if (performancePresent) {
752 clock.performance = Object.create(_global.performance);
753
754
755 if (performanceConstructorExists) {
756 var proto = _global.Performance.prototype;
757
758 Object
759 .getOwnPropertyNames(proto)
760 .forEach(function (name) {
761 if (Object.getOwnPropertyDescriptor(proto, name).writable) {
762 clock.performance[name] = proto[name];
763 }
764 });
765 }
766
767 clock.performance.now = function lolexNow() {
768 return clock.hrNow;
769 };
770 }
771 if (hrtimePresent) {
772 clock.hrtime = function (prev) {
773 if (Array.isArray(prev)) {
774 var oldSecs = (prev[0] + prev[1] / 1e9);
775 var newSecs = (clock.hrNow / 1000);
776 var difference = (newSecs - oldSecs);
777 var secs = fixedFloor(difference);
778 var nanosecs = fixedModulo(difference * 1e9, 1e9);
779 return [
780 secs,
781 nanosecs
782 ];
783 }
784 return [
785 fixedFloor(clock.hrNow / 1000),
786 fixedModulo(clock.hrNow * 1e6, 1e9)
787 ];
788 };
789 }
790
791 return clock;
792 }
793
794 /**
795 * @param config {Object} optional config
796 * @param config.target {Object} the target to install timers in (default `window`)
797 * @param config.now {number|Date} a number (in milliseconds) or a Date object (default epoch)
798 * @param config.toFake {string[]} names of the methods that should be faked.
799 * @param config.loopLimit {number} the maximum number of timers that will be run when calling runAll()
800 * @param config.shouldAdvanceTime {Boolean} tells lolex to increment mocked time automatically (default false)
801 * @param config.advanceTimeDelta {Number} increment mocked time every <<advanceTimeDelta>> ms (default: 20ms)
802 */
803 function install(config) {
804 if ( arguments.length > 1 || config instanceof Date || Array.isArray(config) || typeof config === "number") {
805 throw new TypeError("lolex.install called with " + String(config) +
806 " lolex 2.0+ requires an object parameter - see https://github.com/sinonjs/lolex");
807 }
808 config = typeof config !== "undefined" ? config : {};
809 config.shouldAdvanceTime = config.shouldAdvanceTime || false;
810 config.advanceTimeDelta = config.advanceTimeDelta || 20;
811
812 var i, l;
813 var target = config.target || _global;
814 var clock = createClock(config.now, config.loopLimit);
815
816 clock.uninstall = function () {
817 return uninstall(clock, target, config);
818 };
819
820 clock.methods = config.toFake || [];
821
822 if (clock.methods.length === 0) {
823 // do not fake nextTick by default - GitHub#126
824 clock.methods = keys(timers).filter(function (key) {return key !== "nextTick";});
825 }
826
827 for (i = 0, l = clock.methods.length; i < l; i++) {
828 if (clock.methods[i] === "hrtime") {
829 if (target.process && typeof target.process.hrtime === "function") {
830 hijackMethod(target.process, clock.methods[i], clock);
831 }
832 } else if (clock.methods[i] === "nextTick") {
833 if (target.process && typeof target.process.nextTick === "function") {
834 hijackMethod(target.process, clock.methods[i], clock);
835 }
836 } else {
837 if (clock.methods[i] === "setInterval" && config.shouldAdvanceTime === true) {
838 var intervalTick = doIntervalTick.bind(null, clock, config.advanceTimeDelta);
839 var intervalId = target[clock.methods[i]](
840 intervalTick,
841 config.advanceTimeDelta);
842 clock.attachedInterval = intervalId;
843 }
844 hijackMethod(target, clock.methods[i], clock);
845 }
846 }
847
848 return clock;
849 }
850
851 return {
852 timers: timers,
853 createClock: createClock,
854 install: install,
855 withGlobal: withGlobal
856 };
857}
858
859var defaultImplementation = withGlobal(global || window);
860
861exports.timers = defaultImplementation.timers;
862exports.createClock = defaultImplementation.createClock;
863exports.install = defaultImplementation.install;
864exports.withGlobal = withGlobal;
865
866}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
867},{}]},{},[1])(1)
868});
\No newline at end of file