3scale_time_range 0.0.6 → 0.3.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.
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