timely 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +13 -0
- data/HISTORY.md +3 -0
- data/LICENSE +21 -0
- data/README.md +55 -0
- data/Rakefile +150 -4
- data/lib/timely/date.rb +3 -3
- data/lib/timely/date_chooser.rb +98 -0
- data/lib/timely/date_range.rb +51 -0
- data/lib/timely/date_time.rb +11 -0
- data/lib/timely/rails/date_group.rb +115 -0
- data/lib/timely/rails/extensions.rb +43 -0
- data/lib/timely/rails/season.rb +99 -0
- data/lib/timely/rails.rb +4 -0
- data/lib/timely/range.rb +15 -0
- data/lib/timely/string.rb +25 -0
- data/lib/timely/temporal_patterns.rb +441 -0
- data/lib/timely/time.rb +5 -4
- data/lib/timely/trackable_date_set.rb +148 -0
- data/lib/timely/week_days.rb +128 -0
- data/lib/timely.rb +15 -6
- data/rails/init.rb +1 -0
- data/spec/date_chooser_spec.rb +101 -0
- data/spec/date_group_spec.rb +26 -0
- data/spec/date_range_spec.rb +40 -0
- data/spec/date_spec.rb +15 -15
- data/spec/schema.rb +11 -0
- data/spec/season_spec.rb +68 -0
- data/spec/spec_helper.rb +41 -18
- data/spec/string_spec.rb +13 -0
- data/spec/time_spec.rb +28 -9
- data/spec/trackable_date_set_spec.rb +80 -0
- data/spec/week_days_spec.rb +51 -0
- data/timely.gemspec +99 -0
- metadata +61 -61
- data/History.txt +0 -4
- data/License.txt +0 -20
- data/Manifest.txt +0 -23
- data/README.txt +0 -31
- data/config/hoe.rb +0 -73
- data/config/requirements.rb +0 -15
- data/lib/timely/version.rb +0 -9
- data/script/console +0 -10
- data/script/destroy +0 -14
- data/script/generate +0 -14
- data/setup.rb +0 -1585
- data/spec/spec.opts +0 -1
- data/tasks/deployment.rake +0 -34
- data/tasks/environment.rake +0 -7
- data/tasks/rspec.rake +0 -21
- data/tasks/website.rake +0 -9
@@ -0,0 +1,128 @@
|
|
1
|
+
module Timely
|
2
|
+
class WeekDays
|
3
|
+
WEEKDAY_KEYS = [:sun, :mon, :tue, :wed, :thu, :fri, :sat]
|
4
|
+
|
5
|
+
# Create a new Weekdays object
|
6
|
+
# weekdays can be in three formats
|
7
|
+
# integer representing binary string
|
8
|
+
# e.g. 1 = Sun, 2 = Mon, 3 = Sun + Mon, etc.
|
9
|
+
# hash with symbol keys for :sun, :mon, ... with true/false values
|
10
|
+
# e.g. {:sun => true, :tue => true} is Sunday and Tuesday
|
11
|
+
# Not passing in values is the same as setting them explicitly to true
|
12
|
+
# array with true/false values from sun to sat
|
13
|
+
# e.g. [1, 0, 1, 0, 0, 0, 0] is Sunday and Tuesday
|
14
|
+
def initialize(weekdays)
|
15
|
+
@weekdays = {
|
16
|
+
:sun => false,
|
17
|
+
:mon => false,
|
18
|
+
:tue => false,
|
19
|
+
:wed => false,
|
20
|
+
:thu => false,
|
21
|
+
:fri => false,
|
22
|
+
:sat => false
|
23
|
+
}
|
24
|
+
|
25
|
+
case weekdays
|
26
|
+
when Fixnum
|
27
|
+
# 4 -> 0000100 (binary) -> "0010000" (reversed string) -> {:tue => true}
|
28
|
+
weekdays.to_s(2).reverse.each_char.with_index do |char, index|
|
29
|
+
set_day(index, char == '1')
|
30
|
+
end
|
31
|
+
when Hash
|
32
|
+
weekdays.each_pair do |day, value|
|
33
|
+
set_day(day, value)
|
34
|
+
end
|
35
|
+
when Array
|
36
|
+
weekdays.each.with_index do |value, index|
|
37
|
+
set_day(index, value)
|
38
|
+
end
|
39
|
+
when NilClass
|
40
|
+
@weekdays = {
|
41
|
+
:sun => true,
|
42
|
+
:mon => true,
|
43
|
+
:tue => true,
|
44
|
+
:wed => true,
|
45
|
+
:thu => true,
|
46
|
+
:fri => true,
|
47
|
+
:sat => true
|
48
|
+
}
|
49
|
+
else
|
50
|
+
raise ArgumentError, "You must initialize with an Fixnum, Hash or Array"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# Set the weekday on or off
|
55
|
+
# weekdays[:mon] = true
|
56
|
+
# weekdays[:tue] = false
|
57
|
+
# set ideally will be true, but 'true', 1 and '1' are accepted
|
58
|
+
# All other values will be treated as false
|
59
|
+
def []=(day, set)
|
60
|
+
set_day(day, set)
|
61
|
+
end
|
62
|
+
|
63
|
+
def set_day(day, set)
|
64
|
+
key = if day.is_a?(Fixnum)
|
65
|
+
WEEKDAY_KEYS[day]
|
66
|
+
elsif day.is_a?(String)
|
67
|
+
day.to_sym
|
68
|
+
else
|
69
|
+
day
|
70
|
+
end
|
71
|
+
raise ArgumentError, "Invalid week day index #{key}" unless WEEKDAY_KEYS.include?(key)
|
72
|
+
@weekdays[key] = [true, 'true', 1, '1'].include?(set)
|
73
|
+
end
|
74
|
+
|
75
|
+
def applies_for_date?(date)
|
76
|
+
has_day?(date.wday)
|
77
|
+
end
|
78
|
+
|
79
|
+
# Determine if weekdays has day selected
|
80
|
+
# Accepts either symbol or integer
|
81
|
+
# e.g. :sun or 0 = Sunday, :sat or 6 = Saturday
|
82
|
+
def has_day?(weekday)
|
83
|
+
weekday = WEEKDAY_KEYS[weekday] if weekday.is_a?(Fixnum)
|
84
|
+
@weekdays[weekday]
|
85
|
+
end
|
86
|
+
|
87
|
+
def number_of_occurances_in(range)
|
88
|
+
range.inject(0) do |count, date|
|
89
|
+
applies_for_date?(date) ? count+1 : count
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# Returns true if all days are selected
|
94
|
+
def all_days?
|
95
|
+
@weekdays.all?{|day, selected| selected}
|
96
|
+
end
|
97
|
+
|
98
|
+
# Returns array of weekday selected
|
99
|
+
# e.g. [:sun, :sat]
|
100
|
+
def weekdays
|
101
|
+
selected = @weekdays.select{|day, selected| selected}
|
102
|
+
# Ruby 1.8 returns an array for Hash#select and loses order
|
103
|
+
selected.is_a?(Hash) ? selected.keys : selected.map(&:first).sort_by{|v| WEEKDAY_KEYS.index(v)}
|
104
|
+
end
|
105
|
+
|
106
|
+
# Returns comma separated and capitalized in Sun-Sat order
|
107
|
+
# e.g. 'Mon, Tue, Wed' or 'Sat' or 'Sun, Sat'
|
108
|
+
def to_s
|
109
|
+
days = weekdays.map{|day| day.to_s.capitalize}
|
110
|
+
last_day = days.pop
|
111
|
+
|
112
|
+
days.empty? ? last_day : days.join(", ") + ", and " + last_day
|
113
|
+
end
|
114
|
+
|
115
|
+
# 7 bits encoded in decimal number
|
116
|
+
# 0th bit = Sunday, 6th bit = Saturday
|
117
|
+
# Value of 127 => all days are on
|
118
|
+
def weekdays_int
|
119
|
+
int = 0
|
120
|
+
WEEKDAY_KEYS.each.with_index do |day, index|
|
121
|
+
int += 2 ** index if @weekdays[day]
|
122
|
+
end
|
123
|
+
int
|
124
|
+
end
|
125
|
+
|
126
|
+
ALL_WEEKDAYS = WeekDays.new(%w(1 1 1 1 1 1 1))
|
127
|
+
end
|
128
|
+
end
|
data/lib/timely.rb
CHANGED
@@ -1,8 +1,17 @@
|
|
1
|
-
$:.unshift(File.dirname(__FILE__)) unless
|
2
|
-
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
3
|
-
|
4
1
|
module Timely
|
5
|
-
|
2
|
+
VERSION = '0.0.2'
|
6
3
|
|
7
|
-
require '
|
8
|
-
require '
|
4
|
+
require 'time'
|
5
|
+
require 'date'
|
6
|
+
|
7
|
+
require 'timely/string'
|
8
|
+
require 'timely/date'
|
9
|
+
require 'timely/time'
|
10
|
+
require 'timely/date_time'
|
11
|
+
require 'timely/range'
|
12
|
+
require 'timely/date_range'
|
13
|
+
require 'timely/date_chooser'
|
14
|
+
require 'timely/week_days'
|
15
|
+
require 'timely/temporal_patterns'
|
16
|
+
require 'timely/trackable_date_set'
|
17
|
+
end
|
data/rails/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'timely/rails'
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Timely::DateChooser do
|
4
|
+
before(:all) do
|
5
|
+
@from = "01-01-2011".to_date
|
6
|
+
@to = "01-03-2011".to_date
|
7
|
+
end
|
8
|
+
|
9
|
+
#Validation
|
10
|
+
it "rejects blank FROM dates" do
|
11
|
+
lambda { Timely::DateChooser.new({:from=>""}) }.should raise_error(Timely::DateChooserException)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "rejects TO dates later than FROM dates" do
|
15
|
+
lambda {Timely::DateChooser.new(
|
16
|
+
:multiple_dates => true, :from => @from + 10, :to => @from
|
17
|
+
)}.should raise_error(Timely::DateChooserException)
|
18
|
+
end
|
19
|
+
|
20
|
+
#Operation
|
21
|
+
it "returns today if client only wants single date" do
|
22
|
+
Timely::DateChooser.new(
|
23
|
+
:multiple_dates => false, :from => @from
|
24
|
+
).choose_dates.should == [@from]
|
25
|
+
end
|
26
|
+
|
27
|
+
#Test specific date of month
|
28
|
+
it "returns from and to as same (one) day in the case that only from date is given" do
|
29
|
+
Timely::DateChooser.new(
|
30
|
+
:multiple_dates => true, :from => @from, :to => ''
|
31
|
+
).choose_dates.should == [@from]
|
32
|
+
end
|
33
|
+
|
34
|
+
it "returns all days between from and to days in the basic case" do
|
35
|
+
Timely::DateChooser.new(
|
36
|
+
:multiple_dates => true, :from => @from, :to => @to
|
37
|
+
).choose_dates.should == (@from..@to).to_a
|
38
|
+
end
|
39
|
+
|
40
|
+
it "returns the specific dates if this option is picked" do
|
41
|
+
Timely::DateChooser.new(
|
42
|
+
:multiple_dates => true, :select => 'days', :dates => '1,11,3', :from => @from, :to => @to
|
43
|
+
).choose_dates.should == [
|
44
|
+
"1-01-2011", "3-01-2011", "11-01-2011", "1-02-2011",
|
45
|
+
"3-02-2011", "11-02-2011", "1-03-2011"
|
46
|
+
].map(&:to_date)
|
47
|
+
end
|
48
|
+
|
49
|
+
#Test days of week, every X weeks
|
50
|
+
it "returns every sunday correctly" do
|
51
|
+
Timely::DateChooser.new(
|
52
|
+
:multiple_dates => true, :select => 'weekdays', :from => @from, :to => @to,
|
53
|
+
:interval => {:level => "1", :unit => "w"}, :weekdays => {:sun => true}
|
54
|
+
).choose_dates.should == [
|
55
|
+
"2-01-2011", "9-01-2011", "16-01-2011", "23-01-2011", "30-01-2011",
|
56
|
+
"06-02-2011", "13-02-2011", "20-02-2011", "27-02-2011"
|
57
|
+
].map(&:to_date)
|
58
|
+
end
|
59
|
+
|
60
|
+
it "returns every thursday and sunday correctly" do
|
61
|
+
Timely::DateChooser.new(
|
62
|
+
:multiple_dates => true, :select => 'weekdays',
|
63
|
+
:interval => {:level => "1", :unit => "w"},
|
64
|
+
:weekdays => {:sun => true, :thu => true}, :from => @from, :to => @to
|
65
|
+
).choose_dates.should == [
|
66
|
+
"2-01-2011", "6-01-2011", "9-01-2011", "13-01-2011", "16-01-2011",
|
67
|
+
"20-01-2011", "23-01-2011", "27-01-2011", "30-01-2011", "3-02-2011",
|
68
|
+
"06-02-2011", "10-02-2011", "13-02-2011", "17-02-2011", "20-02-2011",
|
69
|
+
"24-02-2011", "27-02-2011"
|
70
|
+
].map(&:to_date)
|
71
|
+
end
|
72
|
+
|
73
|
+
it "returns every 2nd thursday and sunday correctly" do
|
74
|
+
Timely::DateChooser.new(
|
75
|
+
:multiple_dates => true, :select => 'weekdays',
|
76
|
+
:interval => {:level => "2", :unit => "w"},
|
77
|
+
:weekdays => {:sun => "1", :thu => "1"}, :from => @from, :to => @to
|
78
|
+
).choose_dates.should == [
|
79
|
+
"2-01-2011", "6-01-2011", "16-01-2011", "20-01-2011", "30-01-2011",
|
80
|
+
"3-02-2011", "13-02-2011", "17-02-2011", "27-02-2011"
|
81
|
+
].map(&:to_date)
|
82
|
+
end
|
83
|
+
|
84
|
+
#Test correct results for every Nth week of month
|
85
|
+
it "returns every 1st Tuesday" do
|
86
|
+
Timely::DateChooser.new(
|
87
|
+
:multiple_dates => true, :select => 'weekdays', :from => @from, :to => @to,
|
88
|
+
:interval => {:level => "1", :unit => "wom"}, :weekdays => {:tue => true}
|
89
|
+
).choose_dates.should == ["4-01-2011", "1-02-2011", "1-03-2011"].map(&:to_date)
|
90
|
+
end
|
91
|
+
|
92
|
+
it "returns every 3st Monday and Friday" do
|
93
|
+
Timely::DateChooser.new(
|
94
|
+
:multiple_dates => true, :select => 'weekdays',
|
95
|
+
:interval => {:level => "3", :unit => "wom"},
|
96
|
+
:weekdays => {:mon => true, :fri => true}, :from => @from, :to => @to
|
97
|
+
).choose_dates.should == [
|
98
|
+
"17-01-2011", "21-01-2011", "18-02-2011", "21-02-2011"
|
99
|
+
].map(&:to_date)
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
describe Timely::DateGroup do
|
3
|
+
before do
|
4
|
+
@date_group = Timely::DateGroup.create!(
|
5
|
+
:start_date => '2000-01-01', :end_date => '2000-01-03', :weekdays => %w(1 1 1 1 1 1 1)
|
6
|
+
)
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'should detect overlaps' do
|
10
|
+
@date_group.applicable_for_duration?(Timely::DateRange.new('2000-01-01'.to_date, '2000-01-01'.to_date)).should be_true
|
11
|
+
@date_group.applicable_for_duration?(Timely::DateRange.new('2000-01-01'.to_date, '2000-01-06'.to_date)).should be_true
|
12
|
+
@date_group.applicable_for_duration?(Timely::DateRange.new('2001-01-01'.to_date, '2001-01-01'.to_date)).should be_false
|
13
|
+
@date_group.applicable_for_duration?(Timely::DateRange.new('1999-12-29'.to_date, '2000-01-05'.to_date)).should be_true
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should detect overlaps when certain weekdays aren't selected" do
|
17
|
+
@date_group = Timely::DateGroup.create!(
|
18
|
+
:start_date => '2012-01-01', :end_date => '2012-01-07', :weekdays => %w(1 0 1 0 1 0 1)
|
19
|
+
)
|
20
|
+
# Note: 2012-01-1 is a Sunday
|
21
|
+
@date_group.applicable_for_duration?(Timely::DateRange.new('2012-01-01'.to_date, '2012-01-01'.to_date)).should be_true
|
22
|
+
@date_group.applicable_for_duration?(Timely::DateRange.new('2012-01-02'.to_date, '2012-01-02'.to_date)).should be_false
|
23
|
+
@date_group.applicable_for_duration?(Timely::DateRange.new('2012-01-03'.to_date, '2012-01-03'.to_date)).should be_true
|
24
|
+
@date_group.applicable_for_duration?(Timely::DateRange.new('2012-01-01'.to_date, '2012-01-03'.to_date)).should be_true
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Timely::DateRange do
|
4
|
+
|
5
|
+
it "should allow initialization with two dates" do
|
6
|
+
lambda { @date_range = Timely::DateRange.new(Date.today, Date.today + 3) }.should_not raise_error
|
7
|
+
@date_range.start_date.should eql Date.today
|
8
|
+
@date_range.end_date.should eql Date.today + 3
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should allow initialization with one date" do
|
12
|
+
lambda { @date_range = Timely::DateRange.new(Date.today) }.should_not raise_error
|
13
|
+
@date_range.start_date.should eql Date.today
|
14
|
+
@date_range.end_date.should eql Date.today
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should allow initialization with a range" do
|
18
|
+
lambda { @date_range = Timely::DateRange.new(Date.today..Date.today + 3) }.should_not raise_error
|
19
|
+
@date_range.start_date.should eql Date.today
|
20
|
+
@date_range.end_date.should eql Date.today + 3
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should correctly find the interesection between two date ranges" do
|
24
|
+
@date_range = Timely::DateRange.new("2000-01-03".to_date, "2000-01-06".to_date)
|
25
|
+
@date_range.intersecting_dates(Timely::DateRange.new("2000-01-04".to_date, "2000-01-07".to_date)).should == ("2000-01-04".to_date.."2000-01-06".to_date)
|
26
|
+
@date_range.intersecting_dates(Timely::DateRange.new("2000-01-01".to_date, "2000-01-02".to_date)).should == []
|
27
|
+
@date_range.intersecting_dates(Timely::DateRange.new("2000-01-01".to_date, "2000-01-03".to_date)).should == ("2000-01-03".to_date.."2000-01-03".to_date)
|
28
|
+
@date_range.intersecting_dates(Timely::DateRange.new("2000-01-06".to_date, "2000-01-07".to_date)).should == ("2000-01-06".to_date.."2000-01-06".to_date)
|
29
|
+
@date_range.intersecting_dates(Timely::DateRange.new("2000-01-06".to_date, "2000-01-07".to_date)).should == ("2000-01-06".to_date.."2000-01-06".to_date)
|
30
|
+
@date_range.intersecting_dates(Timely::DateRange.new("2000-01-04".to_date, "2000-01-05".to_date)).should == ("2000-01-04".to_date.."2000-01-05".to_date)
|
31
|
+
@date_range.intersecting_dates(Timely::DateRange.new("2000-01-05".to_date, "2000-01-05".to_date)).should == ("2000-01-05".to_date.."2000-01-05".to_date)
|
32
|
+
|
33
|
+
@date_range = Timely::DateRange.new("2000-01-03".to_date, "2000-01-03".to_date)
|
34
|
+
@date_range.intersecting_dates(Timely::DateRange.new("2000-01-04".to_date, "2000-01-07".to_date)).should == []
|
35
|
+
@date_range.intersecting_dates(Timely::DateRange.new("2000-01-01".to_date, "2000-01-03".to_date)).should == ("2000-01-03".to_date.."2000-01-03".to_date)
|
36
|
+
@date_range.intersecting_dates(Timely::DateRange.new("2000-01-03".to_date, "2000-01-05".to_date)).should == ("2000-01-03".to_date.."2000-01-03".to_date)
|
37
|
+
@date_range.intersecting_dates(Timely::DateRange.new("2000-01-02".to_date, "2000-01-04".to_date)).should == ("2000-01-03".to_date.."2000-01-03".to_date)
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
data/spec/date_spec.rb
CHANGED
@@ -1,68 +1,68 @@
|
|
1
|
-
require
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Date do
|
4
4
|
before :each do
|
5
5
|
@date = Date.today - 5
|
6
|
-
|
6
|
+
|
7
7
|
@hour = 1
|
8
8
|
@minute = 2
|
9
9
|
@second = 3
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
it 'should give a time on that date' do
|
13
13
|
@date.should respond_to(:at_time)
|
14
14
|
end
|
15
|
-
|
15
|
+
|
16
16
|
describe 'giving a time on that date' do
|
17
17
|
it 'should accept hour, minute, and second' do
|
18
18
|
lambda { @date.at_time(@hour, @minute, @second) }.should_not raise_error(ArgumentError)
|
19
19
|
end
|
20
|
-
|
20
|
+
|
21
21
|
it 'should accept hour and minute' do
|
22
22
|
lambda { @date.at_time(@hour, @minute) }.should_not raise_error(ArgumentError)
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
25
|
it 'should accept hour' do
|
26
26
|
lambda { @date.at_time(@hour) }.should_not raise_error(ArgumentError)
|
27
27
|
end
|
28
|
-
|
28
|
+
|
29
29
|
it 'should accept no arguments' do
|
30
30
|
lambda { @date.at_time }.should_not raise_error(ArgumentError)
|
31
31
|
end
|
32
|
-
|
32
|
+
|
33
33
|
it 'should return a time for the given hour, minute, and second if all three are specified' do
|
34
34
|
expected = Time.local(@date.year, @date.month, @date.day, @hour, @minute, @second)
|
35
35
|
@date.at_time(@hour, @minute, @second).should == expected
|
36
36
|
end
|
37
|
-
|
37
|
+
|
38
38
|
it 'should default second to 0 if unspecified' do
|
39
39
|
expected = Time.local(@date.year, @date.month, @date.day, @hour, @minute, 0)
|
40
40
|
@date.at_time(@hour, @minute).should == expected
|
41
41
|
end
|
42
|
-
|
42
|
+
|
43
43
|
it 'should default minute to 0 if unspecified' do
|
44
44
|
expected = Time.local(@date.year, @date.month, @date.day, @hour, 0, 0)
|
45
45
|
@date.at_time(@hour).should == expected
|
46
46
|
end
|
47
|
-
|
47
|
+
|
48
48
|
it 'should default hour to 0 if unspecified' do
|
49
49
|
expected = Time.local(@date.year, @date.month, @date.day, 0, 0, 0)
|
50
50
|
@date.at_time.should == expected
|
51
51
|
end
|
52
|
-
|
52
|
+
|
53
53
|
it 'should accept a time' do
|
54
54
|
lambda { @date.at_time(Time.now) }.should_not raise_error(ArgumentError)
|
55
55
|
end
|
56
|
-
|
56
|
+
|
57
57
|
it 'should return the passed-in time on the date' do
|
58
58
|
@time = Time.now - 12345
|
59
59
|
expected = Time.local(@date.year, @date.month, @date.day, @time.hour, @time.min, @time.sec)
|
60
60
|
@date.at_time(@time).should == expected
|
61
61
|
end
|
62
62
|
end
|
63
|
-
|
63
|
+
|
64
64
|
it "should provide 'at' as an alias" do
|
65
|
-
expected =
|
65
|
+
expected = Time.local(@date.year, @date.month, @date.day, @hour, @minute, @second)
|
66
66
|
@date.at(@hour, @minute, @second).should == expected
|
67
67
|
end
|
68
68
|
end
|
data/spec/schema.rb
ADDED
data/spec/season_spec.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Timely::Season, "in general" do
|
4
|
+
before do
|
5
|
+
# 1st and 3rd Quarter
|
6
|
+
@simple_low_season = Timely::Season.new
|
7
|
+
@simple_low_season.date_groups.build(:start_date => '2009-01-01'.to_date, :end_date => '2009-03-31'.to_date)
|
8
|
+
@simple_low_season.date_groups.build(:start_date => '2009-07-01'.to_date, :end_date => '2009-09-30'.to_date)
|
9
|
+
@simple_low_season.save!
|
10
|
+
|
11
|
+
# 2nd and 4th Quarter
|
12
|
+
@simple_high_season = Timely::Season.new
|
13
|
+
@simple_high_season.date_groups.build(:start_date => '2009-04-01'.to_date, :end_date => '2009-06-30'.to_date)
|
14
|
+
@simple_high_season.date_groups.build(:start_date => '2009-10-01'.to_date, :end_date => '2009-12-31'.to_date)
|
15
|
+
@simple_high_season.save!
|
16
|
+
end
|
17
|
+
|
18
|
+
it "be able to tell if a date is in or out of its season" do
|
19
|
+
low_season_date = '2009-02-22'.to_date
|
20
|
+
high_season_date = '2009-04-22'.to_date
|
21
|
+
|
22
|
+
@simple_low_season.includes_date?(low_season_date).should be_true
|
23
|
+
@simple_high_season.includes_date?(low_season_date).should_not be_true
|
24
|
+
|
25
|
+
@simple_low_season.includes_date?(high_season_date).should_not be_true
|
26
|
+
@simple_high_season.includes_date?(high_season_date).should be_true
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should be able to tell the boundary range (the range including the absolute first and last date) of itself" do
|
30
|
+
@simple_low_season.boundary_range.should eql('2009-01-01'.to_date..'2009-09-30'.to_date)
|
31
|
+
@simple_high_season.boundary_range.should eql('2009-04-01'.to_date..'2009-12-31'.to_date)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
describe Timely::Season, 'when asked to build season for given dates' do
|
37
|
+
before do
|
38
|
+
@dates = [Date.current + 1, Date.current + 4, Date.current + 5]
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should generate proper season" do
|
42
|
+
season = Timely::Season.build_season_for(@dates)
|
43
|
+
season.class.should == Timely::Season
|
44
|
+
season.date_groups.size.should == 3
|
45
|
+
season.date_groups.first.start_date.should == (Date.current + 1)
|
46
|
+
season.date_groups.last.start_date.should == (Date.current + 5)
|
47
|
+
season.date_groups.last.end_date.should == (Date.current + 5)
|
48
|
+
@dates = []
|
49
|
+
season = Timely::Season.build_season_for(@dates)
|
50
|
+
season.class.should == Timely::Season
|
51
|
+
season.date_groups.size.should == 0
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
# == Schema Information
|
60
|
+
#
|
61
|
+
# Table name: seasons
|
62
|
+
#
|
63
|
+
# id :integer(4) not null, primary key
|
64
|
+
# name :string(255)
|
65
|
+
# created_at :datetime
|
66
|
+
# updated_at :datetime
|
67
|
+
#
|
68
|
+
|
data/spec/spec_helper.rb
CHANGED
@@ -1,23 +1,46 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
end
|
1
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
2
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
3
|
+
# Require this file using `require "spec_helper.rb"` to ensure that it is only
|
4
|
+
# loaded once.
|
5
|
+
#
|
6
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
8
7
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
require 'rubygems'
|
14
|
-
gem 'mocha'
|
15
|
-
require 'mocha'
|
16
|
-
end
|
8
|
+
require 'rubygems'
|
9
|
+
require 'bundler/setup'
|
10
|
+
require 'active_record'
|
11
|
+
require 'timely/rails'
|
17
12
|
|
18
|
-
|
19
|
-
|
13
|
+
if ENV['COVERAGE']
|
14
|
+
require 'simplecov'
|
15
|
+
require 'simplecov-rcov'
|
16
|
+
SimpleCov.formatter = SimpleCov::Formatter::RcovFormatter
|
17
|
+
SimpleCov.start do
|
18
|
+
add_filter '/vendor/'
|
19
|
+
add_filter '/spec/'
|
20
|
+
add_group 'lib', 'lib'
|
21
|
+
end
|
22
|
+
SimpleCov.at_exit do
|
23
|
+
SimpleCov.result.format!
|
24
|
+
percent = SimpleCov.result.covered_percent
|
25
|
+
unless percent >= 50
|
26
|
+
puts "Coverage must be above 50%. It is #{"%.2f" % percent}%"
|
27
|
+
Kernel.exit(1)
|
28
|
+
end
|
29
|
+
end
|
20
30
|
end
|
21
31
|
|
22
|
-
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
23
32
|
require 'timely'
|
33
|
+
|
34
|
+
DB_FILE = 'tmp/test_db'
|
35
|
+
FileUtils.mkdir_p File.dirname(DB_FILE)
|
36
|
+
FileUtils.rm_f DB_FILE
|
37
|
+
|
38
|
+
ActiveRecord::Base.establish_connection :adapter => 'sqlite3', :database => DB_FILE
|
39
|
+
|
40
|
+
load('spec/schema.rb')
|
41
|
+
|
42
|
+
RSpec.configure do |config|
|
43
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
44
|
+
config.run_all_when_everything_filtered = true
|
45
|
+
config.filter_run :focus
|
46
|
+
end
|
data/spec/string_spec.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe String do
|
4
|
+
it "should convert to date" do
|
5
|
+
"10-2010-01".to_date('%d-%Y-%m').should eql Date.parse("2010-01-10")
|
6
|
+
end
|
7
|
+
|
8
|
+
# Spec currently doesn't work
|
9
|
+
#it 'should handle rails date formats' do
|
10
|
+
# Date::DATE_FORMATS[:db] = '%m-%Y-%d'
|
11
|
+
# "01-2010-10".to_date(:db).should eql Date.parse("2010-01-10")
|
12
|
+
#end
|
13
|
+
end
|
data/spec/time_spec.rb
CHANGED
@@ -1,43 +1,62 @@
|
|
1
|
-
require
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Time do
|
4
|
+
it 'should be able to set date on a time' do
|
5
|
+
xmas = Date.new(2012, 12, 25)
|
6
|
+
lunch_time = Time.parse("12:00")
|
7
|
+
xmas_lunch = lunch_time.on_date(xmas)
|
8
|
+
xmas_lunch.year.should == 2012
|
9
|
+
xmas_lunch.month.should == 12
|
10
|
+
xmas_lunch.day.should == 25
|
11
|
+
xmas_lunch.hour.should == 12
|
12
|
+
xmas_lunch.min.should == 0
|
13
|
+
xmas_lunch.sec.should == 0
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should allow setting the date part given a date" do
|
17
|
+
time = Time.parse("2010-01-01 09:30:00")
|
18
|
+
time.on_date(Date.parse("2012-12-31")).should eql Time.parse("2012-12-31 09:30:00")
|
19
|
+
end
|
20
|
+
end
|
2
21
|
|
3
22
|
describe Time do
|
4
23
|
before :each do
|
5
24
|
@time = Time.now - 12345
|
6
|
-
|
25
|
+
|
7
26
|
@year = 2005
|
8
27
|
@month = 3
|
9
28
|
@day = 15
|
10
29
|
end
|
11
|
-
|
30
|
+
|
12
31
|
it 'should give that time on a date' do
|
13
32
|
@time.should respond_to(:on_date)
|
14
33
|
end
|
15
|
-
|
34
|
+
|
16
35
|
describe 'giving that time on a date' do
|
17
36
|
it 'should accept year, month and day' do
|
18
37
|
lambda { @time.on_date(@year, @month, @day) }.should_not raise_error(ArgumentError)
|
19
38
|
end
|
20
|
-
|
39
|
+
|
21
40
|
it 'should require year, month, and day' do
|
22
41
|
lambda { @time.on_date(@year, @month) }.should raise_error(ArgumentError)
|
23
42
|
end
|
24
|
-
|
43
|
+
|
25
44
|
it 'should return the same time on the specified year, month, and day' do
|
26
45
|
expected = Time.local(@year, @month, @day, @time.hour, @time.min, @time.sec)
|
27
46
|
@time.on_date(@year, @month, @day).should == expected
|
28
47
|
end
|
29
|
-
|
48
|
+
|
30
49
|
it 'should accept a date' do
|
31
50
|
lambda { @time.on_date(Date.today) }.should_not raise_error(ArgumentError)
|
32
51
|
end
|
33
|
-
|
52
|
+
|
34
53
|
it 'should return the same time on the specified date' do
|
35
54
|
@date = Date.today - 2345
|
36
55
|
expected = Time.local(@date.year, @date.month, @date.day, @time.hour, @time.min, @time.sec)
|
37
56
|
@time.on_date(@date).should == expected
|
38
57
|
end
|
39
58
|
end
|
40
|
-
|
59
|
+
|
41
60
|
it "should provide 'on' as an alias" do
|
42
61
|
expected = Time.local(@year, @month, @day, @time.hour, @time.min, @time.sec)
|
43
62
|
@time.on(@year, @month, @day).should == expected
|