timers 4.1.2 → 4.2.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.
@@ -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