zero_fill 0.2.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 +7 -0
- data/.gitignore +3 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +20 -0
- data/LICENSE +21 -0
- data/README.md +121 -0
- data/Rakefile +7 -0
- data/lib/array_series.rb +53 -0
- data/lib/hash_series.rb +36 -0
- data/lib/zero_fill.rb +95 -0
- data/spec/integration_spec.rb +106 -0
- data/spec/spec_helper.rb +27 -0
- data/zero_fill.gemspec +19 -0
- metadata +84 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 230c97d7f63d983b8a950e92e3fc5fb5d5af681b
|
4
|
+
data.tar.gz: 8dbcb7cdf4fb7353ab9679537c96b00b4cd00e3b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f84736c91adeea9ae4f2382409355e8d21c5012aa1bbbc4d9ef4e8c761e960f832b7c525989a045169ccb1be0a63c96e487df49ba632bc47490b48caf35542fb
|
7
|
+
data.tar.gz: 17e3731d76e0c888229ab4585641212a38c436150f8e7113f1016645b1100d85070e03ba1a9eb726d6367aaa1881b9d61f594003bfe8d39498cd9f5b3267cfe8
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
GEM
|
2
|
+
remote: https://rubygems.org/
|
3
|
+
specs:
|
4
|
+
diff-lcs (1.2.5)
|
5
|
+
rake (10.1.0)
|
6
|
+
rspec (2.14.1)
|
7
|
+
rspec-core (~> 2.14.0)
|
8
|
+
rspec-expectations (~> 2.14.0)
|
9
|
+
rspec-mocks (~> 2.14.0)
|
10
|
+
rspec-core (2.14.7)
|
11
|
+
rspec-expectations (2.14.4)
|
12
|
+
diff-lcs (>= 1.1.3, < 2.0)
|
13
|
+
rspec-mocks (2.14.4)
|
14
|
+
|
15
|
+
PLATFORMS
|
16
|
+
ruby
|
17
|
+
|
18
|
+
DEPENDENCIES
|
19
|
+
rake
|
20
|
+
rspec (~> 2.14.1)
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2013 MOBI Wireless Management
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
ZeroFill
|
2
|
+
=====
|
3
|
+
|
4
|
+
ZeroFill makes it easy to add any missing dates to a series of dates. Popular use cases include calendars and charts with no data for some dates.
|
5
|
+
|
6
|
+
Compatible with Ruby 1.9.3 and 2.0.0 (and has no dependencies!). Untested in 1.8.7 but should work.
|
7
|
+
|
8
|
+
Example
|
9
|
+
------
|
10
|
+
|
11
|
+
For instance, say you want to output some info for these days:
|
12
|
+
|
13
|
+
```
|
14
|
+
July 29: 10
|
15
|
+
July 31: 7
|
16
|
+
August 2: 3
|
17
|
+
```
|
18
|
+
Wait - what about July 30 and August 1, the days missing from that list? ZeroFill can help!
|
19
|
+
|
20
|
+
```
|
21
|
+
July 29: 10
|
22
|
+
July 30: 0
|
23
|
+
July 31: 7
|
24
|
+
August 1: 0
|
25
|
+
August 2: 3
|
26
|
+
```
|
27
|
+
Voila! You have a series of 5 dates with zeros added for the missing dates.
|
28
|
+
|
29
|
+
Usage
|
30
|
+
====
|
31
|
+
|
32
|
+
__Simply pass a series (array or hash) into__ `ZeroFill.by_date()`
|
33
|
+
|
34
|
+
1. Pass a __hash__ of pairs of Dates (or DateTimes) and content (a string, integer, or whatever!):
|
35
|
+
```ruby
|
36
|
+
myDates = {
|
37
|
+
Date.parse("2013-07-29") => 10, #Monday
|
38
|
+
Date.parse("2013-07-31") => 7, #Wednesday
|
39
|
+
Date.parse("2013-08-02") => 3 #Friday
|
40
|
+
}
|
41
|
+
ZeroFill.by_date(myDates)
|
42
|
+
```
|
43
|
+
|
44
|
+
2. Or, pass an __array of hashes__. Each hash includes a Date or DateTime object and the value. _Note: the name of the keys in the hash are irrelevant as long as they are consistent throughout the array. ZeroFill automatically detects which key represents a Date/DateTime object_
|
45
|
+
```ruby
|
46
|
+
myDates = [
|
47
|
+
{ date: Date.parse("2013-07-31"), content: "My Birthday" },
|
48
|
+
{ date: Date.parse("2013-07-14"), content: "Movie Night" }
|
49
|
+
]
|
50
|
+
ZeroFill.by_date(myDates)
|
51
|
+
```
|
52
|
+
|
53
|
+
Get fancy with options:
|
54
|
+
--------------------------
|
55
|
+
|
56
|
+
1. Return all dates for any __months__ represented in your date series:
|
57
|
+
```ruby
|
58
|
+
myDates = [
|
59
|
+
{ date: Date.parse("2013-07-31"), content: "My Birthday" },
|
60
|
+
{ date: Date.parse("2013-08-13"), content: "First day of class" }
|
61
|
+
]
|
62
|
+
ZeroFill.by_date(myDates, includes: :month)
|
63
|
+
=> All dates in July & August
|
64
|
+
```
|
65
|
+
|
66
|
+
1. Return all dates for any __weeks__ represented in your date series:
|
67
|
+
```ruby
|
68
|
+
myDates = [
|
69
|
+
{ date: Date.parse("2013-07-31"), content: "My Birthday" }
|
70
|
+
]
|
71
|
+
ZeroFill.by_date(myDates, includes: :week)
|
72
|
+
=> All dates in the week of Saturday, July 28 to Sunday, August 3
|
73
|
+
```
|
74
|
+
|
75
|
+
1. __Sort dates__ from latest to earliest (Default is ascending - earliest to latest)
|
76
|
+
```ruby
|
77
|
+
ZeroFill.by_date(myDates, order: :descending)
|
78
|
+
```
|
79
|
+
|
80
|
+
1. __Change the default value__ of Zero Filled dates (Default is 0)
|
81
|
+
```ruby
|
82
|
+
ZeroFill.by_date(myDates, default_value: "Nothing Found!")
|
83
|
+
=> All missing dates' values are populated with "Nothing Found"
|
84
|
+
```
|
85
|
+
|
86
|
+
1. __Specify the start date__ of returned dates. For instance, to return dates starting with July 10:
|
87
|
+
```ruby
|
88
|
+
ZeroFill.by_date(myDates, start_at: Date.parse("2013-07-10"))
|
89
|
+
=> Returns dates from July 10 until the latest date in your series.
|
90
|
+
```
|
91
|
+
|
92
|
+
1. __Specify the end date__ of returned dates. For instance, to return dates ending with August 7:
|
93
|
+
```ruby
|
94
|
+
ZeroFill.by_date(myDates, end_at: Date.parse("2013-08-07"))
|
95
|
+
=> Returns dates from earliest date in your series through August 7
|
96
|
+
```
|
97
|
+
|
98
|
+
TODOs
|
99
|
+
====
|
100
|
+
|
101
|
+
* by_hour option - allow ZeroFill of hours. Include full-day support (like month option for by_date)
|
102
|
+
* by_month option - ZeroFill by month including support for full-year
|
103
|
+
* Support passing date strings instead of date objects
|
104
|
+
* Date padding option: Allow padding of the results by X days (i.e. show 3 days after the end of the series)
|
105
|
+
|
106
|
+
Contributions
|
107
|
+
=====
|
108
|
+
Knock out TODOs, add support for more input types, more formatting options, etc.
|
109
|
+
|
110
|
+
1. Fork the repo
|
111
|
+
1. Create a branch with a thoughtful name
|
112
|
+
1. Hack away
|
113
|
+
1. Add tests
|
114
|
+
1. Make sure the tests pass by running `rake`
|
115
|
+
1. Document any new options in the README
|
116
|
+
1. Squash your commits into logical groups
|
117
|
+
1. Submit a pull request and we'll see what happens!
|
118
|
+
|
119
|
+
Credits
|
120
|
+
=====
|
121
|
+
Copyright (c) 2013, developed and maintained by [MOBI Wireless Management](http://www.mobiwm.com/), and is released under the open MIT License. See the LICENSE file in this repository for details.
|
data/Rakefile
ADDED
data/lib/array_series.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
class ZeroFill::ArraySeries < ZeroFill
|
2
|
+
|
3
|
+
private #######################################################################
|
4
|
+
|
5
|
+
def initialize(series, options={})
|
6
|
+
@new_series = []
|
7
|
+
setup(series, options)
|
8
|
+
end
|
9
|
+
|
10
|
+
def validate_data_structure
|
11
|
+
arr = @series.sample
|
12
|
+
raise TypeError, "Array elements must be hashes" unless arr.is_a? Hash
|
13
|
+
raise TypeError, "Array elements must be hashes with two key/value pairs (a date and metadata)" unless arr.length == 2
|
14
|
+
@date_key, @info_key = if arr.values.first.kind_of?(Date)
|
15
|
+
[arr.keys.first, arr.keys.last]
|
16
|
+
elsif arr.values.kind_of?(Date)
|
17
|
+
[arr.keys.last, arr.keys.first]
|
18
|
+
else
|
19
|
+
raise TypeError, "No date object found for #{arr.inspect}"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def set_new_series_date_value!(current_date)
|
24
|
+
matching_date = between_input_series?(current_date) ? date_values.detect{|c| c[@date_key] == current_date} : nil
|
25
|
+
@new_series << {
|
26
|
+
@date_key => current_date,
|
27
|
+
@info_key => (matching_date ? matching_date[@info_key] : @options[:default_value])
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
def sort_series!
|
32
|
+
@series.sort!{|a,b| a[@date_key] <=> b[@date_key] }
|
33
|
+
end
|
34
|
+
|
35
|
+
def reverse_series!
|
36
|
+
@new_series.reverse!
|
37
|
+
end
|
38
|
+
|
39
|
+
def first_date
|
40
|
+
@first_date ||= @series.empty? ? nil : @series.first[@date_key]
|
41
|
+
end
|
42
|
+
|
43
|
+
def last_date
|
44
|
+
@last_date ||= @series.empty? ? nil : @series.last[@date_key]
|
45
|
+
end
|
46
|
+
|
47
|
+
def date_values
|
48
|
+
@date_values ||= @series.each do |day|
|
49
|
+
day[@date_key] = day[@date_key].to_date
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
data/lib/hash_series.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
class ZeroFill::HashSeries < ZeroFill
|
2
|
+
|
3
|
+
private #######################################################################
|
4
|
+
|
5
|
+
def initialize(series, options={})
|
6
|
+
@new_series = {}
|
7
|
+
setup(series, options)
|
8
|
+
end
|
9
|
+
|
10
|
+
def validate_data_structure
|
11
|
+
first_key = @series.keys.first
|
12
|
+
raise TypeError, "Hash keys must be a Date or DateTime" unless first_key.kind_of?(Date)
|
13
|
+
end
|
14
|
+
|
15
|
+
def set_new_series_date_value!(current_date)
|
16
|
+
matching_date = @series[current_date]
|
17
|
+
@new_series[current_date] = matching_date || @options[:default_value]
|
18
|
+
end
|
19
|
+
|
20
|
+
def sort_series!
|
21
|
+
@series = Hash[@series.sort{|a,b| a[0] <=> b[0] }]
|
22
|
+
end
|
23
|
+
|
24
|
+
def reverse_series!
|
25
|
+
@new_series = Hash[@new_series.to_a.reverse]
|
26
|
+
end
|
27
|
+
|
28
|
+
def first_date
|
29
|
+
@first_date ||= @series.empty? ? nil : @series.keys.first
|
30
|
+
end
|
31
|
+
|
32
|
+
def last_date
|
33
|
+
@last_date ||= @series.empty? ? nil : @series.keys.last
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
data/lib/zero_fill.rb
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
require "date"
|
2
|
+
class ZeroFill
|
3
|
+
|
4
|
+
# by_date is a factory
|
5
|
+
def self.by_date(series, options={})
|
6
|
+
return series if series.empty? && !date_options_present?(options)
|
7
|
+
|
8
|
+
if series.is_a? Hash
|
9
|
+
zf = ZeroFill::HashSeries.new(series, options)
|
10
|
+
elsif series.is_a? Array
|
11
|
+
zf = ZeroFill::ArraySeries.new(series, options)
|
12
|
+
else
|
13
|
+
raise TypeError, "Date series must be a hash or array"
|
14
|
+
end
|
15
|
+
zf.series_by_date
|
16
|
+
end
|
17
|
+
|
18
|
+
def series_by_date
|
19
|
+
populate_new_series
|
20
|
+
reverse_series! if @options[:order].to_sym == :descending
|
21
|
+
@new_series
|
22
|
+
end
|
23
|
+
|
24
|
+
private #######################################################################
|
25
|
+
|
26
|
+
def initialize(series, options={})
|
27
|
+
raise NotImplementedError, "Use the ZeroFill.by_date factory"
|
28
|
+
end
|
29
|
+
|
30
|
+
def setup(series, options)
|
31
|
+
@series = series
|
32
|
+
unless @series.empty?
|
33
|
+
validate_data_structure
|
34
|
+
sort_series!
|
35
|
+
end
|
36
|
+
validate_date_options(options)
|
37
|
+
|
38
|
+
@options = {
|
39
|
+
order: :ascending,
|
40
|
+
start_at: first_date,
|
41
|
+
end_at: last_date,
|
42
|
+
default_value: 0
|
43
|
+
}.merge(options)
|
44
|
+
|
45
|
+
set_range_series if @options[:includes]
|
46
|
+
end
|
47
|
+
|
48
|
+
def between_input_series?(current_date)
|
49
|
+
@series.empty? || (current_date >= first_date && current_date <= last_date)
|
50
|
+
end
|
51
|
+
|
52
|
+
def set_range_series
|
53
|
+
include_full_months_for_date_range if @options[:includes].to_sym == :month
|
54
|
+
include_full_weeks_for_date_range if @options[:includes].to_sym == :week
|
55
|
+
end
|
56
|
+
|
57
|
+
def include_full_months_for_date_range
|
58
|
+
@options[:start_at] = Date.civil(first_date.year, first_date.month, 1)
|
59
|
+
@options[:end_at] = Date.civil(last_date.year, last_date.month, -1) # -1 gives us the last day of the month
|
60
|
+
end
|
61
|
+
|
62
|
+
def include_full_weeks_for_date_range
|
63
|
+
# Wednesday 2013-04-19 is the 3rd day of the week
|
64
|
+
# So, 2013-04-19 minus 3 (days) returns the previous Sunday
|
65
|
+
day_of_week = first_date.wday
|
66
|
+
@options[:start_at] = first_date - day_of_week
|
67
|
+
|
68
|
+
# Thursday, 2013-04-20 is the 4th day of the week
|
69
|
+
# There are 6 days in the week (zero indexed). So, 6 minus 4 = 2 days until Saturday. So add 2 to the date to get the next Saturday
|
70
|
+
day_of_week = last_date.wday
|
71
|
+
@options[:end_at] = last_date + (6 - day_of_week)
|
72
|
+
end
|
73
|
+
|
74
|
+
def populate_new_series
|
75
|
+
(@options[:start_at].to_date..@options[:end_at].to_date).each do |current_date|
|
76
|
+
set_new_series_date_value!(current_date)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def date_options_present?(options)
|
81
|
+
ZeroFill.date_options_present?(options)
|
82
|
+
end
|
83
|
+
|
84
|
+
def self.date_options_present?(options)
|
85
|
+
!options[:start_at].nil? && !options[:end_at].nil?
|
86
|
+
end
|
87
|
+
|
88
|
+
def validate_date_options(options)
|
89
|
+
raise ArgumentError, "Start At Date cannot be after End At Date" if date_options_present?(options) && (options[:start_at] > options[:end_at])
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
require "hash_series"
|
95
|
+
require "array_series"
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Arguments" do
|
4
|
+
it "series can accept an array of hashes" do
|
5
|
+
ZeroFill.by_date(series_array_of_hashes).count.should == 6
|
6
|
+
end
|
7
|
+
|
8
|
+
it "series can accept a hash of key/value pairs" do
|
9
|
+
ZeroFill.by_date(series_hash).count.should == 6
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should return an empty hash/array if it receives an empty series" do
|
13
|
+
ZeroFill.by_date({}).should == {}
|
14
|
+
ZeroFill.by_date([]).should == []
|
15
|
+
ZeroFill.by_date([], :start_at => Date.today).should == []
|
16
|
+
ZeroFill.by_date([], :end_at => Date.today).should == []
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should reject invalid series input" do
|
20
|
+
expect { ZeroFill.by_date([["herp"]]) }.to raise_exception TypeError
|
21
|
+
expect { ZeroFill.by_date([{:herp => "derp"}]) }.to raise_exception TypeError
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "Results" do
|
27
|
+
it "should properly sort dates ascending (default behavior)" do
|
28
|
+
ZeroFill.by_date(series_array_of_hashes).map{|hash| hash[:date].to_s }.should == [
|
29
|
+
"2013-07-27", "2013-07-28", "2013-07-29", "2013-07-30", "2013-07-31", "2013-08-01"
|
30
|
+
]
|
31
|
+
ZeroFill.by_date(series_hash).keys.map(&:to_s).should == [
|
32
|
+
"2013-07-27", "2013-07-28", "2013-07-29", "2013-07-30", "2013-07-31", "2013-08-01"
|
33
|
+
]
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should return values for each date" do
|
37
|
+
series = ZeroFill.by_date(series_hash)
|
38
|
+
series[Date.parse("2013-07-27")].should == 10
|
39
|
+
series[Date.parse("2013-07-28")].should == 0
|
40
|
+
series[Date.parse("2013-08-01")].should == 7
|
41
|
+
|
42
|
+
series = ZeroFill.by_date(series_array_of_hashes_string_values)
|
43
|
+
series.first[:comida].should == "paella"
|
44
|
+
series.last[:comida].should == "tamale"
|
45
|
+
series[1][:comida].should == 0
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "Options" do
|
50
|
+
it "should return calendar months for included dates" do
|
51
|
+
month_series = ZeroFill.by_date(series_array_of_hashes, includes: :month)
|
52
|
+
month_series.count.should == 62
|
53
|
+
month_series.first[:date].to_s.should == "2013-07-01"
|
54
|
+
month_series.last[:date].to_s.should == "2013-08-31"
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should return calendar weeks for included dates" do
|
58
|
+
week_series = ZeroFill.by_date(series_array_of_hashes, includes: :week)
|
59
|
+
week_series.count.should == 14
|
60
|
+
week_series.first[:date].to_s.should == "2013-07-21"
|
61
|
+
week_series.last[:date].to_s.should == "2013-08-03"
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
it "should allow missing dates to have a custom default value" do
|
66
|
+
series = ZeroFill.by_date(series_array_of_hashes_string_values, default_value: "order pizza")
|
67
|
+
series[1][:comida].should == "order pizza"
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should create dates starting with the start_at date" do
|
71
|
+
start_date = Date.parse("2013-07-26")
|
72
|
+
array_series = ZeroFill.by_date(series_array_of_hashes, start_at: start_date)
|
73
|
+
array_series.count.should == 7
|
74
|
+
array_series.first[:date].should == start_date
|
75
|
+
|
76
|
+
hash_series = ZeroFill.by_date(series_hash, start_at: start_date)
|
77
|
+
hash_series.count.should == 7
|
78
|
+
hash_series.keys.first.should == start_date
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should create dates through the end_at date" do
|
82
|
+
end_date = Date.parse("2013-08-10")
|
83
|
+
|
84
|
+
array_series = ZeroFill.by_date(series_array_of_hashes, end_at: end_date)
|
85
|
+
array_series.count.should == 15
|
86
|
+
array_series.last[:date].to_s.should == end_date.to_s
|
87
|
+
|
88
|
+
hash_series = ZeroFill.by_date(series_hash, end_at: end_date)
|
89
|
+
hash_series.count.should == 15
|
90
|
+
hash_series.keys.last.to_s.should == end_date.to_s
|
91
|
+
end
|
92
|
+
|
93
|
+
it "should accept a start_at and end_at date with an empty series" do
|
94
|
+
ZeroFill.by_date([], start_at: Date.parse("2013-07-01"), end_at: Date.parse("2013-07-30")).count.should == 30
|
95
|
+
ZeroFill.by_date({}, start_at: Date.parse("2013-07-01"), end_at: Date.parse("2013-07-30")).count.should == 30
|
96
|
+
end
|
97
|
+
|
98
|
+
it "should be able to sort series dates descending" do
|
99
|
+
ZeroFill.by_date(series_array_of_hashes, order: :descending).map{|hash| hash[:date].to_s }.should == [
|
100
|
+
"2013-08-01", "2013-07-31", "2013-07-30", "2013-07-29", "2013-07-28", "2013-07-27"
|
101
|
+
]
|
102
|
+
ZeroFill.by_date(series_hash, order: :descending).keys.map{|date| date.to_s }.should == [
|
103
|
+
"2013-08-01", "2013-07-31", "2013-07-30", "2013-07-29", "2013-07-28", "2013-07-27"
|
104
|
+
]
|
105
|
+
end
|
106
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler/setup'
|
3
|
+
require 'zero_fill'
|
4
|
+
|
5
|
+
def series_array_of_hashes
|
6
|
+
@series_array_of_hashes ||= [
|
7
|
+
{ date: Date.parse("2013-07-27"), count: 10 },
|
8
|
+
{ date: Date.parse("2013-08-01"), count: 7 },
|
9
|
+
{ date: Date.parse("2013-07-30"), count: 3 }
|
10
|
+
]
|
11
|
+
end
|
12
|
+
|
13
|
+
def series_array_of_hashes_string_values
|
14
|
+
@series_array_of_hashes ||= [
|
15
|
+
{ dia: Date.parse("2013-07-27"), comida: "paella" },
|
16
|
+
{ dia: Date.parse("2013-08-01"), comida: "tamale" },
|
17
|
+
{ dia: Date.parse("2013-07-30"), comida: "fajita" }
|
18
|
+
]
|
19
|
+
end
|
20
|
+
|
21
|
+
def series_hash
|
22
|
+
@date_list_hash ||= {
|
23
|
+
Date.parse("2013-07-27") => 10,
|
24
|
+
Date.parse("2013-08-01") => 7,
|
25
|
+
Date.parse("2013-07-30") => 3
|
26
|
+
}
|
27
|
+
end
|
data/zero_fill.gemspec
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
Gem::Specification.new do |spec|
|
3
|
+
spec.name = 'zero_fill'
|
4
|
+
spec.version = '0.2.0'
|
5
|
+
spec.authors = ['MOBI Wireless Management', 'Steve Hodges']
|
6
|
+
spec.email = 'gems@mobiwm.com'
|
7
|
+
spec.homepage = 'https://github.com/mobi/zerofill'
|
8
|
+
spec.summary = 'Adds missing dates in a series of dates'
|
9
|
+
spec.description = 'Add missing dates from a date series, such as days in a month.'
|
10
|
+
spec.license = 'MIT'
|
11
|
+
spec.required_ruby_version = '>= 1.9.3'
|
12
|
+
|
13
|
+
spec.files = `git ls-files`.split("\n")
|
14
|
+
spec.test_files = `git ls-files -- {spec}/*`.split("\n")
|
15
|
+
|
16
|
+
spec.add_development_dependency 'rake'
|
17
|
+
spec.add_development_dependency 'rspec', '~>2.14.1'
|
18
|
+
spec.require_paths = ['lib']
|
19
|
+
end
|
metadata
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: zero_fill
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- MOBI Wireless Management
|
8
|
+
- Steve Hodges
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2014-01-15 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rake
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - '>='
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '0'
|
21
|
+
type: :development
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - '>='
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '0'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: rspec
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ~>
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: 2.14.1
|
35
|
+
type: :development
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ~>
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: 2.14.1
|
42
|
+
description: Add missing dates from a date series, such as days in a month.
|
43
|
+
email: gems@mobiwm.com
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- .gitignore
|
49
|
+
- Gemfile
|
50
|
+
- Gemfile.lock
|
51
|
+
- LICENSE
|
52
|
+
- README.md
|
53
|
+
- Rakefile
|
54
|
+
- lib/array_series.rb
|
55
|
+
- lib/hash_series.rb
|
56
|
+
- lib/zero_fill.rb
|
57
|
+
- spec/integration_spec.rb
|
58
|
+
- spec/spec_helper.rb
|
59
|
+
- zero_fill.gemspec
|
60
|
+
homepage: https://github.com/mobi/zerofill
|
61
|
+
licenses:
|
62
|
+
- MIT
|
63
|
+
metadata: {}
|
64
|
+
post_install_message:
|
65
|
+
rdoc_options: []
|
66
|
+
require_paths:
|
67
|
+
- lib
|
68
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
69
|
+
requirements:
|
70
|
+
- - '>='
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: 1.9.3
|
73
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
requirements: []
|
79
|
+
rubyforge_project:
|
80
|
+
rubygems_version: 2.1.9
|
81
|
+
signing_key:
|
82
|
+
specification_version: 4
|
83
|
+
summary: Adds missing dates in a series of dates
|
84
|
+
test_files: []
|