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(@timer, 0.1){ result += 1}
96
- actions << ActionTimer::Action.new(@timer, 0.2){ result += 1}
97
- actions << ActionTimer::Action.new(@timer, 0.3){ result += 1}
98
- timer.mass_add(actions)
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
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.1.1'
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 'ActionPool'
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
@@ -1 +1,4 @@
1
- require 'actiontimer/Timer.rb'
1
+ require 'rubygems'
2
+ require 'actiontimer/Timer.rb'
3
+ require 'splib'
4
+ Splib.load :Array, :Float, :Monitor
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(timer, period, once=false, data=nil, &block)
12
- @period = period.to_f
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 = nil
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
- @timer.wakeup
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 = Mutex.new
24
- @awake_lock = Mutex.new
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
- return unless @awake_lock.try_lock
32
- @timer_thread.wakeup if @timer_thread.status == 'sleep'
33
- @awake_lock.unlock
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(period, once=false, data=nil, owner=nil, &func)
43
- action = Action.new(self, period, once, data, &func)
44
- action.owner = owner unless owner.nil?
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
- return action
57
+ action
48
58
end
49
59
50
- # actions:: Array of actions
51
- # Add multiple Actions to the timer at once
52
- def mass_add(actions)
53
- raise ArgumentError.new('Expecting an array') unless actions.is_a?(Array)
54
- actions.each do |action|
55
- raise ArgumentError.new('Expecting an Action') unless action.is_a?(Action)
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 + 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
- actual_sleep = to_sleep.nil? ? sleep : sleep(to_sleep)
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
- return !@timer_thread.nil?
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.map{|a|a.remaining}.sort[0]
140
- unless(min.nil? || min > 0)
169
+ min = @actions.min{|a,b|a.remaining <=> b.remaining}
170
+ min.remaining if min
141
- @actions.each{|a|@actions.delete(a) if a.remaining == 0} # kill stuck actions
142
- min = get_min_sleep
143
- end
144
- return min
145
171
end
146
172
147
173
def add_waiting_actions
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
-
data/tests/cases/action.rb ADDED
@@ -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
data/tests/cases/timer.rb ADDED
@@ -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
- class TimerTests < Test::Unit::TestCase
7
- def setup
8
- @timer = ActionTimer::Timer.new
9
- end
10
-
11
- # Simple test of basic repetitive action
12
- def test_basic
13
- result = 0
14
- @timer.add(2){ result += 1 }
15
- sleep(5)
16
- assert_equal(2, result)
17
- end
18
-
19
- # Check the the running? method properly reports
20
- def test_running
21
- @timer.add(1){ 1 + 1}
22
- assert(@timer.running?)
23
- @timer.pause
24
- assert(!@timer.running?)
25
- @timer.start
26
- assert(@timer.running?)
27
- @timer.stop
28
- assert(!@timer.running?)
29
- end
30
-
31
- # Check that a value 0 < t < 1 works
32
- # as expected
33
- def test_float
34
- result = 0
35
- @timer.add(0.1){ result += 1 }
36
- sleep(1.01)
37
- assert_equal(10, result)
38
- end
39
-
40
- # Check that a single iterative action is only
41
- # completed once
42
- def test_once
43
- result = 0
44
- @timer.add(1, true){ result += 1 }
45
- sleep(3)
46
- assert_equal(1, result)
47
- end
48
-
49
- # Check that timer can be paused and restarted
50
- # without registered actions being effected
51
- def test_pause
52
- result = 0
53
- @timer.add(1){ result += 1 }
54
- sleep(3.1)
55
- @timer.pause
56
- sleep(2)
57
- @timer.start
58
- sleep(2)
59
- assert_equal(5, result)
60
- end
61
-
62
- # Check that data can be passed to the block
63
- # properly when created
64
- def test_data
65
- result = 0
66
- @timer.add(1, true, 3){|a| result = a}
67
- sleep(2)
68
- assert_equal(3, result)
69
- @timer.add(1, true, [3,4,['foobar']]){|a,b,c| result = [b,a,c]}
70
- sleep(2)
71
- assert_equal(4, result[0])
72
- assert_equal(3, result[1])
73
- assert(result[2].is_a?(Array))
74
- end
75
-
76
- # Check that the timer's auto starting mechanism
77
- # can be disabled
78
- def test_auto_start
79
- timer = ActionTimer::Timer.new(:auto_start => false)
80
- timer.add(1){ 1+1 }
81
- assert(!timer.running?)
82
- timer.start
83
- assert(timer.running?)
84
- end
85
-
86
- # Check that the actions can be cleared out of the
87
- # timer and the timer is still left in a "running"
88
- # state.
89
- def test_clear
90
- result = 0
91
- @timer.add(1){ result += 1 }
92
- sleep(3)
93
- @timer.clear
94
- sleep(2)
95
- assert_equal(2, result)
96
- assert(@timer.running?)
97
- end
98
-
99
- # Check that the timer throws an exception when it
100
- # is instructed to wakeup while not running
101
- def test_wakeup
102
- @timer.stop
103
- assert_raise(ActionTimer::NotRunning){ @timer.wakeup }
104
- end
105
-
106
- # Check that the timer throws an exception when it
107
- # is instructed to start but is already running
108
- def test_start
109
- assert_raise(ActionTimer::AlreadyRunning){ @timer.start }
110
- end
111
-
112
- # Check that multiple actions can be added at once
113
- def test_mass_add
114
- result = 0
115
- actions = []
116
- actions << ActionTimer::Action.new(@timer, 1){ result += 1}
117
- actions << ActionTimer::Action.new(@timer, 3){ result += 1}
118
- actions << ActionTimer::Action.new(@timer, 5){ result += 1}
119
- @timer.mass_add(actions)
120
- sleep(5.3)
121
- assert_equal(7, result)
122
- end
123
-
124
- # Check that an action can be properly removed from
125
- # the timer
126
- def test_remove
127
- result = 0
128
- action = @timer.add(1){result += 1}
129
- sleep(2.1)
130
- @timer.remove(action)
131
- sleep(2)
132
- assert_equal(2, result)
133
- end
134
-
135
- # Check that an action's period can be dynamically
136
- # reset
137
- def test_action_reset
138
- result = 0
139
- action = @timer.add(1){ result += 1}
140
- sleep(2.1)
141
- action.reset_period(3)
142
- sleep(3.1)
143
- assert_equal(result, 3)
144
- end
145
- end
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.1.1
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-05 00:00:00 -08:00
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: ActionPool
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: "0"
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,21 +43,21 @@ extra_rdoc_files:
33
43
- LICENSE
34
44
- CHANGELOG
35
45
files:
36
- - lib
37
- - lib/actiontimer
38
- - lib/actiontimer/Exceptions.rb
46
+ - actiontimer.gemspec
47
+ - tests/cases/timer.rb
48
+ - tests/cases/action.rb
49
+ - tests/run_tests.rb
50
+ - lib/actiontimer.rb
39
51
- lib/actiontimer/Timer.rb
40
52
- lib/actiontimer/Action.rb
41
- - lib/actiontimer.rb
53
+ - lib/actiontimer/Exceptions.rb
42
- - test
43
- - tests
44
- - tests/run_tests.rb
45
54
- CHANGELOG
46
55
- LICENSE
47
56
- README.rdoc
48
- - actiontimer.gemspec
49
57
has_rdoc: true
50
58
homepage: http://github.com/spox/actiontimer
59
+ licenses: []
60
+
51
61
post_install_message:
52
62
rdoc_options:
53
63
- --title
@@ -73,9 +83,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
73
83
requirements: []
74
84
75
85
rubyforge_project:
76
- rubygems_version: 1.3.1
86
+ rubygems_version: 1.3.5
77
87
signing_key:
78
- specification_version: 2
88
+ specification_version: 3
79
89
summary: Simple timer for a complex world
80
90
test_files: []
81
91