timers 4.1.2 → 4.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,45 +1,50 @@
1
1
  # frozen_string_literal: true
2
+ #
3
+ # This file is part of the "timers" project and released under the MIT license.
4
+ #
5
+ # Copyright, 2018, by Samuel Williams. All rights reserved.
6
+ #
2
7
 
3
8
  RSpec.describe Timers::Group do
4
- it "should be able to cancel twice" do
5
- fired = false
9
+ it "should be able to cancel twice" do
10
+ fired = false
6
11
 
7
- timer = subject.after(0.1) { fired = true }
12
+ timer = subject.after(0.1) { fired = true }
8
13
 
9
- 2.times do
10
- timer.cancel
11
- subject.wait
12
- end
14
+ 2.times do
15
+ timer.cancel
16
+ subject.wait
17
+ end
13
18
 
14
- expect(fired).to be false
15
- end
19
+ expect(fired).to be false
20
+ end
16
21
 
17
- it "should be possble to reset after cancel" do
18
- fired = false
22
+ it "should be possble to reset after cancel" do
23
+ fired = false
19
24
 
20
- timer = subject.after(0.1) { fired = true }
21
- timer.cancel
25
+ timer = subject.after(0.1) { fired = true }
26
+ timer.cancel
22
27
 
23
- subject.wait
28
+ subject.wait
24
29
 
25
- timer.reset
30
+ timer.reset
26
31
 
27
- subject.wait
32
+ subject.wait
28
33
 
29
- expect(fired).to be true
30
- end
34
+ expect(fired).to be true
35
+ end
31
36
 
32
- it "should cancel and remove one shot timers after they fire" do
33
- x = 0
37
+ it "should cancel and remove one shot timers after they fire" do
38
+ x = 0
34
39
 
35
- Timers::Wait.for(2) do |_remaining|
36
- timer = subject.every(0.2) { x += 1 }
37
- subject.after(0.1) { timer.cancel }
40
+ Timers::Wait.for(2) do |_remaining|
41
+ timer = subject.every(0.2) { x += 1 }
42
+ subject.after(0.1) { timer.cancel }
38
43
 
39
- subject.wait
40
- end
44
+ subject.wait
45
+ end
41
46
 
42
- expect(subject.timers).to be_empty
43
- expect(x).to be == 0
44
- end
47
+ expect(subject.timers).to be_empty
48
+ expect(x).to be == 0
49
+ end
45
50
  end
@@ -1,56 +1,61 @@
1
1
  # frozen_string_literal: true
2
+ #
3
+ # This file is part of the "timers" project and released under the MIT license.
4
+ #
5
+ # Copyright, 2018, by Samuel Williams. All rights reserved.
6
+ #
2
7
 
3
8
  RSpec.describe Timers::Events do
4
- it "should register an event" do
5
- fired = false
9
+ it "should register an event" do
10
+ fired = false
6
11
 
7
- callback = proc do |_time|
8
- fired = true
9
- end
12
+ callback = proc do |_time|
13
+ fired = true
14
+ end
10
15
 
11
- subject.schedule(0.1, callback)
16
+ subject.schedule(0.1, callback)
12
17
 
13
- expect(subject.size).to be == 1
18
+ expect(subject.size).to be == 1
14
19
 
15
- subject.fire(0.15)
20
+ subject.fire(0.15)
16
21
 
17
- expect(subject.size).to be == 0
22
+ expect(subject.size).to be == 0
18
23
 
19
- expect(fired).to be true
20
- end
24
+ expect(fired).to be true
25
+ end
21
26
 
22
- it "should register events in order" do
23
- fired = []
27
+ it "should register events in order" do
28
+ fired = []
24
29
 
25
- times = [0.95, 0.1, 0.3, 0.5, 0.4, 0.2, 0.01, 0.9]
30
+ times = [0.95, 0.1, 0.3, 0.5, 0.4, 0.2, 0.01, 0.9]
26
31
 
27
- times.each do |requested_time|
28
- callback = proc do |_time|
29
- fired << requested_time
30
- end
32
+ times.each do |requested_time|
33
+ callback = proc do |_time|
34
+ fired << requested_time
35
+ end
31
36
 
32
- subject.schedule(requested_time, callback)
33
- end
37
+ subject.schedule(requested_time, callback)
38
+ end
34
39
 
35
- subject.fire(0.5)
36
- expect(fired).to be == times.sort.first(6)
40
+ subject.fire(0.5)
41
+ expect(fired).to be == times.sort.first(6)
37
42
 
38
- subject.fire(1.0)
39
- expect(fired).to be == times.sort
40
- end
43
+ subject.fire(1.0)
44
+ expect(fired).to be == times.sort
45
+ end
41
46
 
42
- it "should fire events with the time they were fired at" do
43
- fired_at = :not_fired
47
+ it "should fire events with the time they were fired at" do
48
+ fired_at = :not_fired
44
49
 
45
- callback = proc do |time|
46
- # The time we actually were fired at:
47
- fired_at = time
48
- end
50
+ callback = proc do |time|
51
+ # The time we actually were fired at:
52
+ fired_at = time
53
+ end
49
54
 
50
- subject.schedule(0.5, callback)
55
+ subject.schedule(0.5, callback)
51
56
 
52
- subject.fire(1.0)
57
+ subject.fire(1.0)
53
58
 
54
- expect(fired_at).to be == 1.0
55
- end
59
+ expect(fired_at).to be == 1.0
60
+ end
56
61
  end
@@ -1,33 +1,38 @@
1
1
  # frozen_string_literal: true
2
+ #
3
+ # This file is part of the "timers" project and released under the MIT license.
4
+ #
5
+ # Copyright, 2018, by Samuel Williams. All rights reserved.
6
+ #
2
7
 
3
8
  RSpec.describe Timers::Group do
4
- it "should fire several times" do
5
- result = []
9
+ it "should fire several times" do
10
+ result = []
6
11
 
7
- subject.every(0.7) { result << :a }
8
- subject.every(2.3) { result << :b }
9
- subject.every(1.3) { result << :c }
10
- subject.every(2.4) { result << :d }
12
+ subject.every(0.7) { result << :a }
13
+ subject.every(2.3) { result << :b }
14
+ subject.every(1.3) { result << :c }
15
+ subject.every(2.4) { result << :d }
11
16
 
12
- Timers::Wait.for(2.5) do |remaining|
13
- subject.wait if subject.wait_interval < remaining
14
- end
17
+ Timers::Wait.for(2.5) do |remaining|
18
+ subject.wait if subject.wait_interval < remaining
19
+ end
15
20
 
16
- expect(result).to be == [:a, :c, :a, :a, :b, :d]
17
- end
21
+ expect(result).to be == [:a, :c, :a, :a, :b, :d]
22
+ end
18
23
 
19
- it "should fire immediately and then several times later" do
20
- result = []
24
+ it "should fire immediately and then several times later" do
25
+ result = []
21
26
 
22
- subject.every(0.7) { result << :a }
23
- subject.every(2.3) { result << :b }
24
- subject.now_and_every(1.3) { result << :c }
25
- subject.now_and_every(2.4) { result << :d }
27
+ subject.every(0.7) { result << :a }
28
+ subject.every(2.3) { result << :b }
29
+ subject.now_and_every(1.3) { result << :c }
30
+ subject.now_and_every(2.4) { result << :d }
26
31
 
27
- Timers::Wait.for(2.5) do |remaining|
28
- subject.wait if subject.wait_interval < remaining
29
- end
32
+ Timers::Wait.for(2.5) do |remaining|
33
+ subject.wait if subject.wait_interval < remaining
34
+ end
30
35
 
31
- expect(result).to be == [:c, :d, :a, :c, :a, :a, :b, :d]
32
- end
36
+ expect(result).to be == [:c, :d, :a, :c, :a, :a, :b, :d]
37
+ end
33
38
  end
@@ -1,255 +1,260 @@
1
1
  # frozen_string_literal: true
2
+ #
3
+ # This file is part of the "timers" project and released under the MIT license.
4
+ #
5
+ # Copyright, 2018, by Samuel Williams. All rights reserved.
6
+ #
2
7
 
3
8
  RSpec.describe Timers::Group do
4
- describe "#wait" do
5
- it "calls the wait block with nil" do
6
- called = false
9
+ describe "#wait" do
10
+ it "calls the wait block with nil" do
11
+ called = false
7
12
 
8
- subject.wait do |interval|
9
- expect(interval).to be_nil
10
- called = true
11
- end
13
+ subject.wait do |interval|
14
+ expect(interval).to be_nil
15
+ called = true
16
+ end
12
17
 
13
- expect(called).to be true
14
- end
18
+ expect(called).to be true
19
+ end
15
20
 
16
- it "calls the wait block with an interval" do
17
- called = false
18
- fired = false
21
+ it "calls the wait block with an interval" do
22
+ called = false
23
+ fired = false
19
24
 
20
- subject.after(0.1) { fired = true }
25
+ subject.after(0.1) { fired = true }
21
26
 
22
- subject.wait do |interval|
23
- expect(interval).to be_within(TIMER_QUANTUM).of(0.1)
24
- called = true
25
- sleep 0.2
26
- end
27
+ subject.wait do |interval|
28
+ expect(interval).to be_within(TIMER_QUANTUM).of(0.1)
29
+ called = true
30
+ sleep 0.2
31
+ end
27
32
 
28
- expect(called).to be true
29
- expect(fired).to be true
30
- end
31
- end
33
+ expect(called).to be true
34
+ expect(fired).to be true
35
+ end
36
+ end
32
37
 
33
- it "sleeps until the next timer" do
34
- interval = TIMER_QUANTUM * 2
35
- started_at = Time.now
38
+ it "sleeps until the next timer" do
39
+ interval = TIMER_QUANTUM * 2
40
+ started_at = Time.now
36
41
 
37
- fired = false
38
- subject.after(interval) { fired = true }
39
- subject.wait
42
+ fired = false
43
+ subject.after(interval) { fired = true }
44
+ subject.wait
40
45
 
41
- expect(fired).to be true
42
- expect(Time.now - started_at).to be_within(TIMER_QUANTUM).of interval
43
- end
44
-
45
- it "fires instantly when next timer is in the past" do
46
- fired = false
47
- subject.after(TIMER_QUANTUM) { fired = true }
48
- sleep(TIMER_QUANTUM * 2)
49
- subject.wait
50
-
51
- expect(fired).to be true
52
- end
53
-
54
- it "calculates the interval until the next timer should fire" do
55
- interval = 0.1
56
-
57
- subject.after(interval)
58
- expect(subject.wait_interval).to be_within(TIMER_QUANTUM).of interval
59
-
60
- sleep(interval)
61
- expect(subject.wait_interval).to be <= 0
62
- end
63
-
64
- it "fires timers in the correct order" do
65
- result = []
66
-
67
- subject.after(TIMER_QUANTUM * 2) { result << :two }
68
- subject.after(TIMER_QUANTUM * 3) { result << :three }
69
- subject.after(TIMER_QUANTUM * 1) { result << :one }
70
-
71
- sleep TIMER_QUANTUM * 4
72
- subject.fire
73
-
74
- expect(result).to eq [:one, :two, :three]
75
- end
76
-
77
- it "raises TypeError if given an invalid time" do
78
- expect do
79
- subject.after(nil) { nil }
80
- end.to raise_exception(TypeError)
81
- end
82
-
83
- describe "recurring timers" do
84
- it "continues to fire the timers at each interval" do
85
- result = []
86
-
87
- subject.every(TIMER_QUANTUM * 2) { result << :foo }
88
-
89
- sleep TIMER_QUANTUM * 3
90
- subject.fire
91
- expect(result).to eq [:foo]
92
-
93
- sleep TIMER_QUANTUM * 5
94
- subject.fire
95
- expect(result).to eq [:foo, :foo]
96
- end
97
- end
98
-
99
- it "calculates the proper interval to wait until firing" do
100
- interval_ms = 25
101
-
102
- subject.after(interval_ms / 1000.0)
103
-
104
- expect(subject.wait_interval).to be_within(TIMER_QUANTUM).of(interval_ms / 1000.0)
105
- end
106
-
107
- describe "pause and continue timers" do
108
- before(:each) do
109
- @interval = TIMER_QUANTUM * 2
110
-
111
- @fired = false
112
- @timer = subject.after(@interval) { @fired = true }
113
- @fired2 = false
114
- @timer2 = subject.after(@interval) { @fired2 = true }
115
- end
116
-
117
- it "does not fire when paused" do
118
- @timer.pause
119
- subject.wait
120
- expect(@fired).to be false
121
- end
122
-
123
- it "fires when continued after pause" do
124
- @timer.pause
125
- subject.wait
126
- @timer.resume
127
-
128
- sleep @timer.interval
129
- subject.wait
130
-
131
- expect(@fired).to be true
132
- end
133
-
134
- it "can pause all timers at once" do
135
- subject.pause
136
- subject.wait
137
- expect(@fired).to be false
138
- expect(@fired2).to be false
139
- end
140
-
141
- it "can continue all timers at once" do
142
- subject.pause
143
- subject.wait
144
- subject.resume
145
-
146
- # We need to wait until we are sure both timers will fire, otherwise highly accurate clocks
147
- # (e.g. JVM)may only fire the first timer, but not the second, because they are actually
148
- # schedueled at different times.
149
- sleep TIMER_QUANTUM * 2
150
- subject.wait
151
-
152
- expect(@fired).to be true
153
- expect(@fired2).to be true
154
- end
155
-
156
- it "can fire the timer directly" do
157
- fired = false
158
- timer = subject.after(TIMER_QUANTUM * 1) { fired = true }
159
- timer.pause
160
- subject.wait
161
- expect(fired).not_to be true
162
- timer.resume
163
- expect(fired).not_to be true
164
- timer.fire
165
- expect(fired).to be true
166
- end
167
- end
168
-
169
- describe "delay timer" do
170
- it "adds appropriate amount of time to timer" do
171
- timer = subject.after(10)
172
- timer.delay(5)
173
- expect(timer.offset - subject.current_offset).to be_within(TIMER_QUANTUM).of(15)
174
- end
175
- end
176
-
177
- describe "delay timer collection" do
178
- it "delay on set adds appropriate amount of time to all timers" do
179
- timer = subject.after(10)
180
- timer2 = subject.after(20)
181
- subject.delay(5)
182
- expect(timer.offset - subject.current_offset).to be_within(TIMER_QUANTUM).of(15)
183
- expect(timer2.offset - subject.current_offset).to be_within(TIMER_QUANTUM).of(25)
184
- end
185
- end
186
-
187
- describe "on delaying a timer" do
188
- it "fires timers in the correct order" do
189
- result = []
190
-
191
- subject.after(TIMER_QUANTUM * 2) { result << :two }
192
- subject.after(TIMER_QUANTUM * 3) { result << :three }
193
- first = subject.after(TIMER_QUANTUM * 1) { result << :one }
194
- first.delay(TIMER_QUANTUM * 3)
195
-
196
- sleep TIMER_QUANTUM * 5
197
- subject.fire
198
-
199
- expect(result).to eq [:two, :three, :one]
200
- end
201
- end
202
-
203
- describe "#inspect" do
204
- it "before firing" do
205
- fired = false
206
- timer = subject.after(TIMER_QUANTUM * 5) { fired = true }
207
- timer.pause
208
- expect(fired).not_to be true
209
- expect(timer.inspect).to match(/\A#<Timers::Timer:[\da-f]+ fires in [-\.\de]+ seconds>\Z/)
210
- end
211
-
212
- it "after firing" do
213
- fired = false
214
- timer = subject.after(TIMER_QUANTUM) { fired = true }
215
-
216
- subject.wait
217
-
218
- expect(fired).to be true
219
- expect(timer.inspect).to match(/\A#<Timers::Timer:[\da-f]+ fired [-\.\de]+ seconds ago>\Z/)
220
- end
221
-
222
- it "recurring firing" do
223
- result = []
224
- timer = subject.every(TIMER_QUANTUM) { result << :foo }
225
-
226
- subject.wait
227
- expect(result).not_to be_empty
228
- regex = /\A#<Timers::Timer:[\da-f]+ fires in [-\.\de]+ seconds, recurs every #{format("%0.2f", TIMER_QUANTUM)}>\Z/
229
- expect(timer.inspect).to match(regex)
230
- end
231
- end
232
-
233
- describe "#fires_in" do
234
- let(:interval) { TIMER_QUANTUM * 2 }
235
-
236
- it "calculates the interval until the next fire if it's recurring" do
237
- timer = subject.every(interval) { true }
238
- expect(timer.fires_in).to be_within(TIMER_QUANTUM).of(interval)
239
- end
240
-
241
- context "when timer is not recurring" do
242
- let!(:timer) { subject.after(interval) { true } }
243
-
244
- it "calculates the interval until the next fire if it hasn't already fired" do
245
- expect(timer.fires_in).to be_within(TIMER_QUANTUM).of(interval)
246
- end
247
-
248
- it "calculates the interval since last fire if already fired" do
249
- subject.wait
250
- sleep(interval)
251
- expect(timer.fires_in).to be_within(TIMER_QUANTUM).of(0 - interval)
252
- end
253
- end
254
- end
46
+ expect(fired).to be true
47
+ expect(Time.now - started_at).to be_within(TIMER_QUANTUM).of interval
48
+ end
49
+
50
+ it "fires instantly when next timer is in the past" do
51
+ fired = false
52
+ subject.after(TIMER_QUANTUM) { fired = true }
53
+ sleep(TIMER_QUANTUM * 2)
54
+ subject.wait
55
+
56
+ expect(fired).to be true
57
+ end
58
+
59
+ it "calculates the interval until the next timer should fire" do
60
+ interval = 0.1
61
+
62
+ subject.after(interval)
63
+ expect(subject.wait_interval).to be_within(TIMER_QUANTUM).of interval
64
+
65
+ sleep(interval)
66
+ expect(subject.wait_interval).to be <= 0
67
+ end
68
+
69
+ it "fires timers in the correct order" do
70
+ result = []
71
+
72
+ subject.after(TIMER_QUANTUM * 2) { result << :two }
73
+ subject.after(TIMER_QUANTUM * 3) { result << :three }
74
+ subject.after(TIMER_QUANTUM * 1) { result << :one }
75
+
76
+ sleep TIMER_QUANTUM * 4
77
+ subject.fire
78
+
79
+ expect(result).to eq [:one, :two, :three]
80
+ end
81
+
82
+ it "raises TypeError if given an invalid time" do
83
+ expect do
84
+ subject.after(nil) { nil }
85
+ end.to raise_exception(TypeError)
86
+ end
87
+
88
+ describe "recurring timers" do
89
+ it "continues to fire the timers at each interval" do
90
+ result = []
91
+
92
+ subject.every(TIMER_QUANTUM * 2) { result << :foo }
93
+
94
+ sleep TIMER_QUANTUM * 3
95
+ subject.fire
96
+ expect(result).to eq [:foo]
97
+
98
+ sleep TIMER_QUANTUM * 5
99
+ subject.fire
100
+ expect(result).to eq [:foo, :foo]
101
+ end
102
+ end
103
+
104
+ it "calculates the proper interval to wait until firing" do
105
+ interval_ms = 25
106
+
107
+ subject.after(interval_ms / 1000.0)
108
+
109
+ expect(subject.wait_interval).to be_within(TIMER_QUANTUM).of(interval_ms / 1000.0)
110
+ end
111
+
112
+ describe "pause and continue timers" do
113
+ before(:each) do
114
+ @interval = TIMER_QUANTUM * 2
115
+
116
+ @fired = false
117
+ @timer = subject.after(@interval) { @fired = true }
118
+ @fired2 = false
119
+ @timer2 = subject.after(@interval) { @fired2 = true }
120
+ end
121
+
122
+ it "does not fire when paused" do
123
+ @timer.pause
124
+ subject.wait
125
+ expect(@fired).to be false
126
+ end
127
+
128
+ it "fires when continued after pause" do
129
+ @timer.pause
130
+ subject.wait
131
+ @timer.resume
132
+
133
+ sleep @timer.interval
134
+ subject.wait
135
+
136
+ expect(@fired).to be true
137
+ end
138
+
139
+ it "can pause all timers at once" do
140
+ subject.pause
141
+ subject.wait
142
+ expect(@fired).to be false
143
+ expect(@fired2).to be false
144
+ end
145
+
146
+ it "can continue all timers at once" do
147
+ subject.pause
148
+ subject.wait
149
+ subject.resume
150
+
151
+ # We need to wait until we are sure both timers will fire, otherwise highly accurate clocks
152
+ # (e.g. JVM)may only fire the first timer, but not the second, because they are actually
153
+ # schedueled at different times.
154
+ sleep TIMER_QUANTUM * 2
155
+ subject.wait
156
+
157
+ expect(@fired).to be true
158
+ expect(@fired2).to be true
159
+ end
160
+
161
+ it "can fire the timer directly" do
162
+ fired = false
163
+ timer = subject.after(TIMER_QUANTUM * 1) { fired = true }
164
+ timer.pause
165
+ subject.wait
166
+ expect(fired).not_to be true
167
+ timer.resume
168
+ expect(fired).not_to be true
169
+ timer.fire
170
+ expect(fired).to be true
171
+ end
172
+ end
173
+
174
+ describe "delay timer" do
175
+ it "adds appropriate amount of time to timer" do
176
+ timer = subject.after(10)
177
+ timer.delay(5)
178
+ expect(timer.offset - subject.current_offset).to be_within(TIMER_QUANTUM).of(15)
179
+ end
180
+ end
181
+
182
+ describe "delay timer collection" do
183
+ it "delay on set adds appropriate amount of time to all timers" do
184
+ timer = subject.after(10)
185
+ timer2 = subject.after(20)
186
+ subject.delay(5)
187
+ expect(timer.offset - subject.current_offset).to be_within(TIMER_QUANTUM).of(15)
188
+ expect(timer2.offset - subject.current_offset).to be_within(TIMER_QUANTUM).of(25)
189
+ end
190
+ end
191
+
192
+ describe "on delaying a timer" do
193
+ it "fires timers in the correct order" do
194
+ result = []
195
+
196
+ subject.after(TIMER_QUANTUM * 2) { result << :two }
197
+ subject.after(TIMER_QUANTUM * 3) { result << :three }
198
+ first = subject.after(TIMER_QUANTUM * 1) { result << :one }
199
+ first.delay(TIMER_QUANTUM * 3)
200
+
201
+ sleep TIMER_QUANTUM * 5
202
+ subject.fire
203
+
204
+ expect(result).to eq [:two, :three, :one]
205
+ end
206
+ end
207
+
208
+ describe "#inspect" do
209
+ it "before firing" do
210
+ fired = false
211
+ timer = subject.after(TIMER_QUANTUM * 5) { fired = true }
212
+ timer.pause
213
+ expect(fired).not_to be true
214
+ expect(timer.inspect).to match(/\A#<Timers::Timer:0x[\da-f]+ fires in [-\.\de]+ seconds>\Z/)
215
+ end
216
+
217
+ it "after firing" do
218
+ fired = false
219
+ timer = subject.after(TIMER_QUANTUM) { fired = true }
220
+
221
+ subject.wait
222
+
223
+ expect(fired).to be true
224
+ expect(timer.inspect).to match(/\A#<Timers::Timer:0x[\da-f]+ fired [-\.\de]+ seconds ago>\Z/)
225
+ end
226
+
227
+ it "recurring firing" do
228
+ result = []
229
+ timer = subject.every(TIMER_QUANTUM) { result << :foo }
230
+
231
+ subject.wait
232
+ expect(result).not_to be_empty
233
+ regex = /\A#<Timers::Timer:0x[\da-f]+ fires in [-\.\de]+ seconds, recurs every #{format("%0.2f", TIMER_QUANTUM)}>\Z/
234
+ expect(timer.inspect).to match(regex)
235
+ end
236
+ end
237
+
238
+ describe "#fires_in" do
239
+ let(:interval) { TIMER_QUANTUM * 2 }
240
+
241
+ it "calculates the interval until the next fire if it's recurring" do
242
+ timer = subject.every(interval) { true }
243
+ expect(timer.fires_in).to be_within(TIMER_QUANTUM).of(interval)
244
+ end
245
+
246
+ context "when timer is not recurring" do
247
+ let!(:timer) { subject.after(interval) { true } }
248
+
249
+ it "calculates the interval until the next fire if it hasn't already fired" do
250
+ expect(timer.fires_in).to be_within(TIMER_QUANTUM).of(interval)
251
+ end
252
+
253
+ it "calculates the interval since last fire if already fired" do
254
+ subject.wait
255
+ sleep(interval)
256
+ expect(timer.fires_in).to be_within(TIMER_QUANTUM).of(0 - interval)
257
+ end
258
+ end
259
+ end
255
260
  end