time_keeper 0.1.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.
@@ -0,0 +1,21 @@
1
+ module TimeKeeper
2
+ module TimeRangeManipulation
3
+ def split_time_range_by_day(range)
4
+ return [] if range.blank?
5
+ if range.first.to_date < range.last.to_date
6
+ out = []
7
+ current = range.first
8
+ while current.to_i <= range.last.to_i
9
+ eod = current.end_of_day
10
+ eod = range.last if current.to_date == range.last.to_date
11
+ out << (current .. eod)
12
+ current = eod + 1.second
13
+ end
14
+ out
15
+ else
16
+ [range]
17
+ end
18
+ end
19
+ module_function :split_time_range_by_day
20
+ end
21
+ end
@@ -0,0 +1,60 @@
1
+ module TimeKeeper::TimeSpanSupport
2
+ include TimeKeeper::StringMinutesSupport
3
+
4
+ def display
5
+ [
6
+ [
7
+ start_time_string,
8
+ (start_day.to_i > 0) ? "Next Day" : nil,
9
+ ],
10
+ [
11
+ end_time_string,
12
+ (end_day.to_i > 0) ? "Next Day" : nil,
13
+ ]
14
+ ].map { |i| i.compact.join(" ") }.join(" to ")
15
+ end
16
+
17
+ def start_time_string
18
+ to_s_helper(self.start_time) unless self.start_time.nil?
19
+ end
20
+
21
+ def start_time_string=(v)
22
+ begin
23
+ self.start_time = to_i_helper(v)
24
+ rescue ArgumentError => e
25
+ self.errors.add :start_time, e.message
26
+ end
27
+ end
28
+
29
+ def end_time_string
30
+ to_s_helper(self.end_time) unless self.end_time.nil?
31
+ end
32
+
33
+ def end_time_string=(v)
34
+ begin
35
+ self.end_time = to_i_helper(v)
36
+ rescue ArgumentError => e
37
+ self.errors.add :end_time, e.message
38
+ end
39
+ end
40
+
41
+ def duration_string
42
+ to_s_helper(duration)
43
+ end
44
+
45
+ def time_range(on)
46
+ bak, ENV['TZ'] = ENV['TZ'], Time.zone.tzinfo.name
47
+ on = on.to_time
48
+ ENV['TZ'] = bak
49
+ st = on+start_day.days
50
+ en = on+end_day.days
51
+ stt = Time.zone.local(st.year, st.month, st.day, start_time/60, start_time % 60).in_time_zone
52
+ ent = Time.zone.local(en.year, en.month, en.day, end_time/60, end_time % 60).in_time_zone
53
+ stt..ent
54
+ end
55
+
56
+ def duration
57
+ ((end_day * 24 * 60) + end_time) - ((start_day * 24 * 60) + start_time)
58
+ end
59
+
60
+ end
@@ -0,0 +1,101 @@
1
+ require 'spec_helper'
2
+
3
+ describe TimeKeeper::CustomTime do
4
+ subject do
5
+ TimeKeeper::CustomTime.new("09:45 am")
6
+ end
7
+ describe "#initialize" do
8
+ it "should set the time_in_str variable" do
9
+ TimeKeeper::CustomTime.new("06:45 am").instance_variable_get('@time_in_str').should eq("06:45 am")
10
+ end
11
+ end
12
+
13
+ describe "#parse" do
14
+ it "should set the parsed time object to the appropriate time parser" do
15
+ subject.parse.instance_variable_get("@parsed_time").class.should eq(TimeKeeper::Parser::Meridian)
16
+ end
17
+
18
+ it "should call parse on the time parser object" do
19
+ time_parser_obj = TimeKeeper::Parser::Meridian.new("06:45 am")
20
+ TimeKeeper::Parser::Base.stubs(:build).returns(time_parser_obj)
21
+ time_parser_obj.expects(:parse)
22
+ subject.parse
23
+ end
24
+
25
+ it "should return the custom time object" do
26
+ subject.parse.should eq(subject)
27
+ end
28
+ end
29
+
30
+ describe "#in_seconds" do
31
+ context "when the time is parsed" do
32
+ before(:each) do
33
+ subject.instance_variable_set('@parsed_time', TimeKeeper::Parser::Meridian.new("06:45 am").parse)
34
+ end
35
+
36
+ it "should return the time in seconds" do
37
+ subject.in_seconds.should eq(24300)
38
+ end
39
+ end
40
+
41
+ context "when the time is not parsed" do
42
+ before(:each) do
43
+ subject.instance_variable_set('@parsed_time', nil)
44
+ end
45
+
46
+ it "should raise an exception" do
47
+ lambda{subject.in_seconds}.should raise_exception
48
+ end
49
+ end
50
+ end
51
+
52
+ describe "#in_minutes" do
53
+ context "when the time is parsed" do
54
+ before(:each) do
55
+ subject.instance_variable_set('@parsed_time', TimeKeeper::Parser::Meridian.new("06:45 am").parse)
56
+ end
57
+
58
+ it "should return the time in minutes" do
59
+ subject.in_minutes.should eq(405)
60
+ end
61
+ end
62
+
63
+ context "when the time is not parsed" do
64
+ before(:each) do
65
+ subject.instance_variable_set('@parsed_time', nil)
66
+ end
67
+
68
+ it "should raise an exception" do
69
+ lambda{subject.in_minutes}.should raise_exception
70
+ end
71
+ end
72
+ end
73
+ describe "#in_hours" do
74
+ context "when the time is parsed" do
75
+ before(:each) do
76
+ subject.instance_variable_set('@parsed_time', TimeKeeper::Parser::Meridian.new("06:45 am").parse)
77
+ end
78
+
79
+ it "should return the time in hours" do
80
+ subject.in_hours.should eq(6.75)
81
+ end
82
+ end
83
+
84
+ context "when the time is not parsed" do
85
+ before(:each) do
86
+ subject.instance_variable_set('@parsed_time', nil)
87
+ end
88
+
89
+ it "should raise an exception" do
90
+ lambda{subject.in_minutes}.should raise_exception
91
+ end
92
+ end
93
+ end
94
+
95
+ describe "#to_s" do
96
+ it "should return formatted hours and minutes" do
97
+ subject.expects(:in_minutes).twice.returns(405)
98
+ subject.to_s.should eq("06:45")
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,99 @@
1
+ require 'spec_helper'
2
+
3
+ describe TimeKeeper::Parser::Base do
4
+
5
+ context "when time_is_valid method is implemented" do
6
+ before(:each) do
7
+ TimeKeeper::Parser::Base.any_instance.stubs(:time_is_valid).returns(true)
8
+ end
9
+
10
+ subject do
11
+ TimeKeeper::Parser::Base.new("11:20 am")
12
+ end
13
+
14
+ describe "#initialize" do
15
+ it "should set the time in string" do
16
+ TimeKeeper::Parser::Base.new("11:20 am").instance_variable_get('@time_str').should eq("11:20 am")
17
+ end
18
+
19
+ it "should raise an exception if the time is not valid" do
20
+ lambda{TimeKeeper::Parser::Base.new("11:20 xyz")}.should raise_exception
21
+ end
22
+ end
23
+
24
+ describe ".build" do
25
+ context "when the time is in meridian format" do
26
+ it "should return a meridian time parser object" do
27
+ TimeKeeper::Parser::Base.build("11:20 am").class.should eq(TimeKeeper::Parser::Meridian)
28
+ end
29
+ end
30
+
31
+ context "when the time is in military format" do
32
+ it "should return a military time parser object" do
33
+ TimeKeeper::Parser::Base.build("14:20").class.should eq(TimeKeeper::Parser::Military)
34
+ end
35
+ end
36
+ end
37
+
38
+ describe "#parse" do
39
+ it "should raise an exception" do
40
+ lambda{subject.parse}.should raise_exception(NotImplementedError)
41
+ end
42
+ end
43
+
44
+ describe "#extract_hour" do
45
+ it "should raise an exception" do
46
+ lambda{subject.send(:extract_hour)}.should raise_exception(NotImplementedError)
47
+ end
48
+ end
49
+
50
+ describe "#extract_min" do
51
+ it "should assign minute to the @min variable" do
52
+ subject.send(:extract_min, ":45")
53
+ subject.instance_variable_get('@min').should eq(45)
54
+ end
55
+
56
+ context "when min is present" do
57
+ it "should return the number of mins in integer" do
58
+ subject.send(:extract_min, ":45").should eq(45)
59
+ end
60
+ end
61
+
62
+ context "when min is nil or blank" do
63
+ it "should return 0" do
64
+ subject.send(:extract_min, "").should eq(0)
65
+ end
66
+ end
67
+ end
68
+ end
69
+
70
+ context "when time_is_valid method is not implemented" do
71
+ before(:each) do
72
+ TimeKeeper::Parser::Base.any_instance.stubs(:valid?).returns(true)
73
+ end
74
+
75
+ subject do
76
+ TimeKeeper::Parser::Base.new("06:35")
77
+ end
78
+
79
+ describe "#time_is_valid" do
80
+ it "should raise an exception" do
81
+ lambda{subject.send(:time_is_valid)}.should raise_exception(NotImplementedError)
82
+ end
83
+ end
84
+ end
85
+
86
+ describe ".meridian_format?" do
87
+ context "when the time contains am or pm" do
88
+ it "should return true" do
89
+ TimeKeeper::Parser::Base.meridian_format?("6:45 Pm").should be_true
90
+ end
91
+ end
92
+
93
+ context "when the time does not contain am or pm" do
94
+ it "should return false" do
95
+ TimeKeeper::Parser::Base.meridian_format?("18:45").should be_false
96
+ end
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,76 @@
1
+ require 'spec_helper'
2
+
3
+ describe TimeKeeper::Parser::Meridian do
4
+ subject do
5
+ TimeKeeper::Parser::Meridian.new("7:45 pm")
6
+ end
7
+
8
+ describe "#time_is_valid" do
9
+ context "when hour and mins are both valid" do
10
+ it "should return true" do
11
+ subject.send(:time_is_valid).should be_true
12
+ end
13
+ end
14
+
15
+ context "when either hour or min is not valid" do
16
+ before(:each) do
17
+ subject.instance_variable_set('@time_str', "07:60 pm")
18
+ end
19
+
20
+ it "should return false" do
21
+ subject.send(:time_is_valid).should be_false
22
+ end
23
+
24
+ it "should attach an error to the object" do
25
+ subject.send(:time_is_valid)
26
+ subject.errors[:base].should_not be_empty
27
+ end
28
+ end
29
+ end
30
+
31
+ describe "#extract_hour" do
32
+ context "when the time contains 12 am" do
33
+ it "should set hour as 0" do
34
+ subject.send(:extract_hour, "12", "am")
35
+ subject.instance_variable_get('@hour').should == 0
36
+ end
37
+ end
38
+
39
+ context "when the time contains 12 pm" do
40
+ it "should set hour as 12" do
41
+ subject.send(:extract_hour, "12", "pm")
42
+ subject.instance_variable_get('@hour').should == 12
43
+ end
44
+ end
45
+
46
+ context "when the time is between 1 and 11 am" do
47
+ it "should set hour between 1 to 11" do
48
+ subject.send(:extract_hour, "9", "am")
49
+ subject.instance_variable_get('@hour').should == 9
50
+ end
51
+ end
52
+
53
+ context "when the time is between 1 and 12 pm" do
54
+ it "should set hour between 12 to 23" do
55
+ subject.send(:extract_hour, "3", "pm")
56
+ subject.instance_variable_get('@hour').should == 15
57
+ end
58
+ end
59
+
60
+ it "should return back the hour object" do
61
+ subject.send(:extract_hour, "3", "pm").should eq(15)
62
+ end
63
+ end
64
+
65
+ describe "#parse" do
66
+ it "should parse the time and set the hours and mins" do
67
+ subject.parse
68
+ subject.instance_variable_get('@hour').should eq(19)
69
+ subject.instance_variable_get('@min').should eq(45)
70
+ end
71
+
72
+ it "should return back the time parser object" do
73
+ subject.parse.should eq(subject)
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,62 @@
1
+ require 'spec_helper'
2
+
3
+ describe TimeKeeper::Parser::Military do
4
+ subject do
5
+ TimeKeeper::Parser::Military.new("19:45")
6
+ end
7
+
8
+ describe "#time_is_valid" do
9
+ context "when hour and mins are both valid" do
10
+ it "should return true" do
11
+ subject.send(:time_is_valid).should be_true
12
+ end
13
+ end
14
+
15
+ context "when either hour or min is not valid" do
16
+ before(:each) do
17
+ subject.instance_variable_set('@time_str', "19:60")
18
+ end
19
+
20
+ it "should return false" do
21
+ subject.send(:time_is_valid).should be_false
22
+ end
23
+
24
+ it "should attach an error to the object" do
25
+ subject.send(:time_is_valid)
26
+ subject.errors[:base].should_not be_empty
27
+ end
28
+ end
29
+ end
30
+
31
+ describe "#extract_hour" do
32
+ context "when hour is present" do
33
+ it "should set hour" do
34
+ subject.send(:extract_hour, "15")
35
+ subject.instance_variable_get("@hour").should eq(15)
36
+ end
37
+ end
38
+
39
+ context "when hour is not present" do
40
+ it "should set hour to zero" do
41
+ subject.send(:extract_hour, "")
42
+ subject.instance_variable_get("@hour").should eq(0)
43
+ end
44
+ end
45
+
46
+ it "should return back the hour object" do
47
+ subject.send(:extract_hour, "3").should eq(3)
48
+ end
49
+ end
50
+
51
+ describe "#parse" do
52
+ it "should parse the time and set the hours and mins" do
53
+ subject.parse
54
+ subject.instance_variable_get('@hour').should eq(19)
55
+ subject.instance_variable_get('@min').should eq(45)
56
+ end
57
+
58
+ it "should return back the time parser object" do
59
+ subject.parse.should eq(subject)
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+
3
+ describe TimeKeeper::TimeRangeCollection do
4
+ subject do
5
+ TimeKeeper::TimeRangeCollection.new("06:00 pm - 03:00 am\n07:00 - 17:00")
6
+ end
7
+
8
+ describe "#initialize" do
9
+ it "should set the time_ranges_str variable" do
10
+ TimeKeeper::TimeRangeCollection.new("06:00 pm - 03:00 am\n07:00 - 17:00").instance_variable_get('@time_ranges_str').should eq("06:00 pm-03:00 am\n07:00-17:00")
11
+ end
12
+ end
13
+
14
+ describe "#parse" do
15
+ it "should match return proper range sets count" do
16
+ subject.parse
17
+ subject.instance_variable_get("@time_ranges").count.should eq(2)
18
+ end
19
+
20
+ it "should set the time ranges properly" do
21
+ subject.parse
22
+ subject.time_ranges.first.start_time.in_minutes.should eq(1080)
23
+ subject.time_ranges.first.end_time.in_minutes.should eq(180)
24
+ subject.time_ranges.first.start_day.should eq(0)
25
+ subject.time_ranges.first.end_day.should eq(1)
26
+ subject.time_ranges.last.start_time.in_minutes.should eq(420)
27
+ subject.time_ranges.last.end_time.in_minutes.should eq(1020)
28
+ subject.time_ranges.last.start_day.should eq(1)
29
+ subject.time_ranges.last.end_day.should eq(1)
30
+ end
31
+
32
+ it "should return the time ranges collection object" do
33
+ subject.parse.should eq(subject)
34
+ end
35
+ end
36
+ end