rufus-scheduler 2.0.24 → 3.0.0
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.txt +6 -0
- data/CREDITS.txt +4 -0
- data/README.md +1064 -0
- data/Rakefile +1 -4
- data/TODO.txt +145 -55
- data/lib/rufus/scheduler.rb +502 -26
- data/lib/rufus/{sc → scheduler}/cronline.rb +46 -17
- data/lib/rufus/{sc/version.rb → scheduler/job_array.rb} +56 -4
- data/lib/rufus/scheduler/jobs.rb +548 -0
- data/lib/rufus/scheduler/util.rb +318 -0
- data/rufus-scheduler.gemspec +30 -4
- data/spec/cronline_spec.rb +29 -8
- data/spec/error_spec.rb +116 -0
- data/spec/job_array_spec.rb +39 -0
- data/spec/job_at_spec.rb +58 -0
- data/spec/job_cron_spec.rb +67 -0
- data/spec/job_every_spec.rb +71 -0
- data/spec/job_in_spec.rb +20 -0
- data/spec/job_interval_spec.rb +68 -0
- data/spec/job_repeat_spec.rb +308 -0
- data/spec/job_spec.rb +387 -115
- data/spec/lockfile_spec.rb +61 -0
- data/spec/parse_spec.rb +203 -0
- data/spec/schedule_at_spec.rb +129 -0
- data/spec/schedule_cron_spec.rb +66 -0
- data/spec/schedule_every_spec.rb +109 -0
- data/spec/schedule_in_spec.rb +80 -0
- data/spec/schedule_interval_spec.rb +128 -0
- data/spec/scheduler_spec.rb +831 -124
- data/spec/spec_helper.rb +65 -0
- data/spec/threads_spec.rb +75 -0
- metadata +64 -59
- data/README.rdoc +0 -661
- data/lib/rufus/otime.rb +0 -3
- data/lib/rufus/sc/jobqueues.rb +0 -160
- data/lib/rufus/sc/jobs.rb +0 -471
- data/lib/rufus/sc/rtime.rb +0 -363
- data/lib/rufus/sc/scheduler.rb +0 -636
- data/spec/at_in_spec.rb +0 -47
- data/spec/at_spec.rb +0 -125
- data/spec/blocking_spec.rb +0 -64
- data/spec/cron_spec.rb +0 -134
- data/spec/every_spec.rb +0 -304
- data/spec/exception_spec.rb +0 -113
- data/spec/in_spec.rb +0 -150
- data/spec/mutex_spec.rb +0 -159
- data/spec/rtime_spec.rb +0 -137
- data/spec/schedulable_spec.rb +0 -97
- data/spec/spec_base.rb +0 -87
- data/spec/stress_schedule_unschedule_spec.rb +0 -159
- data/spec/timeout_spec.rb +0 -148
- data/test/kjw.rb +0 -113
- data/test/t.rb +0 -20
data/spec/exception_spec.rb
DELETED
@@ -1,113 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# Specifying rufus-scheduler
|
3
|
-
#
|
4
|
-
# Mon May 4 17:07:17 JST 2009
|
5
|
-
#
|
6
|
-
|
7
|
-
require 'spec_base'
|
8
|
-
|
9
|
-
|
10
|
-
describe SCHEDULER_CLASS do
|
11
|
-
|
12
|
-
before(:each) do
|
13
|
-
@s = start_scheduler
|
14
|
-
end
|
15
|
-
after(:each) do
|
16
|
-
stop_scheduler(@s)
|
17
|
-
end
|
18
|
-
|
19
|
-
it 'emits exception messages to stderr' do
|
20
|
-
|
21
|
-
require 'stringio' unless defined?(StringIO) # ruby 1.9
|
22
|
-
|
23
|
-
stderr = $stderr
|
24
|
-
s = StringIO.new
|
25
|
-
$stderr = s
|
26
|
-
|
27
|
-
@s.in 0.400 do
|
28
|
-
raise 'Houston we have a problem'
|
29
|
-
end
|
30
|
-
|
31
|
-
sleep 0.500
|
32
|
-
sleep 0.500
|
33
|
-
$stderr = stderr
|
34
|
-
s.close
|
35
|
-
|
36
|
-
s.string.should match(/Houston we have a problem/)
|
37
|
-
end
|
38
|
-
|
39
|
-
it 'accepts custom handling of exceptions' do
|
40
|
-
|
41
|
-
$job = nil
|
42
|
-
|
43
|
-
def @s.handle_exception(j, e)
|
44
|
-
$job = j
|
45
|
-
end
|
46
|
-
|
47
|
-
@s.in 0.400 do
|
48
|
-
raise 'Houston we have a problem'
|
49
|
-
end
|
50
|
-
|
51
|
-
sleep 0.500
|
52
|
-
sleep 0.500
|
53
|
-
|
54
|
-
$job.class.should == Rufus::Scheduler::InJob
|
55
|
-
end
|
56
|
-
|
57
|
-
it 'accepts defining #log_exception' do
|
58
|
-
|
59
|
-
$e = nil
|
60
|
-
|
61
|
-
def @s.log_exception(e)
|
62
|
-
$e = e
|
63
|
-
end
|
64
|
-
|
65
|
-
@s.in 0.400 do
|
66
|
-
raise 'Houston we have a problem'
|
67
|
-
end
|
68
|
-
|
69
|
-
sleep 0.500
|
70
|
-
sleep 0.500
|
71
|
-
|
72
|
-
$e.to_s.should == 'Houston we have a problem'
|
73
|
-
end
|
74
|
-
|
75
|
-
it 'accepts defining #on_exception' do
|
76
|
-
|
77
|
-
$j = nil
|
78
|
-
$e = nil
|
79
|
-
|
80
|
-
def @s.on_exception(j, e)
|
81
|
-
$j = j
|
82
|
-
$e = e
|
83
|
-
end
|
84
|
-
|
85
|
-
@s.in 0.400 do
|
86
|
-
raise 'Houston we have a problem'
|
87
|
-
end
|
88
|
-
|
89
|
-
sleep 0.500
|
90
|
-
sleep 0.500
|
91
|
-
|
92
|
-
$j.class.should == Rufus::Scheduler::InJob
|
93
|
-
$e.to_s.should == 'Houston we have a problem'
|
94
|
-
end
|
95
|
-
|
96
|
-
it 'allow custom exception rescue' do
|
97
|
-
@s.options[:exception]= StandardError
|
98
|
-
|
99
|
-
job = @s.in 0 do
|
100
|
-
exit
|
101
|
-
end
|
102
|
-
|
103
|
-
@e= nil
|
104
|
-
begin
|
105
|
-
wait_next_tick
|
106
|
-
rescue SystemExit => e
|
107
|
-
@e= e
|
108
|
-
end
|
109
|
-
|
110
|
-
@e.should_not == nil
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
data/spec/in_spec.rb
DELETED
@@ -1,150 +0,0 @@
|
|
1
|
-
|
2
|
-
#
|
3
|
-
# Specifying rufus-scheduler
|
4
|
-
#
|
5
|
-
# Sat Mar 21 17:36:36 JST 2009
|
6
|
-
#
|
7
|
-
|
8
|
-
require 'spec_base'
|
9
|
-
|
10
|
-
|
11
|
-
describe "#{SCHEDULER_CLASS}#in" do
|
12
|
-
|
13
|
-
before(:each) do
|
14
|
-
@s = start_scheduler
|
15
|
-
end
|
16
|
-
after(:each) do
|
17
|
-
stop_scheduler(@s)
|
18
|
-
end
|
19
|
-
|
20
|
-
it 'has job ids with the class name in it' do
|
21
|
-
|
22
|
-
j0 = @s.in(1) {}
|
23
|
-
j0.job_id.should match(/Rufus::Scheduler::InJob/)
|
24
|
-
end
|
25
|
-
|
26
|
-
it 'tracks scheduled in jobs' do
|
27
|
-
|
28
|
-
@s.in(1) {}
|
29
|
-
|
30
|
-
wait_next_tick
|
31
|
-
@s.jobs.size.should == 1
|
32
|
-
|
33
|
-
sleep 1.5
|
34
|
-
|
35
|
-
@s.jobs.size.should == 0
|
36
|
-
end
|
37
|
-
|
38
|
-
it 'schedules in 1' do
|
39
|
-
|
40
|
-
var = nil
|
41
|
-
|
42
|
-
@s.in 1 do
|
43
|
-
var = true
|
44
|
-
end
|
45
|
-
|
46
|
-
var.should == nil
|
47
|
-
sleep 1.5
|
48
|
-
|
49
|
-
var.should == true
|
50
|
-
end
|
51
|
-
|
52
|
-
it 'schedules in 1.0' do
|
53
|
-
|
54
|
-
var = nil
|
55
|
-
|
56
|
-
@s.in 1.0 do
|
57
|
-
var = true
|
58
|
-
end
|
59
|
-
|
60
|
-
var.should == nil
|
61
|
-
sleep 1.5
|
62
|
-
|
63
|
-
var.should == true
|
64
|
-
end
|
65
|
-
|
66
|
-
it 'schedules in 1s' do
|
67
|
-
|
68
|
-
var = nil
|
69
|
-
|
70
|
-
@s.in '1s' do
|
71
|
-
var = true
|
72
|
-
end
|
73
|
-
|
74
|
-
var.should == nil
|
75
|
-
sleep 1.5
|
76
|
-
|
77
|
-
var.should == true
|
78
|
-
end
|
79
|
-
|
80
|
-
it 'returns the new job' do
|
81
|
-
|
82
|
-
r = @s.in '1s' do
|
83
|
-
end
|
84
|
-
|
85
|
-
r.class.should == Rufus::Scheduler::InJob
|
86
|
-
end
|
87
|
-
|
88
|
-
it 'triggers [almost] immediately jobs in the past' do
|
89
|
-
|
90
|
-
var = nil
|
91
|
-
|
92
|
-
r = @s.in -2 do
|
93
|
-
var = true
|
94
|
-
end
|
95
|
-
|
96
|
-
#wait_next_tick
|
97
|
-
sleep 0.550
|
98
|
-
|
99
|
-
r.class.should == Rufus::Scheduler::InJob
|
100
|
-
var.should == true
|
101
|
-
@s.jobs.should == {}
|
102
|
-
end
|
103
|
-
|
104
|
-
it 'does not trigger jobs in the past when :discard_past => true' do
|
105
|
-
|
106
|
-
var = nil
|
107
|
-
|
108
|
-
r = @s.in -2, :discard_past => true do
|
109
|
-
var = true
|
110
|
-
end
|
111
|
-
|
112
|
-
r.should == nil
|
113
|
-
var.should == nil
|
114
|
-
@s.jobs.should == {}
|
115
|
-
end
|
116
|
-
|
117
|
-
it 'unschedules jobs' do
|
118
|
-
|
119
|
-
job = @s.in '2d' do
|
120
|
-
end
|
121
|
-
|
122
|
-
wait_next_tick
|
123
|
-
|
124
|
-
@s.jobs.size.should == 1
|
125
|
-
|
126
|
-
@s.unschedule(job.job_id)
|
127
|
-
|
128
|
-
@s.jobs.size.should == 0
|
129
|
-
end
|
130
|
-
|
131
|
-
it 'accepts tags for jobs' do
|
132
|
-
|
133
|
-
job = @s.in '2d', :tags => 'spec' do
|
134
|
-
end
|
135
|
-
|
136
|
-
wait_next_tick
|
137
|
-
|
138
|
-
@s.find_by_tag('spec').size.should == 1
|
139
|
-
@s.find_by_tag('spec').first.job_id.should == job.job_id
|
140
|
-
end
|
141
|
-
|
142
|
-
it 'raises on unknown options' do
|
143
|
-
|
144
|
-
lambda {
|
145
|
-
@s.in '2d', :first_at => (Time.now + 3600).to_s do
|
146
|
-
end
|
147
|
-
}.should raise_error(ArgumentError)
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
data/spec/mutex_spec.rb
DELETED
@@ -1,159 +0,0 @@
|
|
1
|
-
|
2
|
-
#
|
3
|
-
# Specifying rufus-scheduler
|
4
|
-
#
|
5
|
-
# Fri Oct 7 17:30:45 JST 2011
|
6
|
-
#
|
7
|
-
|
8
|
-
require 'spec_base'
|
9
|
-
|
10
|
-
|
11
|
-
describe SCHEDULER_CLASS do
|
12
|
-
|
13
|
-
before(:each) do
|
14
|
-
@s = start_scheduler
|
15
|
-
end
|
16
|
-
after(:each) do
|
17
|
-
stop_scheduler(@s)
|
18
|
-
end
|
19
|
-
|
20
|
-
MJOB = Proc.new do |x|
|
21
|
-
begin
|
22
|
-
$var << "in#{x}"
|
23
|
-
sleep 0.500
|
24
|
-
$var << "out#{x}"
|
25
|
-
rescue Exception => e
|
26
|
-
puts '=' * 80
|
27
|
-
p e
|
28
|
-
puts '=' * 80
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
context ':mutex => String' do
|
33
|
-
|
34
|
-
it 'prevents overlapping' do
|
35
|
-
|
36
|
-
$var = ''
|
37
|
-
|
38
|
-
@s.in('1s', :mutex => 'toto') { MJOB.call(0) }
|
39
|
-
@s.in('1s', :mutex => 'toto') { MJOB.call(1) }
|
40
|
-
|
41
|
-
sleep 3.0
|
42
|
-
|
43
|
-
%w[ in0out0in1out1 in1out1in0out0 ].should include($var)
|
44
|
-
end
|
45
|
-
|
46
|
-
it 'creates a new mutex when the name is first encountered' do
|
47
|
-
|
48
|
-
@s.instance_variable_get(:@mutexes).size.should == 0
|
49
|
-
|
50
|
-
@s.in('1s', :mutex => 'fruit') { sleep 0.1 }
|
51
|
-
|
52
|
-
sleep 1.5
|
53
|
-
|
54
|
-
@s.instance_variable_get(:@mutexes).size.should == 1
|
55
|
-
end
|
56
|
-
|
57
|
-
it 'creates a unique mutex for a given name' do
|
58
|
-
|
59
|
-
@s.in('1s', :mutex => 'gum') { sleep 0.1 }
|
60
|
-
@s.in('1s', :mutex => 'gum') { sleep 0.1 }
|
61
|
-
|
62
|
-
sleep 1.5
|
63
|
-
|
64
|
-
@s.instance_variable_get(:@mutexes).size.should == 1
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
context ':mutex => Mutex' do
|
69
|
-
|
70
|
-
it 'prevents overlapping' do
|
71
|
-
|
72
|
-
$var = ''
|
73
|
-
m = Mutex.new
|
74
|
-
|
75
|
-
@s.in('1s', :mutex => m) { MJOB.call(0) }
|
76
|
-
@s.in('1s', :mutex => m) { MJOB.call(1) }
|
77
|
-
|
78
|
-
sleep 3.0
|
79
|
-
|
80
|
-
%w[ in0out0in1out1 in1out1in0out0 ].should include($var)
|
81
|
-
end
|
82
|
-
|
83
|
-
it 'does not register the mutex' do
|
84
|
-
|
85
|
-
@s.in('1s', :mutex => Mutex.new) { sleep 0.1 }
|
86
|
-
|
87
|
-
sleep 1.5
|
88
|
-
|
89
|
-
@s.instance_variable_get(:@mutexes).size.should == 0
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
context ':mutexes => Array of String' do
|
94
|
-
|
95
|
-
it 'ensure exclusivity' do
|
96
|
-
|
97
|
-
$var = ''
|
98
|
-
m0 = 'm0'
|
99
|
-
m1 = 'm1'
|
100
|
-
|
101
|
-
@s.in('1s', :mutex => m0) { MJOB.call(0) }
|
102
|
-
@s.in('1s', :mutex => m1) { MJOB.call(1) }
|
103
|
-
@s.in('1s', :mutex => [m0, m1]) { MJOB.call(2) }
|
104
|
-
|
105
|
-
sleep 4.5
|
106
|
-
|
107
|
-
$var.should include('in2out2')
|
108
|
-
end
|
109
|
-
|
110
|
-
it 'creates new mutexes when the names are first encountered' do
|
111
|
-
|
112
|
-
@s.instance_variable_get(:@mutexes).size.should == 0
|
113
|
-
|
114
|
-
@s.in('1s', :mutex => ['fruit', 'bread']) { sleep 0.1 }
|
115
|
-
|
116
|
-
sleep 1.5
|
117
|
-
|
118
|
-
@s.instance_variable_get(:@mutexes).size.should == 2
|
119
|
-
end
|
120
|
-
|
121
|
-
it 'creates a unique mutex for a given name' do
|
122
|
-
|
123
|
-
@s.in('1s', :mutex => ['fruit', 'bread']) { sleep 0.1 }
|
124
|
-
@s.in('1s', :mutex => ['fruit', 'bread']) { sleep 0.1 }
|
125
|
-
|
126
|
-
sleep 1.5
|
127
|
-
|
128
|
-
@s.instance_variable_get(:@mutexes).size.should == 2
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
|
-
context ':mutexes => Array of Mutex' do
|
133
|
-
|
134
|
-
it 'ensure exclusivity' do
|
135
|
-
|
136
|
-
$var = ''
|
137
|
-
m0 = Mutex.new
|
138
|
-
m1 = Mutex.new
|
139
|
-
|
140
|
-
@s.in('1s', :mutex => m0) { MJOB.call(0) }
|
141
|
-
@s.in('1s', :mutex => m1) { MJOB.call(1) }
|
142
|
-
@s.in('1s', :mutex => [m0, m1]) { MJOB.call(2) }
|
143
|
-
|
144
|
-
sleep 4.5
|
145
|
-
|
146
|
-
$var.should include('in2out2')
|
147
|
-
end
|
148
|
-
|
149
|
-
it 'does not register the mutexes' do
|
150
|
-
|
151
|
-
@s.in('1s', :mutex => [Mutex.new, Mutex.new]) { sleep 0.1 }
|
152
|
-
|
153
|
-
sleep 1.5
|
154
|
-
|
155
|
-
@s.instance_variable_get(:@mutexes).size.should == 0
|
156
|
-
end
|
157
|
-
end
|
158
|
-
end
|
159
|
-
|
data/spec/rtime_spec.rb
DELETED
@@ -1,137 +0,0 @@
|
|
1
|
-
|
2
|
-
#
|
3
|
-
# Specifying rufus-scheduler
|
4
|
-
#
|
5
|
-
# Fri Mar 20 23:46:32 JST 2009
|
6
|
-
#
|
7
|
-
|
8
|
-
require 'spec_base'
|
9
|
-
|
10
|
-
|
11
|
-
describe 'rufus/rtime' do
|
12
|
-
|
13
|
-
def pts(s)
|
14
|
-
Rufus.parse_time_string(s)
|
15
|
-
end
|
16
|
-
|
17
|
-
def tts(f, opts={})
|
18
|
-
Rufus.to_time_string(f, opts)
|
19
|
-
end
|
20
|
-
|
21
|
-
def tdh(f, opts={})
|
22
|
-
Rufus.to_duration_hash(f, opts)
|
23
|
-
end
|
24
|
-
|
25
|
-
it 'parses duration strings' do
|
26
|
-
|
27
|
-
pts('-1.0d1.0w1.0d').should == -777600.0
|
28
|
-
pts('-1d1w1d').should == -777600.0
|
29
|
-
pts('-1w2d').should == -777600.0
|
30
|
-
pts('-1h10s').should == -3610.0
|
31
|
-
pts('-1h').should == -3600.0
|
32
|
-
pts('-5.').should == -5.0
|
33
|
-
pts('-2.5s').should == -2.5
|
34
|
-
pts('-1s').should == -1.0
|
35
|
-
pts('-500').should == -0.5
|
36
|
-
pts('').should == 0.0
|
37
|
-
pts('5.0').should == 5.0
|
38
|
-
pts('0.5').should == 0.5
|
39
|
-
pts('.5').should == 0.5
|
40
|
-
pts('5.').should == 5.0
|
41
|
-
pts('500').should == 0.5
|
42
|
-
pts('1000').should == 1.0
|
43
|
-
pts('1').should == 0.001
|
44
|
-
pts('1s').should == 1.0
|
45
|
-
pts('2.5s').should == 2.5
|
46
|
-
pts('1h').should == 3600.0
|
47
|
-
pts('1h10s').should == 3610.0
|
48
|
-
pts('1w2d').should == 777600.0
|
49
|
-
pts('1d1w1d').should == 777600.0
|
50
|
-
pts('1.0d1.0w1.0d').should == 777600.0
|
51
|
-
|
52
|
-
pts('.5m').should == 30.0
|
53
|
-
pts('5.m').should == 300.0
|
54
|
-
pts('1m.5s').should == 60.5
|
55
|
-
pts('-.5m').should == -30.0
|
56
|
-
|
57
|
-
pts('1d').should == 86400.0
|
58
|
-
pts('0.1d').should == 8640.0
|
59
|
-
pts('0.1s').should == 0.1
|
60
|
-
|
61
|
-
pts('0.1').should == 0.1
|
62
|
-
pts('1').should == 0.001
|
63
|
-
#
|
64
|
-
# the two evil twins :-(
|
65
|
-
end
|
66
|
-
|
67
|
-
it 'parses duration "strings"' do
|
68
|
-
|
69
|
-
o = Object.new
|
70
|
-
def o.to_s; '-2'; end
|
71
|
-
|
72
|
-
pts(o).should == -0.002
|
73
|
-
end
|
74
|
-
|
75
|
-
it 'raises on wrong duration strings' do
|
76
|
-
|
77
|
-
lambda { pts('-') }.should raise_error(ArgumentError)
|
78
|
-
lambda { pts('h') }.should raise_error(ArgumentError)
|
79
|
-
lambda { pts('whatever') }.should raise_error(ArgumentError)
|
80
|
-
lambda { pts('hms') }.should raise_error(ArgumentError)
|
81
|
-
|
82
|
-
lambda { pts(' 1h ') }.should raise_error(ArgumentError)
|
83
|
-
end
|
84
|
-
|
85
|
-
it 'generates duration strings' do
|
86
|
-
|
87
|
-
tts(0).should == '0s'
|
88
|
-
tts(0, :drop_seconds => true).should == '0m'
|
89
|
-
tts(60).should == '1m'
|
90
|
-
tts(61).should == '1m1s'
|
91
|
-
tts(3661).should == '1h1m1s'
|
92
|
-
tts(24 * 3600).should == '1d'
|
93
|
-
tts(7 * 24 * 3600 + 1).should == '1w1s'
|
94
|
-
tts(30 * 24 * 3600 + 1).should == '4w2d1s'
|
95
|
-
tts(30 * 24 * 3600 + 1, :months => true).should == '1M1s'
|
96
|
-
end
|
97
|
-
|
98
|
-
it 'computes duration hashes' do
|
99
|
-
|
100
|
-
tdh(0).should == {}
|
101
|
-
tdh(0.128).should == { :ms => 128 }
|
102
|
-
tdh(60.127).should == { :m => 1, :ms => 127 }
|
103
|
-
tdh(61.127).should == { :m => 1, :s => 1, :ms => 127 }
|
104
|
-
tdh(61.127, :drop_seconds => true).should == { :m => 1 }
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
describe 'Rufus.at_to_f' do
|
109
|
-
|
110
|
-
def atf(o)
|
111
|
-
Rufus.at_to_f(o)
|
112
|
-
end
|
113
|
-
|
114
|
-
it 'turns Time at values to float' do
|
115
|
-
|
116
|
-
t = Time.now
|
117
|
-
tf = t.to_f.to_i.to_f
|
118
|
-
|
119
|
-
atf(t + 2).to_i.to_f.should == tf + 2
|
120
|
-
end
|
121
|
-
|
122
|
-
it 'turns String at values to float' do
|
123
|
-
|
124
|
-
atf('Sat Mar 21 20:08:01 +0900 2009').should == 1237633681.0
|
125
|
-
atf('Sat Mar 21 20:08:01 -0900 2009').should == 1237698481.0
|
126
|
-
atf('Sat Mar 21 20:08:01 +0000 2009').should == 1237666081.0
|
127
|
-
atf('Sat Mar 21 20:08:01 2009').should == 1237666081.0
|
128
|
-
atf('Mar 21 20:08:01 2009').should == 1237666081.0
|
129
|
-
atf('2009/03/21 20:08').should == 1237666080.0
|
130
|
-
end
|
131
|
-
|
132
|
-
it 'accepts integers' do
|
133
|
-
|
134
|
-
atf(1).should == 1.0
|
135
|
-
end
|
136
|
-
end
|
137
|
-
|