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(){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){
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 var res = {
251 id: timer.id,
252 ref: function () { return res; },
253 unref: function () { return res; },
254 refresh: function () { return res; }
255 };
256 return res;
257 }
258
259 return timer.id;
260 }
261
262
263 /* eslint consistent-return: "off" */
264 function compareTimers(a, b) {
265 // Sort first by absolute timing
266 if (a.callAt < b.callAt) {
267 return -1;
268 }
269 if (a.callAt > b.callAt) {
270 return 1;
271 }
272
273 // Sort next by immediate, immediate timers take precedence
274 if (a.immediate && !b.immediate) {
275 return -1;
276 }
277 if (!a.immediate && b.immediate) {
278 return 1;
279 }
280
281 // Sort next by creation time, earlier-created timers take precedence
282 if (a.createdAt < b.createdAt) {
283 return -1;
284 }
285 if (a.createdAt > b.createdAt) {
286 return 1;
287 }
288
289 // Sort next by id, lower-id timers take precedence
290 if (a.id < b.id) {
291 return -1;
292 }
293 if (a.id > b.id) {
294 return 1;
295 }
296
297 // As timer ids are unique, no fallback `0` is necessary
298 }
299
300 function firstTimerInRange(clock, from, to) {
301 var timers = clock.timers;
302 var timer = null;
303 var id, isInRange;
304
305 for (id in timers) {
306 if (timers.hasOwnProperty(id)) {
307 isInRange = inRange(from, to, timers[id]);
308
309 if (isInRange && (!timer || compareTimers(timer, timers[id]) === 1)) {
310 timer = timers[id];
311 }
312 }
313 }
314
315 return timer;
316 }
317
318 function firstTimer(clock) {
319 var timers = clock.timers;
320 var timer = null;
321 var id;
322
323 for (id in timers) {
324 if (timers.hasOwnProperty(id)) {
325 if (!timer || compareTimers(timer, timers[id]) === 1) {
326 timer = timers[id];
327 }
328 }
329 }
330
331 return timer;
332 }
333
334 function lastTimer(clock) {
335 var timers = clock.timers;
336 var timer = null;
337 var id;
338
339 for (id in timers) {
340 if (timers.hasOwnProperty(id)) {
341 if (!timer || compareTimers(timer, timers[id]) === -1) {
342 timer = timers[id];
343 }
344 }
345 }
346
347 return timer;
348 }
349
350 function callTimer(clock, timer) {
351 if (typeof timer.interval === "number") {
352 clock.timers[timer.id].callAt += timer.interval;
353 } else {
354 delete clock.timers[timer.id];
355 }
356
357 if (typeof timer.func === "function") {
358 timer.func.apply(null, timer.args);
359 } else {
360 /* eslint no-eval: "off" */
361 eval(timer.func);
362 }
363 }
364
365 function clearTimer(clock, timerId, ttype) {
366 if (!timerId) {
367 // null appears to be allowed in most browsers, and appears to be
368 // relied upon by some libraries, like Bootstrap carousel
369 return;
370 }
371
372 if (!clock.timers) {
373 clock.timers = {};
374 }
375
376 // in Node, timerId is an object with .ref()/.unref(), and
377 // its .id field is the actual timer id.
378 if (typeof timerId === "object") {
379 timerId = timerId.id;
380 }
381
382 if (clock.timers.hasOwnProperty(timerId)) {
383 // check that the ID matches a timer of the correct type
384 var timer = clock.timers[timerId];
385 if (timer.type === ttype) {
386 delete clock.timers[timerId];
387 } else {
388 var clear = ttype === "AnimationFrame" ? "cancelAnimationFrame" : "clear" + ttype;
389 var schedule = timer.type === "AnimationFrame" ? "requestAnimationFrame" : "set" + timer.type;
390 throw new Error("Cannot clear timer: timer created with " + schedule
391 + "() but cleared with " + clear + "()");
392 }
393 }
394 }
395
396 function uninstall(clock, target, config) {
397 var method,
398 i,
399 l;
400 var installedHrTime = "_hrtime";
401 var installedNextTick = "_nextTick";
402
403 for (i = 0, l = clock.methods.length; i < l; i++) {
404 method = clock.methods[i];
405 if (method === "hrtime" && target.process) {
406 target.process.hrtime = clock[installedHrTime];
407 } else if (method === "nextTick" && target.process) {
408 target.process.nextTick = clock[installedNextTick];
409 } else if (method === "performance") {
410 target[method] = clock["_" + method];
411 } else {
412 if (target[method] && target[method].hadOwnProperty) {
413 target[method] = clock["_" + method];
414 if (method === "clearInterval" && config.shouldAdvanceTime === true) {
415 target[method](clock.attachedInterval);
416 }
417 } else {
418 try {
419 delete target[method];
420 } catch (ignore) { /* eslint empty-block: "off" */ }
421 }
422 }
423 }
424
425 // Prevent multiple executions which will completely remove these props
426 clock.methods = [];
427
428 // return pending timers, to enable checking what timers remained on uninstall
429 if (!clock.timers) {
430 return [];
431 }
432 return Object.keys(clock.timers).map(function mapper(key) {
433 return clock.timers[key];
434 });
435 }
436
437 function hijackMethod(target, method, clock) {
438 var prop;
439 clock[method].hadOwnProperty = Object.prototype.hasOwnProperty.call(target, method);
440 clock["_" + method] = target[method];
441
442 if (method === "Date") {
443 var date = mirrorDateProperties(clock[method], target[method]);
444 target[method] = date;
445 } else if (method === "performance") {
446 target[method] = clock[method];
447 } else {
448 target[method] = function () {
449 return clock[method].apply(clock, arguments);
450 };
451
452 for (prop in clock[method]) {
453 if (clock[method].hasOwnProperty(prop)) {
454 target[method][prop] = clock[method][prop];
455 }
456 }
457 }
458
459 target[method].clock = clock;
460 }
461
462 function doIntervalTick(clock, advanceTimeDelta) {
463 clock.tick(advanceTimeDelta);
464 }
465
466 var timers = {
467 setTimeout: _global.setTimeout,
468 clearTimeout: _global.clearTimeout,
469 setImmediate: _global.setImmediate,
470 clearImmediate: _global.clearImmediate,
471 setInterval: _global.setInterval,
472 clearInterval: _global.clearInterval,
473 Date: _global.Date
474 };
475
476 if (hrtimePresent) {
477 timers.hrtime = _global.process.hrtime;
478 }
479
480 if (nextTickPresent) {
481 timers.nextTick = _global.process.nextTick;
482 }
483
484 if (performancePresent) {
485 timers.performance = _global.performance;
486 }
487
488 if (requestAnimationFramePresent) {
489 timers.requestAnimationFrame = _global.requestAnimationFrame;
490 }
491
492 if (cancelAnimationFramePresent) {
493 timers.cancelAnimationFrame = _global.cancelAnimationFrame;
494 }
495
496 var keys = Object.keys || function (obj) {
497 var ks = [];
498 var key;
499
500 for (key in obj) {
501 if (obj.hasOwnProperty(key)) {
502 ks.push(key);
503 }
504 }
505
506 return ks;
507 };
508
509 /**
510 * @param start {Date|number} the system time
511 * @param loopLimit {number} maximum number of timers that will be run when calling runAll()
512 */
513 function createClock(start, loopLimit) {
514 start = start || 0;
515 loopLimit = loopLimit || 1000;
516
517 var clock = {
518 now: getEpoch(start),
519 hrNow: 0,
520 timeouts: {},
521 Date: createDate(),
522 loopLimit: loopLimit
523 };
524
525 clock.Date.clock = clock;
526
527 function getTimeToNextFrame() {
528 return 16 - ((clock.now - start) % 16);
529 }
530
531 clock.setTimeout = function setTimeout(func, timeout) {
532 return addTimer(clock, {
533 func: func,
534 args: Array.prototype.slice.call(arguments, 2),
535 delay: timeout
536 });
537 };
538
539 clock.clearTimeout = function clearTimeout(timerId) {
540 return clearTimer(clock, timerId, "Timeout");
541 };
542 clock.nextTick = function nextTick(func) {
543 return enqueueJob(clock, {
544 func: func,
545 args: Array.prototype.slice.call(arguments, 1)
546 });
547 };
548 clock.setInterval = function setInterval(func, timeout) {
549 return addTimer(clock, {
550 func: func,
551 args: Array.prototype.slice.call(arguments, 2),
552 delay: timeout,
553 interval: timeout
554 });
555 };
556
557 clock.clearInterval = function clearInterval(timerId) {
558 return clearTimer(clock, timerId, "Interval");
559 };
560
561 clock.setImmediate = function setImmediate(func) {
562 return addTimer(clock, {
563 func: func,
564 args: Array.prototype.slice.call(arguments, 1),
565 immediate: true
566 });
567 };
568
569 clock.clearImmediate = function clearImmediate(timerId) {
570 return clearTimer(clock, timerId, "Immediate");
571 };
572
573 clock.requestAnimationFrame = function requestAnimationFrame(func) {
574 var result = addTimer(clock, {
575 func: func,
576 delay: getTimeToNextFrame(),
577 args: [clock.now + getTimeToNextFrame()],
578 animation: true
579 });
580
581 return result.id || result;
582 };
583
584 clock.cancelAnimationFrame = function cancelAnimationFrame(timerId) {
585 return clearTimer(clock, timerId, "AnimationFrame");
586 };
587
588 function updateHrTime(newNow) {
589 clock.hrNow += (newNow - clock.now);
590 }
591
592 clock.runMicrotasks = function runMicrotasks() {
593 runJobs(clock);
594 };
595
596 clock.tick = function tick(ms) {
597 ms = typeof ms === "number" ? ms : parseTime(ms);
598 var tickFrom = clock.now;
599 var tickTo = clock.now + ms;
600 var previous = clock.now;
601 var timer, firstException, oldNow;
602
603 clock.duringTick = true;
604
605 // perform process.nextTick()s
606 oldNow = clock.now;
607 runJobs(clock);
608 if (oldNow !== clock.now) {
609 // compensate for any setSystemTime() call during process.nextTick() callback
610 tickFrom += clock.now - oldNow;
611 tickTo += clock.now - oldNow;
612 }
613
614 // perform each timer in the requested range
615 timer = firstTimerInRange(clock, tickFrom, tickTo);
616 while (timer && tickFrom <= tickTo) {
617 if (clock.timers[timer.id]) {
618 updateHrTime(timer.callAt);
619 tickFrom = timer.callAt;
620 clock.now = timer.callAt;
621 oldNow = clock.now;
622 try {
623 runJobs(clock);
624 callTimer(clock, timer);
625 } catch (e) {
626 firstException = firstException || e;
627 }
628
629 // compensate for any setSystemTime() call during timer callback
630 if (oldNow !== clock.now) {
631 tickFrom += clock.now - oldNow;
632 tickTo += clock.now - oldNow;
633 previous += clock.now - oldNow;
634 }
635 }
636
637 timer = firstTimerInRange(clock, previous, tickTo);
638 previous = tickFrom;
639 }
640
641 // perform process.nextTick()s again
642 oldNow = clock.now;
643 runJobs(clock);
644 if (oldNow !== clock.now) {
645 // compensate for any setSystemTime() call during process.nextTick() callback
646 tickFrom += clock.now - oldNow;
647 tickTo += clock.now - oldNow;
648 }
649 clock.duringTick = false;
650
651 // corner case: during runJobs, new timers were scheduled which could be in the range [clock.now, tickTo]
652 timer = firstTimerInRange(clock, tickFrom, tickTo);
653 if (timer) {
654 try {
655 clock.tick(tickTo - clock.now); // do it all again - for the remainder of the requested range
656 } catch (e) {
657 firstException = firstException || e;
658 }
659 } else {
660 // no timers remaining in the requested range: move the clock all the way to the end
661 updateHrTime(tickTo);
662 clock.now = tickTo;
663 }
664 if (firstException) {
665 throw firstException;
666 }
667 return clock.now;
668 };
669
670 clock.next = function next() {
671 runJobs(clock);
672 var timer = firstTimer(clock);
673 if (!timer) {
674 return clock.now;
675 }
676
677 clock.duringTick = true;
678 try {
679 updateHrTime(timer.callAt);
680 clock.now = timer.callAt;
681 callTimer(clock, timer);
682 runJobs(clock);
683 return clock.now;
684 } finally {
685 clock.duringTick = false;
686 }
687 };
688
689 clock.runAll = function runAll() {
690 var numTimers, i;
691 runJobs(clock);
692 for (i = 0; i < clock.loopLimit; i++) {
693 if (!clock.timers) {
694 return clock.now;
695 }
696
697 numTimers = keys(clock.timers).length;
698 if (numTimers === 0) {
699 return clock.now;
700 }
701
702 clock.next();
703 }
704
705 throw new Error("Aborting after running " + clock.loopLimit + " timers, assuming an infinite loop!");
706 };
707
708 clock.runToFrame = function runToFrame() {
709 return clock.tick(getTimeToNextFrame());
710 };
711
712 clock.runToLast = function runToLast() {
713 var timer = lastTimer(clock);
714 if (!timer) {
715 runJobs(clock);
716 return clock.now;
717 }
718
719 return clock.tick(timer.callAt);
720 };
721
722 clock.reset = function reset() {
723 clock.timers = {};
724 clock.jobs = [];
725 clock.now = getEpoch(start);
726 };
727
728 clock.setSystemTime = function setSystemTime(systemTime) {
729 // determine time difference
730 var newNow = getEpoch(systemTime);
731 var difference = newNow - clock.now;
732 var id, timer;
733
734 // update 'system clock'
735 clock.now = newNow;
736
737 // update timers and intervals to keep them stable
738 for (id in clock.timers) {
739 if (clock.timers.hasOwnProperty(id)) {
740 timer = clock.timers[id];
741 timer.createdAt += difference;
742 timer.callAt += difference;
743 }
744 }
745 };
746
747 if (performancePresent) {
748 clock.performance = Object.create(_global.performance);
749
750
751 if (performanceConstructorExists) {
752 var proto = _global.Performance.prototype;
753
754 Object
755 .getOwnPropertyNames(proto)
756 .forEach(function (name) {
757 if (Object.getOwnPropertyDescriptor(proto, name).writable) {
758 clock.performance[name] = proto[name];
759 }
760 });
761 }
762
763 clock.performance.now = function lolexNow() {
764 return clock.hrNow;
765 };
766 }
767 if (hrtimePresent) {
768 clock.hrtime = function (prev) {
769 if (Array.isArray(prev)) {
770 var oldSecs = (prev[0] + prev[1] / 1e9);
771 var newSecs = (clock.hrNow / 1000);
772 var difference = (newSecs - oldSecs);
773 var secs = fixedFloor(difference);
774 var nanosecs = fixedModulo(difference * 1e9, 1e9);
775 return [
776 secs,
777 nanosecs
778 ];
779 }
780 return [
781 fixedFloor(clock.hrNow / 1000),
782 fixedModulo(clock.hrNow * 1e6, 1e9)
783 ];
784 };
785 }
786
787 return clock;
788 }
789
790 /**
791 * @param config {Object} optional config
792 * @param config.target {Object} the target to install timers in (default `window`)
793 * @param config.now {number|Date} a number (in milliseconds) or a Date object (default epoch)
794 * @param config.toFake {string[]} names of the methods that should be faked.
795 * @param config.loopLimit {number} the maximum number of timers that will be run when calling runAll()
796 * @param config.shouldAdvanceTime {Boolean} tells lolex to increment mocked time automatically (default false)
797 * @param config.advanceTimeDelta {Number} increment mocked time every <<advanceTimeDelta>> ms (default: 20ms)
798 */
799 function install(config) {
800 if ( arguments.length > 1 || config instanceof Date || Array.isArray(config) || typeof config === "number") {
801 throw new TypeError("lolex.install called with " + String(config) +
802 " lolex 2.0+ requires an object parameter - see https://github.com/sinonjs/lolex");
803 }
804 config = typeof config !== "undefined" ? config : {};
805 config.shouldAdvanceTime = config.shouldAdvanceTime || false;
806 config.advanceTimeDelta = config.advanceTimeDelta || 20;
807
808 var i, l;
809 var target = config.target || _global;
810 var clock = createClock(config.now, config.loopLimit);
811
812 clock.uninstall = function () {
813 return uninstall(clock, target, config);
814 };
815
816 clock.methods = config.toFake || [];
817
818 if (clock.methods.length === 0) {
819 // do not fake nextTick by default - GitHub#126
820 clock.methods = keys(timers).filter(function (key) {return key !== "nextTick";});
821 }
822
823 for (i = 0, l = clock.methods.length; i < l; i++) {
824 if (clock.methods[i] === "hrtime") {
825 if (target.process && typeof target.process.hrtime === "function") {
826 hijackMethod(target.process, clock.methods[i], clock);
827 }
828 } else if (clock.methods[i] === "nextTick") {
829 if (target.process && typeof target.process.nextTick === "function") {
830 hijackMethod(target.process, clock.methods[i], clock);
831 }
832 } else {
833 if (clock.methods[i] === "setInterval" && config.shouldAdvanceTime === true) {
834 var intervalTick = doIntervalTick.bind(null, clock, config.advanceTimeDelta);
835 var intervalId = target[clock.methods[i]](
836 intervalTick,
837 config.advanceTimeDelta);
838 clock.attachedInterval = intervalId;
839 }
840 hijackMethod(target, clock.methods[i], clock);
841 }
842 }
843
844 return clock;
845 }
846
847 return {
848 timers: timers,
849 createClock: createClock,
850 install: install,
851 withGlobal: withGlobal
852 };
853}
854
855var defaultImplementation = withGlobal(global || window);
856
857exports.timers = defaultImplementation.timers;
858exports.createClock = defaultImplementation.createClock;
859exports.install = defaultImplementation.install;
860exports.withGlobal = withGlobal;
861
862}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
863},{}]},{},[1])(1)
864});