ActionTimer 0.1.1 → 0.2.1
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.
- data/CHANGELOG +13 -0
- data/README.rdoc +13 -4
- data/actiontimer-0.2.1.gem +0 -0
- data/actiontimer.gemspec +3 -2
- data/lib/actiontimer.rb +4 -1
- data/lib/actiontimer/Action.rb +25 -7
- data/lib/actiontimer/Timer.rb +53 -27
- data/tests/cases/action.rb +128 -0
- data/tests/cases/timer.rb +85 -0
- data/tests/run_tests.rb +145 -140
- metadata +22 -10
- data/test +0 -11
data/CHANGELOG
CHANGED
@@ -1,5 +1,18 @@
|
|
1
1
|
= CHANGELOG
|
2
2
|
|
3
|
+
== 0.2.1
|
4
|
+
* Use simple monitor
|
5
|
+
* Add support for rounding sleep time within a delta
|
6
|
+
* Raise unexpected exception to creator thread after shutting down
|
7
|
+
* Fix arity checks for < 1.9 versions
|
8
|
+
|
9
|
+
== 0.2.0
|
10
|
+
* hashed arguments for Timer#add and Action#new
|
11
|
+
* Timer#mass_add replaced with Timer#register for single and arrays of Actions
|
12
|
+
* Timer#registered? added to see if an Action is registered with the timer
|
13
|
+
* Timer#actions to see Actions registered with the timer
|
14
|
+
* Action#timer= to allow Actions to be moved
|
15
|
+
|
3
16
|
== 0.1.1
|
4
17
|
* fix for float calculations
|
5
18
|
* downcased gem name
|
data/README.rdoc
CHANGED
@@ -16,6 +16,15 @@ ActionTimer is a helper for timed events. It allows for single and recurring act
|
|
16
16
|
|
17
17
|
{rip}[http://hellorip.com/about.html] makes it easy to install directly from a github repository.
|
18
18
|
|
19
|
+
=== Testing
|
20
|
+
|
21
|
+
ActionTimer is currently tested on:
|
22
|
+
|
23
|
+
* Ruby 1.8.6-p383
|
24
|
+
* Ruby 1.8.7-p248
|
25
|
+
* Ruby 1.9.1-p376
|
26
|
+
* JRuby 1.4.0
|
27
|
+
|
19
28
|
=== Using the timer:
|
20
29
|
|
21
30
|
==== Simple example:
|
@@ -92,10 +101,10 @@ What if you want to add multiple actions at one time? We can do this:
|
|
92
101
|
timer = ActionTimer::Timer.new
|
93
102
|
result = 0
|
94
103
|
actions = []
|
95
|
-
actions << ActionTimer::Action.new(
|
96
|
-
actions << ActionTimer::Action.new(
|
97
|
-
actions << ActionTimer::Action.new(
|
98
|
-
timer.
|
104
|
+
actions << ActionTimer::Action.new(timer, 0.1){ result += 1}
|
105
|
+
actions << ActionTimer::Action.new(timer, 0.2){ result += 1}
|
106
|
+
actions << ActionTimer::Action.new(timer, 0.3){ result += 1}
|
107
|
+
timer.register(actions)
|
99
108
|
sleep(0.41)
|
100
109
|
p result
|
101
110
|
|
Binary file
|
data/actiontimer.gemspec
CHANGED
@@ -2,7 +2,7 @@ spec = Gem::Specification.new do |s|
|
|
2
2
|
s.name = 'ActionTimer'
|
3
3
|
s.author = 'spox'
|
4
4
|
s.email = 'spox@modspox.com'
|
5
|
-
s.version = '0.
|
5
|
+
s.version = '0.2.1'
|
6
6
|
s.summary = 'Simple timer for a complex world'
|
7
7
|
s.platform = Gem::Platform::RUBY
|
8
8
|
s.has_rdoc = true
|
@@ -10,7 +10,8 @@ spec = Gem::Specification.new do |s|
|
|
10
10
|
s.extra_rdoc_files = %w(README.rdoc LICENSE CHANGELOG)
|
11
11
|
s.files = Dir['**/*']
|
12
12
|
s.require_paths = %w(lib)
|
13
|
-
s.add_dependency '
|
13
|
+
s.add_dependency 'actionpool', '~> 0.2.3'
|
14
|
+
s.add_dependency 'splib', '~> 1.4'
|
14
15
|
s.required_ruby_version = '>= 1.8.6'
|
15
16
|
s.homepage = 'http://github.com/spox/actiontimer'
|
16
17
|
s.description = 'ActionTimer is a simple timer for recurring actions. It supports single and recurring actions with an easy to use API.'
|
data/lib/actiontimer.rb
CHANGED
data/lib/actiontimer/Action.rb
CHANGED
@@ -2,21 +2,36 @@ module ActionTimer
|
|
2
2
|
class Action
|
3
3
|
|
4
4
|
attr_accessor :owner
|
5
|
+
attr_accessor :timer
|
5
6
|
|
6
7
|
# timer:: Timer this action resides within
|
7
8
|
# period:: amount of time between runs
|
8
9
|
# once:: only run this action once
|
9
10
|
# data:: data to pass to block
|
10
11
|
# block:: block to be executed
|
11
|
-
def initialize(
|
12
|
-
|
12
|
+
def initialize(hash, &block)
|
13
|
+
raise ArgumentError.new('Period must be supplied') unless hash[:period]
|
14
|
+
raise ArgumentError.new('Block must be provided') unless block_given?
|
15
|
+
raise ArgumentError.new('Block must accept data value') if hash[:data] && block.arity == 0
|
16
|
+
if((block.arity > 0 || block.arity < -1) && (!hash.has_key?(:data) || hash[:data].nil?))
|
17
|
+
raise ArgumentError.new('Data must be supplied for block')
|
18
|
+
end
|
19
|
+
args = {:once => false, :data => nil, :owner => nil}.merge(hash)
|
20
|
+
@period = args[:period].to_f
|
13
21
|
@block = block
|
14
|
-
@data = data
|
15
|
-
@once = once
|
16
|
-
@timer = timer
|
22
|
+
@data = args[:data]
|
23
|
+
@once = args[:once]
|
24
|
+
@timer = args[:timer]
|
17
25
|
@completed = false
|
18
26
|
@wait_remaining = @period
|
19
|
-
@owner =
|
27
|
+
@owner = args[:owner]
|
28
|
+
end
|
29
|
+
|
30
|
+
# t:: ActionTimer::Timer
|
31
|
+
# Set timer for action to be associated with
|
32
|
+
def timer=(t)
|
33
|
+
raise ArgumentError.new('Expecting an ActionTimer::Timer') unless t.is_a?(ActionTimer::Timer)
|
34
|
+
@timer = t
|
20
35
|
end
|
21
36
|
|
22
37
|
# o:: Object that added this action
|
@@ -30,6 +45,8 @@ module ActionTimer
|
|
30
45
|
# amount:: amount of time that has passed
|
31
46
|
# Decrement remaining wait time by given amount
|
32
47
|
def tick(amount)
|
48
|
+
amount = amount.to_f
|
49
|
+
amount = 0 if amount < 0
|
33
50
|
@wait_remaining = @wait_remaining - amount if @wait_remaining > 0
|
34
51
|
@wait_remaining = 0 if @wait_remaining < 0
|
35
52
|
@completed = true if @once && @wait_remaining <= 0
|
@@ -45,7 +62,8 @@ module ActionTimer
|
|
45
62
|
def reset_period(new_time)
|
46
63
|
@period = new_time.to_f
|
47
64
|
@wait_remaining = @period
|
48
|
-
@
|
65
|
+
@completed = false
|
66
|
+
@timer.wakeup unless @timer.nil?
|
49
67
|
end
|
50
68
|
|
51
69
|
# Action is ready to be destroyed
|
data/lib/actiontimer/Timer.rb
CHANGED
@@ -8,10 +8,12 @@ module ActionTimer
|
|
8
8
|
# Argument hash: {:pool, :logger, :auto_start}
|
9
9
|
def initialize(args={}, extra=nil)
|
10
10
|
auto_start = true
|
11
|
+
@delta = nil
|
11
12
|
if(args.is_a?(Hash))
|
12
13
|
@pool = args[:pool] ? args[:pool] : ActionPool::Pool.new
|
13
14
|
@logger = args[:logger] && args[:logger].is_a?(Logger) ? args[:logger] : Logger.new(nil)
|
14
15
|
auto_start = args.has_key?(:auto_start) ? args[:auto_start] : true
|
16
|
+
@delta = args[:delta] ? args[:delta].to_f : nil
|
15
17
|
else
|
16
18
|
@pool = args.is_a?(ActionPool::Pool) ? args : ActionPool::Pool.new
|
17
19
|
@logger = extra && extra.is_a?(Logger) ? extra : Logger.new(nil)
|
@@ -20,17 +22,21 @@ module ActionTimer
|
|
20
22
|
@new_actions = []
|
21
23
|
@timer_thread = nil
|
22
24
|
@stop_timer = false
|
23
|
-
@add_lock =
|
24
|
-
@awake_lock =
|
25
|
+
@add_lock = Splib::Monitor.new
|
26
|
+
@awake_lock = Splib::Monitor.new
|
27
|
+
@sleeper = Splib::Monitor.new
|
28
|
+
@respond_to = Thread.current
|
25
29
|
start if auto_start
|
26
30
|
end
|
27
31
|
|
28
32
|
# Forcibly wakes the timer early
|
29
33
|
def wakeup
|
30
34
|
raise NotRunning.new unless running?
|
31
|
-
|
32
|
-
|
33
|
-
|
35
|
+
if(@sleeper.waiters > 0)
|
36
|
+
@sleeper.signal
|
37
|
+
else
|
38
|
+
@timer_thread.wakeup if @timer_thread.alive? && @timer_thread.stop?
|
39
|
+
end
|
34
40
|
end
|
35
41
|
|
36
42
|
# period:: amount of time between runs
|
@@ -39,22 +45,30 @@ module ActionTimer
|
|
39
45
|
# owner:: owner of Action
|
40
46
|
# func:: block to be executed
|
41
47
|
# Add a new action to block
|
42
|
-
def add(
|
43
|
-
|
44
|
-
|
48
|
+
def add(hash, &func)
|
49
|
+
raise ArgumentError.new('Expecting hash of arguments') unless hash.is_a?(Hash)
|
50
|
+
raise ArgumentError.new('A period must be provided for timed action') unless hash[:period]
|
51
|
+
raise ArgumentError.new('Block must be provided') unless block_given?
|
52
|
+
raise ArgumentError.new('Block must accept data value') if hash[:data] && func.arity == 0
|
53
|
+
args = {:once => false, :data => nil, :owner => nil}.merge(hash)
|
54
|
+
action = Action.new(args.merge(:timer => self), &func)
|
45
55
|
@add_lock.synchronize{ @new_actions << action }
|
46
56
|
wakeup if running?
|
47
|
-
|
57
|
+
action
|
48
58
|
end
|
49
59
|
|
50
|
-
# actions:: Array of actions
|
51
|
-
# Add multiple Actions to the timer at once
|
52
|
-
def
|
53
|
-
|
54
|
-
|
55
|
-
|
60
|
+
# actions:: Array of actions or single ActionTimer::Action
|
61
|
+
# Add single or multiple Actions to the timer at once
|
62
|
+
def register(action)
|
63
|
+
if(action.is_a?(Array))
|
64
|
+
if(action.find{|x|x.is_a?(Action)}.nil?)
|
65
|
+
raise ArgumentError.new('Array contains non ActionTimer::Action objects')
|
66
|
+
end
|
67
|
+
else
|
68
|
+
raise ArgumentError.new('Expecting an ActionTimer::Action object') unless action.is_a?(Action)
|
69
|
+
action = [action]
|
56
70
|
end
|
57
|
-
@add_lock.synchronize{ @new_actions = @new_actions +
|
71
|
+
@add_lock.synchronize{ @new_actions = @new_actions + action }
|
58
72
|
wakeup if running?
|
59
73
|
end
|
60
74
|
|
@@ -76,19 +90,24 @@ module ActionTimer
|
|
76
90
|
to_sleep = get_min_sleep
|
77
91
|
if((to_sleep.nil? || to_sleep > 0) && @new_actions.empty?)
|
78
92
|
@awake_lock.unlock if @awake_lock.locked?
|
79
|
-
|
93
|
+
start = Time.now.to_f
|
94
|
+
to_sleep.nil? ? @sleeper.wait : sleep(to_sleep)
|
95
|
+
actual_sleep = Time.now.to_f - start
|
96
|
+
if(@delta && to_sleep && actual_sleep.within_delta?(:expected => to_sleep, :delta => @delta))
|
97
|
+
actual_sleep = to_sleep
|
98
|
+
end
|
80
99
|
@awake_lock.lock
|
81
100
|
else
|
82
101
|
actual_sleep = 0
|
83
102
|
end
|
84
|
-
actual_sleep = to_sleep if actual_sleep <= 0
|
85
103
|
tick(actual_sleep)
|
86
104
|
add_waiting_actions
|
87
105
|
end
|
88
106
|
rescue Object => boom
|
89
107
|
@timer_thread = nil
|
90
108
|
clean_actions
|
91
|
-
@logger.fatal("Timer encountered an unexpected error: #{boom}\n#{boom.backtrace.join("\n")}")
|
109
|
+
@logger.fatal("Timer encountered an unexpected error and is shutting down: #{boom}\n#{boom.backtrace.join("\n")}")
|
110
|
+
@respond_to.raise boom
|
92
111
|
end
|
93
112
|
end
|
94
113
|
end
|
@@ -125,23 +144,30 @@ module ActionTimer
|
|
125
144
|
else
|
126
145
|
@actions.each{|a| @actions.delete(a) if a.owner == owner}
|
127
146
|
end
|
128
|
-
wakeup
|
147
|
+
wakeup if running?
|
129
148
|
end
|
130
149
|
|
131
150
|
# Is timer currently running?
|
132
151
|
def running?
|
133
|
-
|
152
|
+
!@timer_thread.nil?
|
153
|
+
end
|
154
|
+
|
155
|
+
# action:: ActionTimer::Action
|
156
|
+
# Is action currently in timer
|
157
|
+
def registered?(action)
|
158
|
+
@actions.include?(action)
|
159
|
+
end
|
160
|
+
|
161
|
+
# Actions registered with the timer
|
162
|
+
def actions
|
163
|
+
@actions.dup
|
134
164
|
end
|
135
165
|
|
136
166
|
private
|
137
167
|
|
138
168
|
def get_min_sleep
|
139
|
-
min = @actions.
|
140
|
-
|
141
|
-
@actions.each{|a|@actions.delete(a) if a.remaining == 0} # kill stuck actions
|
142
|
-
min = get_min_sleep
|
143
|
-
end
|
144
|
-
return min
|
169
|
+
min = @actions.min{|a,b|a.remaining <=> b.remaining}
|
170
|
+
min.remaining if min
|
145
171
|
end
|
146
172
|
|
147
173
|
def add_waiting_actions
|
@@ -0,0 +1,128 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'actiontimer'
|
3
|
+
|
4
|
+
class ActionTests < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
@timer = ActionTimer::Timer.new
|
7
|
+
end
|
8
|
+
def teardown
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_create
|
12
|
+
assert_raise(ArgumentError) do
|
13
|
+
action = ActionTimer::Action.new(:timer => @timer){true}
|
14
|
+
end
|
15
|
+
assert_raise(ArgumentError) do
|
16
|
+
action = ActionTimer::Action.new(:timer => @timer, :period => 1){|x|true}
|
17
|
+
end
|
18
|
+
assert_raise(ArgumentError) do
|
19
|
+
action = ActionTimer::Action.new(:timer => @timer, :period => 1, :data => 1)
|
20
|
+
end
|
21
|
+
if(RUBY_VERSION > "1.9.0")
|
22
|
+
assert_raise(ArgumentError) do
|
23
|
+
action = ActionTimer::Action.new(:timer => @timer, :period => 1, :data => 1){true}
|
24
|
+
end
|
25
|
+
end
|
26
|
+
assert_kind_of(ActionTimer::Action, ActionTimer::Action.new(:timer => @timer, :period => 1){true})
|
27
|
+
assert_kind_of(ActionTimer::Action, ActionTimer::Action.new(:timer => @timer, :period => 1, :once => true){true})
|
28
|
+
assert_kind_of(ActionTimer::Action, ActionTimer::Action.new(:timer => @timer, :period => 1, :once => false){true})
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_timer
|
32
|
+
mytimer = ActionTimer::Timer.new
|
33
|
+
action = ActionTimer::Action.new(:timer => @timer, :period => 1){true}
|
34
|
+
assert_equal(@timer, action.timer)
|
35
|
+
action.timer = mytimer
|
36
|
+
assert_equal(mytimer, action.timer)
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_owner
|
40
|
+
object = Object.new
|
41
|
+
action = ActionTimer::Action.new(:timer => @timer, :period => 1, :owner => object){true}
|
42
|
+
assert_equal(object, action.owner)
|
43
|
+
other_object = Object.new
|
44
|
+
action.owner = other_object
|
45
|
+
assert_equal(other_object, action.owner)
|
46
|
+
action.owner = object
|
47
|
+
assert_equal(object, action.owner)
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_tick
|
51
|
+
action = ActionTimer::Action.new(:timer => @timer, :period => 2){true}
|
52
|
+
action.tick(1)
|
53
|
+
assert_equal(1, action.remaining)
|
54
|
+
action.tick(0.1)
|
55
|
+
assert_equal(0.9, action.remaining)
|
56
|
+
action.tick(0.11)
|
57
|
+
assert_equal(0.79, action.remaining)
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_reset_period
|
61
|
+
action = ActionTimer::Action.new(:timer => @timer, :period => 2){true}
|
62
|
+
action.tick(1)
|
63
|
+
assert_equal(1, action.remaining)
|
64
|
+
action.reset_period(3)
|
65
|
+
assert_equal(3, action.remaining)
|
66
|
+
action.tick(3)
|
67
|
+
assert_equal(0, action.remaining)
|
68
|
+
assert(!action.is_complete?)
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_complete
|
72
|
+
action = ActionTimer::Action.new(:timer => @timer, :period => 2, :once => true){true}
|
73
|
+
action.tick(2)
|
74
|
+
assert_equal(0, action.remaining)
|
75
|
+
assert(action.is_complete?)
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_schedule
|
79
|
+
action = ActionTimer::Action.new(:timer => @timer, :period => 2){true}
|
80
|
+
action.tick(1)
|
81
|
+
assert_equal(1, action.remaining)
|
82
|
+
assert_equal(action, action.schedule)
|
83
|
+
assert_equal(2, action.remaining)
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_due
|
87
|
+
action = ActionTimer::Action.new(:timer => @timer, :period => 2){true}
|
88
|
+
assert(!action.due?)
|
89
|
+
action.tick(2)
|
90
|
+
assert(action.due?)
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_run_noargs
|
94
|
+
a = false
|
95
|
+
action = ActionTimer::Action.new(:timer => @timer, :period => 2){ a = true }
|
96
|
+
assert(!a)
|
97
|
+
action.run
|
98
|
+
assert(a)
|
99
|
+
end
|
100
|
+
|
101
|
+
def test_run_args
|
102
|
+
a = []
|
103
|
+
action = ActionTimer::Action.new(:timer => @timer, :period => 2, :data => [1,2,[3]]) do |b,c,d|
|
104
|
+
a << b
|
105
|
+
a << c
|
106
|
+
a << d
|
107
|
+
end
|
108
|
+
action.run
|
109
|
+
assert_kind_of(Array, a.pop)
|
110
|
+
assert_equal(2, a.pop)
|
111
|
+
assert_equal(1, a.pop)
|
112
|
+
assert(a.empty?)
|
113
|
+
action = ActionTimer::Action.new(:timer => @timer, :period => 2, :data => [1,2,[3]]) do |*b|
|
114
|
+
a = b
|
115
|
+
end
|
116
|
+
action.run
|
117
|
+
assert_kind_of(Array, a)
|
118
|
+
assert_kind_of(Array, a.pop)
|
119
|
+
assert_equal(2, a.pop)
|
120
|
+
assert_equal(1, a.pop)
|
121
|
+
assert(a.empty?)
|
122
|
+
action = ActionTimer::Action.new(:timer => @timer, :period => 2, :data => :foo) do |b|
|
123
|
+
a = b
|
124
|
+
end
|
125
|
+
action.run
|
126
|
+
assert_equal(:foo, a)
|
127
|
+
end
|
128
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'actiontimer'
|
3
|
+
|
4
|
+
class TimerTests < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
@timer = ActionTimer::Timer.new
|
7
|
+
end
|
8
|
+
|
9
|
+
def teardown
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_add_bad
|
13
|
+
assert_raise(ArgumentError) do
|
14
|
+
@timer.add{true}
|
15
|
+
end
|
16
|
+
assert_raise(ArgumentError) do
|
17
|
+
@timer.add(1){true}
|
18
|
+
end
|
19
|
+
assert_raise(ArgumentError) do
|
20
|
+
@timer.add(:period => 1)
|
21
|
+
end
|
22
|
+
if(RUBY_VERSION > "1.9.0")
|
23
|
+
assert_raise(ArgumentError) do
|
24
|
+
@timer.add(:period => 1, :data => 2){true}
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_add
|
30
|
+
output = []
|
31
|
+
action = @timer.add(:period => 0.1){true}
|
32
|
+
assert_kind_of(ActionTimer::Action, action)
|
33
|
+
sleep(0.01)
|
34
|
+
assert_equal(1, @timer.actions.size)
|
35
|
+
assert(@timer.registered?(action))
|
36
|
+
@timer.add(:period => 0.1, :once => true, :data => :foo){|x| output << x }
|
37
|
+
sleep(0.01)
|
38
|
+
assert_equal(2, @timer.actions.size)
|
39
|
+
sleep(0.14)
|
40
|
+
assert_equal(:foo, output.pop)
|
41
|
+
assert_equal(1, @timer.actions.size)
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_register
|
45
|
+
output = []
|
46
|
+
action = ActionTimer::Action.new(:period => 0.01){output << :action}
|
47
|
+
@timer.register(action)
|
48
|
+
sleep(0.113)
|
49
|
+
@timer.pause
|
50
|
+
assert_equal(10, output.size)
|
51
|
+
assert_equal(1, @timer.actions.size)
|
52
|
+
assert(@timer.registered?(action))
|
53
|
+
@timer.clear
|
54
|
+
assert(@timer.actions.empty?)
|
55
|
+
@timer.start
|
56
|
+
output.clear
|
57
|
+
actions = [action]
|
58
|
+
actions << ActionTimer::Action.new(:period => 0.02){output << :fubar}
|
59
|
+
@timer.register(actions)
|
60
|
+
sleep(0.051)
|
61
|
+
@timer.pause
|
62
|
+
assert_equal(7, output.size)
|
63
|
+
assert(output.include?(:fubar))
|
64
|
+
assert_equal(2, @timer.actions.size)
|
65
|
+
actions.each{|x| assert(@timer.registered?(x)) }
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_remove
|
69
|
+
output = []
|
70
|
+
action = ActionTimer::Action.new(:period => 0.01){output << :action}
|
71
|
+
@timer.register(action)
|
72
|
+
sleep(0.029)
|
73
|
+
@timer.remove(action)
|
74
|
+
assert_equal(2, output.size)
|
75
|
+
assert(@timer.actions.empty?)
|
76
|
+
output.clear
|
77
|
+
assert(output.empty?)
|
78
|
+
action = @timer.add(:period => 0.01){output << :action}
|
79
|
+
sleep(0.021)
|
80
|
+
@timer.remove(action)
|
81
|
+
assert(!@timer.registered?(action))
|
82
|
+
assert(2, output.size)
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
data/tests/run_tests.rb
CHANGED
@@ -3,143 +3,148 @@ $LOAD_PATH.unshift(File.expand_path("#{__FILE__}/../../lib"))
|
|
3
3
|
require 'test/unit'
|
4
4
|
require 'actiontimer'
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
6
|
+
Dir.new("#{File.dirname(__FILE__)}/cases").each{|f|
|
7
|
+
require "#{File.dirname(__FILE__)}/cases/#{f}" if f[-2..f.size] == 'rb'
|
8
|
+
}
|
9
|
+
#
|
10
|
+
#
|
11
|
+
# class TimerTests < Test::Unit::TestCase
|
12
|
+
# def setup
|
13
|
+
# @timer = ActionTimer::Timer.new
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# # Simple test of basic repetitive action
|
17
|
+
# def test_basic
|
18
|
+
# result = 0
|
19
|
+
# @timer.add(2){ result += 1 }
|
20
|
+
# sleep(5)
|
21
|
+
# assert_equal(2, result)
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# # Check the the running? method properly reports
|
25
|
+
# def test_running
|
26
|
+
# @timer.add(1){ 1 + 1}
|
27
|
+
# assert(@timer.running?)
|
28
|
+
# @timer.pause
|
29
|
+
# assert(!@timer.running?)
|
30
|
+
# @timer.start
|
31
|
+
# assert(@timer.running?)
|
32
|
+
# @timer.stop
|
33
|
+
# assert(!@timer.running?)
|
34
|
+
# end
|
35
|
+
#
|
36
|
+
# # Check that a value 0 < t < 1 works
|
37
|
+
# # as expected
|
38
|
+
# def test_float
|
39
|
+
# result = 0
|
40
|
+
# @timer.add(0.1){ result += 1 }
|
41
|
+
# sleep(1.01)
|
42
|
+
# assert_equal(10, result)
|
43
|
+
# end
|
44
|
+
#
|
45
|
+
# # Check that a single iterative action is only
|
46
|
+
# # completed once
|
47
|
+
# def test_once
|
48
|
+
# result = 0
|
49
|
+
# @timer.add(1, true){ result += 1 }
|
50
|
+
# sleep(3)
|
51
|
+
# assert_equal(1, result)
|
52
|
+
# end
|
53
|
+
#
|
54
|
+
# # Check that timer can be paused and restarted
|
55
|
+
# # without registered actions being effected
|
56
|
+
# def test_pause
|
57
|
+
# result = 0
|
58
|
+
# @timer.add(1){ result += 1 }
|
59
|
+
# sleep(3.1)
|
60
|
+
# @timer.pause
|
61
|
+
# sleep(2)
|
62
|
+
# @timer.start
|
63
|
+
# sleep(2)
|
64
|
+
# assert_equal(5, result)
|
65
|
+
# end
|
66
|
+
#
|
67
|
+
# # Check that data can be passed to the block
|
68
|
+
# # properly when created
|
69
|
+
# def test_data
|
70
|
+
# result = 0
|
71
|
+
# @timer.add(1, true, 3){|a| result = a}
|
72
|
+
# sleep(2)
|
73
|
+
# assert_equal(3, result)
|
74
|
+
# @timer.add(1, true, [3,4,['foobar']]){|a,b,c| result = [b,a,c]}
|
75
|
+
# sleep(2)
|
76
|
+
# assert_equal(4, result[0])
|
77
|
+
# assert_equal(3, result[1])
|
78
|
+
# assert(result[2].is_a?(Array))
|
79
|
+
# end
|
80
|
+
#
|
81
|
+
# # Check that the timer's auto starting mechanism
|
82
|
+
# # can be disabled
|
83
|
+
# def test_auto_start
|
84
|
+
# timer = ActionTimer::Timer.new(:auto_start => false)
|
85
|
+
# timer.add(1){ 1+1 }
|
86
|
+
# assert(!timer.running?)
|
87
|
+
# timer.start
|
88
|
+
# assert(timer.running?)
|
89
|
+
# end
|
90
|
+
#
|
91
|
+
# # Check that the actions can be cleared out of the
|
92
|
+
# # timer and the timer is still left in a "running"
|
93
|
+
# # state.
|
94
|
+
# def test_clear
|
95
|
+
# result = 0
|
96
|
+
# @timer.add(1){ result += 1 }
|
97
|
+
# sleep(3)
|
98
|
+
# @timer.clear
|
99
|
+
# sleep(2)
|
100
|
+
# assert_equal(2, result)
|
101
|
+
# assert(@timer.running?)
|
102
|
+
# end
|
103
|
+
#
|
104
|
+
# # Check that the timer throws an exception when it
|
105
|
+
# # is instructed to wakeup while not running
|
106
|
+
# def test_wakeup
|
107
|
+
# @timer.stop
|
108
|
+
# assert_raise(ActionTimer::NotRunning){ @timer.wakeup }
|
109
|
+
# end
|
110
|
+
#
|
111
|
+
# # Check that the timer throws an exception when it
|
112
|
+
# # is instructed to start but is already running
|
113
|
+
# def test_start
|
114
|
+
# assert_raise(ActionTimer::AlreadyRunning){ @timer.start }
|
115
|
+
# end
|
116
|
+
#
|
117
|
+
# # Check that multiple actions can be added at once
|
118
|
+
# def test_mass_add
|
119
|
+
# result = 0
|
120
|
+
# actions = []
|
121
|
+
# actions << ActionTimer::Action.new(@timer, 1){ result += 1}
|
122
|
+
# actions << ActionTimer::Action.new(@timer, 3){ result += 1}
|
123
|
+
# actions << ActionTimer::Action.new(@timer, 5){ result += 1}
|
124
|
+
# @timer.mass_add(actions)
|
125
|
+
# sleep(5.3)
|
126
|
+
# assert_equal(7, result)
|
127
|
+
# end
|
128
|
+
#
|
129
|
+
# # Check that an action can be properly removed from
|
130
|
+
# # the timer
|
131
|
+
# def test_remove
|
132
|
+
# result = 0
|
133
|
+
# action = @timer.add(1){result += 1}
|
134
|
+
# sleep(2.1)
|
135
|
+
# @timer.remove(action)
|
136
|
+
# sleep(2)
|
137
|
+
# assert_equal(2, result)
|
138
|
+
# end
|
139
|
+
#
|
140
|
+
# # Check that an action's period can be dynamically
|
141
|
+
# # reset
|
142
|
+
# def test_action_reset
|
143
|
+
# result = 0
|
144
|
+
# action = @timer.add(1){ result += 1}
|
145
|
+
# sleep(2.1)
|
146
|
+
# action.reset_period(3)
|
147
|
+
# sleep(3.1)
|
148
|
+
# assert_equal(result, 3)
|
149
|
+
# end
|
150
|
+
# end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ActionTimer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- spox
|
@@ -9,18 +9,28 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-01-
|
12
|
+
date: 2010-01-13 00:00:00 -08:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
|
-
name:
|
16
|
+
name: actionpool
|
17
17
|
type: :runtime
|
18
18
|
version_requirement:
|
19
19
|
version_requirements: !ruby/object:Gem::Requirement
|
20
20
|
requirements:
|
21
|
-
- -
|
21
|
+
- - ~>
|
22
22
|
- !ruby/object:Gem::Version
|
23
|
-
version:
|
23
|
+
version: 0.2.3
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: splib
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: "1.4"
|
24
34
|
version:
|
25
35
|
description: ActionTimer is a simple timer for recurring actions. It supports single and recurring actions with an easy to use API.
|
26
36
|
email: spox@modspox.com
|
@@ -33,16 +43,18 @@ extra_rdoc_files:
|
|
33
43
|
- LICENSE
|
34
44
|
- CHANGELOG
|
35
45
|
files:
|
36
|
-
-
|
46
|
+
- actiontimer.gemspec
|
47
|
+
- tests/cases/timer.rb
|
48
|
+
- tests/cases/action.rb
|
49
|
+
- tests/run_tests.rb
|
50
|
+
- lib/actiontimer.rb
|
37
51
|
- lib/actiontimer/Timer.rb
|
38
52
|
- lib/actiontimer/Action.rb
|
39
|
-
- lib/actiontimer.rb
|
40
|
-
- test
|
41
|
-
- tests/run_tests.rb
|
53
|
+
- lib/actiontimer/Exceptions.rb
|
42
54
|
- CHANGELOG
|
43
55
|
- LICENSE
|
44
56
|
- README.rdoc
|
45
|
-
- actiontimer.
|
57
|
+
- actiontimer-0.2.1.gem
|
46
58
|
has_rdoc: true
|
47
59
|
homepage: http://github.com/spox/actiontimer
|
48
60
|
licenses: []
|
data/test
DELETED
@@ -1,11 +0,0 @@
|
|
1
|
-
require 'actiontimer'
|
2
|
-
timer = ActionTimer::Timer.new
|
3
|
-
result = 0
|
4
|
-
actions = []
|
5
|
-
actions << ActionTimer::Action.new(@timer, 0.1){ result += 1}
|
6
|
-
actions << ActionTimer::Action.new(@timer, 0.2){ result += 1}
|
7
|
-
actions << ActionTimer::Action.new(@timer, 0.3){ result += 1}
|
8
|
-
timer.mass_add(actions)
|
9
|
-
sleep(0.41)
|
10
|
-
p result
|
11
|
-
|