vrinek-periodicity 0.1.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/History.txt +4 -0
- data/Manifest.txt +14 -0
- data/PostInstall.txt +2 -0
- data/README.rdoc +33 -0
- data/Rakefile +27 -0
- data/lib/periodicity.rb +9 -0
- data/lib/periodicity/period.rb +265 -0
- data/script/console +10 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/spec/periodicity_spec.rb +94 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +10 -0
- data/tasks/rspec.rake +21 -0
- metadata +91 -0
data/History.txt
ADDED
data/Manifest.txt
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
History.txt
|
|
2
|
+
Manifest.txt
|
|
3
|
+
PostInstall.txt
|
|
4
|
+
README.rdoc
|
|
5
|
+
Rakefile
|
|
6
|
+
lib/periodicity.rb
|
|
7
|
+
lib/periodicity/period.rb
|
|
8
|
+
script/console
|
|
9
|
+
script/destroy
|
|
10
|
+
script/generate
|
|
11
|
+
spec/periodicity_spec.rb
|
|
12
|
+
spec/spec.opts
|
|
13
|
+
spec/spec_helper.rb
|
|
14
|
+
tasks/rspec.rake
|
data/PostInstall.txt
ADDED
data/README.rdoc
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
= periodicity
|
|
2
|
+
|
|
3
|
+
* http://github.com/vrinek/periodicity
|
|
4
|
+
|
|
5
|
+
== DESCRIPTION:
|
|
6
|
+
|
|
7
|
+
Helps calculate the next run for schedulers using a human readable syntax.
|
|
8
|
+
|
|
9
|
+
== SYNOPSIS:
|
|
10
|
+
|
|
11
|
+
period = Period.new(Time.now).every(2).hours.at(20).from(10).to(15)
|
|
12
|
+
means: every 2 hours at :20 from 10:00 to 15:00 (10:20, 12:20, 14:20)
|
|
13
|
+
|
|
14
|
+
period.next_run # returns the next calculated time as a Time object
|
|
15
|
+
period.next_run(1) # skips 1 run (as of 0.1, it behaves buggy with from and to limits)
|
|
16
|
+
|
|
17
|
+
Period.new.every(:half).hour # every 30 minutes
|
|
18
|
+
Period.every.week # every week
|
|
19
|
+
Period.every(5).seconds # every 5 seconds
|
|
20
|
+
|
|
21
|
+
== REQUIREMENTS:
|
|
22
|
+
|
|
23
|
+
* active support (not sure about the exact version yet)
|
|
24
|
+
|
|
25
|
+
== INSTALL:
|
|
26
|
+
|
|
27
|
+
* gem sources -a http://gems.github.com
|
|
28
|
+
* sudo gem install vrinek-periodicity
|
|
29
|
+
|
|
30
|
+
== TODO:
|
|
31
|
+
|
|
32
|
+
* support "overnight" limits (from 22:00 tonight to 02:00 tomorrow) like:
|
|
33
|
+
Period.every.hour.from(20).to(2)
|
data/Rakefile
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
require 'rubygems'
|
|
2
|
+
gem 'hoe', '>= 2.1.0'
|
|
3
|
+
require 'hoe'
|
|
4
|
+
require 'fileutils'
|
|
5
|
+
require './lib/periodicity'
|
|
6
|
+
|
|
7
|
+
Hoe.plugin :newgem
|
|
8
|
+
# Hoe.plugin :website
|
|
9
|
+
# Hoe.plugin :cucumberfeatures
|
|
10
|
+
|
|
11
|
+
# Generate all the Rake tasks
|
|
12
|
+
# Run 'rake -T' to see list of generated tasks (from gem root directory)
|
|
13
|
+
$hoe = Hoe.spec 'periodicity' do
|
|
14
|
+
self.developer 'Kostas Karachalios', 'kostas.karachalios@me.com'
|
|
15
|
+
self.post_install_message = 'PostInstall.txt' # TODO remove if post-install message not required
|
|
16
|
+
self.extra_deps = [['activesupport','>= 2.3.2']]
|
|
17
|
+
self.extra_rdoc_files = ['README.rdoc']
|
|
18
|
+
self.url = 'http://github.com/vrinek/periodicity'
|
|
19
|
+
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
require 'newgem/tasks'
|
|
23
|
+
Dir['tasks/**/*.rake'].each { |t| load t }
|
|
24
|
+
|
|
25
|
+
# TODO - want other tests/tasks run by default? Add them to the list
|
|
26
|
+
remove_task :default
|
|
27
|
+
task :default => :spec
|
data/lib/periodicity.rb
ADDED
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
class Period
|
|
2
|
+
DAY_PERIODS = {
|
|
3
|
+
"morning" => 9,
|
|
4
|
+
"noon" => 12,
|
|
5
|
+
"afternoon" => 19,
|
|
6
|
+
"midnight" => 0
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
=begin rdoc
|
|
10
|
+
Initializes a new Period object with the last_run used for the next_run calculations
|
|
11
|
+
|
|
12
|
+
A Period object needs at least an every and time period (minutes, hours etc) to functions properly:
|
|
13
|
+
Period.new.every.day
|
|
14
|
+
Period.new(2.hours.ago).every(4).hours
|
|
15
|
+
|
|
16
|
+
If last_run is nil, next_run will always return Time.now
|
|
17
|
+
=end
|
|
18
|
+
def initialize(last_run = nil)
|
|
19
|
+
@last_run = last_run
|
|
20
|
+
@at = 0
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
=begin rdoc
|
|
24
|
+
Sets the interval at which the runs should be calculated:
|
|
25
|
+
|
|
26
|
+
every.day
|
|
27
|
+
every(20).minutes
|
|
28
|
+
every(2).hours
|
|
29
|
+
=end
|
|
30
|
+
def every(int = 1)
|
|
31
|
+
@interval = int
|
|
32
|
+
return self
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
=begin rdoc
|
|
36
|
+
Sets the scope to one week so that <tt>every(2).weeks</tt> means "every 2 weeks"
|
|
37
|
+
=end
|
|
38
|
+
def weeks
|
|
39
|
+
@scope = 1.week
|
|
40
|
+
reset_on_base 7
|
|
41
|
+
|
|
42
|
+
return self
|
|
43
|
+
end
|
|
44
|
+
alias_method :week, :weeks
|
|
45
|
+
|
|
46
|
+
=begin rdoc
|
|
47
|
+
Sets the scope to one day so that <tt>every(4).days</tt> means "every 4 days"
|
|
48
|
+
=end
|
|
49
|
+
def days
|
|
50
|
+
@scope = 1.days
|
|
51
|
+
reset_on_base 24
|
|
52
|
+
|
|
53
|
+
return self
|
|
54
|
+
end
|
|
55
|
+
alias_method :day, :days
|
|
56
|
+
|
|
57
|
+
=begin rdoc
|
|
58
|
+
Sets the scope to one hour so that <tt>every(6).hours</tt> means "every 6 hours"
|
|
59
|
+
=end
|
|
60
|
+
def hours
|
|
61
|
+
@scope = 1.hour
|
|
62
|
+
reset_on_base 60
|
|
63
|
+
|
|
64
|
+
return self
|
|
65
|
+
end
|
|
66
|
+
alias_method :hour, :hours
|
|
67
|
+
|
|
68
|
+
=begin rdoc
|
|
69
|
+
Sets the scope to one minute so that <tt>every(20).minutes</tt> means "every 20 minutes"
|
|
70
|
+
=end
|
|
71
|
+
def minutes
|
|
72
|
+
@scope = 1.minute
|
|
73
|
+
reset_on_base 60
|
|
74
|
+
|
|
75
|
+
return self
|
|
76
|
+
end
|
|
77
|
+
alias_method :minute, :minutes
|
|
78
|
+
|
|
79
|
+
=begin rdoc
|
|
80
|
+
Sets the scope to one second so that <tt>every(5).seconds</tt> means "every 5 seconds"
|
|
81
|
+
=end
|
|
82
|
+
def seconds
|
|
83
|
+
@scope = 1.second
|
|
84
|
+
reset_on_base false
|
|
85
|
+
|
|
86
|
+
return self
|
|
87
|
+
end
|
|
88
|
+
alias_method :second, :seconds
|
|
89
|
+
|
|
90
|
+
=begin rdoc
|
|
91
|
+
Sets the from limit based on the scope:
|
|
92
|
+
every(2).hours.from(8) # means "every 2 hours beginning from 8:00"
|
|
93
|
+
=end
|
|
94
|
+
def from(time)
|
|
95
|
+
raise "From can't be after to" if @to and @to < time
|
|
96
|
+
|
|
97
|
+
@from = time
|
|
98
|
+
return self
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
=begin rdoc
|
|
102
|
+
Sets the to limit based on the scope:
|
|
103
|
+
every(2).hours.to(12) # means "every 2 hours until 12:00"
|
|
104
|
+
=end
|
|
105
|
+
def to(time)
|
|
106
|
+
raise "To can't be before from" if @from and time < @from
|
|
107
|
+
|
|
108
|
+
@to = time
|
|
109
|
+
return self
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
=begin rdoc
|
|
113
|
+
Sets a specific "sub-time" for the next_run:
|
|
114
|
+
every(2).hours.at(15) # means "every 2 hours at the first quarter of each" e.g. 12:15, 14:15, 16:15
|
|
115
|
+
|
|
116
|
+
NOTE: when using at and from, to limits together the limits *always* calculate at 0 "sub-time":
|
|
117
|
+
every(2).hours.at(15).from(12).to(16) # will return 12:15, 14:15 but not 16:15 because the to limit ends at 16:00
|
|
118
|
+
=end
|
|
119
|
+
def at(time)
|
|
120
|
+
unless time.is_a?(Integer)
|
|
121
|
+
time = case time.to_s
|
|
122
|
+
when /^\d+:00$/
|
|
123
|
+
time[/^\d+/].to_i
|
|
124
|
+
when /^\d+:\d{2}$/
|
|
125
|
+
raise 'Precise timing like "20:15" is not yet supported'
|
|
126
|
+
when /^(noon|afternoon|midnight|morning)$/
|
|
127
|
+
DAY_PERIODS[time.to_s]
|
|
128
|
+
else
|
|
129
|
+
time.to_i
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
@at = time
|
|
134
|
+
return self
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
=begin rdoc
|
|
138
|
+
This return a Time object for the next calculated time:
|
|
139
|
+
now = "Aug 05 14:40:23 2009".to_time
|
|
140
|
+
Period.new(now).every(2).hours.next_run # => Wed Aug 05 16:00:00 UTC 2009
|
|
141
|
+
|
|
142
|
+
Note that it round all "sub-time" to 0 by default (can be overriden with at)
|
|
143
|
+
=end
|
|
144
|
+
def next_run(skip = 0)
|
|
145
|
+
return Time.now unless @last_run
|
|
146
|
+
|
|
147
|
+
@next_run = @last_run
|
|
148
|
+
|
|
149
|
+
if @scope and @interval
|
|
150
|
+
@next_run += @interval * @scope
|
|
151
|
+
|
|
152
|
+
calc_precision
|
|
153
|
+
|
|
154
|
+
calc_limits
|
|
155
|
+
|
|
156
|
+
unless skip.zero?
|
|
157
|
+
@next_run += @interval * @scope * skip
|
|
158
|
+
|
|
159
|
+
calc_limits
|
|
160
|
+
end
|
|
161
|
+
else
|
|
162
|
+
raise 'No proper period specified'
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
return @next_run
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
private
|
|
169
|
+
|
|
170
|
+
def reset_on_base(base)
|
|
171
|
+
@interval = 1 unless base
|
|
172
|
+
|
|
173
|
+
@interval = case @interval.to_s
|
|
174
|
+
when /half/i
|
|
175
|
+
@scope = @scope/base
|
|
176
|
+
base/2
|
|
177
|
+
when /quarter/i
|
|
178
|
+
@scope = @scope/base
|
|
179
|
+
base/4
|
|
180
|
+
when /other/i
|
|
181
|
+
2
|
|
182
|
+
else
|
|
183
|
+
@interval
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def calc_precision(scope = nil)
|
|
188
|
+
@at = 0 if scope
|
|
189
|
+
|
|
190
|
+
case scope || @scope
|
|
191
|
+
when 1.minute
|
|
192
|
+
unless @next_run.sec == @at
|
|
193
|
+
@next_run += (@at - @next_run.sec)
|
|
194
|
+
end
|
|
195
|
+
when 1.hour
|
|
196
|
+
unless @next_run.min == @at
|
|
197
|
+
@next_run += (@at - @next_run.min).minutes
|
|
198
|
+
end
|
|
199
|
+
calc_precision 1.minute
|
|
200
|
+
when 1.day
|
|
201
|
+
unless @next_run.hour == @at
|
|
202
|
+
@next_run += (@at - @next_run.hour).hours
|
|
203
|
+
end
|
|
204
|
+
calc_precision 1.hour
|
|
205
|
+
when 1.week
|
|
206
|
+
unless @next_run.hour == @at
|
|
207
|
+
@next_run += (@at - @next_run.hour).hours
|
|
208
|
+
end
|
|
209
|
+
calc_precision 1.hour
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
def calc_limits
|
|
214
|
+
if @from or @to
|
|
215
|
+
now = case @scope
|
|
216
|
+
when 1.second
|
|
217
|
+
@next_run.sec
|
|
218
|
+
when 1.minute
|
|
219
|
+
@next_run.min
|
|
220
|
+
when 1.hour
|
|
221
|
+
@next_run.hour
|
|
222
|
+
when 1.day
|
|
223
|
+
@next_run.day
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
if @from and now < @from
|
|
227
|
+
@next_run += (@from - now) * @scope
|
|
228
|
+
elsif @to and now > @to
|
|
229
|
+
@next_run += ((@from || 0) - now) * @scope + uptime
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
def uptime
|
|
235
|
+
case @scope
|
|
236
|
+
when 1.second
|
|
237
|
+
1.minute
|
|
238
|
+
when 1.minute
|
|
239
|
+
1.hour
|
|
240
|
+
when 1.hour
|
|
241
|
+
1.day
|
|
242
|
+
when 1.day
|
|
243
|
+
days_of_month.days
|
|
244
|
+
when 1.week
|
|
245
|
+
days_of_month.days
|
|
246
|
+
end
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
def downtime
|
|
250
|
+
case @scope
|
|
251
|
+
when 1.minute
|
|
252
|
+
1.second
|
|
253
|
+
when 1.hour
|
|
254
|
+
1.minute
|
|
255
|
+
when 1.day
|
|
256
|
+
1.hour
|
|
257
|
+
when 1.week
|
|
258
|
+
1.hour
|
|
259
|
+
end
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
def days_of_month
|
|
263
|
+
(Date.new(Time.now.year, 12, 31).to_date << (12 - @last_run.month)).day
|
|
264
|
+
end
|
|
265
|
+
end
|
data/script/console
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# File: script/console
|
|
3
|
+
irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
|
|
4
|
+
|
|
5
|
+
libs = " -r irb/completion"
|
|
6
|
+
# Perhaps use a console_lib to store any extra methods I may want available in the cosole
|
|
7
|
+
# libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
|
|
8
|
+
libs << " -r #{File.dirname(__FILE__) + '/../lib/periodicity.rb'}"
|
|
9
|
+
puts "Loading periodicity gem"
|
|
10
|
+
exec "#{irb} #{libs} --simple-prompt"
|
data/script/destroy
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
|
3
|
+
|
|
4
|
+
begin
|
|
5
|
+
require 'rubigen'
|
|
6
|
+
rescue LoadError
|
|
7
|
+
require 'rubygems'
|
|
8
|
+
require 'rubigen'
|
|
9
|
+
end
|
|
10
|
+
require 'rubigen/scripts/destroy'
|
|
11
|
+
|
|
12
|
+
ARGV.shift if ['--help', '-h'].include?(ARGV[0])
|
|
13
|
+
RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
|
|
14
|
+
RubiGen::Scripts::Destroy.new.run(ARGV)
|
data/script/generate
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
|
3
|
+
|
|
4
|
+
begin
|
|
5
|
+
require 'rubigen'
|
|
6
|
+
rescue LoadError
|
|
7
|
+
require 'rubygems'
|
|
8
|
+
require 'rubigen'
|
|
9
|
+
end
|
|
10
|
+
require 'rubigen/scripts/generate'
|
|
11
|
+
|
|
12
|
+
ARGV.shift if ['--help', '-h'].include?(ARGV[0])
|
|
13
|
+
RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
|
|
14
|
+
RubiGen::Scripts::Generate.new.run(ARGV)
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
|
2
|
+
|
|
3
|
+
describe Period do
|
|
4
|
+
it "should return now if not run before" do
|
|
5
|
+
Period.new.next_run.to_i.should == Time.now.to_i
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
it "should raise when period not set properly" do
|
|
9
|
+
lambda {Period.new(Time.now).next_run}.should raise_error
|
|
10
|
+
lambda {Period.new(Time.now).every(12).next_run}.should raise_error
|
|
11
|
+
lambda {Period.new(Time.now).minutes.next_run}.should raise_error
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it "should return correct time on simple stuff" do
|
|
15
|
+
period.every(3).weeks.next_run.should == "Aug 26 00:00:00 2009".to_time
|
|
16
|
+
period.every(4).days.next_run.should == "Aug 09 00:00:00 2009".to_time
|
|
17
|
+
period.every(2).hours.next_run.should == "Aug 05 16:00:00 2009".to_time
|
|
18
|
+
period.every(30).minutes.next_run.should == "Aug 05 15:10:00 2009".to_time
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it "should return correct time on a little bit more complex stuff" do
|
|
22
|
+
period.every.day.next_run.should == "Aug 06 00:00:00 2009".to_time
|
|
23
|
+
period.every(:quarter).hour.next_run.should == "Aug 05 14:55:00 2009".to_time
|
|
24
|
+
period.every(:half).minute.next_run.should == "Aug 05 14:40:53 2009".to_time
|
|
25
|
+
period.every(:other).hour.next_run.should == period.every(2).hours.next_run
|
|
26
|
+
|
|
27
|
+
period.every.day.at(:morning).next_run.should == "Aug 06 09:00:00 2009".to_time
|
|
28
|
+
period.every.day.at(:noon).next_run.should == "Aug 06 12:00:00 2009".to_time
|
|
29
|
+
period.every.day.at(:afternoon).next_run.should == "Aug 06 19:00:00 2009".to_time
|
|
30
|
+
|
|
31
|
+
period.every.day.at(:midnight).next_run.should == "Aug 06 00:00:00 2009".to_time
|
|
32
|
+
period.every.day.at(:midnight).next_run(1).should == "Aug 07 00:00:00 2009".to_time
|
|
33
|
+
period.every.day.at(:midnight).next_run(2).should == "Aug 08 00:00:00 2009".to_time
|
|
34
|
+
|
|
35
|
+
period.every.day.at('5').next_run.should == "Aug 06 05:00:00 2009".to_time
|
|
36
|
+
period.every.day.at('5:00').next_run.should == "Aug 06 05:00:00 2009".to_time
|
|
37
|
+
period.every.day.at('05:00').next_run.should == "Aug 06 05:00:00 2009".to_time
|
|
38
|
+
|
|
39
|
+
lambda {period.every.day.at('05:30').next_run}.should raise_error # not yet implemented
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it "should return correct time with precision" do
|
|
43
|
+
period.every.week.at(20).next_run.should == "Aug 12 20:00:00 2009".to_time
|
|
44
|
+
period.every.day.at(14).next_run.should == "Aug 06 14:00:00 2009".to_time
|
|
45
|
+
|
|
46
|
+
period.every.hour.at(30).next_run.should == "Aug 05 15:30:00 2009".to_time
|
|
47
|
+
period.every.hour.at(30).next_run(1).should == "Aug 05 16:30:00 2009".to_time
|
|
48
|
+
period.every.hour.at(30).next_run(2).should == "Aug 05 17:30:00 2009".to_time
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it "should take into account the limits" do
|
|
52
|
+
period.every(2).hours.from(18).next_run.should == "Aug 05 18:00:00 2009".to_time
|
|
53
|
+
period.every.hour.from(13).next_run.should == "Aug 05 15:00:00 2009".to_time
|
|
54
|
+
period.every(2).hours.from(12).next_run.should == "Aug 05 16:00:00 2009".to_time
|
|
55
|
+
|
|
56
|
+
period.every(2).hours.from(21).next_run.should == "Aug 05 21:00:00 2009".to_time
|
|
57
|
+
period.every(2).hours.from(21).next_run(1).should == "Aug 05 23:00:00 2009".to_time
|
|
58
|
+
period.every(2).hours.from(21).next_run(2).should == "Aug 06 21:00:00 2009".to_time
|
|
59
|
+
|
|
60
|
+
period.every(2).hours.to(12).next_run.should == "Aug 06 00:00:00 2009".to_time
|
|
61
|
+
period.every(2).hours.to(12).next_run(1).should == "Aug 06 02:00:00 2009".to_time
|
|
62
|
+
period.every(2).hours.to(12).next_run(2).should == "Aug 06 04:00:00 2009".to_time
|
|
63
|
+
|
|
64
|
+
period.every(5).minutes.from(15).to(50).next_run(0).should == "Aug 05 14:45:00 2009".to_time
|
|
65
|
+
period.every(5).minutes.from(15).to(50).next_run(1).should == "Aug 05 14:50:00 2009".to_time
|
|
66
|
+
period.every(5).minutes.from(15).to(50).next_run(2).should == "Aug 05 15:15:00 2009".to_time
|
|
67
|
+
# period.every(5).minutes.from(15).to(50).next_run(3).should == "Aug 05 15:20:00 2009".to_time # skip has limits...
|
|
68
|
+
|
|
69
|
+
period.every(2).hours.from(8).to(12).next_run(0).should == "Aug 06 08:00:00 2009".to_time
|
|
70
|
+
period.every(2).hours.from(8).to(12).next_run(1).should == "Aug 06 10:00:00 2009".to_time
|
|
71
|
+
period.every(2).hours.from(8).to(12).next_run(2).should == "Aug 06 12:00:00 2009".to_time
|
|
72
|
+
period.every(2).hours.from(8).to(12).next_run(3).should == "Aug 07 08:00:00 2009".to_time
|
|
73
|
+
# period.every(2).hours.from(8).to(12).next_run(4).should == "Aug 07 10:00:00 2009".to_time # skip has limits...
|
|
74
|
+
|
|
75
|
+
period.every(3).days.from(5).to(20).next_run(0).should == "Aug 08 00:00:00 2009".to_time
|
|
76
|
+
period.every(3).days.from(5).to(20).next_run(1).should == "Aug 11 00:00:00 2009".to_time
|
|
77
|
+
period.every(3).days.from(5).to(20).next_run(2).should == "Aug 14 00:00:00 2009".to_time
|
|
78
|
+
period.every(3).days.from(5).to(20).next_run(3).should == "Aug 17 00:00:00 2009".to_time
|
|
79
|
+
period.every(3).days.from(5).to(20).next_run(4).should == "Aug 20 00:00:00 2009".to_time
|
|
80
|
+
period.every(3).days.from(5).to(20).next_run(5).should == "Sep 05 00:00:00 2009".to_time
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
it "should avoid some pitfalls" do
|
|
84
|
+
Period.new("Aug 05 14:41:23 2009".to_time).every.hour.at(40).next_run.should == "Aug 05 15:40:00 2009".to_time
|
|
85
|
+
Period.new("Aug 05 14:39:23 2009".to_time).every.hour.at(40).next_run.should == "Aug 05 15:40:00 2009".to_time
|
|
86
|
+
|
|
87
|
+
lambda {period.from(5).to(1)}.should raise_error
|
|
88
|
+
lambda {period.to(1).from(5)}.should raise_error
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def period
|
|
92
|
+
return Period.new("Aug 05 14:40:23 2009".to_time)
|
|
93
|
+
end
|
|
94
|
+
end
|
data/spec/spec.opts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
--colour
|
data/spec/spec_helper.rb
ADDED
data/tasks/rspec.rake
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
begin
|
|
2
|
+
require 'spec'
|
|
3
|
+
rescue LoadError
|
|
4
|
+
require 'rubygems' unless ENV['NO_RUBYGEMS']
|
|
5
|
+
require 'spec'
|
|
6
|
+
end
|
|
7
|
+
begin
|
|
8
|
+
require 'spec/rake/spectask'
|
|
9
|
+
rescue LoadError
|
|
10
|
+
puts <<-EOS
|
|
11
|
+
To use rspec for testing you must install rspec gem:
|
|
12
|
+
gem install rspec
|
|
13
|
+
EOS
|
|
14
|
+
exit(0)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
desc "Run the specs under spec/models"
|
|
18
|
+
Spec::Rake::SpecTask.new do |t|
|
|
19
|
+
t.spec_opts = ['--options', "spec/spec.opts"]
|
|
20
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
|
21
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: vrinek-periodicity
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Kostas Karachalios
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
|
|
12
|
+
date: 2009-08-06 00:00:00 -07:00
|
|
13
|
+
default_executable:
|
|
14
|
+
dependencies:
|
|
15
|
+
- !ruby/object:Gem::Dependency
|
|
16
|
+
name: activesupport
|
|
17
|
+
type: :runtime
|
|
18
|
+
version_requirement:
|
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
20
|
+
requirements:
|
|
21
|
+
- - ">="
|
|
22
|
+
- !ruby/object:Gem::Version
|
|
23
|
+
version: 2.3.2
|
|
24
|
+
version:
|
|
25
|
+
- !ruby/object:Gem::Dependency
|
|
26
|
+
name: hoe
|
|
27
|
+
type: :development
|
|
28
|
+
version_requirement:
|
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - ">="
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: 2.3.2
|
|
34
|
+
version:
|
|
35
|
+
description: Helps calculate the next run for schedulers using a human readable syntax.
|
|
36
|
+
email:
|
|
37
|
+
- kostas.karachalios@me.com
|
|
38
|
+
executables: []
|
|
39
|
+
|
|
40
|
+
extensions: []
|
|
41
|
+
|
|
42
|
+
extra_rdoc_files:
|
|
43
|
+
- History.txt
|
|
44
|
+
- Manifest.txt
|
|
45
|
+
- PostInstall.txt
|
|
46
|
+
- README.rdoc
|
|
47
|
+
files:
|
|
48
|
+
- History.txt
|
|
49
|
+
- Manifest.txt
|
|
50
|
+
- PostInstall.txt
|
|
51
|
+
- README.rdoc
|
|
52
|
+
- Rakefile
|
|
53
|
+
- lib/periodicity.rb
|
|
54
|
+
- lib/periodicity/period.rb
|
|
55
|
+
- script/console
|
|
56
|
+
- script/destroy
|
|
57
|
+
- script/generate
|
|
58
|
+
- spec/periodicity_spec.rb
|
|
59
|
+
- spec/spec.opts
|
|
60
|
+
- spec/spec_helper.rb
|
|
61
|
+
- tasks/rspec.rake
|
|
62
|
+
has_rdoc: false
|
|
63
|
+
homepage: http://github.com/vrinek/periodicity
|
|
64
|
+
licenses:
|
|
65
|
+
post_install_message: PostInstall.txt
|
|
66
|
+
rdoc_options:
|
|
67
|
+
- --main
|
|
68
|
+
- README.rdoc
|
|
69
|
+
require_paths:
|
|
70
|
+
- lib
|
|
71
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - ">="
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: "0"
|
|
76
|
+
version:
|
|
77
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
78
|
+
requirements:
|
|
79
|
+
- - ">="
|
|
80
|
+
- !ruby/object:Gem::Version
|
|
81
|
+
version: "0"
|
|
82
|
+
version:
|
|
83
|
+
requirements: []
|
|
84
|
+
|
|
85
|
+
rubyforge_project: periodicity
|
|
86
|
+
rubygems_version: 1.3.5
|
|
87
|
+
signing_key:
|
|
88
|
+
specification_version: 3
|
|
89
|
+
summary: Helps calculate the next run for schedulers using a human readable syntax.
|
|
90
|
+
test_files: []
|
|
91
|
+
|