3scale_time_range 0.0.6 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8f44bc184306146b1182c2b1453a8598193c52e8
4
- data.tar.gz: 26b347ae284d20377a83dd6082f9ac2f1008518a
3
+ metadata.gz: f48ca9ad688668fe899b7be2cec2a53294890ace
4
+ data.tar.gz: 349ebce201722a0c4de5a298ef38d2a27effd07f
5
5
  SHA512:
6
- metadata.gz: b55a7dba0dd5cfd701845de8b9ff69f29644b2184bc2822c72ab358ebaf5612be0afb1f150aab8150829b95632952d820aaf2fd401d2fc1a6be08aa18aa6ad1d
7
- data.tar.gz: 5e44d1e22c17163c856de2468fe97bce1841195cd7c7ae918dbaf7ce68a0ec3ac76bde81de7ba36f48096d546038e575553067b4d576c0648342c06309020322
6
+ metadata.gz: b463ef4d67758bc596de440019620ba8d6eeaa0bb36d74a9451e03f1d215c7b6c339b6d1303b8699cc85673ec8b65ed745f0d4e7359df718ba4339cfedb787a6
7
+ data.tar.gz: 868c4fdd292f83014593d3550bbaff2b0d4eef14e6236251385eefaadae5d885dfffc0e78e4ac27205997837b80134d53bbb131edb4db4dd54875e675668963b
data/README.md CHANGED
@@ -27,3 +27,18 @@ Enumerate by custom period
27
27
  Supports all Enumerable interface: find, select, reject, inject, etc.
28
28
 
29
29
 
30
+ Version compatibility
31
+ --------
32
+ 0.3.0: Public repository along with the very first RubyGems gem
33
+
34
+ 0.2.0: The Granulate class has been converted to a class method that returns a
35
+ hash. Granulate was not easy to use because it returned an instance of
36
+ 'Granulate'. This prevented clients from iterating through the result.
37
+
38
+ 0.1.0: breaks compatibility with previous versions because it adds hours to the
39
+ Granulate class. This means that in previous versions Granulate.rest contained
40
+ time ranges that cannot be separated into days when granulating, but now it
41
+ just contains ranges that cannot be separated into hours.
42
+
43
+
44
+
@@ -1,55 +1,58 @@
1
- class TimeRange
2
- class Granulate
3
- attr_accessor :days, :months, :years, :rest
1
+ module Granulate
2
+ def self.included(base)
3
+ base.extend ClassMethods
4
+ end
4
5
 
5
- def initialize(range)
6
- raise 'Supports only TimeRange objects' unless range.is_a? TimeRange
6
+ module ClassMethods
7
+ GRANULARITIES = [:year, :month, :day, :hour]
7
8
 
8
- @days = []
9
- @years = []
10
- @months = []
11
- @rest = []
12
- extract(range, :year)
9
+ def granulate(range)
10
+ result = { rest: [] }
11
+ GRANULARITIES.each do |granularity|
12
+ result[(granularity.to_s + 's').to_sym] = []
13
+ end
14
+ time_range = TimeRange.new(range.begin, range.end, range.exclude_end?)
15
+ extract(time_range, GRANULARITIES.first, result)
16
+ result
13
17
  end
14
18
 
15
19
  private
16
20
 
17
- def extract(range, cycle)
21
+ def extract(range, cycle, result)
18
22
  if cycle.nil?
19
- rest << range unless empty_range?(range)
23
+ result[:rest] << range unless empty_range?(range)
20
24
  return
21
25
  end
22
26
 
23
27
  cycle_start, cycle_end = extract_boundaries(range, cycle)
24
28
  if cycle_start && cycle_end
25
- send("#{cycle}s") << TimeRange.new(cycle_start, cycle_end)
29
+ result[(cycle.to_s + 's').to_sym] << TimeRange.new(cycle_start, cycle_end)
26
30
 
27
31
  if range.begin < cycle_start
28
- extract(
29
- TimeRange.new(range.begin, (cycle_start - 1.hour).end_of_day, false),
30
- next_cycle(cycle)
31
- )
32
+ # Getting the last hour is enough because is the smallest resolution
33
+ # that we support. If we supported minutes, we would need to get the
34
+ # last minute non included.
35
+ last_hour_not_treated = (cycle_start - 1.hour).end_of_hour
36
+ extract(TimeRange.new(range.begin, last_hour_not_treated, false),
37
+ next_cycle(cycle),
38
+ result)
32
39
  end
40
+
33
41
  if range.end > cycle_end
34
- extract(
35
- TimeRange.new(
36
- (cycle_end + 1.hour).beginning_of_day, range.end, range.exclude_end?
37
- ),
38
- next_cycle(cycle)
39
- )
42
+ first_hour_not_treated = (cycle_end + 1.hour).beginning_of_hour
43
+ extract(TimeRange.new(first_hour_not_treated, range.end, range.exclude_end?),
44
+ next_cycle(cycle),
45
+ result)
40
46
  end
41
47
  else
42
- extract(range, next_cycle(cycle))
48
+ extract(range, next_cycle(cycle), result)
43
49
  end
44
50
  end
45
51
 
46
52
  def next_cycle(current_cycle)
47
- case current_cycle
48
- when :year then :month
49
- when :month then :day
50
- when :day then nil
51
- else raise "Unknown cycle: #{current_cycle.inspect}"
52
- end
53
+ current_cycle_index = GRANULARITIES.find_index(current_cycle)
54
+ raise "Unknown cycle: #{current_cycle.inspect}" unless current_cycle_index
55
+ GRANULARITIES[current_cycle_index + 1]
53
56
  end
54
57
 
55
58
  def extract_boundaries(range, cycle)
@@ -80,6 +83,5 @@ class TimeRange
80
83
  def empty_range?(range)
81
84
  (range.begin.to_i == range.end.to_i) && range.exclude_end?
82
85
  end
83
-
84
86
  end
85
87
  end
@@ -1,3 +1,3 @@
1
1
  class TimeRange < Range
2
- VERSION = "0.0.6"
2
+ VERSION = '0.3.0'
3
3
  end
@@ -4,6 +4,8 @@ require '3scale_time_range/granulate'
4
4
 
5
5
  class TimeRange < Range
6
6
 
7
+ include Granulate
8
+
7
9
  def initialize(start_time, end_time, exclusive = false)
8
10
  raise ArgumentError, 'start and end must act like Time' unless start_time.acts_like?(:time) && end_time.acts_like?(:time)
9
11
 
@@ -114,10 +116,6 @@ class TimeRange < Range
114
116
  "#{self.class.name}(#{super})"
115
117
  end
116
118
 
117
- def granulate
118
- @granulate ||= Granulate.new(self)
119
- end
120
-
121
119
  class SimpleEnumerator
122
120
  include Enumerable
123
121
 
@@ -4,133 +4,133 @@ require_relative '../lib/3scale_time_range'
4
4
  class GranulateTest < Minitest::Test
5
5
 
6
6
  def setup
7
- @gran = TimeRange.new(
8
- DateTime.parse("2012-10-09 07:23"), DateTime.parse("2014-02-05 13:45")
9
- ).granulate
7
+ range = DateTime.parse('2012-10-09 07:23')..DateTime.parse('2014-02-05 13:45')
8
+ @granulated_range = TimeRange.granulate(range)
10
9
  end
11
10
 
12
11
  def test_granulates_by_year
13
- assert_equal @gran.years, [
14
- TimeRange.new(
15
- DateTime.parse("2013-01-01").beginning_of_year,
16
- DateTime.parse("2013-12-31").end_of_year)
17
- ]
12
+ assert_equal @granulated_range[:years],
13
+ [TimeRange.new(
14
+ DateTime.parse('2013-01-01').beginning_of_year,
15
+ DateTime.parse('2013-12-31').end_of_year)]
18
16
  end
19
17
 
20
18
  def test_granulates_by_month
21
- assert_equal @gran.months, [
22
- TimeRange.new(
23
- DateTime.parse("2012-11-01").beginning_of_month,
24
- DateTime.parse("2012-12-31").end_of_month),
25
-
26
- TimeRange.new(
27
- DateTime.parse("2014-01-01").beginning_of_month,
28
- DateTime.parse("2014-01-31").end_of_month)
29
- ]
19
+ assert_equal @granulated_range[:months],
20
+ [TimeRange.new(
21
+ DateTime.parse('2012-11-01').beginning_of_month,
22
+ DateTime.parse('2012-12-31').end_of_month),
23
+ TimeRange.new(
24
+ DateTime.parse('2014-01-01').beginning_of_month,
25
+ DateTime.parse('2014-01-31').end_of_month)]
30
26
  end
31
27
 
28
+
32
29
  def test_granulates_by_day
33
- assert_equal @gran.days, [
34
- TimeRange.new(
35
- DateTime.parse("2012-10-10").beginning_of_day,
36
- DateTime.parse("2012-10-31").end_of_day),
37
-
38
- TimeRange.new(
39
- DateTime.parse("2014-02-01").beginning_of_day,
40
- DateTime.parse("2014-02-04").end_of_day)
41
- ]
30
+ assert_equal @granulated_range[:days],
31
+ [TimeRange.new(
32
+ DateTime.parse('2012-10-10').beginning_of_day,
33
+ DateTime.parse('2012-10-31').end_of_day),
34
+ TimeRange.new(
35
+ DateTime.parse('2014-02-01').beginning_of_day,
36
+ DateTime.parse('2014-02-04').end_of_day)]
42
37
  end
43
38
 
44
- def test_exposes_information_on_not_granulated_ranges
45
- assert_equal @gran.rest, [
46
- TimeRange.new(
47
- DateTime.parse("2012-10-09 07:23"),
48
- DateTime.parse("2012-10-09").end_of_day),
49
-
50
- TimeRange.new(
51
- DateTime.parse("2014-02-05").beginning_of_day,
52
- DateTime.parse("2014-02-05 13:45"))
53
- ]
39
+ def test_granulates_by_hour
40
+ assert_equal @granulated_range[:hours],
41
+ [TimeRange.new(
42
+ DateTime.parse('2012-10-09 08:00').beginning_of_hour,
43
+ DateTime.parse('2012-10-09 23:00').end_of_hour),
44
+ TimeRange.new(
45
+ DateTime.parse('2014-02-05 00:00').beginning_of_hour,
46
+ DateTime.parse('2014-02-05 12:00').end_of_hour)]
54
47
  end
55
48
 
56
- def test_works_also_for_short_ranges
57
- @gran = TimeRange.new(
58
- DateTime.parse("2012-10-09 07:23"), DateTime.parse("2012-10-09 13:45")
59
- ).granulate
60
-
61
- assert_equal @gran.rest, [
62
- TimeRange.new(
63
- DateTime.parse("2012-10-09 07:23"),
64
- DateTime.parse("2012-10-09 13:45"))
65
- ]
49
+ def test_exposes_information_on_not_granulated_ranges
50
+ assert_equal @granulated_range[:rest],
51
+ [TimeRange.new(
52
+ DateTime.parse('2012-10-09 07:23'),
53
+ DateTime.parse('2012-10-09 07:00').end_of_hour),
54
+ TimeRange.new(
55
+ DateTime.parse('2014-02-05 13:45').beginning_of_hour,
56
+ DateTime.parse('2014-02-05 13:45'))]
66
57
  end
67
58
 
68
- def test_granulation_is_cached_in_time_range
69
- range = TimeRange.new(
70
- DateTime.parse("2012-10-09 07:23"), DateTime.parse("2012-10-09 13:45")
71
- )
59
+ def test_range_that_cannot_be_granulated
60
+ granulated_range = TimeRange.granulate(
61
+ DateTime.parse('2012-10-09 07:23')..DateTime.parse('2012-10-09 07:45'))
72
62
 
73
- assert_equal range.granulate.object_id, range.granulate.object_id
63
+ assert_equal granulated_range[:rest],
64
+ [TimeRange.new(
65
+ DateTime.parse('2012-10-09 07:23'),
66
+ DateTime.parse('2012-10-09 07:45'))]
74
67
  end
75
68
 
76
69
  def test_properly_parses_open_ended_ranges_1
77
- gran = (DateTime.parse("2011-01-01")...DateTime.parse("2012-01-01")).
78
- to_time_range.granulate
70
+ granulated_range = TimeRange.granulate(
71
+ DateTime.parse('2011-01-01')...DateTime.parse('2012-01-01'))
79
72
 
80
- assert_equal 1, gran.years.size
81
- assert_equal 0, gran.months.size
82
- assert_equal 0, gran.days.size
83
- assert_equal 0, gran.rest.size
73
+ assert_equal 1, granulated_range[:years].size
74
+ assert_equal 0, granulated_range[:months].size
75
+ assert_equal 0, granulated_range[:days].size
76
+ assert_equal 0, granulated_range[:hours].size
77
+ assert_equal 0, granulated_range[:rest].size
84
78
 
85
- refute gran.years.first.exclude_end?
79
+ refute granulated_range[:years].first.exclude_end?
86
80
  end
87
81
 
88
82
  def test_properly_parses_open_ended_ranges_2
89
- gran = (DateTime.parse("2011-01-01")...DateTime.parse("2011-12-31").end_of_year).
90
- to_time_range.granulate
91
-
92
- assert_equal 0, gran.years.size
93
- assert_equal 1, gran.months.size
94
- assert_equal 1, gran.days.size
95
- assert_equal 1, gran.rest.size
96
-
97
- refute gran.months.first.exclude_end?
98
- refute gran.days.first.exclude_end?
99
- assert gran.rest.first.exclude_end?
83
+ granulated_range = TimeRange.granulate(
84
+ DateTime.parse('2011-01-01')...DateTime.parse('2011-12-31').end_of_year)
85
+
86
+ assert_equal 0, granulated_range[:years].size
87
+ assert_equal 1, granulated_range[:months].size
88
+ assert_equal 1, granulated_range[:days].size
89
+ assert_equal 1, granulated_range[:hours].size
90
+ assert_equal 1, granulated_range[:rest].size
91
+
92
+ refute granulated_range[:hours].first.exclude_end?
93
+ refute granulated_range[:months].first.exclude_end?
94
+ refute granulated_range[:days].first.exclude_end?
95
+ assert granulated_range[:rest].first.exclude_end?
100
96
  end
101
97
 
102
98
  def test_properly_parses_close_ended_ranges_1
103
- gran = (DateTime.parse("2011-01-01")..DateTime.parse("2012-01-01")).
104
- to_time_range.granulate
99
+ granulated_range = TimeRange.granulate(
100
+ DateTime.parse('2011-01-01')..DateTime.parse('2012-01-01'))
105
101
 
106
- assert_equal 1, gran.years.size
107
- assert_equal 0, gran.months.size
108
- assert_equal 0, gran.days.size
109
- assert_equal 1, gran.rest.size
102
+ assert_equal 1, granulated_range[:years].size
103
+ assert_equal 0, granulated_range[:months].size
104
+ assert_equal 0, granulated_range[:days].size
105
+ assert_equal 0, granulated_range[:hours].size
106
+ assert_equal 1, granulated_range[:rest].size
110
107
 
111
- refute gran.rest.first.exclude_end?
108
+ refute granulated_range[:rest].first.exclude_end?
112
109
  end
113
110
 
114
111
  def test_properly_parses_close_ended_ranges_2
115
- gran = (DateTime.parse("2011-01-01")..DateTime.parse("2011-12-31").end_of_year).
116
- to_time_range.granulate
112
+ granulated_range = TimeRange.granulate(
113
+ DateTime.parse('2011-01-01')..DateTime.parse('2011-12-31').end_of_year)
117
114
 
118
- assert_equal 1, gran.years.size
119
- assert_equal 0, gran.months.size
120
- assert_equal 0, gran.days.size
121
- assert_equal 0, gran.rest.size
115
+ assert_equal 1, granulated_range[:years].size
116
+ assert_equal 0, granulated_range[:months].size
117
+ assert_equal 0, granulated_range[:days].size
118
+ assert_equal 0, granulated_range[:hours].size
119
+ assert_equal 0, granulated_range[:rest].size
122
120
 
123
- refute gran.years.first.exclude_end?
121
+ refute granulated_range[:years].first.exclude_end?
124
122
  end
125
123
 
126
124
  def test_properly_handles_Time_UTC_ends_of_months
127
125
  d = DateTime.parse('2010-01-01')
128
- gran = (d.beginning_of_month.to_time.utc..d.end_of_month.to_time.utc).to_time_range.granulate
129
-
130
- assert_equal 0, gran.years.size
131
- assert_equal 1, gran.months.size
132
- assert_equal 0, gran.days.size
133
- assert_equal 0, gran.rest.size
126
+ granulated_range = TimeRange.granulate(
127
+ d.beginning_of_month.to_time.utc..d.end_of_month.to_time.utc)
128
+
129
+ assert_equal 0, granulated_range[:years].size
130
+ assert_equal 1, granulated_range[:months].size
131
+ assert_equal 0, granulated_range[:days].size
132
+ assert_equal 0, granulated_range[:hours].size
133
+ assert_equal 0, granulated_range[:rest].size
134
134
  end
135
135
 
136
136
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: 3scale_time_range
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Wojciech Ogrodowczyk