tempr 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,9 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.4 / 2012-02-20
4
+
5
+ - add range adjacency methods (`precedes?`, `succeeds?`, `adjacent_to?`)
6
+
3
7
  ## 0.1.3 / 2012-02-19
4
8
 
5
9
  - convert date to time ranges for date <-> time comparisons in `within?/subsume?/intersection_with`
@@ -31,6 +31,10 @@ module Tempr
31
31
  #
32
32
  # Or check for inclusion of a date/time:
33
33
  #
34
+ # subrange.cover? Time.parse("2012-05-17 2:30pm")
35
+ #
36
+ # which is a shortcut for
37
+ #
34
38
  # subrange.any? {|r| r.cover?(Time.parse("2012-05-17 2:30pm")) }
35
39
  #
36
40
  # Note that the order of the chained rules is important, they must be defined
@@ -511,6 +515,22 @@ module Tempr
511
515
  !!intersection_with(other)
512
516
  end
513
517
 
518
+ # true iff self immediately precedes other range
519
+ def precedes?(other)
520
+ range_precedes(self, other)
521
+ end
522
+
523
+ # true iff self immediately succeeds (follows) other range
524
+ def succeeds?(other)
525
+ range_precedes(other, self)
526
+ end
527
+ alias follows? succeeds?
528
+
529
+ # true iff self either succeeds or follows other range
530
+ def adjacent_to?(other)
531
+ succeeds?(other) || precedes?(other)
532
+ end
533
+
514
534
  # ---
515
535
 
516
536
  # convenience wrapper for SubRangeIterator.new(self) { ... }
@@ -539,6 +559,18 @@ module Tempr
539
559
  end
540
560
  end
541
561
 
562
+ # note that date ranges will always be adjusted to exclude the end,
563
+ # so only inclusive time ranges will need to add +1 second to check adjacency
564
+ def range_precedes(rng,oth)
565
+ r1, r2 = matched_range_types(rng,oth)
566
+ diff = if r1.respond_to?(:exclude_end?) && r1.exclude_end?
567
+ 0
568
+ else
569
+ 1
570
+ end
571
+ (r1.end + diff) == r2.begin
572
+ end
573
+
542
574
  # ---
543
575
 
544
576
  # Iterators are defined by
@@ -3,7 +3,7 @@ module Tempr
3
3
  module Version
4
4
  MAJOR = 0
5
5
  MINOR = 1
6
- TINY = 3
6
+ TINY = 4
7
7
  STRING = "#{MAJOR}.#{MINOR}.#{TINY}"
8
8
  end
9
9
  end
@@ -0,0 +1,257 @@
1
+ require File.expand_path('test_helper', File.dirname(__FILE__))
2
+
3
+ module RangeAdjacencyTests
4
+
5
+ Fixtures = [
6
+ {
7
+ :case => "inclusive date ranges, other equals self",
8
+ :subject => (Date.civil(2012,2,13)..
9
+ Date.civil(2012,2,17)).extend(Tempr::DateTimeRange),
10
+ :other => Date.civil(2012,2,13)..Date.civil(2012,2,17),
11
+ :precedes => false,
12
+ :succeeds => false,
13
+ :adjacent => false
14
+ },
15
+ {
16
+ :case => "inclusive date ranges, other within self",
17
+ :subject => (Date.civil(2012,2,13)..
18
+ Date.civil(2012,2,17)).extend(Tempr::DateTimeRange),
19
+ :other => Date.civil(2012,2,13)..Date.civil(2012,2,16),
20
+ :precedes => false,
21
+ :succeeds => false,
22
+ :adjacent => false
23
+ },
24
+ {
25
+ :case => "inclusive date ranges, other precedes self",
26
+ :subject => (Date.civil(2012,2,13)..
27
+ Date.civil(2012,2,17)).extend(Tempr::DateTimeRange),
28
+ :other => Date.civil(2012,2,1)..Date.civil(2012,2,12),
29
+ :precedes => false,
30
+ :succeeds => true,
31
+ :adjacent => true
32
+ },
33
+ {
34
+ :case => "inclusive date ranges, self precedes other",
35
+ :subject => (Date.civil(2012,2,13)..
36
+ Date.civil(2012,2,17)).extend(Tempr::DateTimeRange),
37
+ :other => Date.civil(2012,2,18)..Date.civil(2012,2,25),
38
+ :precedes => true,
39
+ :succeeds => false,
40
+ :adjacent => true
41
+ },
42
+ {
43
+ :case => "exclusive date ranges, other equals self",
44
+ :subject => (Date.civil(2012,2,13)...
45
+ Date.civil(2012,2,18)).extend(Tempr::DateTimeRange),
46
+ :other => Date.civil(2012,2,13)...Date.civil(2012,2,18),
47
+ :precedes => false,
48
+ :succeeds => false,
49
+ :adjacent => false
50
+ },
51
+ {
52
+ :case => "exclusive date ranges, other within self",
53
+ :subject => (Date.civil(2012,2,13)...
54
+ Date.civil(2012,2,18)).extend(Tempr::DateTimeRange),
55
+ :other => Date.civil(2012,2,13)...Date.civil(2012,2,17),
56
+ :precedes => false,
57
+ :succeeds => false,
58
+ :adjacent => false
59
+ },
60
+ {
61
+ :case => "exclusive date ranges, other precedes self",
62
+ :subject => (Date.civil(2012,2,13)...
63
+ Date.civil(2012,2,18)).extend(Tempr::DateTimeRange),
64
+ :other => Date.civil(2012,2,1)...Date.civil(2012,2,13),
65
+ :precedes => false,
66
+ :succeeds => true,
67
+ :adjacent => true
68
+ },
69
+ {
70
+ :case => "exclusive date ranges, self precedes other",
71
+ :subject => (Date.civil(2012,2,13)...
72
+ Date.civil(2012,2,18)).extend(Tempr::DateTimeRange),
73
+ :other => Date.civil(2012,2,18)...Date.civil(2012,2,25),
74
+ :precedes => true,
75
+ :succeeds => false,
76
+ :adjacent => true
77
+ },
78
+
79
+ #---------- time range cases
80
+
81
+ {
82
+ :case => "inclusive time ranges, other equals self",
83
+ :subject => (Time.new(2012,2,13,12,11,10)..
84
+ Time.new(2012,2,17,16,15,14)).extend(Tempr::DateTimeRange),
85
+ :other => (Time.new(2012,2,13,12,11,10)..
86
+ Time.new(2012,2,17,16,15,14)),
87
+ :precedes => false,
88
+ :succeeds => false,
89
+ :adjacent => false
90
+ },
91
+ {
92
+ :case => "inclusive time ranges, other within self",
93
+ :subject => (Time.new(2012,2,13,12,11,10)..
94
+ Time.new(2012,2,17,16,15,14)).extend(Tempr::DateTimeRange),
95
+ :other => (Time.new(2012,2,13,12,11,10)..
96
+ Time.new(2012,2,17,16,15,13)),
97
+ :precedes => false,
98
+ :succeeds => false,
99
+ :adjacent => false
100
+ },
101
+ {
102
+ :case => "inclusive time ranges, self precedes other",
103
+ :subject => (Time.new(2012,2,13,12,11,10)..
104
+ Time.new(2012,2,17,16,15,14)).extend(Tempr::DateTimeRange),
105
+ :other => (Time.new(2012,2,17,16,15,15)..
106
+ Time.new(2012,2,17,16,15,16)),
107
+ :precedes => true,
108
+ :succeeds => false,
109
+ :adjacent => true
110
+ },
111
+ {
112
+ :case => "inclusive time ranges, other precedes self",
113
+ :subject => (Time.new(2012,2,13,0,0,0)..
114
+ Time.new(2012,2,17,0,0,0)).extend(Tempr::DateTimeRange),
115
+ :other => (Time.new(2012,2,1,0,0,0)..
116
+ Time.new(2012,2,12,23,59,59)),
117
+ :precedes => false,
118
+ :succeeds => true,
119
+ :adjacent => true
120
+ },
121
+ {
122
+ :case => "exclusive time ranges, other equals self",
123
+ :subject => (Time.new(2012,2,13,12,11,10)...
124
+ Time.new(2012,2,17,16,15,14)).extend(Tempr::DateTimeRange),
125
+ :other => (Time.new(2012,2,13,12,11,10)...
126
+ Time.new(2012,2,17,16,15,14)),
127
+ :precedes => false,
128
+ :succeeds => false,
129
+ :adjacent => false
130
+ },
131
+ {
132
+ :case => "inclusive time ranges, other within self",
133
+ :subject => (Time.new(2012,2,13,12,11,10)...
134
+ Time.new(2012,2,17,16,15,14)).extend(Tempr::DateTimeRange),
135
+ :other => (Time.new(2012,2,13,12,11,10)...
136
+ Time.new(2012,2,17,16,15,13)),
137
+ :precedes => false,
138
+ :succeeds => false,
139
+ :adjacent => false
140
+ },
141
+ {
142
+ :case => "inclusive time ranges, self precedes other",
143
+ :subject => (Time.new(2012,2,13,12,11,10)...
144
+ Time.new(2012,2,17,16,15,14)).extend(Tempr::DateTimeRange),
145
+ :other => (Time.new(2012,2,17,16,15,14)..
146
+ Time.new(2012,2,17,16,15,16)),
147
+ :precedes => true,
148
+ :succeeds => false,
149
+ :adjacent => true
150
+ },
151
+ {
152
+ :case => "inclusive time ranges, other precedes self",
153
+ :subject => (Time.new(2012,2,13,0,0,0)..
154
+ Time.new(2012,2,17,0,0,0)).extend(Tempr::DateTimeRange),
155
+ :other => (Time.new(2012,2,1,0,0,0)...
156
+ Time.new(2012,2,13,0,0,0)),
157
+ :precedes => false,
158
+ :succeeds => true,
159
+ :adjacent => true
160
+ },
161
+ #---------- date/time range cases
162
+
163
+ {
164
+ :case => "date range intersects other time range, other equivalent to self",
165
+ :subject => (Date.civil(2012,2,13)..
166
+ Date.civil(2012,2,17)).extend(Tempr::DateTimeRange),
167
+ :other => (Time.new(2012,2,13,0,0,0)...
168
+ Time.new(2012,2,18,0,0,0)),
169
+ :precedes => false,
170
+ :succeeds => false,
171
+ :adjacent => false
172
+ },
173
+ {
174
+ :case => "time range compared to other date range, other within self",
175
+ :subject => (Time.new(2012,2,13,0,0,0)...
176
+ Time.new(2012,2,18,0,0,0)).extend(Tempr::DateTimeRange),
177
+ :other => (Date.civil(2012,2,13)..
178
+ Date.civil(2012,2,16)),
179
+ :precedes => false,
180
+ :succeeds => false,
181
+ :adjacent => false
182
+ },
183
+ {
184
+ :case => "date range compared to other time range, self precedes other",
185
+ :subject => (Date.civil(2012,2,13)..
186
+ Date.civil(2012,2,17)).extend(Tempr::DateTimeRange),
187
+ :other => (Time.new(2012,2,18,0,0,0)...
188
+ Time.new(2012,2,19,0,0,0)),
189
+ :precedes => true,
190
+ :succeeds => false,
191
+ :adjacent => true
192
+ },
193
+ {
194
+ :case => "time range compared to other date range, self precedes other",
195
+ :subject => (Time.new(2012,2,13,0,0,0)...
196
+ Time.new(2012,2,18,0,0,0)).extend(Tempr::DateTimeRange),
197
+ :other => (Date.civil(2012,2,18)..
198
+ Date.civil(2012,2,19)),
199
+ :precedes => true,
200
+ :succeeds => false,
201
+ :adjacent => true
202
+ },
203
+ {
204
+ :case => "date range compared to other time range, other precedes self",
205
+ :subject => (Date.civil(2012,2,13)..
206
+ Date.civil(2012,2,17)).extend(Tempr::DateTimeRange),
207
+ :other => (Time.new(2012,2,1,0,0,0)...
208
+ Time.new(2012,2,13,0,0,0)),
209
+ :precedes => false,
210
+ :succeeds => true,
211
+ :adjacent => true
212
+ },
213
+ {
214
+ :case => "time range compared to other date range, other precedes self",
215
+ :subject => (Time.new(2012,2,13,0,0,0)...
216
+ Time.new(2012,2,18,0,0,0)).extend(Tempr::DateTimeRange),
217
+ :other => (Date.civil(2012,2,1)..
218
+ Date.civil(2012,2,12)),
219
+ :precedes => false,
220
+ :succeeds => true,
221
+ :adjacent => true
222
+ }
223
+ ]
224
+
225
+ describe "DateTimeRange#intersection_with, date ranges" do
226
+
227
+ Fixtures.each do |fixture|
228
+
229
+ describe fixture[:case] do
230
+ let(:subject) { fixture[:subject] }
231
+ let(:other) { fixture[:other] }
232
+ let(:expected_precedes) { fixture[:precedes] }
233
+ let(:expected_succeeds) { fixture[:succeeds] }
234
+ let(:expected_adjacent) { fixture[:adjacent] }
235
+
236
+ it 'should return expected precedes status' do
237
+ actual = subject.precedes?(other)
238
+ assert_equal expected_precedes, actual
239
+ end
240
+
241
+ it 'should return expected succeeds status' do
242
+ actual = subject.succeeds?(other)
243
+ assert_equal expected_succeeds, actual
244
+ end
245
+
246
+ it 'should return expected adjacent_to status' do
247
+ actual = subject.adjacent_to?(other)
248
+ assert_equal expected_adjacent, actual
249
+ end
250
+
251
+ end
252
+
253
+ end
254
+
255
+ end
256
+
257
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tempr
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-02-19 00:00:00.000000000Z
12
+ date: 2012-02-20 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: minitest
16
- requirement: &13275580 !ruby/object:Gem::Requirement
16
+ requirement: &11232140 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *13275580
24
+ version_requirements: *11232140
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rake
27
- requirement: &13275120 !ruby/object:Gem::Requirement
27
+ requirement: &11231560 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,7 +32,7 @@ dependencies:
32
32
  version: '0'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *13275120
35
+ version_requirements: *11231560
36
36
  description: ''
37
37
  email:
38
38
  - ericgj72@gmail.com
@@ -49,6 +49,7 @@ files:
49
49
  - lib/tempr/date_time_range.rb
50
50
  - lib/tempr/version.rb
51
51
  - test/each_time_of_day.rb
52
+ - test/range_adjacency.rb
52
53
  - test/range_intersection.rb
53
54
  - test/range_within_other.rb
54
55
  - test/suite.rb