hyper-spec 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,8 @@
1
+ require 'rails'
2
+
3
+ module HyperSpec
4
+ module Rails
5
+ class Engine < ::Rails::Engine
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,44 @@
1
+ require 'timecop'
2
+
3
+ module HyperSpec
4
+ class Timecop
5
+ private
6
+
7
+ def travel(mock_type, *args, &block)
8
+ raise SafeModeException if Timecop.safe_mode? && !block_given?
9
+
10
+ stack_item = TimeStackItem.new(mock_type, *args)
11
+
12
+ stack_backup = @_stack.dup
13
+ @_stack << stack_item
14
+
15
+ Lolex.push(mock_type, *args)
16
+
17
+ if block_given?
18
+ begin
19
+ yield stack_item.time
20
+ ensure
21
+ Lolex.pop
22
+ @_stack.replace stack_backup
23
+ end
24
+ end
25
+ end
26
+
27
+ def return(&block)
28
+ current_stack = @_stack
29
+ current_baseline = @baseline
30
+ unmock!
31
+ yield
32
+ ensure
33
+ Lolex.restore
34
+ @_stack = current_stack
35
+ @baseline = current_baseline
36
+ end
37
+
38
+ def unmock! #:nodoc:
39
+ @baseline = nil
40
+ @_stack = []
41
+ Lolex.unmock
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,3 @@
1
+ module HyperSpec
2
+ VERSION = '0.1.0'
3
+ end
@@ -0,0 +1,30 @@
1
+ module HyperSpec
2
+ module WaitForAjax
3
+ def wait_for_ajax
4
+ Timeout.timeout(Capybara.default_max_wait_time) do
5
+ loop do
6
+ sleep 0.25
7
+ break if finished_all_ajax_requests?
8
+ end
9
+ end
10
+ end
11
+
12
+ def running?
13
+ result = page.evaluate_script('(function(active) { return active; })(jQuery.active)')
14
+ result && !result.zero?
15
+ rescue Exception => e
16
+ puts "wait_for_ajax failed while testing state of jQuery.active: #{e}"
17
+ end
18
+
19
+ def finished_all_ajax_requests?
20
+ unless running?
21
+ sleep 0.25 # this was 1 second, not sure if its necessary to be so long...
22
+ !running?
23
+ end
24
+ rescue Capybara::NotSupportedByDriverError
25
+ true
26
+ rescue Exception => e
27
+ e.message == 'jQuery is not defined'
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,7 @@
1
+ module React
2
+ module IsomorphicHelpers
3
+ def self.load_context(ctx, controller, name = nil)
4
+ @context = Context.new("#{controller.object_id}-#{Time.now.to_i}", ctx, controller, name)
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,104 @@
1
+ module React
2
+ class TopLevelRailsComponent
3
+ class << self
4
+ attr_accessor :event_history
5
+
6
+ def callback_history_for(proc_name)
7
+ event_history[proc_name]
8
+ end
9
+
10
+ def last_callback_for(proc_name)
11
+ event_history[proc_name].last
12
+ end
13
+
14
+ def clear_callback_history_for(proc_name)
15
+ event_history[proc_name] = []
16
+ end
17
+
18
+ def event_history_for(event_name)
19
+ event_history["_on#{event_name.event_camelize}"]
20
+ end
21
+
22
+ def last_event_for(event_name)
23
+ event_history["_on#{event_name.event_camelize}"].last
24
+ end
25
+
26
+ def clear_event_history_for(event_name)
27
+ event_history["_on#{event_name.event_camelize}"] = []
28
+ end
29
+ end
30
+
31
+ def component
32
+ return @component if @component
33
+ paths_searched = []
34
+
35
+ if params.component_name.start_with?('::')
36
+ paths_searched << params.component_name.gsub(/^\:\:/, '')
37
+
38
+ @component =
39
+ begin
40
+ params.component_name.gsub(/^\:\:/, '').split('::')
41
+ .inject(Module) { |scope, next_const| scope.const_get(next_const, false) }
42
+ rescue
43
+ nil
44
+ end
45
+
46
+ return @component if @component && @component.method_defined?(:render)
47
+ else
48
+ self.class.search_path.each do |path|
49
+ # try each path + params.controller + params.component_name
50
+ paths_searched << "#{path.name + '::' unless path == Module}"\
51
+ "#{params.controller}::#{params.component_name}"
52
+
53
+ @component =
54
+ begin
55
+ [params.controller, params.component_name]
56
+ .join('::').split('::')
57
+ .inject(path) { |scope, next_const| scope.const_get(next_const, false) }
58
+ rescue
59
+ nil
60
+ end
61
+
62
+ return @component if @component && @component.method_defined?(:render)
63
+ end
64
+
65
+ self.class.search_path.each do |path|
66
+ # then try each path + params.component_name
67
+ paths_searched << "#{path.name + '::' unless path == Module}#{params.component_name}"
68
+ @component =
69
+ begin
70
+ params.component_name.to_s.split('::')
71
+ .inject(path) { |scope, next_const| scope.const_get(next_const, false) }
72
+ rescue
73
+ nil
74
+ end
75
+
76
+ return @component if @component && @component.method_defined?(:render)
77
+ end
78
+ end
79
+
80
+ @component = nil
81
+
82
+ raise "Could not find component class '#{params.component_name}' "\
83
+ "for params.controller '#{params.controller}' in any component directory. "\
84
+ "Tried [#{paths_searched.join(', ')}]"
85
+ end
86
+
87
+ before_mount do
88
+ TopLevelRailsComponent.event_history = Hash.new { |h, k| h[k] = [] }
89
+ @render_params = params.render_params
90
+ component.validator.rules.each do |name, rules|
91
+ next unless rules[:type] == Proc
92
+
93
+ TopLevelRailsComponent.event_history[name] = []
94
+ @render_params[name] = lambda do |*args|
95
+ TopLevelRailsComponent.event_history[name] << args.collect { |arg| Native(arg).to_n }
96
+ end
97
+ end
98
+ end
99
+
100
+ def render
101
+ present component, @render_params
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,55 @@
1
+ module Selenium
2
+ module WebDriver
3
+ module Firefox
4
+ class Profile
5
+ class << self
6
+ attr_accessor :firebug_version
7
+
8
+ def firebug_version
9
+ @firebug_version ||= '2.0.13-fx'
10
+ end
11
+ end
12
+
13
+ def frame_position
14
+ @frame_position ||= 'detached'
15
+ end
16
+
17
+ def frame_position=(position)
18
+ @frame_position = %w(left right top detached).detect do |side|
19
+ position && position[0].downcase == side[0]
20
+ end || 'detached'
21
+ end
22
+
23
+ def enable_firebug(version = nil)
24
+ version ||= Selenium::WebDriver::Firefox::Profile.firebug_version
25
+ add_extension(File.expand_path("../../../../bin/firebug-#{version}.xpi", __FILE__))
26
+
27
+ # For some reason, Firebug seems to trigger the Firefox plugin check
28
+ # (navigating to https://www.mozilla.org/en-US/plugincheck/ at startup).
29
+ # This prevents it. See http://code.google.com/p/selenium/issues/detail?id=4619.
30
+ self['extensions.blocklist.enabled'] = false
31
+
32
+ # Prevent "Welcome!" tab
33
+ self['extensions.firebug.showFirstRunPage'] = false
34
+
35
+ # Enable for all sites.
36
+ self['extensions.firebug.allPagesActivation'] = 'on'
37
+
38
+ # Enable all features.
39
+ %w(console net script).each do |feature|
40
+ self["extensions.firebug.#{feature}.enableSites"] = true
41
+ end
42
+
43
+ # Closed by default, will open detached.
44
+ self['extensions.firebug.framePosition'] = frame_position
45
+ self['extensions.firebug.previousPlacement'] = 3
46
+ self['extensions.firebug.defaultPanelName'] = 'console'
47
+
48
+ # Disable native "Inspect Element" menu item.
49
+ self['devtools.inspector.enabled'] = false
50
+ self['extensions.firebug.hideDefaultInspector'] = true
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,658 @@
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
+ (function (global) {
4
+ "use strict";
5
+
6
+ var userAgent = global.navigator && global.navigator.userAgent;
7
+ var isRunningInIE = userAgent && userAgent.indexOf("MSIE ") > -1;
8
+
9
+ // Make properties writable in IE, as per
10
+ // http://www.adequatelygood.com/Replacing-setTimeout-Globally.html
11
+ if (isRunningInIE) {
12
+ global.setTimeout = global.setTimeout;
13
+ global.clearTimeout = global.clearTimeout;
14
+ global.setInterval = global.setInterval;
15
+ global.clearInterval = global.clearInterval;
16
+ global.Date = global.Date;
17
+ }
18
+
19
+ // setImmediate is not a standard function
20
+ // avoid adding the prop to the window object if not present
21
+ if (global.setImmediate !== undefined) {
22
+ global.setImmediate = global.setImmediate;
23
+ global.clearImmediate = global.clearImmediate;
24
+ }
25
+
26
+ // node expects setTimeout/setInterval to return a fn object w/ .ref()/.unref()
27
+ // browsers, a number.
28
+ // see https://github.com/cjohansen/Sinon.JS/pull/436
29
+
30
+ var NOOP = function () { return undefined; };
31
+ var timeoutResult = setTimeout(NOOP, 0);
32
+ var addTimerReturnsObject = typeof timeoutResult === "object";
33
+ var hrtimePresent = (global.process && typeof global.process.hrtime === "function");
34
+ clearTimeout(timeoutResult);
35
+
36
+ var NativeDate = Date;
37
+ var uniqueTimerId = 1;
38
+
39
+ /**
40
+ * Parse strings like "01:10:00" (meaning 1 hour, 10 minutes, 0 seconds) into
41
+ * number of milliseconds. This is used to support human-readable strings passed
42
+ * to clock.tick()
43
+ */
44
+ function parseTime(str) {
45
+ if (!str) {
46
+ return 0;
47
+ }
48
+
49
+ var strings = str.split(":");
50
+ var l = strings.length, i = l;
51
+ var ms = 0, parsed;
52
+
53
+ if (l > 3 || !/^(\d\d:){0,2}\d\d?$/.test(str)) {
54
+ throw new Error("tick only understands numbers, 'm:s' and 'h:m:s'. Each part must be two digits");
55
+ }
56
+
57
+ while (i--) {
58
+ parsed = parseInt(strings[i], 10);
59
+
60
+ if (parsed >= 60) {
61
+ throw new Error("Invalid time " + str);
62
+ }
63
+
64
+ ms += parsed * Math.pow(60, (l - i - 1));
65
+ }
66
+
67
+ return ms * 1000;
68
+ }
69
+
70
+ /**
71
+ * Floor function that also works for negative numbers
72
+ */
73
+ function fixedFloor(n) {
74
+ return (n >= 0 ? Math.floor(n) : Math.ceil(n));
75
+ }
76
+
77
+ /**
78
+ * % operator that also works for negative numbers
79
+ */
80
+ function fixedModulo(n, m) {
81
+ return ((n % m) + m) % m;
82
+ }
83
+
84
+ /**
85
+ * Used to grok the `now` parameter to createClock.
86
+ */
87
+ function getEpoch(epoch) {
88
+ if (!epoch) { return 0; }
89
+ if (typeof epoch.getTime === "function") { return epoch.getTime(); }
90
+ if (typeof epoch === "number") { return epoch; }
91
+ throw new TypeError("now should be milliseconds since UNIX epoch");
92
+ }
93
+
94
+ function inRange(from, to, timer) {
95
+ return timer && timer.callAt >= from && timer.callAt <= to;
96
+ }
97
+
98
+ function mirrorDateProperties(target, source) {
99
+ var prop;
100
+ for (prop in source) {
101
+ if (source.hasOwnProperty(prop)) {
102
+ target[prop] = source[prop];
103
+ }
104
+ }
105
+
106
+ // set special now implementation
107
+ if (source.now) {
108
+ target.now = function now() {
109
+ return target.clock.now;
110
+ };
111
+ } else {
112
+ delete target.now;
113
+ }
114
+
115
+ // set special toSource implementation
116
+ if (source.toSource) {
117
+ target.toSource = function toSource() {
118
+ return source.toSource();
119
+ };
120
+ } else {
121
+ delete target.toSource;
122
+ }
123
+
124
+ // set special toString implementation
125
+ target.toString = function toString() {
126
+ return source.toString();
127
+ };
128
+
129
+ target.prototype = source.prototype;
130
+ target.parse = source.parse;
131
+ target.UTC = source.UTC;
132
+ target.prototype.toUTCString = source.prototype.toUTCString;
133
+
134
+ return target;
135
+ }
136
+
137
+ function createDate() {
138
+ function ClockDate(year, month, date, hour, minute, second, ms) {
139
+ // Defensive and verbose to avoid potential harm in passing
140
+ // explicit undefined when user does not pass argument
141
+ switch (arguments.length) {
142
+ case 0:
143
+ return new NativeDate(ClockDate.clock.now);
144
+ case 1:
145
+ return new NativeDate(year);
146
+ case 2:
147
+ return new NativeDate(year, month);
148
+ case 3:
149
+ return new NativeDate(year, month, date);
150
+ case 4:
151
+ return new NativeDate(year, month, date, hour);
152
+ case 5:
153
+ return new NativeDate(year, month, date, hour, minute);
154
+ case 6:
155
+ return new NativeDate(year, month, date, hour, minute, second);
156
+ default:
157
+ return new NativeDate(year, month, date, hour, minute, second, ms);
158
+ }
159
+ }
160
+
161
+ return mirrorDateProperties(ClockDate, NativeDate);
162
+ }
163
+
164
+ function addTimer(clock, timer) {
165
+ if (timer.func === undefined) {
166
+ throw new Error("Callback must be provided to timer calls");
167
+ }
168
+
169
+ if (!clock.timers) {
170
+ clock.timers = {};
171
+ }
172
+
173
+ timer.id = uniqueTimerId++;
174
+ timer.createdAt = clock.now;
175
+ timer.callAt = clock.now + (parseInt(timer.delay) || (clock.duringTick ? 1 : 0));
176
+
177
+ clock.timers[timer.id] = timer;
178
+
179
+ if (addTimerReturnsObject) {
180
+ return {
181
+ id: timer.id,
182
+ ref: NOOP,
183
+ unref: NOOP
184
+ };
185
+ }
186
+
187
+ return timer.id;
188
+ }
189
+
190
+
191
+ /* eslint consistent-return: "off" */
192
+ function compareTimers(a, b) {
193
+ // Sort first by absolute timing
194
+ if (a.callAt < b.callAt) {
195
+ return -1;
196
+ }
197
+ if (a.callAt > b.callAt) {
198
+ return 1;
199
+ }
200
+
201
+ // Sort next by immediate, immediate timers take precedence
202
+ if (a.immediate && !b.immediate) {
203
+ return -1;
204
+ }
205
+ if (!a.immediate && b.immediate) {
206
+ return 1;
207
+ }
208
+
209
+ // Sort next by creation time, earlier-created timers take precedence
210
+ if (a.createdAt < b.createdAt) {
211
+ return -1;
212
+ }
213
+ if (a.createdAt > b.createdAt) {
214
+ return 1;
215
+ }
216
+
217
+ // Sort next by id, lower-id timers take precedence
218
+ if (a.id < b.id) {
219
+ return -1;
220
+ }
221
+ if (a.id > b.id) {
222
+ return 1;
223
+ }
224
+
225
+ // As timer ids are unique, no fallback `0` is necessary
226
+ }
227
+
228
+ function firstTimerInRange(clock, from, to) {
229
+ var timers = clock.timers,
230
+ timer = null,
231
+ id,
232
+ isInRange;
233
+
234
+ for (id in timers) {
235
+ if (timers.hasOwnProperty(id)) {
236
+ isInRange = inRange(from, to, timers[id]);
237
+
238
+ if (isInRange && (!timer || compareTimers(timer, timers[id]) === 1)) {
239
+ timer = timers[id];
240
+ }
241
+ }
242
+ }
243
+
244
+ return timer;
245
+ }
246
+
247
+ function firstTimer(clock) {
248
+ var timers = clock.timers,
249
+ timer = null,
250
+ id;
251
+
252
+ for (id in timers) {
253
+ if (timers.hasOwnProperty(id)) {
254
+ if (!timer || compareTimers(timer, timers[id]) === 1) {
255
+ timer = timers[id];
256
+ }
257
+ }
258
+ }
259
+
260
+ return timer;
261
+ }
262
+
263
+ function lastTimer(clock) {
264
+ var timers = clock.timers,
265
+ timer = null,
266
+ id;
267
+
268
+ for (id in timers) {
269
+ if (timers.hasOwnProperty(id)) {
270
+ if (!timer || compareTimers(timer, timers[id]) === -1) {
271
+ timer = timers[id];
272
+ }
273
+ }
274
+ }
275
+
276
+ return timer;
277
+ }
278
+
279
+ function callTimer(clock, timer) {
280
+ var exception;
281
+
282
+ if (typeof timer.interval === "number") {
283
+ clock.timers[timer.id].callAt += timer.interval;
284
+ } else {
285
+ delete clock.timers[timer.id];
286
+ }
287
+
288
+ try {
289
+ if (typeof timer.func === "function") {
290
+ timer.func.apply(null, timer.args);
291
+ } else {
292
+ /* eslint no-eval: "off" */
293
+ eval(timer.func);
294
+ }
295
+ } catch (e) {
296
+ exception = e;
297
+ }
298
+
299
+ if (!clock.timers[timer.id]) {
300
+ if (exception) {
301
+ throw exception;
302
+ }
303
+ return;
304
+ }
305
+
306
+ if (exception) {
307
+ throw exception;
308
+ }
309
+ }
310
+
311
+ function timerType(timer) {
312
+ if (timer.immediate) {
313
+ return "Immediate";
314
+ }
315
+ if (timer.interval !== undefined) {
316
+ return "Interval";
317
+ }
318
+ return "Timeout";
319
+ }
320
+
321
+ function clearTimer(clock, timerId, ttype) {
322
+ if (!timerId) {
323
+ // null appears to be allowed in most browsers, and appears to be
324
+ // relied upon by some libraries, like Bootstrap carousel
325
+ return;
326
+ }
327
+
328
+ if (!clock.timers) {
329
+ clock.timers = [];
330
+ }
331
+
332
+ // in Node, timerId is an object with .ref()/.unref(), and
333
+ // its .id field is the actual timer id.
334
+ if (typeof timerId === "object") {
335
+ timerId = timerId.id;
336
+ }
337
+
338
+ if (clock.timers.hasOwnProperty(timerId)) {
339
+ // check that the ID matches a timer of the correct type
340
+ var timer = clock.timers[timerId];
341
+ if (timerType(timer) === ttype) {
342
+ delete clock.timers[timerId];
343
+ } else {
344
+ throw new Error("Cannot clear timer: timer created with set" + timerType(timer)
345
+ + "() but cleared with clear" + ttype + "()");
346
+ }
347
+ }
348
+ }
349
+
350
+ function uninstall(clock, target) {
351
+ var method,
352
+ i,
353
+ l;
354
+ var installedHrTime = "_hrtime";
355
+
356
+ for (i = 0, l = clock.methods.length; i < l; i++) {
357
+ method = clock.methods[i];
358
+ if (method === "hrtime" && target.process) {
359
+ target.process.hrtime = clock[installedHrTime];
360
+ } else {
361
+ if (target[method] && target[method].hadOwnProperty) {
362
+ target[method] = clock["_" + method];
363
+ } else {
364
+ try {
365
+ delete target[method];
366
+ } catch (ignore) { /* eslint empty-block: "off" */ }
367
+ }
368
+ }
369
+ }
370
+
371
+ // Prevent multiple executions which will completely remove these props
372
+ clock.methods = [];
373
+ }
374
+
375
+ function hijackMethod(target, method, clock) {
376
+ var prop;
377
+
378
+ clock[method].hadOwnProperty = Object.prototype.hasOwnProperty.call(target, method);
379
+ clock["_" + method] = target[method];
380
+
381
+ if (method === "Date") {
382
+ var date = mirrorDateProperties(clock[method], target[method]);
383
+ target[method] = date;
384
+ } else {
385
+ target[method] = function () {
386
+ return clock[method].apply(clock, arguments);
387
+ };
388
+
389
+ for (prop in clock[method]) {
390
+ if (clock[method].hasOwnProperty(prop)) {
391
+ target[method][prop] = clock[method][prop];
392
+ }
393
+ }
394
+ }
395
+
396
+ target[method].clock = clock;
397
+ }
398
+
399
+ var timers = {
400
+ setTimeout: setTimeout,
401
+ clearTimeout: clearTimeout,
402
+ setImmediate: global.setImmediate,
403
+ clearImmediate: global.clearImmediate,
404
+ setInterval: setInterval,
405
+ clearInterval: clearInterval,
406
+ Date: Date
407
+ };
408
+
409
+ if (hrtimePresent) {
410
+ timers.hrtime = global.process.hrtime;
411
+ }
412
+
413
+ var keys = Object.keys || function (obj) {
414
+ var ks = [],
415
+ key;
416
+
417
+ for (key in obj) {
418
+ if (obj.hasOwnProperty(key)) {
419
+ ks.push(key);
420
+ }
421
+ }
422
+
423
+ return ks;
424
+ };
425
+
426
+ exports.timers = timers;
427
+
428
+ function createClock(now, loopLimit) {
429
+ loopLimit = loopLimit || 1000;
430
+
431
+ var clock = {
432
+ now: getEpoch(now),
433
+ hrNow: 0,
434
+ timeouts: {},
435
+ Date: createDate(),
436
+ loopLimit: loopLimit
437
+ };
438
+
439
+ clock.Date.clock = clock;
440
+
441
+ clock.setTimeout = function setTimeout(func, timeout) {
442
+ return addTimer(clock, {
443
+ func: func,
444
+ args: Array.prototype.slice.call(arguments, 2),
445
+ delay: timeout
446
+ });
447
+ };
448
+
449
+ clock.clearTimeout = function clearTimeout(timerId) {
450
+ return clearTimer(clock, timerId, "Timeout");
451
+ };
452
+
453
+ clock.setInterval = function setInterval(func, timeout) {
454
+ return addTimer(clock, {
455
+ func: func,
456
+ args: Array.prototype.slice.call(arguments, 2),
457
+ delay: timeout,
458
+ interval: timeout
459
+ });
460
+ };
461
+
462
+ clock.clearInterval = function clearInterval(timerId) {
463
+ return clearTimer(clock, timerId, "Interval");
464
+ };
465
+
466
+ clock.setImmediate = function setImmediate(func) {
467
+ return addTimer(clock, {
468
+ func: func,
469
+ args: Array.prototype.slice.call(arguments, 1),
470
+ immediate: true
471
+ });
472
+ };
473
+
474
+ clock.clearImmediate = function clearImmediate(timerId) {
475
+ return clearTimer(clock, timerId, "Immediate");
476
+ };
477
+
478
+ clock.tick = function tick(ms) {
479
+ ms = typeof ms === "number" ? ms : parseTime(ms);
480
+ var tickFrom = clock.now, tickTo = clock.now + ms, previous = clock.now;
481
+ var timer = firstTimerInRange(clock, tickFrom, tickTo);
482
+ var oldNow;
483
+
484
+ clock.duringTick = true;
485
+
486
+ function updateHrTime(newNow) {
487
+ clock.hrNow += (newNow - clock.now);
488
+ }
489
+
490
+ var firstException;
491
+ while (timer && tickFrom <= tickTo) {
492
+ if (clock.timers[timer.id]) {
493
+ updateHrTime(timer.callAt);
494
+ tickFrom = timer.callAt;
495
+ clock.now = timer.callAt;
496
+ try {
497
+ oldNow = clock.now;
498
+ callTimer(clock, timer);
499
+ // compensate for any setSystemTime() call during timer callback
500
+ if (oldNow !== clock.now) {
501
+ tickFrom += clock.now - oldNow;
502
+ tickTo += clock.now - oldNow;
503
+ previous += clock.now - oldNow;
504
+ }
505
+ } catch (e) {
506
+ firstException = firstException || e;
507
+ }
508
+ }
509
+
510
+ timer = firstTimerInRange(clock, previous, tickTo);
511
+ previous = tickFrom;
512
+ }
513
+
514
+ clock.duringTick = false;
515
+ updateHrTime(tickTo);
516
+ clock.now = tickTo;
517
+
518
+ if (firstException) {
519
+ throw firstException;
520
+ }
521
+
522
+ return clock.now;
523
+ };
524
+
525
+ clock.next = function next() {
526
+ var timer = firstTimer(clock);
527
+ if (!timer) {
528
+ return clock.now;
529
+ }
530
+
531
+ clock.duringTick = true;
532
+ try {
533
+ clock.now = timer.callAt;
534
+ callTimer(clock, timer);
535
+ return clock.now;
536
+ } finally {
537
+ clock.duringTick = false;
538
+ }
539
+ };
540
+
541
+ clock.runAll = function runAll() {
542
+ var numTimers, i;
543
+ for (i = 0; i < clock.loopLimit; i++) {
544
+ if (!clock.timers) {
545
+ return clock.now;
546
+ }
547
+
548
+ numTimers = Object.keys(clock.timers).length;
549
+ if (numTimers === 0) {
550
+ return clock.now;
551
+ }
552
+
553
+ clock.next();
554
+ }
555
+
556
+ throw new Error("Aborting after running " + clock.loopLimit + "timers, assuming an infinite loop!");
557
+ };
558
+
559
+ clock.runToLast = function runToLast() {
560
+ var timer = lastTimer(clock);
561
+ if (!timer) {
562
+ return clock.now;
563
+ }
564
+
565
+ return clock.tick(timer.callAt);
566
+ };
567
+
568
+ clock.reset = function reset() {
569
+ clock.timers = {};
570
+ };
571
+
572
+ clock.setSystemTime = function setSystemTime(now) {
573
+ // determine time difference
574
+ var newNow = getEpoch(now);
575
+ var difference = newNow - clock.now;
576
+ var id, timer;
577
+
578
+ // update 'system clock'
579
+ clock.now = newNow;
580
+
581
+ // update timers and intervals to keep them stable
582
+ for (id in clock.timers) {
583
+ if (clock.timers.hasOwnProperty(id)) {
584
+ timer = clock.timers[id];
585
+ timer.createdAt += difference;
586
+ timer.callAt += difference;
587
+ }
588
+ }
589
+ };
590
+
591
+ if (hrtimePresent) {
592
+ clock.hrtime = function (prev) {
593
+ if (Array.isArray(prev)) {
594
+ var oldSecs = (prev[0] + prev[1] / 1e9);
595
+ var newSecs = (clock.hrNow / 1000);
596
+ var difference = (newSecs - oldSecs);
597
+ var secs = fixedFloor(difference);
598
+ var nanosecs = fixedModulo(difference * 1e9, 1e9);
599
+ return [
600
+ secs,
601
+ nanosecs
602
+ ];
603
+ }
604
+ return [
605
+ fixedFloor(clock.hrNow / 1000),
606
+ fixedModulo(clock.hrNow * 1e6, 1e9)
607
+ ];
608
+ };
609
+ }
610
+
611
+ return clock;
612
+ }
613
+ exports.createClock = createClock;
614
+
615
+ exports.install = function install(target, now, toFake, loopLimit) {
616
+ var i,
617
+ l;
618
+
619
+ if (typeof target === "number") {
620
+ toFake = now;
621
+ now = target;
622
+ target = null;
623
+ }
624
+
625
+ if (!target) {
626
+ target = global;
627
+ }
628
+
629
+ var clock = createClock(now, loopLimit);
630
+
631
+ clock.uninstall = function () {
632
+ uninstall(clock, target);
633
+ };
634
+
635
+ clock.methods = toFake || [];
636
+
637
+ if (clock.methods.length === 0) {
638
+ clock.methods = keys(timers);
639
+ }
640
+
641
+ for (i = 0, l = clock.methods.length; i < l; i++) {
642
+ if (clock.methods[i] === "hrtime") {
643
+ if (target.process && typeof target.process.hrtime === "function") {
644
+ hijackMethod(target.process, clock.methods[i], clock);
645
+ }
646
+ } else {
647
+ hijackMethod(target, clock.methods[i], clock);
648
+ }
649
+ }
650
+
651
+ return clock;
652
+ };
653
+
654
+ }(global || this));
655
+
656
+ }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
657
+ },{}]},{},[1])(1)
658
+ });