gregfitz23-chrono_trigger 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +9 -0
- data/Manifest.txt +21 -0
- data/PostInstall.txt +3 -0
- data/README.rdoc +58 -0
- data/VERSION.yml +4 -0
- data/lib/chrono_trigger.rb +11 -0
- data/lib/chrono_trigger/cron_entry.rb +54 -0
- data/lib/chrono_trigger/shell.rb +36 -0
- data/lib/chrono_trigger/tasks.rb +3 -0
- data/lib/chrono_trigger/trigger.rb +92 -0
- data/lib/triggers/test_triggers.rb +26 -0
- data/test/test_chrono_trigger.rb +11 -0
- data/test/test_cron_entry.rb +136 -0
- data/test/test_helper.rb +5 -0
- data/test/test_shell.rb +52 -0
- data/test/test_trigger.rb +116 -0
- data/test/triggers.rb +11 -0
- metadata +72 -0
data/History.txt
ADDED
data/Manifest.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
History.txt
|
2
|
+
Manifest.txt
|
3
|
+
PostInstall.txt
|
4
|
+
README.rdoc
|
5
|
+
Rakefile
|
6
|
+
lib/chrono_trigger.rb
|
7
|
+
lib/chrono_trigger/cron_entry.rb
|
8
|
+
lib/chrono_trigger/shell.rb
|
9
|
+
lib/chrono_trigger/tasks.rb
|
10
|
+
lib/chrono_trigger/trigger.rb
|
11
|
+
lib/triggers/test_triggers.rb
|
12
|
+
script/console
|
13
|
+
script/destroy
|
14
|
+
script/generate
|
15
|
+
tasks/chrono_trigger.rake
|
16
|
+
test/test_chrono_trigger.rb
|
17
|
+
test/test_cron_entry.rb
|
18
|
+
test/test_helper.rb
|
19
|
+
test/test_shell.rb
|
20
|
+
test/test_trigger.rb
|
21
|
+
test/triggers.rb
|
data/PostInstall.txt
ADDED
data/README.rdoc
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
= chrono_trigger
|
2
|
+
|
3
|
+
* http://github.com/gregfitz23/chrono_trigger/tree/master
|
4
|
+
|
5
|
+
== DESCRIPTION:
|
6
|
+
|
7
|
+
A cron framework for defining cron tasks using a readable DSL.
|
8
|
+
|
9
|
+
== FEATURES/PROBLEMS:
|
10
|
+
|
11
|
+
== SYNOPSIS:
|
12
|
+
|
13
|
+
After installation, create lib/tasks/chrono_trigger.rake containing: require 'chrono_trigger/tasks'
|
14
|
+
|
15
|
+
Create trigger files (by default in the lib/triggers) directory.
|
16
|
+
Triggers should follow the pattern:
|
17
|
+
|
18
|
+
trigger "name" do
|
19
|
+
runs { code to execute }
|
20
|
+
on :monday
|
21
|
+
every :minutes=>10
|
22
|
+
at :hour=>9, :minute=>[30,50]
|
23
|
+
end
|
24
|
+
|
25
|
+
Execute rake RAILS_ENV={env} chrono_trigger:run
|
26
|
+
|
27
|
+
== REQUIREMENTS:
|
28
|
+
|
29
|
+
* ActiveSupport >= 2.0.2
|
30
|
+
|
31
|
+
== INSTALL:
|
32
|
+
|
33
|
+
* sudo gem install gregfitz23-chrono_trigger
|
34
|
+
|
35
|
+
== LICENSE:
|
36
|
+
|
37
|
+
(The MIT License)
|
38
|
+
|
39
|
+
Copyright (c) 2009 FIXME full name
|
40
|
+
|
41
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
42
|
+
a copy of this software and associated documentation files (the
|
43
|
+
'Software'), to deal in the Software without restriction, including
|
44
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
45
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
46
|
+
permit persons to whom the Software is furnished to do so, subject to
|
47
|
+
the following conditions:
|
48
|
+
|
49
|
+
The above copyright notice and this permission notice shall be
|
50
|
+
included in all copies or substantial portions of the Software.
|
51
|
+
|
52
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
53
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
54
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
55
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
56
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
57
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
58
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/VERSION.yml
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__)) unless
|
2
|
+
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
3
|
+
|
4
|
+
module ChronoTrigger
|
5
|
+
VERSION = '0.0.2'
|
6
|
+
end
|
7
|
+
|
8
|
+
require "activesupport"
|
9
|
+
require "chrono_trigger/shell"
|
10
|
+
require "chrono_trigger/trigger"
|
11
|
+
require "chrono_trigger/cron_entry"
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module ChronoTrigger
|
2
|
+
|
3
|
+
class CronEntry
|
4
|
+
|
5
|
+
def initialize(options={})
|
6
|
+
set_days(options[:days])
|
7
|
+
set_hours(options[:hours])
|
8
|
+
set_minutes(options[:minutes])
|
9
|
+
end
|
10
|
+
|
11
|
+
DAYS_CONVERSION = {
|
12
|
+
:sunday => 0,
|
13
|
+
:monday => 1,
|
14
|
+
:tuesday => 2,
|
15
|
+
:wednesday => 3,
|
16
|
+
:thursday => 4,
|
17
|
+
:friday => 5,
|
18
|
+
:saturday => 6
|
19
|
+
}
|
20
|
+
|
21
|
+
def set_hours(*args)
|
22
|
+
args.compact!
|
23
|
+
args.flatten!
|
24
|
+
raise ChronoTrigger::ConfigurationException.new("Hours must be less than 24") if args.any? {|hour| hour >= 24}
|
25
|
+
@hours = args
|
26
|
+
end
|
27
|
+
|
28
|
+
def set_days(*args)
|
29
|
+
args.compact!
|
30
|
+
args.flatten!
|
31
|
+
args.each {|day| raise ChronoTrigger::ConfigurationException.new("Day #{day} setting is invalid") if !DAYS_CONVERSION.keys.include?(day)}
|
32
|
+
@days = args.map { |day| DAYS_CONVERSION[day] }
|
33
|
+
end
|
34
|
+
|
35
|
+
def set_minutes(*args)
|
36
|
+
args.compact!
|
37
|
+
args.flatten!
|
38
|
+
raise ChronoTrigger::ConfigurationException.new("Minutes must be less than 60") if args.any? {|minute| minute >= 60}
|
39
|
+
@minutes = args
|
40
|
+
end
|
41
|
+
|
42
|
+
def matches?(datetime)
|
43
|
+
if @minutes.blank? && !@days.blank?
|
44
|
+
raise ChronoTrigger::ConfigurationException.new("Days were specified for a CronEntry with no minutes specified")
|
45
|
+
end
|
46
|
+
|
47
|
+
return false if !@minutes.blank? && !@minutes.include?(datetime.min)
|
48
|
+
return false if !@hours.blank? && !@hours.include?(datetime.hour)
|
49
|
+
return false if !@days.blank? && !@days.include?(datetime.wday)
|
50
|
+
return true
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module ChronoTrigger
|
2
|
+
|
3
|
+
class ConfigurationException < Exception; end
|
4
|
+
|
5
|
+
class Shell
|
6
|
+
|
7
|
+
DEFAULT_TRIGGERS = "lib/triggers/*.rb"
|
8
|
+
#Load triggers defined in the trigger files by evaluating them in the context of this Shell instance.
|
9
|
+
def load_triggers(files = Dir.glob("#{DEFAULT_TRIGGERS}"))
|
10
|
+
files.each { |file| self.instance_eval(File.read(file), file) }
|
11
|
+
end
|
12
|
+
|
13
|
+
#Instantiate a trigger and evaluate the passed in block in the context of the trigger.
|
14
|
+
#This is the initial method call when setting up a configuration using the DSL.
|
15
|
+
def trigger(name, &block)
|
16
|
+
raise ConfigurationException.new("No configuration specified for trigger #{name}") unless block_given?
|
17
|
+
|
18
|
+
trigger = Trigger.new(name)
|
19
|
+
trigger.instance_eval(&block)
|
20
|
+
|
21
|
+
triggers << trigger
|
22
|
+
trigger
|
23
|
+
end
|
24
|
+
|
25
|
+
#Run execute on any trigger who's cron entry matches the current time.
|
26
|
+
def execute_triggers
|
27
|
+
now = Time.now
|
28
|
+
triggers.map {|trigger| trigger.execute_on_match(now)}
|
29
|
+
end
|
30
|
+
|
31
|
+
def triggers
|
32
|
+
@triggers ||= []
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
module ChronoTrigger
|
2
|
+
class Trigger
|
3
|
+
|
4
|
+
attr_accessor :name
|
5
|
+
|
6
|
+
def initialize(name)
|
7
|
+
self.name = name
|
8
|
+
end
|
9
|
+
|
10
|
+
#Define the code to be run when the cron job is ready to be executed.
|
11
|
+
def runs(&block)
|
12
|
+
@exec_block = block
|
13
|
+
end
|
14
|
+
|
15
|
+
#Specify what days the task should run on.
|
16
|
+
#Values are :monday, :tuesday, :wednesday, :thursday, :friday, :saturday, :sunday
|
17
|
+
def on(*days)
|
18
|
+
cron_entry.set_days(days)
|
19
|
+
end
|
20
|
+
|
21
|
+
#Specify what hours and minutes the task should run at
|
22
|
+
#(e.g. :minute=>10, :hour=>3 or :minute=>[10,20,30], :hour=>[1,2,3])
|
23
|
+
def at(options={})
|
24
|
+
validate_hours_or_minutes!(options)
|
25
|
+
|
26
|
+
if hour = options[:hour]
|
27
|
+
cron_entry.set_hours(hour)
|
28
|
+
end
|
29
|
+
|
30
|
+
if minute = options[:minute]
|
31
|
+
cron_entry.set_minutes(minute)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
#Specify a repeating interval of hours and minutes to run.
|
36
|
+
#Specifying minutes not divisible by 60 result in an exception, use #at instead.
|
37
|
+
def every(options={})
|
38
|
+
validate_hours_or_minutes!(options)
|
39
|
+
if minutes = options[:minutes]
|
40
|
+
cron_entry.set_minutes(extract_minutes_for_every(minutes))
|
41
|
+
end
|
42
|
+
|
43
|
+
if hours = options[:hours]
|
44
|
+
cron_entry.set_hours(extract_hours_for_every(hours))
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def dates
|
49
|
+
@dates ||= []
|
50
|
+
end
|
51
|
+
|
52
|
+
#Execute this Trigger's code block if the datetime param matches this Trigger's cron entry.
|
53
|
+
def execute_on_match(datetime)
|
54
|
+
self.execute if cron_entry.matches?(datetime)
|
55
|
+
end
|
56
|
+
|
57
|
+
def execute
|
58
|
+
@exec_block.call
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
private
|
63
|
+
def cron_entry
|
64
|
+
@cron_entry ||= CronEntry.new
|
65
|
+
end
|
66
|
+
|
67
|
+
#Raise an exception unless minutes and hours are set.
|
68
|
+
def validate_hours_or_minutes!(options={})
|
69
|
+
unless (options[:hours] || options[:hour]) || (options[:minutes] || options[:minute])
|
70
|
+
raise ChronoTrigger::ConfigurationException.new("Hours or minutes not specified in call to 'at' or 'every' method.")
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def extract_minutes_for_every(minutes)
|
75
|
+
extract_for_every(minutes, 60)
|
76
|
+
end
|
77
|
+
|
78
|
+
def extract_hours_for_every(hours)
|
79
|
+
extract_for_every(hours, 24)
|
80
|
+
end
|
81
|
+
|
82
|
+
#Extract an array of integers representing the minutes or hours a task should be run at.
|
83
|
+
#Raise an exception if time_value is not evenly divisible by base.
|
84
|
+
def extract_for_every(time_value, base)
|
85
|
+
unless (base % time_value == 0)
|
86
|
+
raise ChronoTrigger::ConfigurationException.new("#{time_value} is not evenly divisible by #{base}. Consider using #at instead.")
|
87
|
+
end
|
88
|
+
|
89
|
+
(0...base).select {|num| num % time_value == 0}
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
trigger "trigger1" do
|
2
|
+
runs { puts "trigger 1 runs every 1 minutes; executed at #{Time.now}"}
|
3
|
+
every :minutes=>1
|
4
|
+
end
|
5
|
+
|
6
|
+
trigger "trigger2" do
|
7
|
+
runs { puts "trigger 2 runs every 5 minutes; executed at #{Time.now}"}
|
8
|
+
every :minutes=>5
|
9
|
+
end
|
10
|
+
|
11
|
+
trigger "trigger3" do
|
12
|
+
runs { puts "trigger 3 runs at 9:48; executed at #{Time.now}"}
|
13
|
+
at :hour=>9, :minute=>48
|
14
|
+
end
|
15
|
+
|
16
|
+
trigger "trigger4" do
|
17
|
+
runs { puts "trigger 4 runs on monday at 9:53 and 9:56; executed at #{Time.now}"}
|
18
|
+
on :monday
|
19
|
+
at :hour=>9, :minute=>[53, 56]
|
20
|
+
end
|
21
|
+
|
22
|
+
trigger "trigger5" do
|
23
|
+
runs { puts "trigger 5 runs on thursday at 9:58/59; executed at #{Time.now}"}
|
24
|
+
on :thursday
|
25
|
+
at :hour=>9, :minute=>[58, 59]
|
26
|
+
end
|
@@ -0,0 +1,136 @@
|
|
1
|
+
class TestCronEntry < Test::Unit::TestCase
|
2
|
+
|
3
|
+
class << self
|
4
|
+
|
5
|
+
def should_match(options={})
|
6
|
+
context "and a datetime of #{options.inspect}" do
|
7
|
+
setup do
|
8
|
+
@datetime = time_from_options(options)
|
9
|
+
end
|
10
|
+
|
11
|
+
should "return true on a call to matches?" do
|
12
|
+
assert @cron.matches?(@datetime)
|
13
|
+
end
|
14
|
+
end #and a datetime of options[]
|
15
|
+
end
|
16
|
+
|
17
|
+
def should_not_match(options={})
|
18
|
+
context "and a datetime of #{options.inspect}" do
|
19
|
+
setup do
|
20
|
+
@datetime = time_from_options(options)
|
21
|
+
end
|
22
|
+
|
23
|
+
should "return false on a call to matches?" do
|
24
|
+
assert !@cron.matches?(@datetime)
|
25
|
+
end
|
26
|
+
end #and a datetime of options[]
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
context "A CronEntry, @cron," do
|
32
|
+
setup do
|
33
|
+
@cron = ChronoTrigger::CronEntry.new
|
34
|
+
end
|
35
|
+
|
36
|
+
context "with a minutes entry of 10 minutes" do
|
37
|
+
setup do
|
38
|
+
@cron.set_minutes(10)
|
39
|
+
end
|
40
|
+
|
41
|
+
should_match(:minutes=>10)
|
42
|
+
|
43
|
+
should_not_match(:minutes=>11)
|
44
|
+
|
45
|
+
context "and 25 minutes" do
|
46
|
+
setup do
|
47
|
+
@cron.set_minutes(10, 25)
|
48
|
+
end
|
49
|
+
|
50
|
+
should_match(:minutes=>25)
|
51
|
+
|
52
|
+
should_match(:minutes=>10)
|
53
|
+
|
54
|
+
should_not_match(:minutes=>12)
|
55
|
+
|
56
|
+
context "and a day entry of monday" do
|
57
|
+
setup do
|
58
|
+
@cron.set_days(:monday)
|
59
|
+
end
|
60
|
+
|
61
|
+
should_match(:minutes=>10, :wday=>1)
|
62
|
+
|
63
|
+
should_not_match(:minutes=>10, :wday=>2)
|
64
|
+
|
65
|
+
context "and wednesday" do
|
66
|
+
setup do
|
67
|
+
@cron.set_days(:monday, :wednesday)
|
68
|
+
end
|
69
|
+
|
70
|
+
should_match(:minutes=>10, :wday=>1)
|
71
|
+
|
72
|
+
should_match(:minutes=>10, :wday=>3)
|
73
|
+
|
74
|
+
should_not_match(:minutes=>25, :wday=>5)
|
75
|
+
|
76
|
+
should_not_match(:minutes=>11, :wday=>3)
|
77
|
+
|
78
|
+
context "and an hour entry of 2" do
|
79
|
+
setup do
|
80
|
+
@cron.set_hours(5)
|
81
|
+
end
|
82
|
+
|
83
|
+
should_match(:minutes=>25, :wday=>3, :hour=>5)
|
84
|
+
|
85
|
+
should_not_match(:minutes=>25, :wday=>3, :hour=>6)
|
86
|
+
end #and an hour entry of 2
|
87
|
+
end #and wednesday
|
88
|
+
end #and a day entry of monday
|
89
|
+
end #and 25 minutes
|
90
|
+
end #with a minutes entry of 10 minutes
|
91
|
+
|
92
|
+
context "with a day entry of monday" do
|
93
|
+
setup do
|
94
|
+
@cron.set_days(:monday)
|
95
|
+
end
|
96
|
+
|
97
|
+
context "and no minutes_entry" do
|
98
|
+
setup do
|
99
|
+
@cron.set_minutes(nil)
|
100
|
+
end
|
101
|
+
|
102
|
+
should "raise a ChronoTrigger::CronEntry:ConfigException exception on matches?" do
|
103
|
+
assert_raise ChronoTrigger::ConfigurationException do
|
104
|
+
@cron.matches?(time_from_options)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end #and no minutes_entry
|
108
|
+
end #with a day entry
|
109
|
+
|
110
|
+
should "raise an exception when setting an hour entry greater than 25" do
|
111
|
+
assert_raise ChronoTrigger::ConfigurationException do
|
112
|
+
@cron.set_hours(25)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end #A CronEntry, @cron,
|
116
|
+
|
117
|
+
|
118
|
+
private
|
119
|
+
def time_from_options(options={})
|
120
|
+
datetime = Time.utc(options[:year] || 2000,
|
121
|
+
options[:month] || "jan",
|
122
|
+
options[:day]||1,
|
123
|
+
options[:hour]||0,
|
124
|
+
options[:minutes]||0,
|
125
|
+
options[:second]||0)
|
126
|
+
|
127
|
+
if wday = options[:wday]
|
128
|
+
while datetime.wday != wday
|
129
|
+
datetime += 1.day
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
datetime
|
134
|
+
end
|
135
|
+
|
136
|
+
end
|
data/test/test_helper.rb
ADDED
data/test/test_shell.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
class TestShell < Test::Unit::TestCase
|
2
|
+
|
3
|
+
context "A shell instance, @shell" do
|
4
|
+
setup do
|
5
|
+
@shell = ChronoTrigger::Shell.new
|
6
|
+
end
|
7
|
+
|
8
|
+
should "return an empty array on call to triggers" do
|
9
|
+
assert_equal [], @shell.triggers
|
10
|
+
end
|
11
|
+
|
12
|
+
should "raise an exception unless a block is provided to #trigger" do
|
13
|
+
assert_raise(ChronoTrigger::ConfigurationException) { @shell.trigger("test trigger") }
|
14
|
+
end
|
15
|
+
|
16
|
+
context "when provided a valid block" do
|
17
|
+
setup do
|
18
|
+
@trigger = @shell.trigger("name") { runs { "x" } }
|
19
|
+
end
|
20
|
+
|
21
|
+
should "create a new trigger" do
|
22
|
+
assert_equal 1, @shell.triggers.size
|
23
|
+
end
|
24
|
+
|
25
|
+
should "create a trigger that will run x with execute" do
|
26
|
+
assert_equal "x", @shell.triggers.first.execute
|
27
|
+
end
|
28
|
+
|
29
|
+
context "and configured to run the next time shell.execute_triggers is called" do
|
30
|
+
setup do
|
31
|
+
ChronoTrigger::CronEntry.any_instance.stubs(:matches?).returns(true)
|
32
|
+
end
|
33
|
+
|
34
|
+
should "execute the code block" do
|
35
|
+
@trigger.expects(:execute)
|
36
|
+
@shell.execute_triggers
|
37
|
+
end
|
38
|
+
end #and configured to run the next time shell.execute_triggers is called
|
39
|
+
end #when provided a valid block
|
40
|
+
|
41
|
+
context "calling load_context with a valid trigger file" do
|
42
|
+
setup do
|
43
|
+
@shell.load_triggers("test/triggers.rb")
|
44
|
+
end
|
45
|
+
|
46
|
+
should "create 2 triggers" do
|
47
|
+
assert_equal 2, @shell.triggers.size
|
48
|
+
end
|
49
|
+
end #calling load_context with a valid trigger file
|
50
|
+
end #A shell instance, @shell
|
51
|
+
|
52
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
class TestTrigger < Test::Unit::TestCase
|
2
|
+
|
3
|
+
context "A Trigger, @trigger," do
|
4
|
+
setup do
|
5
|
+
@trigger = ChronoTrigger::Trigger.new("test trigger")
|
6
|
+
end
|
7
|
+
|
8
|
+
context "and a block of code to run" do
|
9
|
+
setup do
|
10
|
+
@block_to_run = "hello"
|
11
|
+
@trigger.runs { @block_to_run }
|
12
|
+
end
|
13
|
+
|
14
|
+
should "assign @exec_block on call to runs" do
|
15
|
+
assert_equal @block_to_run, @trigger.instance_variable_get(:@exec_block).call
|
16
|
+
end
|
17
|
+
|
18
|
+
should "execute @block_to_run on call to execute" do
|
19
|
+
assert_equal @block_to_run, @trigger.execute
|
20
|
+
end
|
21
|
+
end #and a block of code to run
|
22
|
+
|
23
|
+
context "and a call to #on with some days" do
|
24
|
+
setup do
|
25
|
+
@days = [:monday, :wednesday]
|
26
|
+
@expected_days = [1, 3]
|
27
|
+
@trigger.on(@days)
|
28
|
+
end
|
29
|
+
|
30
|
+
should "set the triggers cron entry days" do
|
31
|
+
assert_equal @expected_days, @trigger.instance_variable_get(:@cron_entry).instance_variable_get(:@days)
|
32
|
+
end
|
33
|
+
end #and a call to on with some days
|
34
|
+
|
35
|
+
context "and a call to #at with :hours and :minutes" do
|
36
|
+
setup do
|
37
|
+
@hours = 10
|
38
|
+
@minutes = 5
|
39
|
+
@trigger.at :hour=>@hours, :minute=>@minutes
|
40
|
+
end
|
41
|
+
|
42
|
+
should "set the trigger's cron entry's hours" do
|
43
|
+
assert_equal [@hours], @trigger.instance_variable_get(:@cron_entry).instance_variable_get(:@hours)
|
44
|
+
end
|
45
|
+
|
46
|
+
should "set the trigger's cron entry's minutes" do
|
47
|
+
assert_equal [@minutes], @trigger.instance_variable_get(:@cron_entry).instance_variable_get(:@minutes)
|
48
|
+
end
|
49
|
+
|
50
|
+
context "that are nil" do
|
51
|
+
setup do
|
52
|
+
@hours, @minutes = nil, nil
|
53
|
+
end
|
54
|
+
|
55
|
+
should "raise an exception" do
|
56
|
+
assert_raise ChronoTrigger::ConfigurationException do
|
57
|
+
@trigger.at :hours=>@hours, :minutes=>@minutes
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end #that are nil
|
61
|
+
end #and a call to #at with :hours and :minutes
|
62
|
+
|
63
|
+
|
64
|
+
context "on a call to #every" do
|
65
|
+
context "for 10 minutes" do
|
66
|
+
setup do
|
67
|
+
@minutes = 10
|
68
|
+
end
|
69
|
+
|
70
|
+
context "when called" do
|
71
|
+
setup do
|
72
|
+
@trigger.every :minutes=>@minutes
|
73
|
+
end
|
74
|
+
|
75
|
+
should "set the trigger's cron entry's minutes to [0, 10,20,30,40,50]" do
|
76
|
+
assert_equal [0,10,20,30,40,50], @trigger.instance_variable_get(:@cron_entry).instance_variable_get(:@minutes)
|
77
|
+
end
|
78
|
+
|
79
|
+
context "in addition to setting #at to hour 2" do
|
80
|
+
setup do
|
81
|
+
@hour = 2
|
82
|
+
@trigger.at :hour=>@hour
|
83
|
+
end
|
84
|
+
|
85
|
+
should "set the trigger's cron entry's minutes to [0, 10,20,30,40,50]" do
|
86
|
+
assert_equal [0,10,20,30,40,50], @trigger.instance_variable_get(:@cron_entry).instance_variable_get(:@minutes)
|
87
|
+
end
|
88
|
+
|
89
|
+
should "set the trigger's cron entry's hours to 2" do
|
90
|
+
assert_equal [2], @trigger.instance_variable_get(:@cron_entry).instance_variable_get(:@hours)
|
91
|
+
end
|
92
|
+
end #in addition to setting #{}
|
93
|
+
end #when called
|
94
|
+
end #for 10 minutes
|
95
|
+
|
96
|
+
context "for 11 minutes" do
|
97
|
+
setup do
|
98
|
+
@minutes = 11
|
99
|
+
end
|
100
|
+
|
101
|
+
should "raise an exception" do
|
102
|
+
assert_raise ChronoTrigger::ConfigurationException do
|
103
|
+
@trigger.every :minutes=>@minutes
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end #for 11 minutes
|
107
|
+
end #on a call to #every
|
108
|
+
|
109
|
+
should "raise an exception on call to #every without minutes or hours" do
|
110
|
+
assert_raise ChronoTrigger::ConfigurationException do
|
111
|
+
@trigger.every()
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end #A Trigger, @trigger,
|
115
|
+
|
116
|
+
end
|
data/test/triggers.rb
ADDED
metadata
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: gregfitz23-chrono_trigger
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Greg Fitzgerald
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-04-03 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: TODO
|
17
|
+
email: greg_fitz@yahoo.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- README.rdoc
|
24
|
+
files:
|
25
|
+
- History.txt
|
26
|
+
- Manifest.txt
|
27
|
+
- PostInstall.txt
|
28
|
+
- README.rdoc
|
29
|
+
- VERSION.yml
|
30
|
+
- lib/chrono_trigger
|
31
|
+
- lib/chrono_trigger/cron_entry.rb
|
32
|
+
- lib/chrono_trigger/shell.rb
|
33
|
+
- lib/chrono_trigger/tasks.rb
|
34
|
+
- lib/chrono_trigger/trigger.rb
|
35
|
+
- lib/chrono_trigger.rb
|
36
|
+
- lib/triggers
|
37
|
+
- lib/triggers/test_triggers.rb
|
38
|
+
- test/test_chrono_trigger.rb
|
39
|
+
- test/test_cron_entry.rb
|
40
|
+
- test/test_helper.rb
|
41
|
+
- test/test_shell.rb
|
42
|
+
- test/test_trigger.rb
|
43
|
+
- test/triggers.rb
|
44
|
+
has_rdoc: true
|
45
|
+
homepage: ""
|
46
|
+
post_install_message:
|
47
|
+
rdoc_options:
|
48
|
+
- --inline-source
|
49
|
+
- --charset=UTF-8
|
50
|
+
require_paths:
|
51
|
+
- lib
|
52
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: "0"
|
57
|
+
version:
|
58
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: "0"
|
63
|
+
version:
|
64
|
+
requirements: []
|
65
|
+
|
66
|
+
rubyforge_project:
|
67
|
+
rubygems_version: 1.2.0
|
68
|
+
signing_key:
|
69
|
+
specification_version: 2
|
70
|
+
summary: TODO
|
71
|
+
test_files: []
|
72
|
+
|