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 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
@@ -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
 
Binary file
@@ -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.'
@@ -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
@@ -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
@@ -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)
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
@@ -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,16 +43,18 @@ extra_rdoc_files:
33
43
  - LICENSE
34
44
  - CHANGELOG
35
45
  files:
36
- - 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
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.gemspec
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
-