acts_as_flux_capacitor 0.5.4 → 0.6.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/History.txt +11 -0
- data/Manifest.txt +1 -0
- data/lib/acts_as_flux_capacitor/acts_as_flux_capacitor.rb +24 -33
- data/lib/acts_as_flux_capacitor/core_class_extensions.rb +11 -9
- data/lib/acts_as_flux_capacitor/range_overlap.rb +1 -14
- data/lib/acts_as_flux_capacitor/temporal.rb +36 -31
- data/lib/acts_as_flux_capacitor/version.rb +2 -2
- data/spec/acts_as_flux_capacitor_spec.rb +116 -2
- data/spec/report.html +45 -33
- data/spec/spec_helper.rb +1 -0
- data/spec/time_helper.rb +54 -0
- metadata +3 -2
data/History.txt
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
== 0.6.0 2008-05-23
|
2
|
+
|
3
|
+
* WAAAY more hardcore spec'ng
|
4
|
+
* removed debugging printing to STDOUT
|
5
|
+
* removed unnessary helper methods
|
6
|
+
|
7
|
+
== 0.5.4 2008-05-22
|
8
|
+
|
9
|
+
* Added Range specs
|
10
|
+
* Refactored Range#overlaps? (thanks to Nick Ang)
|
11
|
+
|
1
12
|
== 0.5.3 2008-05-21
|
2
13
|
|
3
14
|
* Fixed git stuff
|
data/Manifest.txt
CHANGED
@@ -58,16 +58,13 @@ module HolmesLabs #:nodoc:
|
|
58
58
|
def find(*args)
|
59
59
|
options = args.extract_options!
|
60
60
|
|
61
|
-
current_time = options.delete(:current_time)
|
61
|
+
current_time = options.delete(:current_time) || Time.now
|
62
62
|
temporal_conditions = extract_temporal_conditions!(options)
|
63
63
|
sql_temporal = sql_generate_temporal(temporal_conditions,current_time)
|
64
64
|
|
65
|
-
puts temporal_conditions.size
|
66
|
-
puts sql_temporal
|
67
|
-
|
68
65
|
with_scope( :find => {
|
69
|
-
|
70
|
-
|
66
|
+
:conditions => sql_temporal ,
|
67
|
+
:order => sql_oldest_first }) do
|
71
68
|
original_find(*(args << options))
|
72
69
|
end
|
73
70
|
end
|
@@ -87,9 +84,6 @@ private
|
|
87
84
|
temporal_conditions.merge!({key, options.delete(key)}) if CUSTOM_FIND_OPTIONS.include?(key)
|
88
85
|
end
|
89
86
|
|
90
|
-
|
91
|
-
require 'pp'# ; pp "(#{temporal_conditions.class}) #{temporal_conditions.first.keys}: #{temporal_conditions.first.values}"
|
92
|
-
pp temporal_conditions
|
93
87
|
temporal_conditions
|
94
88
|
end
|
95
89
|
end
|
@@ -97,59 +91,59 @@ private
|
|
97
91
|
module QueryGenerators
|
98
92
|
private
|
99
93
|
|
100
|
-
def sql_before(some_time, current_time
|
94
|
+
def sql_before(some_time, current_time)
|
101
95
|
# table_name comes from ActiveRecord.
|
102
96
|
"#{table_name}.ends_at < '#{some_time.to_s(:db)}'"
|
103
97
|
end
|
104
98
|
alias sql_to sql_before
|
105
99
|
alias sql_ends_before sql_before
|
106
100
|
|
107
|
-
def sql_after(some_time , current_time
|
101
|
+
def sql_after(some_time , current_time)
|
108
102
|
# table_name comes from ActiveRecord.
|
109
103
|
"#{table_name}.begins_at > '#{some_time.to_s(:db)}'"
|
110
104
|
end
|
111
105
|
alias sql_from sql_after
|
112
106
|
alias sql_begins_after sql_after
|
113
107
|
|
114
|
-
def sql_at(some_time , current_time
|
115
|
-
sql_join_conditions([ sql_starts_before( some_time),
|
116
|
-
sql_ends_after( some_time)])
|
108
|
+
def sql_at(some_time , current_time)
|
109
|
+
sql_join_conditions([ sql_starts_before( some_time , current_time),
|
110
|
+
sql_ends_after( some_time , current_time)])
|
117
111
|
end
|
118
112
|
|
119
|
-
def sql_ends_after(some_time
|
113
|
+
def sql_ends_after(some_time, current_time)
|
120
114
|
"#{table_name}.ends_at > '#{some_time.to_s(:db)}'"
|
121
115
|
end
|
122
116
|
|
123
|
-
def sql_starts_before(some_time , current_time
|
117
|
+
def sql_starts_before(some_time , current_time)
|
124
118
|
"#{table_name}.begins_at < '#{some_time.to_s(:db)}'"
|
125
119
|
end
|
126
120
|
|
127
|
-
def sql_past(is_true , current_time
|
121
|
+
def sql_past(is_true , current_time)
|
128
122
|
if is_true
|
129
|
-
sql_before(current_time)
|
123
|
+
sql_before(current_time, current_time)
|
130
124
|
else
|
131
|
-
sql_join_conditions_or([ sql_present(
|
132
|
-
sql_future(
|
125
|
+
sql_join_conditions_or([ sql_present( current_time),
|
126
|
+
sql_future( current_time)])
|
133
127
|
end
|
134
128
|
end
|
135
129
|
alias sql_ended sql_past
|
136
130
|
|
137
|
-
def sql_present(is_true , current_time
|
131
|
+
def sql_present(is_true , current_time)
|
138
132
|
if is_true
|
139
|
-
sql_at(current_time)
|
133
|
+
sql_at(current_time,current_time)
|
140
134
|
else
|
141
|
-
sql_join_conditions_or([ sql_past(
|
142
|
-
sql_future(
|
135
|
+
sql_join_conditions_or([ sql_past( current_time),
|
136
|
+
sql_future( current_time)])
|
143
137
|
end
|
144
138
|
end
|
145
139
|
alias sql_now sql_present
|
146
140
|
|
147
|
-
def sql_future(is_true, current_time
|
141
|
+
def sql_future(is_true, current_time)
|
148
142
|
if is_true
|
149
|
-
sql_after(current_time)
|
143
|
+
sql_after(current_time,current_time)
|
150
144
|
else
|
151
|
-
sql_join_conditions_or([ sql_present(
|
152
|
-
sql_past(
|
145
|
+
sql_join_conditions_or([ sql_present(current_time),
|
146
|
+
sql_past( current_time)])
|
153
147
|
end
|
154
148
|
end
|
155
149
|
|
@@ -165,15 +159,12 @@ private
|
|
165
159
|
"#{conditions.join(") OR (")}"
|
166
160
|
end
|
167
161
|
|
168
|
-
def sql_generate_temporal
|
162
|
+
def sql_generate_temporal temporal_conditions , current_time
|
169
163
|
sql_conditions = []
|
170
164
|
temporal_conditions.each do |condition,parameter|
|
171
|
-
|
172
|
-
sql_conditions << send("sql_#{condition}" , parameter , current_time)
|
165
|
+
sql_conditions << send("sql_#{condition}".to_sym , parameter, current_time)
|
173
166
|
end
|
174
167
|
|
175
|
-
require 'pp' ; pp sql_conditions
|
176
|
-
pp sql_join_conditions(sql_conditions)
|
177
168
|
sql_join_conditions(sql_conditions)
|
178
169
|
end
|
179
170
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
class Time
|
2
2
|
|
3
|
-
@@approx_eql_tolerance_in_seconds = 2
|
3
|
+
@@approx_eql_tolerance_in_seconds = 2
|
4
4
|
|
5
5
|
def Time.approx_eql_tolerance_in_seconds
|
6
6
|
@@approx_eql_tolerance_in_seconds
|
@@ -17,17 +17,19 @@ class Time
|
|
17
17
|
end
|
18
18
|
|
19
19
|
class Array
|
20
|
-
def within?
|
21
|
-
|
22
|
-
#
|
23
|
-
|
24
|
-
|
20
|
+
def within? tolerance
|
21
|
+
|
22
|
+
# thanks, nick ang!
|
23
|
+
unless self.size == 2
|
24
|
+
raise ArgumentError <<ERROR_STRING
|
25
|
+
within? only works with arrays of two numbers. do something like
|
26
|
+
([a,b,c].max,[a,b,c].min).within?(tolerance) as an implementation
|
27
|
+
for an array with more than two values
|
28
|
+
ERROR_STRING
|
29
|
+
end
|
25
30
|
|
26
31
|
difference = self.first - self.last
|
27
32
|
difference.abs <= tolerance
|
28
33
|
end
|
29
34
|
end
|
30
35
|
|
31
|
-
class Range
|
32
|
-
# to_event?
|
33
|
-
end
|
@@ -14,12 +14,7 @@ class Range
|
|
14
14
|
|
15
15
|
def overlap(other_range)
|
16
16
|
return 0 unless self.overlaps?(other_range)
|
17
|
-
|
18
|
-
overlap_range = greater_of(self.first,other_range.first)..smaller_of(self.last,other_range.last)
|
19
|
-
# puts "overlap range: #{overlap_range}"
|
20
|
-
# puts "greater of firsts: #{greater_of(self.first,other_range.first)}"
|
21
|
-
# puts "smaller of lasts: #{smaller_of(self.last,other_range.last)}"
|
22
|
-
return overlap_range
|
17
|
+
([self.first,other_range.first].max)..([self.last,other_range.last].min)
|
23
18
|
end
|
24
19
|
|
25
20
|
def size
|
@@ -43,13 +38,5 @@ private
|
|
43
38
|
|
44
39
|
def number_size # technically, off by infinity^(-1) when either or both endpoints are excluded. meh.
|
45
40
|
return self.last-self.first+1
|
46
|
-
end
|
47
|
-
|
48
|
-
def greater_of(num1,num2)
|
49
|
-
num1 > num2 ? num1 : num2
|
50
|
-
end
|
51
|
-
|
52
|
-
def smaller_of(num1,num2)
|
53
|
-
num1 < num2 ? num1 : num2
|
54
41
|
end
|
55
42
|
end
|
@@ -1,10 +1,5 @@
|
|
1
|
-
# require 'activesupport'
|
2
|
-
|
3
1
|
module Temporal
|
4
2
|
|
5
|
-
include ActiveSupport::CoreExtensions::Numeric::Time
|
6
|
-
include ActiveSupport::CoreExtensions::Time
|
7
|
-
|
8
3
|
def self.included(base) # :nodoc:
|
9
4
|
base.extend ClassMethods
|
10
5
|
base.extend ClassAndInstanceMethods
|
@@ -12,7 +7,6 @@ module Temporal
|
|
12
7
|
|
13
8
|
module ClassMethods
|
14
9
|
def range_between(obj,another_obj)
|
15
|
-
verify_temporal obj, another_obj
|
16
10
|
first_obj,second_obj = ordered_tuple(obj,another_obj)
|
17
11
|
beginning = extract_time(first_obj,:ends_at)
|
18
12
|
ending = extract_time(second_obj,:begins_at)
|
@@ -23,36 +17,50 @@ module Temporal
|
|
23
17
|
first_obj,second_obj = ordered_tuple(obj,another_obj)
|
24
18
|
beginning = extract_time(first_obj,:ends_at)
|
25
19
|
ending = extract_time(second_obj,:begins_at)
|
26
|
-
beginning.
|
20
|
+
beginning.before_or_at?(ending) ? ending - beginning : nil
|
27
21
|
end
|
28
22
|
|
29
|
-
def length_of_time_until(obj,
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
23
|
+
def length_of_time_until(obj,reference_obj=Time.now)
|
24
|
+
begins_at = extract_time(obj,:begins_at)
|
25
|
+
ends_at = extract_time(obj,:ends_at)
|
26
|
+
reference_point = extract_time(reference_obj,:ends_at)
|
27
|
+
|
28
|
+
time_until_begins = begins_at - reference_point
|
29
|
+
# has not started
|
30
|
+
if time_until_begins >= 0
|
31
|
+
time_until_begins
|
32
|
+
# has started, but not ended
|
33
|
+
elsif time_until_begins < 0 && reference_point.before?(ends_at)
|
34
|
+
0
|
35
|
+
# has ended
|
36
|
+
else
|
37
|
+
nil
|
38
|
+
end
|
34
39
|
end
|
35
40
|
|
36
|
-
def length_of_time_since(obj,
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
+
def length_of_time_since(obj,reference_obj=Time.now)
|
42
|
+
begins_at = extract_time(obj,:begins_at)
|
43
|
+
ends_at = extract_time(obj,:ends_at)
|
44
|
+
|
45
|
+
reference_point = extract_time(reference_obj,:begins_at)
|
46
|
+
|
47
|
+
time_since_ended = reference_point - ends_at
|
48
|
+
has_started_but_not_ended = time_since_ended <= 0 && reference_point.after?(begins_at)
|
49
|
+
has_ended = time_since_ended >= 0
|
50
|
+
if has_ended
|
51
|
+
time_since_ended
|
52
|
+
elsif has_started_but_not_ended
|
53
|
+
0
|
54
|
+
else # has not started
|
55
|
+
nil
|
56
|
+
end
|
41
57
|
end
|
42
58
|
end
|
43
59
|
|
44
60
|
module ClassAndInstanceMethods
|
45
|
-
|
46
|
-
args.each do |obj|
|
47
|
-
unless obj.class.included_modules.include?(Temporal)
|
48
|
-
raise "This method requires objects it interacts with to have the Temporal module; instead received #{obj.class}."
|
49
|
-
end
|
50
|
-
end
|
51
|
-
return nil
|
52
|
-
end
|
61
|
+
|
53
62
|
private
|
54
63
|
def ordered_tuple(an_obj,other_obj)
|
55
|
-
verify_temporal an_obj , other_obj
|
56
64
|
if an_obj.before?(other_obj)
|
57
65
|
return an_obj,other_obj
|
58
66
|
else
|
@@ -64,7 +72,6 @@ module Temporal
|
|
64
72
|
# if object possesses accessor method, return obj.accessor.
|
65
73
|
# if not, return object. This is useful for fudging duck typing-
|
66
74
|
# style interaction between Events and Times/Dates, etc.
|
67
|
-
verify_temporal(obj)
|
68
75
|
obj.respond_to?(accessor.to_sym) ? obj.send(accessor.to_sym) : obj
|
69
76
|
end
|
70
77
|
end
|
@@ -76,7 +83,6 @@ module Temporal
|
|
76
83
|
end
|
77
84
|
|
78
85
|
def before?(obj)
|
79
|
-
verify_temporal(obj)
|
80
86
|
extract_time(self,:ends_at) < extract_time(obj,:begins_at)
|
81
87
|
end
|
82
88
|
|
@@ -85,7 +91,6 @@ module Temporal
|
|
85
91
|
end
|
86
92
|
|
87
93
|
def after?(obj)
|
88
|
-
verify_temporal(obj)
|
89
94
|
extract_time(self,:begins_at) > extract_time(obj,:ends_at)
|
90
95
|
end
|
91
96
|
|
@@ -103,12 +108,12 @@ module Temporal
|
|
103
108
|
end
|
104
109
|
|
105
110
|
def in_the_future?(time = Time.now)
|
106
|
-
extract_time(self,:
|
111
|
+
extract_time(self,:begins_at).after?(time)
|
107
112
|
end
|
108
113
|
alias future? in_the_future?
|
109
114
|
|
110
115
|
def in_the_past?(time=Time.now)
|
111
|
-
extract_time(self,:
|
116
|
+
extract_time(self,:ends_at).before?(time)
|
112
117
|
end
|
113
118
|
alias past? in_the_past?
|
114
119
|
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/spec_helper.rb'
|
2
2
|
|
3
|
+
# ...and no, it won't work to put everything in a giant Time.freeze block.
|
4
|
+
|
3
5
|
describe "The Temporal mixin" do
|
4
6
|
|
5
7
|
before(:all) do
|
@@ -15,34 +17,66 @@ describe "The Temporal mixin" do
|
|
15
17
|
|
16
18
|
it "should determine the length of time between two Temporal objects" do
|
17
19
|
Time.period_between(@present_time,@twenty_mins_later).should == 20.minutes
|
20
|
+
Time.period_between(@twenty_mins_later,@present_time).should == 20.minutes
|
21
|
+
|
22
|
+
Time.period_between(@twenty_mins_later,@twenty_mins_later).should == 0.minutes
|
18
23
|
end
|
19
24
|
|
20
25
|
it "should determine the length of time until a Temporal object" do
|
21
26
|
Time.length_of_time_until(@twenty_mins_later,@present_time).should == 20.minutes
|
27
|
+
Time.length_of_time_until(@present_time,@twenty_mins_later).should be_nil
|
28
|
+
Time.length_of_time_until(@present_time,@present_time).should == 0.minutes
|
29
|
+
|
30
|
+
Time.freeze do
|
31
|
+
Time.length_of_time_until(20.minutes.from_now).should == 20.minutes
|
32
|
+
Time.length_of_time_until(20.minutes.ago).should be_nil
|
33
|
+
Time.length_of_time_until(Time.now).should == 0.minutes
|
34
|
+
end
|
22
35
|
end
|
23
36
|
|
24
37
|
it "should determine if a temporal object is in the future" do
|
25
38
|
@twenty_mins_later.in_the_future?(@present_time).should be_true
|
26
39
|
@present_time.in_the_future?(@twenty_mins_later).should be_false
|
40
|
+
@present_time.in_the_future?(@present_time).should be_false
|
41
|
+
|
42
|
+
Time.freeze do
|
43
|
+
20.minutes.from_now.in_the_future?.should be_true
|
44
|
+
20.minutes.ago.in_the_future?.should be_false
|
45
|
+
Time.now.in_the_future?.should be_false
|
46
|
+
end
|
27
47
|
end
|
28
48
|
|
29
49
|
it "should determine the length of time since a Temporal object" do
|
30
50
|
Time.length_of_time_since(@present_time,@twenty_mins_later).should == 20.minutes
|
51
|
+
|
52
|
+
Time.freeze do
|
53
|
+
Time.length_of_time_since(20.minutes.ago).should == 20.minutes
|
54
|
+
Time.length_of_time_since(20.minutes.from_now).should be_nil
|
55
|
+
Time.length_of_time_since(Time.now).should == 0.minutes
|
56
|
+
end
|
31
57
|
end
|
32
58
|
|
33
59
|
it "should determine if a temporal object is in the past" do
|
34
60
|
@present_time.in_the_past?(@twenty_mins_later).should be_true
|
35
61
|
@twenty_mins_later.in_the_past?(@present_time).should be_false
|
62
|
+
|
63
|
+
Time.freeze do
|
64
|
+
10.minutes.ago.in_the_past?.should be_true
|
65
|
+
10.minutes.from_now.in_the_past?.should be_false
|
66
|
+
Time.now.in_the_future?.should be_false
|
67
|
+
end
|
36
68
|
end
|
37
69
|
|
38
70
|
it "should determine if one Temporal object is before another" do
|
39
71
|
@present_time.before?(@twenty_mins_later).should be_true
|
40
72
|
@twenty_mins_later.before?(@present_time).should be_false
|
73
|
+
@twenty_mins_later.before?(@twenty_mins_later).should be_false
|
41
74
|
end
|
42
75
|
|
43
76
|
it "should determine if one Temporal object is after another" do
|
44
|
-
@twenty_mins_later.
|
45
|
-
@present_time.
|
77
|
+
@twenty_mins_later.after?(@present_time).should be_true
|
78
|
+
@present_time.after?(@twenty_mins_later).should be_false
|
79
|
+
@present_time.after?(@present_time).should be_false
|
46
80
|
end
|
47
81
|
|
48
82
|
end
|
@@ -81,25 +115,57 @@ describe "The TimePeriod.find extensions" do
|
|
81
115
|
it "should find time_periods in the present" do
|
82
116
|
TimePeriod.find(:first,:present=>true ,:current_time => present_time).
|
83
117
|
happening_now?(present_time).should be_true
|
118
|
+
|
119
|
+
Time.freeze(present_time) do
|
120
|
+
TimePeriod.find(:first,:present=>true).happening_now?.should be_true
|
121
|
+
|
122
|
+
time_periods = TimePeriod.find(:all,:present=>true)
|
123
|
+
time_periods.size.should eql(2)
|
124
|
+
time_periods.each { |period| period.happening_now?.should be_true }
|
125
|
+
end
|
84
126
|
end
|
85
127
|
|
86
128
|
it "should find time_periods in the past" do
|
87
129
|
TimePeriod.find(:first,:past=>true ,:current_time => present_time).
|
88
130
|
in_the_past?(present_time).should be_true
|
131
|
+
|
132
|
+
Time.freeze(present_time) do
|
133
|
+
TimePeriod.find(:first,:past=>true).in_the_past?.should be_true
|
134
|
+
|
135
|
+
time_periods = TimePeriod.find(:all,:past=>true)
|
136
|
+
time_periods.size.should eql(1)
|
137
|
+
time_periods.each { |period| period.past?.should be_true }
|
138
|
+
end
|
89
139
|
end
|
90
140
|
|
91
141
|
it "should find time_periods in the future" do
|
92
142
|
TimePeriod.find(:first,:future=>true ,:current_time => present_time).
|
93
143
|
in_the_future?(present_time).should be_true
|
144
|
+
|
145
|
+
Time.freeze(present_time) do
|
146
|
+
TimePeriod.find(:first,:future=>true).in_the_future?.should be_true
|
147
|
+
|
148
|
+
time_periods = TimePeriod.find(:all,:future=>true)
|
149
|
+
time_periods.size.should eql(1)
|
150
|
+
time_periods.each { |period| period.future?.should be_true }
|
151
|
+
end
|
94
152
|
end
|
95
153
|
|
96
154
|
it "should find time_periods occuring at a specific time" do
|
97
155
|
TimePeriod.find(:first,:at=>future_time).at?(future_time).should be_true
|
156
|
+
|
157
|
+
time_periods = TimePeriod.find(:all,:at=>future_time)
|
158
|
+
time_periods.size.should eql(1)
|
159
|
+
time_periods.first.at?(future_time).should be_true
|
98
160
|
end
|
99
161
|
|
100
162
|
it "should find time_periods occuring within a specific range of time" do
|
101
163
|
TimePeriod.find(:first,:from => more_past_time , :to => more_future_time).
|
102
164
|
at?(present_time).should be_true
|
165
|
+
|
166
|
+
time_periods = TimePeriod.find(:all,:from => more_past_time , :to => more_future_time)
|
167
|
+
time_periods.size.should eql(1)
|
168
|
+
time_periods.first.at?(present_time).should be_true
|
103
169
|
end
|
104
170
|
|
105
171
|
end
|
@@ -107,6 +173,18 @@ end
|
|
107
173
|
describe "The TimePeriod comparison helpers" do
|
108
174
|
|
109
175
|
include TimePeriodFixtures
|
176
|
+
|
177
|
+
it "should determine if one time period is before another" do
|
178
|
+
present_period.before_or_at?(future_period).should be_true
|
179
|
+
future_period.before?(past_period).should be_false
|
180
|
+
present_period.before?(present_period).should be_false
|
181
|
+
end
|
182
|
+
|
183
|
+
it "should determine if one time period is after another" do
|
184
|
+
future_period.after?(present_time).should be_true
|
185
|
+
present_time.after?(future_period).should be_false
|
186
|
+
past_period.after?(past_period).should be_false
|
187
|
+
end
|
110
188
|
|
111
189
|
it "should calculate the time between time_periods" do
|
112
190
|
TimePeriod.period_between(past_period,future_period).should == 140.minutes
|
@@ -133,6 +211,42 @@ end
|
|
133
211
|
|
134
212
|
describe "The TimePeriod status helpers" do
|
135
213
|
|
214
|
+
before(:all) do
|
215
|
+
@present_time = Time.parse "Sun May 18 16:41:58 2008"
|
216
|
+
end
|
217
|
+
|
218
|
+
it "should determine the length of time until a time_period" do
|
219
|
+
Time.freeze(@present_time) do
|
220
|
+
Time.length_of_time_until(future_period).should == 20.minutes
|
221
|
+
Time.length_of_time_until(present_period).should == 0.minutes
|
222
|
+
Time.length_of_time_until(past_period).should be_nil
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
it "should determine if a time_period is in the future" do
|
227
|
+
Time.freeze(@present_time) do
|
228
|
+
future_period.in_the_future?.should be_true
|
229
|
+
past_period.in_the_future?.should be_false
|
230
|
+
present_period.future?.should be_false
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
it "should determine the length of time since a time_period ended" do
|
235
|
+
Time.freeze(@present_time) do
|
236
|
+
Time.length_of_time_since(past_period).should == 2.hours
|
237
|
+
Time.length_of_time_since(future_period).should be_nil
|
238
|
+
Time.length_of_time_since(present_period).should == 0.minutes
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
it "should determine if a time_period is in the past" do
|
243
|
+
Time.freeze(@present_time) do
|
244
|
+
past_period.past?.should be_true
|
245
|
+
present_period.past?.should be_false
|
246
|
+
future_period.past?.should be_false
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
136
250
|
it "should determine if a time_period has started" do
|
137
251
|
past_period.started?(present_time).should be_true
|
138
252
|
present_period.started?(present_time).should be_true
|
data/spec/report.html
CHANGED
@@ -179,104 +179,116 @@ a {
|
|
179
179
|
<div class="example_group">
|
180
180
|
<dl>
|
181
181
|
<dt id="example_group_1">The Temporal mixin</dt>
|
182
|
-
<script type="text/javascript">moveProgressBar('
|
182
|
+
<script type="text/javascript">moveProgressBar('2.6');</script>
|
183
183
|
<dd class="spec passed"><span class="passed_spec_name">should make Time, Date and DateTime into Temporal objects</span></dd>
|
184
|
-
<script type="text/javascript">moveProgressBar('
|
184
|
+
<script type="text/javascript">moveProgressBar('5.2');</script>
|
185
185
|
<dd class="spec passed"><span class="passed_spec_name">should determine the length of time between two Temporal objects</span></dd>
|
186
|
-
<script type="text/javascript">moveProgressBar('
|
186
|
+
<script type="text/javascript">moveProgressBar('7.8');</script>
|
187
187
|
<dd class="spec passed"><span class="passed_spec_name">should determine the length of time until a Temporal object</span></dd>
|
188
|
-
<script type="text/javascript">moveProgressBar('
|
188
|
+
<script type="text/javascript">moveProgressBar('10.5');</script>
|
189
189
|
<dd class="spec passed"><span class="passed_spec_name">should determine if a temporal object is in the future</span></dd>
|
190
|
-
<script type="text/javascript">moveProgressBar('
|
190
|
+
<script type="text/javascript">moveProgressBar('13.1');</script>
|
191
191
|
<dd class="spec passed"><span class="passed_spec_name">should determine the length of time since a Temporal object</span></dd>
|
192
|
-
<script type="text/javascript">moveProgressBar('
|
192
|
+
<script type="text/javascript">moveProgressBar('15.7');</script>
|
193
193
|
<dd class="spec passed"><span class="passed_spec_name">should determine if a temporal object is in the past</span></dd>
|
194
|
-
<script type="text/javascript">moveProgressBar('
|
194
|
+
<script type="text/javascript">moveProgressBar('18.4');</script>
|
195
195
|
<dd class="spec passed"><span class="passed_spec_name">should determine if one Temporal object is before another</span></dd>
|
196
|
-
<script type="text/javascript">moveProgressBar('
|
196
|
+
<script type="text/javascript">moveProgressBar('21.0');</script>
|
197
197
|
<dd class="spec passed"><span class="passed_spec_name">should determine if one Temporal object is after another</span></dd>
|
198
198
|
</dl>
|
199
199
|
</div>
|
200
200
|
<div class="example_group">
|
201
201
|
<dl>
|
202
202
|
<dt id="example_group_2">The class TimePeriod < ActiveRecord::Base</dt>
|
203
|
-
<script type="text/javascript">moveProgressBar('
|
203
|
+
<script type="text/javascript">moveProgressBar('23.6');</script>
|
204
204
|
<dd class="spec passed"><span class="passed_spec_name">should be a flux capacitor</span></dd>
|
205
|
-
<script type="text/javascript">moveProgressBar('
|
205
|
+
<script type="text/javascript">moveProgressBar('26.3');</script>
|
206
206
|
<dd class="spec passed"><span class="passed_spec_name">should be a Temporal object</span></dd>
|
207
|
-
<script type="text/javascript">moveProgressBar('
|
207
|
+
<script type="text/javascript">moveProgressBar('28.9');</script>
|
208
208
|
<dd class="spec passed"><span class="passed_spec_name">should possess all four bitemporal database attributes</span></dd>
|
209
|
-
<script type="text/javascript">moveProgressBar('
|
209
|
+
<script type="text/javascript">moveProgressBar('31.5');</script>
|
210
210
|
<dd class="spec passed"><span class="passed_spec_name">should not be valid if either of the two time spans are 0 or less</span></dd>
|
211
211
|
</dl>
|
212
212
|
</div>
|
213
213
|
<div class="example_group">
|
214
214
|
<dl>
|
215
215
|
<dt id="example_group_3">The TimePeriod.find extensions</dt>
|
216
|
-
<script type="text/javascript">moveProgressBar('
|
216
|
+
<script type="text/javascript">moveProgressBar('34.2');</script>
|
217
217
|
<dd class="spec passed"><span class="passed_spec_name">should find time_periods in the present</span></dd>
|
218
|
-
<script type="text/javascript">moveProgressBar('
|
218
|
+
<script type="text/javascript">moveProgressBar('36.8');</script>
|
219
219
|
<dd class="spec passed"><span class="passed_spec_name">should find time_periods in the past</span></dd>
|
220
|
-
<script type="text/javascript">moveProgressBar('
|
220
|
+
<script type="text/javascript">moveProgressBar('39.4');</script>
|
221
221
|
<dd class="spec passed"><span class="passed_spec_name">should find time_periods in the future</span></dd>
|
222
|
-
<script type="text/javascript">moveProgressBar('
|
222
|
+
<script type="text/javascript">moveProgressBar('42.1');</script>
|
223
223
|
<dd class="spec passed"><span class="passed_spec_name">should find time_periods occuring at a specific time</span></dd>
|
224
|
-
<script type="text/javascript">moveProgressBar('
|
224
|
+
<script type="text/javascript">moveProgressBar('44.7');</script>
|
225
225
|
<dd class="spec passed"><span class="passed_spec_name">should find time_periods occuring within a specific range of time</span></dd>
|
226
226
|
</dl>
|
227
227
|
</div>
|
228
228
|
<div class="example_group">
|
229
229
|
<dl>
|
230
230
|
<dt id="example_group_4">The TimePeriod comparison helpers</dt>
|
231
|
-
<script type="text/javascript">moveProgressBar('
|
231
|
+
<script type="text/javascript">moveProgressBar('47.3');</script>
|
232
|
+
<dd class="spec passed"><span class="passed_spec_name">should determine if one time period is before another</span></dd>
|
233
|
+
<script type="text/javascript">moveProgressBar('50.0');</script>
|
234
|
+
<dd class="spec passed"><span class="passed_spec_name">should determine if one time period is after another</span></dd>
|
235
|
+
<script type="text/javascript">moveProgressBar('52.6');</script>
|
232
236
|
<dd class="spec passed"><span class="passed_spec_name">should calculate the time between time_periods</span></dd>
|
233
|
-
<script type="text/javascript">moveProgressBar('
|
237
|
+
<script type="text/javascript">moveProgressBar('55.2');</script>
|
234
238
|
<dd class="spec passed"><span class="passed_spec_name">should determine whether two time_periods overlap</span></dd>
|
235
|
-
<script type="text/javascript">moveProgressBar('
|
239
|
+
<script type="text/javascript">moveProgressBar('57.8');</script>
|
236
240
|
<dd class="spec passed"><span class="passed_spec_name">should determine the length of time by which two time_periods overlap</span></dd>
|
237
|
-
<script type="text/javascript">moveProgressBar('
|
241
|
+
<script type="text/javascript">moveProgressBar('60.5');</script>
|
238
242
|
<dd class="spec passed"><span class="passed_spec_name">should determine if two time_periods are back-to-back</span></dd>
|
239
|
-
<script type="text/javascript">moveProgressBar('
|
243
|
+
<script type="text/javascript">moveProgressBar('63.1');</script>
|
240
244
|
<dd class="spec passed"><span class="passed_spec_name">should determine if a time_period is between two other time_periods</span></dd>
|
241
245
|
</dl>
|
242
246
|
</div>
|
243
247
|
<div class="example_group">
|
244
248
|
<dl>
|
245
249
|
<dt id="example_group_5">The TimePeriod status helpers</dt>
|
246
|
-
<script type="text/javascript">moveProgressBar('
|
250
|
+
<script type="text/javascript">moveProgressBar('65.7');</script>
|
251
|
+
<dd class="spec passed"><span class="passed_spec_name">should determine the length of time until a time_period</span></dd>
|
252
|
+
<script type="text/javascript">moveProgressBar('68.4');</script>
|
253
|
+
<dd class="spec passed"><span class="passed_spec_name">should determine if a time_period is in the future</span></dd>
|
254
|
+
<script type="text/javascript">moveProgressBar('71.0');</script>
|
255
|
+
<dd class="spec passed"><span class="passed_spec_name">should determine the length of time since a time_period ended</span></dd>
|
256
|
+
<script type="text/javascript">moveProgressBar('73.6');</script>
|
257
|
+
<dd class="spec passed"><span class="passed_spec_name">should determine if a time_period is in the past</span></dd>
|
258
|
+
<script type="text/javascript">moveProgressBar('76.3');</script>
|
247
259
|
<dd class="spec passed"><span class="passed_spec_name">should determine if a time_period has started</span></dd>
|
248
|
-
<script type="text/javascript">moveProgressBar('
|
260
|
+
<script type="text/javascript">moveProgressBar('78.9');</script>
|
249
261
|
<dd class="spec passed"><span class="passed_spec_name">should determine how much time has elapsed since an event started</span></dd>
|
250
|
-
<script type="text/javascript">moveProgressBar('
|
262
|
+
<script type="text/javascript">moveProgressBar('81.5');</script>
|
251
263
|
<dd class="spec passed"><span class="passed_spec_name">should determine what percentage of time has elapsed since an event started</span></dd>
|
252
|
-
<script type="text/javascript">moveProgressBar('
|
264
|
+
<script type="text/javascript">moveProgressBar('84.2');</script>
|
253
265
|
<dd class="spec passed"><span class="passed_spec_name">should determine how much time is remaining until an event ends</span></dd>
|
254
|
-
<script type="text/javascript">moveProgressBar('
|
266
|
+
<script type="text/javascript">moveProgressBar('86.8');</script>
|
255
267
|
<dd class="spec passed"><span class="passed_spec_name">should determine what percentage of time is remaining until an event ends</span></dd>
|
256
|
-
<script type="text/javascript">moveProgressBar('
|
268
|
+
<script type="text/javascript">moveProgressBar('89.4');</script>
|
257
269
|
<dd class="spec passed"><span class="passed_spec_name">should determine if a time_period has ended</span></dd>
|
258
|
-
<script type="text/javascript">moveProgressBar('
|
270
|
+
<script type="text/javascript">moveProgressBar('92.1');</script>
|
259
271
|
<dd class="spec passed"><span class="passed_spec_name">should determine the duration of a time_period</span></dd>
|
260
272
|
</dl>
|
261
273
|
</div>
|
262
274
|
<div class="example_group">
|
263
275
|
<dl>
|
264
276
|
<dt id="example_group_6">The TimePeriod modification helpers</dt>
|
265
|
-
<script type="text/javascript">moveProgressBar('
|
277
|
+
<script type="text/javascript">moveProgressBar('94.7');</script>
|
266
278
|
<dd class="spec passed"><span class="passed_spec_name">should shift a time_period into the past or future</span></dd>
|
267
279
|
</dl>
|
268
280
|
</div>
|
269
281
|
<div class="example_group">
|
270
282
|
<dl>
|
271
283
|
<dt id="example_group_7">The Range overlap helpers</dt>
|
272
|
-
<script type="text/javascript">moveProgressBar('
|
284
|
+
<script type="text/javascript">moveProgressBar('97.3');</script>
|
273
285
|
<dd class="spec passed"><span class="passed_spec_name">should determine if two ranges do not overlap</span></dd>
|
274
286
|
<script type="text/javascript">moveProgressBar('100.0');</script>
|
275
287
|
<dd class="spec passed"><span class="passed_spec_name">should determine if two ranges do overlap</span></dd>
|
276
288
|
</dl>
|
277
289
|
</div>
|
278
|
-
<script type="text/javascript">document.getElementById('duration').innerHTML = "Finished in <strong>0.
|
279
|
-
<script type="text/javascript">document.getElementById('totals').innerHTML = "
|
290
|
+
<script type="text/javascript">document.getElementById('duration').innerHTML = "Finished in <strong>0.368839 seconds</strong>";</script>
|
291
|
+
<script type="text/javascript">document.getElementById('totals').innerHTML = "38 examples, 0 failures";</script>
|
280
292
|
</div>
|
281
293
|
</div>
|
282
294
|
</body>
|
data/spec/spec_helper.rb
CHANGED
@@ -11,6 +11,7 @@ require 'ruby-debug'
|
|
11
11
|
require 'activerecord'
|
12
12
|
require 'activesupport'
|
13
13
|
require 'spec/fixtures.rb'
|
14
|
+
require 'spec/time_helper.rb'
|
14
15
|
|
15
16
|
config = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))
|
16
17
|
ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + "/../log/debug.log")
|
data/spec/time_helper.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
class Time
|
2
|
+
|
3
|
+
# this code adds a Time.freeze method to make time "stand still"
|
4
|
+
# during execution of a block. This can be helpful during testing of
|
5
|
+
# methods that depend on Time.new or Time.now
|
6
|
+
#
|
7
|
+
# Example:
|
8
|
+
#
|
9
|
+
# Time.freeze do
|
10
|
+
# puts Time.new.to_f
|
11
|
+
# # ... do stuff; real time passes
|
12
|
+
# puts Time.new.to_f # outputs same time as above
|
13
|
+
# end
|
14
|
+
# # ... time returns to normal
|
15
|
+
#
|
16
|
+
# An optional Time object may be passed to freeze to a specific time:
|
17
|
+
#
|
18
|
+
# Time.freeze(Time.at(2007, 11, 15)) do
|
19
|
+
# # ...
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# While inside the block, Time.frozen? will return true
|
23
|
+
|
24
|
+
class << self
|
25
|
+
|
26
|
+
def now
|
27
|
+
@time || orig_new
|
28
|
+
end
|
29
|
+
|
30
|
+
alias_method :orig_freeze, :freeze
|
31
|
+
alias_method :orig_new, :new
|
32
|
+
alias_method :new, :now
|
33
|
+
|
34
|
+
# makes time "stand still" during execution of a block. if no time is
|
35
|
+
# supplied, the current time is used. While in the block, Time.new and
|
36
|
+
# Time.now will always return the "frozen" value.
|
37
|
+
def freeze(time = nil)
|
38
|
+
raise "A block is required" unless block_given?
|
39
|
+
begin
|
40
|
+
prev = @time
|
41
|
+
@time = time || now
|
42
|
+
yield
|
43
|
+
ensure
|
44
|
+
@time = prev
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def frozen?
|
49
|
+
!@time.nil?
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: acts_as_flux_capacitor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jim Cropcho
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-05-
|
12
|
+
date: 2008-05-23 00:00:00 -04:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -52,6 +52,7 @@ files:
|
|
52
52
|
- spec/schema.rb
|
53
53
|
- spec/spec.opts
|
54
54
|
- spec/spec_helper.rb
|
55
|
+
- spec/time_helper.rb
|
55
56
|
- tasks/deployment.rake
|
56
57
|
- tasks/environment.rake
|
57
58
|
- tasks/rspec.rake
|