reservation 0.0.4 → 0.0.5
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.
- data/README.md +9 -3
- data/lib/core_ext/date.rb +29 -0
- data/lib/generators/reservation/migration/migration_generator.rb +1 -1
- data/lib/reservation.rb +6 -0
- data/lib/reservation/daily.rb +36 -0
- data/lib/reservation/event.rb +1 -1
- data/lib/reservation/hour_minute.rb +51 -0
- data/lib/reservation/interval.rb +32 -0
- data/lib/reservation/reservation.rb +1 -1
- data/lib/reservation/schedule.rb +5 -187
- data/lib/reservation/version.rb +1 -1
- data/lib/reservation/weekly.rb +83 -0
- data/reservation.gemspec +1 -0
- data/spec/models/date_spec.rb +239 -0
- data/spec/models/schedule/daily_spec.rb +59 -19
- data/spec/models/schedule/weekly_spec.rb +32 -0
- metadata +25 -2
data/README.md
CHANGED
@@ -36,15 +36,21 @@ This will create a set of events, with the given subjects, within the given cons
|
|
36
36
|
{ "role" => "place", "subject" => here, "status" => "tentative" }
|
37
37
|
]
|
38
38
|
|
39
|
-
|
40
|
-
|
41
|
-
|
39
|
+
patterns = [ { "day" => "wed", "start" => "0930", "finish" => "1030"},
|
40
|
+
{ "day" => "wed", "start" => "18", "finish" => "20" },
|
41
|
+
{ "day" => "tue", "start" => "7", "finish" => "830" } ]
|
42
42
|
|
43
43
|
Reservation::Event.create_weekly "the_title", "2013-09-03", "2013-10-13", subjects, pattern
|
44
44
|
|
45
|
+
A 'pattern' may contain an 'nth_of_month' key, in which case the gem will generate events only on days which
|
46
|
+
are the given nth day of the month (for example, "2nd wednesday of each month", "last saturday of the month").
|
47
|
+
|
45
48
|
You can use Reservation::Event#build_weekly instead in order to instantiate the object graph without
|
46
49
|
persisting it.
|
47
50
|
|
51
|
+
## History
|
52
|
+
|
53
|
+
v0.0.5 Add "nth day of month" feature
|
48
54
|
|
49
55
|
## Contributing
|
50
56
|
|
@@ -0,0 +1,29 @@
|
|
1
|
+
class Date
|
2
|
+
def nth_day_of_month
|
3
|
+
1 + ( (self.mday - 1) / 7 )
|
4
|
+
end
|
5
|
+
|
6
|
+
def nth_last_day_of_month
|
7
|
+
last_day = self.end_of_month.mday
|
8
|
+
- 1 - (last_day - self.mday) / 7
|
9
|
+
end
|
10
|
+
|
11
|
+
#
|
12
|
+
# return true if this is the nth of this day within the month,
|
13
|
+
# for example, if n is 2, and this is the second wednesday of the month,
|
14
|
+
# return true. If n is -1, and this is the last saturday of the month,
|
15
|
+
# return true. It doesn't matter which *day* it is, it matters whether
|
16
|
+
# it's the first, second, third, etc, or if it's the last, second last,
|
17
|
+
# third last, etc
|
18
|
+
#
|
19
|
+
def nth_day_of_month? n
|
20
|
+
case n <=> 0
|
21
|
+
when -1
|
22
|
+
nth_last_day_of_month == n
|
23
|
+
when 0
|
24
|
+
raise ArgumentError.new("must be non-zero integer")
|
25
|
+
when 1
|
26
|
+
nth_day_of_month == n
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -17,6 +17,6 @@ class Reservation::MigrationGenerator < Rails::Generators::Base
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def create_migration_file
|
20
|
-
migration_template 'migration.rb', 'db/migrate/
|
20
|
+
migration_template 'migration.rb', 'db/migrate/create_reservations.rb'
|
21
21
|
end
|
22
22
|
end
|
data/lib/reservation.rb
CHANGED
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'core_ext/date'
|
2
|
+
|
3
|
+
module Reservation
|
4
|
+
module Schedule
|
5
|
+
#
|
6
|
+
# a utility class to represent an interval starting on a day
|
7
|
+
#
|
8
|
+
class Daily
|
9
|
+
attr_accessor :wday, :nth_of_month, :interval
|
10
|
+
|
11
|
+
def initialize wday, nth_of_month, interval
|
12
|
+
@wday = wday
|
13
|
+
@nth_of_month = nth_of_month
|
14
|
+
@interval = interval
|
15
|
+
end
|
16
|
+
|
17
|
+
def matches? event
|
18
|
+
good_day?(event.start.to_date) && interval.matches?(event)
|
19
|
+
end
|
20
|
+
|
21
|
+
def generate date, list
|
22
|
+
return list unless good_day?(date)
|
23
|
+
list << interval.generate(date)
|
24
|
+
list
|
25
|
+
end
|
26
|
+
|
27
|
+
def good_day? date
|
28
|
+
(date.wday == self.wday) && ((self.nth_of_month == :all) || date.nth_day_of_month?(self.nth_of_month))
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_s
|
32
|
+
"#{MAP_DAY[wday]} => #{interval}"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/reservation/event.rb
CHANGED
@@ -4,7 +4,7 @@ class Reservation::Event < ActiveRecord::Base
|
|
4
4
|
extend Reservation::TimeOffset
|
5
5
|
extend Reservation::EventFilter
|
6
6
|
|
7
|
-
has_many :reservations, :class_name => "Reservation::Reservation"
|
7
|
+
has_many :reservations, :class_name => "Reservation::Reservation", :inverse_of => :event
|
8
8
|
attr_accessible :finish, :start, :title
|
9
9
|
|
10
10
|
scope :since, lambda { |time| where("reservation_events.finish > ?", time) }
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Reservation
|
2
|
+
module Schedule
|
3
|
+
#
|
4
|
+
# a utility class to match the hour and minute elements of a Time instance, without considering any other values
|
5
|
+
#
|
6
|
+
class HourMinute
|
7
|
+
attr_accessor :hour, :minute
|
8
|
+
|
9
|
+
def initialize hour, minute
|
10
|
+
@hour, @minute = hour, minute
|
11
|
+
end
|
12
|
+
|
13
|
+
def matches_time? time
|
14
|
+
time.hour == self.hour && time.min == self.minute
|
15
|
+
end
|
16
|
+
|
17
|
+
#
|
18
|
+
# hhmm is a string containg an hour-and-minute value
|
19
|
+
#
|
20
|
+
# #parse will remove all nondigit characters, pad the result to 4 digits,
|
21
|
+
# and interpret the first two as an hour value, the last two as a minute value
|
22
|
+
#
|
23
|
+
# padding takes place as follows :
|
24
|
+
# * one digit becomes 0d00 (assumes "7" means "0700")
|
25
|
+
# * two digits become dd00 (assumes "11" means "1100")
|
26
|
+
# * three digits become 0ddd (assumes "830" means "0830")
|
27
|
+
#
|
28
|
+
def self.parse hhmm
|
29
|
+
orig = hhmm
|
30
|
+
hhmm = hhmm.gsub(/[^\d]/, "")
|
31
|
+
hhmm = "0#{hhmm}00" if hhmm.length == 1
|
32
|
+
hhmm = "#{hhmm}00" if hhmm.length == 2
|
33
|
+
hhmm = "0#{hhmm}" if hhmm.length == 3
|
34
|
+
raise "Can't parse #{orig.inspect}" unless hhmm.match(/^\d\d\d\d$/)
|
35
|
+
|
36
|
+
hh = hhmm[0,2].to_i
|
37
|
+
mm = hhmm[2,4].to_i
|
38
|
+
|
39
|
+
new hh, mm
|
40
|
+
end
|
41
|
+
|
42
|
+
def change date
|
43
|
+
date.to_time.change :hour => hour, :min => minute
|
44
|
+
end
|
45
|
+
|
46
|
+
def to_s
|
47
|
+
"#{hour.to_s.rjust 2, "0"}#{minute.to_s.rjust 2, "0"}"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Reservation
|
2
|
+
module Schedule
|
3
|
+
#
|
4
|
+
# a utility class to match the start and end times of an Event instance, without considering the event date
|
5
|
+
#
|
6
|
+
class Interval
|
7
|
+
attr_accessor :start, :finish
|
8
|
+
|
9
|
+
def initialize start, finish
|
10
|
+
@start, @finish = start, finish
|
11
|
+
end
|
12
|
+
|
13
|
+
# true if the start time and finish time of the given event matches start and finish times of this Interval
|
14
|
+
def matches? event
|
15
|
+
start.matches_time?(event.start) && finish.matches_time?(event.finish)
|
16
|
+
end
|
17
|
+
|
18
|
+
# build a new Event with this Interval's start and finish times, on the given date
|
19
|
+
def generate date
|
20
|
+
Event.new :start => start.change(date), :finish => finish.change(date)
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.from start, finish
|
24
|
+
new HourMinute.parse(start), HourMinute.parse(finish)
|
25
|
+
end
|
26
|
+
|
27
|
+
def to_s
|
28
|
+
"#{start}-#{finish}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module Reservation
|
2
2
|
class Reservation < ActiveRecord::Base
|
3
|
-
belongs_to :event, :class_name => "Reservation::Event"
|
3
|
+
belongs_to :event, :class_name => "Reservation::Event", :inverse_of => :reservations
|
4
4
|
belongs_to :subject, :polymorphic => true
|
5
5
|
attr_accessible :reservation_status, :role, :subject_id, :subject_type, :event_id, :event, :subject
|
6
6
|
end
|
data/lib/reservation/schedule.rb
CHANGED
@@ -1,191 +1,9 @@
|
|
1
|
+
require 'reservation/hour_minute'
|
2
|
+
require 'reservation/interval'
|
3
|
+
require 'reservation/daily'
|
4
|
+
require 'reservation/weekly'
|
5
|
+
|
1
6
|
module Reservation
|
2
7
|
DAY_MAP = { "sun" => 0, "mon" => 1, "tue" => 2, "wed" => 3, "thu" => 4, "fri" => 5, "sat" => 6 }
|
3
8
|
MAP_DAY = %w{ sun mon tue wed thu fri sat }
|
4
|
-
|
5
|
-
module Schedule
|
6
|
-
#
|
7
|
-
# a utility class to match the hour and minute elements of a Time instance, without considering any other values
|
8
|
-
#
|
9
|
-
class HourMinute
|
10
|
-
attr_accessor :hour, :minute
|
11
|
-
def initialize hour, minute
|
12
|
-
@hour, @minute = hour, minute
|
13
|
-
end
|
14
|
-
|
15
|
-
def matches_time? time
|
16
|
-
time.hour == self.hour && time.min == self.minute
|
17
|
-
end
|
18
|
-
|
19
|
-
#
|
20
|
-
# hhmm is a string containg an hour-and-minute value
|
21
|
-
#
|
22
|
-
# #parse will remove all nondigit characters, pad the result to 4 digits,
|
23
|
-
# and interpret the first two as an hour value, the last two as a minute value
|
24
|
-
#
|
25
|
-
# padding takes place as follows :
|
26
|
-
# * one digit becomes 0d00 (assumes "7" means "0700")
|
27
|
-
# * two digits become dd00 (assumes "11" means "1100")
|
28
|
-
# * three digits become 0ddd (assumes "830" means "0830")
|
29
|
-
#
|
30
|
-
def self.parse hhmm
|
31
|
-
orig = hhmm
|
32
|
-
hhmm = hhmm.gsub /[^\d]/, ""
|
33
|
-
hhmm = "0#{hhmm}00" if hhmm.length == 1
|
34
|
-
hhmm = "#{hhmm}00" if hhmm.length == 2
|
35
|
-
hhmm = "0#{hhmm}" if hhmm.length == 3
|
36
|
-
raise "Can't parse #{orig.inspect}" unless hhmm.match(/^\d\d\d\d$/)
|
37
|
-
|
38
|
-
hh = hhmm[0,2].to_i
|
39
|
-
mm = hhmm[2,4].to_i
|
40
|
-
|
41
|
-
new hh, mm
|
42
|
-
end
|
43
|
-
|
44
|
-
def change date
|
45
|
-
date.to_time.change :hour => hour, :min => minute
|
46
|
-
end
|
47
|
-
|
48
|
-
def to_s
|
49
|
-
"#{hour.to_s.rjust 2, "0"}#{minute.to_s.rjust 2, "0"}"
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
#
|
54
|
-
# a utility class to match the start and end times of an Event instance, without considering the event date
|
55
|
-
#
|
56
|
-
class Interval
|
57
|
-
attr_accessor :start, :finish
|
58
|
-
|
59
|
-
def initialize start, finish
|
60
|
-
@start, @finish = start, finish
|
61
|
-
end
|
62
|
-
|
63
|
-
# true if the start time and finish time of the given event matches start and finish times of this Interval
|
64
|
-
def matches? event
|
65
|
-
start.matches_time?(event.start) && finish.matches_time?(event.finish)
|
66
|
-
end
|
67
|
-
|
68
|
-
# build a new Event with this Interval's start and finish times, on the given date
|
69
|
-
def generate date
|
70
|
-
Event.new :start => start.change(date), :finish => finish.change(date)
|
71
|
-
end
|
72
|
-
|
73
|
-
def self.from start, finish
|
74
|
-
new HourMinute.parse(start), HourMinute.parse(finish)
|
75
|
-
end
|
76
|
-
|
77
|
-
def to_s
|
78
|
-
"#{start}-#{finish}"
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
#
|
83
|
-
# a utility class to represent a set of intervals on a single day
|
84
|
-
#
|
85
|
-
class Daily
|
86
|
-
attr_accessor :wday, :intervals
|
87
|
-
|
88
|
-
def initialize wday
|
89
|
-
@wday = wday
|
90
|
-
@intervals = []
|
91
|
-
end
|
92
|
-
|
93
|
-
def add interval
|
94
|
-
intervals << interval
|
95
|
-
end
|
96
|
-
|
97
|
-
def matches? event
|
98
|
-
return false if event.start.wday != self.wday
|
99
|
-
intervals.each { |interval|
|
100
|
-
return true if interval.matches? event
|
101
|
-
}
|
102
|
-
false
|
103
|
-
end
|
104
|
-
|
105
|
-
def generate date, list
|
106
|
-
return list if date.wday != wday
|
107
|
-
intervals.inject(list) { |list, interval|
|
108
|
-
list << interval.generate(date)
|
109
|
-
list
|
110
|
-
}
|
111
|
-
end
|
112
|
-
|
113
|
-
def to_s
|
114
|
-
"#{MAP_DAY[wday]} => #{intervals}"
|
115
|
-
end
|
116
|
-
end
|
117
|
-
|
118
|
-
#
|
119
|
-
# Weekly defines a set of intervals that recur weekly
|
120
|
-
#
|
121
|
-
# This class maintains an array of intervals for each weekday
|
122
|
-
#
|
123
|
-
# This class will never match multi-day events, as it assumes each event starts and ends within the same day
|
124
|
-
#
|
125
|
-
class Weekly
|
126
|
-
|
127
|
-
# wdays is a 7-element array of Daily instances
|
128
|
-
#
|
129
|
-
# the zeroth element corresponds to Sunday, because Time#wday behaves that way.
|
130
|
-
#
|
131
|
-
attr_accessor :wdays
|
132
|
-
|
133
|
-
# pattern is an array of the form
|
134
|
-
#
|
135
|
-
# [ { "day" => "wed", "start" => "0930", "finish" => "10:30"},
|
136
|
-
# { "day" => "wed", "start" => "18", "finish" => "20" },
|
137
|
-
# { "day" => "tue", "start" => "7", "finish" => "8h30" } ]
|
138
|
-
#
|
139
|
-
# see HourMinute#parse for how "start" and "finish" values are read
|
140
|
-
#
|
141
|
-
def initialize pattern
|
142
|
-
self.wdays = (0..6).map { |i| Daily.new(i) }
|
143
|
-
|
144
|
-
pattern.each { |interval_spec|
|
145
|
-
wday = DAY_MAP[interval_spec["day"]]
|
146
|
-
raise "unrecognised day #{spec["day"].inspect} in #{pattern.inspect}" if wday.nil?
|
147
|
-
|
148
|
-
start = HourMinute.parse interval_spec["start"]
|
149
|
-
finish = HourMinute.parse interval_spec["finish"]
|
150
|
-
wdays[wday].add Interval.new(start, finish)
|
151
|
-
}
|
152
|
-
end
|
153
|
-
|
154
|
-
# true if there exists a Daily corresponding to this event's weekday, with
|
155
|
-
# an Interval corresponding to this event's start and finish times;
|
156
|
-
# false otherwise
|
157
|
-
#
|
158
|
-
def matches? event
|
159
|
-
return false if event.start.day != event.finish.day
|
160
|
-
wdays[event.start.wday].matches? event
|
161
|
-
end
|
162
|
-
|
163
|
-
#
|
164
|
-
# generate a set of Events according to this Weekly schedule, starting
|
165
|
-
# on #from at the earliest, ending on #upto at the latest.
|
166
|
-
#
|
167
|
-
# Note: #upto is *inclusive*, this will generate events on #upto,
|
168
|
-
# if the schedule allows
|
169
|
-
#
|
170
|
-
def generate from, upto
|
171
|
-
events = []
|
172
|
-
from.upto(upto).map { |date|
|
173
|
-
wdays.each { |day| day.generate date, events }
|
174
|
-
}
|
175
|
-
events
|
176
|
-
end
|
177
|
-
|
178
|
-
#
|
179
|
-
# return a new list including only those events in the given list
|
180
|
-
# that match this weekly schedule
|
181
|
-
#
|
182
|
-
def filter events
|
183
|
-
events.select { |e| matches? e }
|
184
|
-
end
|
185
|
-
|
186
|
-
def to_s
|
187
|
-
wdays.map(&:to_s).join "\n"
|
188
|
-
end
|
189
|
-
end
|
190
|
-
end
|
191
9
|
end
|
data/lib/reservation/version.rb
CHANGED
@@ -0,0 +1,83 @@
|
|
1
|
+
module Reservation
|
2
|
+
module Schedule
|
3
|
+
#
|
4
|
+
# Weekly defines a set of intervals that recur weekly
|
5
|
+
#
|
6
|
+
# This class maintains an array of weekdays with an interval for each
|
7
|
+
#
|
8
|
+
# This class will never match multi-day events, as it assumes each event starts and ends within the same day
|
9
|
+
#
|
10
|
+
class Weekly
|
11
|
+
|
12
|
+
# wdays is an array of Daily instances
|
13
|
+
attr_accessor :wdays
|
14
|
+
|
15
|
+
# pattern is an array of the form
|
16
|
+
#
|
17
|
+
# [ { "nth_of_month" => "all", "day" => "wed", "start" => "0930", "finish" => "10:30"},
|
18
|
+
# { "nth_of_month" => "1", "day" => "wed", "start" => "18", "finish" => "20" },
|
19
|
+
# { "nth_of_month" => "-1", "day" => "tue", "start" => "7", "finish" => "8h30" } ]
|
20
|
+
#
|
21
|
+
# see HourMinute#parse for how "start" and "finish" values are read
|
22
|
+
#
|
23
|
+
# "nth_of_month" => "all", "day" => "mon" :: all mondays in the month are considered
|
24
|
+
# "nth_of_month" => "1", "day" => "fri" :: only the first friday of the month is considered
|
25
|
+
# "nth_of_month" => "-1", "day" => "tue" :: only the last tuesday of the month is considered
|
26
|
+
# "nth_of_month" => "-2", "day" => "sat" :: only the second-last saturday of the month is considered
|
27
|
+
#
|
28
|
+
def initialize patterns
|
29
|
+
self.wdays = []
|
30
|
+
|
31
|
+
patterns.each { |pattern|
|
32
|
+
day = pattern["day"]
|
33
|
+
nth_of_month = parse_nth_of_month pattern["nth_of_month"]
|
34
|
+
|
35
|
+
start = HourMinute.parse pattern["start"]
|
36
|
+
finish = HourMinute.parse pattern["finish"]
|
37
|
+
self.wdays << Daily.new(DAY_MAP[day], nth_of_month, Interval.new(start, finish))
|
38
|
+
}
|
39
|
+
end
|
40
|
+
|
41
|
+
# true if there exists a Daily corresponding to this event's weekday, with
|
42
|
+
# an Interval corresponding to this event's start and finish times;
|
43
|
+
# false otherwise
|
44
|
+
#
|
45
|
+
def matches? event
|
46
|
+
return false if event.start.day != event.finish.day
|
47
|
+
self.wdays.each { |wday| return true if wday.matches?(event) }
|
48
|
+
false
|
49
|
+
end
|
50
|
+
|
51
|
+
#
|
52
|
+
# generate a set of Events according to this Weekly schedule, starting
|
53
|
+
# on #from at the earliest, ending on #upto at the latest.
|
54
|
+
#
|
55
|
+
# Note: #upto is *inclusive*, this will generate events on #upto,
|
56
|
+
# if the schedule allows
|
57
|
+
#
|
58
|
+
def generate from, upto
|
59
|
+
events = []
|
60
|
+
from.upto(upto).map { |date|
|
61
|
+
wdays.each { |day| day.generate date, events }
|
62
|
+
}
|
63
|
+
events
|
64
|
+
end
|
65
|
+
|
66
|
+
#
|
67
|
+
# return a new list including only those events in the given list
|
68
|
+
# that match this weekly schedule
|
69
|
+
#
|
70
|
+
def filter events
|
71
|
+
events.select { |e| matches? e }
|
72
|
+
end
|
73
|
+
|
74
|
+
def to_s
|
75
|
+
wdays.map(&:to_s).join "\n"
|
76
|
+
end
|
77
|
+
|
78
|
+
def parse_nth_of_month txt
|
79
|
+
(txt.to_s == '' || txt.to_s == 'all') ? :all : txt.to_i
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
data/reservation.gemspec
CHANGED
@@ -21,6 +21,7 @@ Gem::Specification.new do |gem|
|
|
21
21
|
|
22
22
|
gem.add_development_dependency 'rspec', '~> 2.9'
|
23
23
|
gem.add_development_dependency "sqlite3"
|
24
|
+
gem.add_development_dependency 'rspec_numbering_formatter'
|
24
25
|
|
25
26
|
gem.files = `git ls-files`.split($/)
|
26
27
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
@@ -0,0 +1,239 @@
|
|
1
|
+
require 'core_ext/date'
|
2
|
+
|
3
|
+
describe Date do
|
4
|
+
describe :nth_day_of_month do
|
5
|
+
it "should return the index of this week-day in the month" do
|
6
|
+
expect(Date.new(2014, 1, 1).nth_day_of_month).to eq 1 # this is the first wednesday of the month
|
7
|
+
expect(Date.new(2014, 1, 2).nth_day_of_month).to eq 1
|
8
|
+
expect(Date.new(2014, 1, 3).nth_day_of_month).to eq 1
|
9
|
+
expect(Date.new(2014, 1, 4).nth_day_of_month).to eq 1
|
10
|
+
expect(Date.new(2014, 1, 5).nth_day_of_month).to eq 1
|
11
|
+
expect(Date.new(2014, 1, 6).nth_day_of_month).to eq 1
|
12
|
+
expect(Date.new(2014, 1, 7).nth_day_of_month).to eq 1
|
13
|
+
expect(Date.new(2014, 1, 8).nth_day_of_month).to eq 2 # this is the second wednesday of the month
|
14
|
+
expect(Date.new(2014, 1, 9).nth_day_of_month).to eq 2
|
15
|
+
expect(Date.new(2014, 1, 10).nth_day_of_month).to eq 2
|
16
|
+
expect(Date.new(2014, 1, 11).nth_day_of_month).to eq 2
|
17
|
+
expect(Date.new(2014, 1, 12).nth_day_of_month).to eq 2
|
18
|
+
expect(Date.new(2014, 1, 13).nth_day_of_month).to eq 2
|
19
|
+
expect(Date.new(2014, 1, 14).nth_day_of_month).to eq 2
|
20
|
+
expect(Date.new(2014, 1, 15).nth_day_of_month).to eq 3
|
21
|
+
expect(Date.new(2014, 1, 16).nth_day_of_month).to eq 3
|
22
|
+
expect(Date.new(2014, 1, 17).nth_day_of_month).to eq 3
|
23
|
+
expect(Date.new(2014, 1, 18).nth_day_of_month).to eq 3
|
24
|
+
expect(Date.new(2014, 1, 19).nth_day_of_month).to eq 3
|
25
|
+
expect(Date.new(2014, 1, 20).nth_day_of_month).to eq 3
|
26
|
+
expect(Date.new(2014, 1, 21).nth_day_of_month).to eq 3
|
27
|
+
expect(Date.new(2014, 1, 22).nth_day_of_month).to eq 4
|
28
|
+
expect(Date.new(2014, 1, 23).nth_day_of_month).to eq 4
|
29
|
+
expect(Date.new(2014, 1, 24).nth_day_of_month).to eq 4
|
30
|
+
expect(Date.new(2014, 1, 25).nth_day_of_month).to eq 4
|
31
|
+
expect(Date.new(2014, 1, 26).nth_day_of_month).to eq 4
|
32
|
+
expect(Date.new(2014, 1, 27).nth_day_of_month).to eq 4
|
33
|
+
expect(Date.new(2014, 1, 28).nth_day_of_month).to eq 4
|
34
|
+
expect(Date.new(2014, 1, 29).nth_day_of_month).to eq 5 # this is the 5th wednesday of the month
|
35
|
+
expect(Date.new(2014, 1, 30).nth_day_of_month).to eq 5
|
36
|
+
expect(Date.new(2014, 1, 31).nth_day_of_month).to eq 5
|
37
|
+
|
38
|
+
expect(Date.new(2014, 2, 1).nth_day_of_month).to eq 1 # this is the first saturday of the month
|
39
|
+
expect(Date.new(2014, 2, 2).nth_day_of_month).to eq 1
|
40
|
+
expect(Date.new(2014, 2, 3).nth_day_of_month).to eq 1
|
41
|
+
expect(Date.new(2014, 2, 4).nth_day_of_month).to eq 1
|
42
|
+
expect(Date.new(2014, 2, 5).nth_day_of_month).to eq 1
|
43
|
+
expect(Date.new(2014, 2, 6).nth_day_of_month).to eq 1
|
44
|
+
expect(Date.new(2014, 2, 7).nth_day_of_month).to eq 1
|
45
|
+
expect(Date.new(2014, 2, 8).nth_day_of_month).to eq 2 # this is the second saturday of the month
|
46
|
+
expect(Date.new(2014, 2, 9).nth_day_of_month).to eq 2
|
47
|
+
expect(Date.new(2014, 2, 10).nth_day_of_month).to eq 2
|
48
|
+
expect(Date.new(2014, 2, 11).nth_day_of_month).to eq 2
|
49
|
+
expect(Date.new(2014, 2, 12).nth_day_of_month).to eq 2
|
50
|
+
expect(Date.new(2014, 2, 13).nth_day_of_month).to eq 2
|
51
|
+
expect(Date.new(2014, 2, 14).nth_day_of_month).to eq 2
|
52
|
+
expect(Date.new(2014, 2, 15).nth_day_of_month).to eq 3
|
53
|
+
expect(Date.new(2014, 2, 16).nth_day_of_month).to eq 3
|
54
|
+
expect(Date.new(2014, 2, 17).nth_day_of_month).to eq 3
|
55
|
+
expect(Date.new(2014, 2, 18).nth_day_of_month).to eq 3
|
56
|
+
expect(Date.new(2014, 2, 19).nth_day_of_month).to eq 3
|
57
|
+
expect(Date.new(2014, 2, 20).nth_day_of_month).to eq 3
|
58
|
+
expect(Date.new(2014, 2, 21).nth_day_of_month).to eq 3
|
59
|
+
expect(Date.new(2014, 2, 22).nth_day_of_month).to eq 4
|
60
|
+
expect(Date.new(2014, 2, 23).nth_day_of_month).to eq 4
|
61
|
+
expect(Date.new(2014, 2, 24).nth_day_of_month).to eq 4
|
62
|
+
expect(Date.new(2014, 2, 25).nth_day_of_month).to eq 4
|
63
|
+
expect(Date.new(2014, 2, 26).nth_day_of_month).to eq 4
|
64
|
+
expect(Date.new(2014, 2, 27).nth_day_of_month).to eq 4
|
65
|
+
expect(Date.new(2014, 2, 28).nth_day_of_month).to eq 4 # this is the fourth friday of the month
|
66
|
+
|
67
|
+
expect(Date.new(2014, 3, 1).nth_day_of_month).to eq 1
|
68
|
+
expect(Date.new(2014, 3, 2).nth_day_of_month).to eq 1
|
69
|
+
expect(Date.new(2014, 3, 3).nth_day_of_month).to eq 1
|
70
|
+
expect(Date.new(2014, 3, 4).nth_day_of_month).to eq 1
|
71
|
+
expect(Date.new(2014, 3, 5).nth_day_of_month).to eq 1
|
72
|
+
expect(Date.new(2014, 3, 6).nth_day_of_month).to eq 1
|
73
|
+
expect(Date.new(2014, 3, 7).nth_day_of_month).to eq 1
|
74
|
+
expect(Date.new(2014, 3, 8).nth_day_of_month).to eq 2
|
75
|
+
expect(Date.new(2014, 3, 9).nth_day_of_month).to eq 2
|
76
|
+
expect(Date.new(2014, 3, 10).nth_day_of_month).to eq 2
|
77
|
+
expect(Date.new(2014, 3, 11).nth_day_of_month).to eq 2
|
78
|
+
expect(Date.new(2014, 3, 12).nth_day_of_month).to eq 2
|
79
|
+
expect(Date.new(2014, 3, 13).nth_day_of_month).to eq 2
|
80
|
+
expect(Date.new(2014, 3, 14).nth_day_of_month).to eq 2
|
81
|
+
expect(Date.new(2014, 3, 15).nth_day_of_month).to eq 3
|
82
|
+
expect(Date.new(2014, 3, 16).nth_day_of_month).to eq 3
|
83
|
+
expect(Date.new(2014, 3, 17).nth_day_of_month).to eq 3
|
84
|
+
expect(Date.new(2014, 3, 18).nth_day_of_month).to eq 3
|
85
|
+
expect(Date.new(2014, 3, 19).nth_day_of_month).to eq 3
|
86
|
+
expect(Date.new(2014, 3, 20).nth_day_of_month).to eq 3
|
87
|
+
expect(Date.new(2014, 3, 21).nth_day_of_month).to eq 3
|
88
|
+
expect(Date.new(2014, 3, 22).nth_day_of_month).to eq 4
|
89
|
+
expect(Date.new(2014, 3, 23).nth_day_of_month).to eq 4
|
90
|
+
expect(Date.new(2014, 3, 24).nth_day_of_month).to eq 4
|
91
|
+
expect(Date.new(2014, 3, 25).nth_day_of_month).to eq 4
|
92
|
+
expect(Date.new(2014, 3, 26).nth_day_of_month).to eq 4
|
93
|
+
expect(Date.new(2014, 3, 27).nth_day_of_month).to eq 4
|
94
|
+
expect(Date.new(2014, 3, 28).nth_day_of_month).to eq 4
|
95
|
+
expect(Date.new(2014, 3, 29).nth_day_of_month).to eq 5
|
96
|
+
expect(Date.new(2014, 3, 30).nth_day_of_month).to eq 5
|
97
|
+
expect(Date.new(2014, 3, 31).nth_day_of_month).to eq 5
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe :nth_last_day_of_month do
|
102
|
+
it "should return the index of this week-day in the month" do
|
103
|
+
expect(Date.new(2014, 1, 1).nth_last_day_of_month).to eq(-5) # this is the fifth last wednesday of the month
|
104
|
+
expect(Date.new(2014, 1, 2).nth_last_day_of_month).to eq(-5)
|
105
|
+
expect(Date.new(2014, 1, 3).nth_last_day_of_month).to eq(-5)
|
106
|
+
expect(Date.new(2014, 1, 4).nth_last_day_of_month).to eq(-4)
|
107
|
+
expect(Date.new(2014, 1, 5).nth_last_day_of_month).to eq(-4)
|
108
|
+
expect(Date.new(2014, 1, 6).nth_last_day_of_month).to eq(-4)
|
109
|
+
expect(Date.new(2014, 1, 7).nth_last_day_of_month).to eq(-4)
|
110
|
+
expect(Date.new(2014, 1, 8).nth_last_day_of_month).to eq(-4) # this is the fourth last wednesday of the month
|
111
|
+
expect(Date.new(2014, 1, 9).nth_last_day_of_month).to eq(-4)
|
112
|
+
expect(Date.new(2014, 1, 10).nth_last_day_of_month).to eq(-4)
|
113
|
+
expect(Date.new(2014, 1, 11).nth_last_day_of_month).to eq(-3)
|
114
|
+
expect(Date.new(2014, 1, 12).nth_last_day_of_month).to eq(-3)
|
115
|
+
expect(Date.new(2014, 1, 13).nth_last_day_of_month).to eq(-3)
|
116
|
+
expect(Date.new(2014, 1, 14).nth_last_day_of_month).to eq(-3)
|
117
|
+
expect(Date.new(2014, 1, 15).nth_last_day_of_month).to eq(-3)
|
118
|
+
expect(Date.new(2014, 1, 16).nth_last_day_of_month).to eq(-3)
|
119
|
+
expect(Date.new(2014, 1, 17).nth_last_day_of_month).to eq(-3)
|
120
|
+
expect(Date.new(2014, 1, 18).nth_last_day_of_month).to eq(-2)
|
121
|
+
expect(Date.new(2014, 1, 19).nth_last_day_of_month).to eq(-2)
|
122
|
+
expect(Date.new(2014, 1, 20).nth_last_day_of_month).to eq(-2)
|
123
|
+
expect(Date.new(2014, 1, 21).nth_last_day_of_month).to eq(-2)
|
124
|
+
expect(Date.new(2014, 1, 22).nth_last_day_of_month).to eq(-2)
|
125
|
+
expect(Date.new(2014, 1, 23).nth_last_day_of_month).to eq(-2)
|
126
|
+
expect(Date.new(2014, 1, 24).nth_last_day_of_month).to eq(-2)
|
127
|
+
expect(Date.new(2014, 1, 25).nth_last_day_of_month).to eq(-1)
|
128
|
+
expect(Date.new(2014, 1, 26).nth_last_day_of_month).to eq(-1)
|
129
|
+
expect(Date.new(2014, 1, 27).nth_last_day_of_month).to eq(-1)
|
130
|
+
expect(Date.new(2014, 1, 28).nth_last_day_of_month).to eq(-1)
|
131
|
+
expect(Date.new(2014, 1, 29).nth_last_day_of_month).to eq(-1) # this is the last wednesday of the month
|
132
|
+
expect(Date.new(2014, 1, 30).nth_last_day_of_month).to eq(-1)
|
133
|
+
expect(Date.new(2014, 1, 31).nth_last_day_of_month).to eq(-1)
|
134
|
+
|
135
|
+
expect(Date.new(2014, 2, 1).nth_last_day_of_month).to eq(-4) # this is the fourth last saturday of the month
|
136
|
+
expect(Date.new(2014, 2, 2).nth_last_day_of_month).to eq(-4)
|
137
|
+
expect(Date.new(2014, 2, 3).nth_last_day_of_month).to eq(-4)
|
138
|
+
expect(Date.new(2014, 2, 4).nth_last_day_of_month).to eq(-4)
|
139
|
+
expect(Date.new(2014, 2, 5).nth_last_day_of_month).to eq(-4)
|
140
|
+
expect(Date.new(2014, 2, 6).nth_last_day_of_month).to eq(-4)
|
141
|
+
expect(Date.new(2014, 2, 7).nth_last_day_of_month).to eq(-4)
|
142
|
+
expect(Date.new(2014, 2, 8).nth_last_day_of_month).to eq(-3) # this is the third last saturday of the month
|
143
|
+
expect(Date.new(2014, 2, 9).nth_last_day_of_month).to eq(-3)
|
144
|
+
expect(Date.new(2014, 2, 10).nth_last_day_of_month).to eq(-3)
|
145
|
+
expect(Date.new(2014, 2, 11).nth_last_day_of_month).to eq(-3)
|
146
|
+
expect(Date.new(2014, 2, 12).nth_last_day_of_month).to eq(-3)
|
147
|
+
expect(Date.new(2014, 2, 13).nth_last_day_of_month).to eq(-3)
|
148
|
+
expect(Date.new(2014, 2, 14).nth_last_day_of_month).to eq(-3)
|
149
|
+
expect(Date.new(2014, 2, 15).nth_last_day_of_month).to eq(-2)
|
150
|
+
expect(Date.new(2014, 2, 16).nth_last_day_of_month).to eq(-2)
|
151
|
+
expect(Date.new(2014, 2, 17).nth_last_day_of_month).to eq(-2)
|
152
|
+
expect(Date.new(2014, 2, 18).nth_last_day_of_month).to eq(-2)
|
153
|
+
expect(Date.new(2014, 2, 19).nth_last_day_of_month).to eq(-2)
|
154
|
+
expect(Date.new(2014, 2, 20).nth_last_day_of_month).to eq(-2)
|
155
|
+
expect(Date.new(2014, 2, 21).nth_last_day_of_month).to eq(-2)
|
156
|
+
expect(Date.new(2014, 2, 22).nth_last_day_of_month).to eq(-1)
|
157
|
+
expect(Date.new(2014, 2, 23).nth_last_day_of_month).to eq(-1)
|
158
|
+
expect(Date.new(2014, 2, 24).nth_last_day_of_month).to eq(-1)
|
159
|
+
expect(Date.new(2014, 2, 25).nth_last_day_of_month).to eq(-1)
|
160
|
+
expect(Date.new(2014, 2, 26).nth_last_day_of_month).to eq(-1)
|
161
|
+
expect(Date.new(2014, 2, 27).nth_last_day_of_month).to eq(-1)
|
162
|
+
expect(Date.new(2014, 2, 28).nth_last_day_of_month).to eq(-1) # this is the last friday of the month
|
163
|
+
|
164
|
+
expect(Date.new(2014, 3, 1).nth_last_day_of_month).to eq(-5)
|
165
|
+
expect(Date.new(2014, 3, 2).nth_last_day_of_month).to eq(-5)
|
166
|
+
expect(Date.new(2014, 3, 3).nth_last_day_of_month).to eq(-5)
|
167
|
+
expect(Date.new(2014, 3, 4).nth_last_day_of_month).to eq(-4)
|
168
|
+
expect(Date.new(2014, 3, 5).nth_last_day_of_month).to eq(-4)
|
169
|
+
expect(Date.new(2014, 3, 6).nth_last_day_of_month).to eq(-4)
|
170
|
+
expect(Date.new(2014, 3, 7).nth_last_day_of_month).to eq(-4)
|
171
|
+
expect(Date.new(2014, 3, 8).nth_last_day_of_month).to eq(-4)
|
172
|
+
expect(Date.new(2014, 3, 9).nth_last_day_of_month).to eq(-4)
|
173
|
+
expect(Date.new(2014, 3, 10).nth_last_day_of_month).to eq(-4)
|
174
|
+
expect(Date.new(2014, 3, 11).nth_last_day_of_month).to eq(-3)
|
175
|
+
expect(Date.new(2014, 3, 12).nth_last_day_of_month).to eq(-3)
|
176
|
+
expect(Date.new(2014, 3, 13).nth_last_day_of_month).to eq(-3)
|
177
|
+
expect(Date.new(2014, 3, 14).nth_last_day_of_month).to eq(-3)
|
178
|
+
expect(Date.new(2014, 3, 15).nth_last_day_of_month).to eq(-3)
|
179
|
+
expect(Date.new(2014, 3, 16).nth_last_day_of_month).to eq(-3)
|
180
|
+
expect(Date.new(2014, 3, 17).nth_last_day_of_month).to eq(-3)
|
181
|
+
expect(Date.new(2014, 3, 18).nth_last_day_of_month).to eq(-2)
|
182
|
+
expect(Date.new(2014, 3, 19).nth_last_day_of_month).to eq(-2)
|
183
|
+
expect(Date.new(2014, 3, 20).nth_last_day_of_month).to eq(-2)
|
184
|
+
expect(Date.new(2014, 3, 21).nth_last_day_of_month).to eq(-2)
|
185
|
+
expect(Date.new(2014, 3, 22).nth_last_day_of_month).to eq(-2)
|
186
|
+
expect(Date.new(2014, 3, 23).nth_last_day_of_month).to eq(-2)
|
187
|
+
expect(Date.new(2014, 3, 24).nth_last_day_of_month).to eq(-2)
|
188
|
+
expect(Date.new(2014, 3, 25).nth_last_day_of_month).to eq(-1)
|
189
|
+
expect(Date.new(2014, 3, 26).nth_last_day_of_month).to eq(-1)
|
190
|
+
expect(Date.new(2014, 3, 27).nth_last_day_of_month).to eq(-1)
|
191
|
+
expect(Date.new(2014, 3, 28).nth_last_day_of_month).to eq(-1)
|
192
|
+
expect(Date.new(2014, 3, 29).nth_last_day_of_month).to eq(-1)
|
193
|
+
expect(Date.new(2014, 3, 30).nth_last_day_of_month).to eq(-1)
|
194
|
+
expect(Date.new(2014, 3, 31).nth_last_day_of_month).to eq(-1)
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
describe :nth_day_of_month? do
|
199
|
+
it "should return true or false depnding whether the date is the given nth day of the month" do
|
200
|
+
d = Date.new(2014, 3, 1)
|
201
|
+
expect(d.nth_day_of_month?( 1)).to be_true
|
202
|
+
expect(d.nth_day_of_month?( 2)).to be_false
|
203
|
+
expect(d.nth_day_of_month?( 3)).to be_false
|
204
|
+
expect(d.nth_day_of_month?( 4)).to be_false
|
205
|
+
expect(d.nth_day_of_month?( 5)).to be_false
|
206
|
+
expect(d.nth_day_of_month?(-5)).to be_true
|
207
|
+
expect(d.nth_day_of_month?(-4)).to be_false
|
208
|
+
expect(d.nth_day_of_month?(-3)).to be_false
|
209
|
+
expect(d.nth_day_of_month?(-2)).to be_false
|
210
|
+
expect(d.nth_day_of_month?(-1)).to be_false
|
211
|
+
|
212
|
+
d = Date.new(2014, 3, 15)
|
213
|
+
expect(d.nth_day_of_month?( 1)).to be_false
|
214
|
+
expect(d.nth_day_of_month?( 2)).to be_false
|
215
|
+
expect(d.nth_day_of_month?( 3)).to be_true
|
216
|
+
expect(d.nth_day_of_month?( 4)).to be_false
|
217
|
+
expect(d.nth_day_of_month?( 5)).to be_false
|
218
|
+
expect(d.nth_day_of_month?(-5)).to be_false
|
219
|
+
expect(d.nth_day_of_month?(-4)).to be_false
|
220
|
+
expect(d.nth_day_of_month?(-3)).to be_true
|
221
|
+
expect(d.nth_day_of_month?(-2)).to be_false
|
222
|
+
expect(d.nth_day_of_month?(-1)).to be_false
|
223
|
+
|
224
|
+
d = Date.new(2014, 3, 31)
|
225
|
+
expect(d.nth_day_of_month?( 1)).to be_false
|
226
|
+
expect(d.nth_day_of_month?( 2)).to be_false
|
227
|
+
expect(d.nth_day_of_month?( 3)).to be_false
|
228
|
+
expect(d.nth_day_of_month?( 4)).to be_false
|
229
|
+
expect(d.nth_day_of_month?( 5)).to be_true
|
230
|
+
expect(d.nth_day_of_month?(-5)).to be_false
|
231
|
+
expect(d.nth_day_of_month?(-4)).to be_false
|
232
|
+
expect(d.nth_day_of_month?(-3)).to be_false
|
233
|
+
expect(d.nth_day_of_month?(-2)).to be_false
|
234
|
+
expect(d.nth_day_of_month?(-1)).to be_true
|
235
|
+
|
236
|
+
expect { d.nth_day_of_month?(0) }.to raise_error(ArgumentError)
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
@@ -13,45 +13,85 @@ describe Reservation::Schedule::Daily do
|
|
13
13
|
end
|
14
14
|
|
15
15
|
it "should match when there exists a matching interval on the same day as the given event" do
|
16
|
-
daily = Reservation::Schedule::Daily.new(5)
|
17
|
-
daily.
|
18
|
-
|
16
|
+
daily = Reservation::Schedule::Daily.new(5, :all, interval("7h", "9:30"))
|
17
|
+
daily.matches?(event).should be_true
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should match when there exists a matching interval on the same nth day as the given event" do
|
21
|
+
daily = Reservation::Schedule::Daily.new(5, 2, interval("7h", "9:30"))
|
22
|
+
daily.matches?(event).should be_true
|
23
|
+
end
|
19
24
|
|
25
|
+
it "should match when there exists a matching interval on the same nth-last day as the given event" do
|
26
|
+
daily = Reservation::Schedule::Daily.new(5, -3, interval("7h", "9:30"))
|
20
27
|
daily.matches?(event).should be_true
|
21
28
|
end
|
22
29
|
|
23
30
|
it "should not match when the day is different" do
|
24
|
-
daily = Reservation::Schedule::Daily.new(3)
|
25
|
-
daily.
|
26
|
-
|
31
|
+
daily = Reservation::Schedule::Daily.new(3, :all, interval("7h", "9:30"))
|
32
|
+
daily.matches?(event).should be_false
|
33
|
+
end
|
27
34
|
|
35
|
+
it "should not match when the nth day is different" do
|
36
|
+
daily = Reservation::Schedule::Daily.new(3, 5, interval("7h", "9:30"))
|
28
37
|
daily.matches?(event).should be_false
|
29
38
|
end
|
30
39
|
|
31
|
-
it "should not match when
|
32
|
-
daily = Reservation::Schedule::Daily.new(
|
33
|
-
daily.
|
34
|
-
|
40
|
+
it "should not match when the nth-last day is different" do
|
41
|
+
daily = Reservation::Schedule::Daily.new(3, -1, interval("7h", "9:30"))
|
42
|
+
daily.matches?(event).should be_false
|
43
|
+
end
|
35
44
|
|
45
|
+
it "should not match when there is no corresponding interval" do
|
46
|
+
daily = Reservation::Schedule::Daily.new(5, :all, interval("7h", "9:45"))
|
36
47
|
daily.matches?(event).should be_false
|
37
48
|
end
|
38
49
|
|
39
50
|
it "should generate events corresponding to its intervals on the given matching date" do
|
40
|
-
daily = Reservation::Schedule::Daily.new(5)
|
41
|
-
|
42
|
-
|
51
|
+
daily = Reservation::Schedule::Daily.new(5, :all, interval("7h", "9:45"))
|
52
|
+
|
53
|
+
events = []
|
54
|
+
daily.generate date("2013-07-12"), events
|
55
|
+
actual = events.map { |e| "#{e.start.prettyd} #{e.finish.pretty}"}.join("\n")
|
56
|
+
actual.should == "Fri,20130712T0700 20130712T0945"
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should generate events corresponding to its intervals on the given matching nth day" do
|
60
|
+
daily = Reservation::Schedule::Daily.new(5, 2, interval("7h", "9:45"))
|
43
61
|
|
44
62
|
events = []
|
45
63
|
daily.generate date("2013-07-12"), events
|
46
|
-
events.map { |e| "#{e.start.prettyd} #{e.finish.pretty}"}.join("\n")
|
47
|
-
|
48
|
-
|
64
|
+
actual = events.map { |e| "#{e.start.prettyd} #{e.finish.pretty}"}.join("\n")
|
65
|
+
actual.should == "Fri,20130712T0700 20130712T0945"
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should generate events corresponding to its intervals on the given matching nth-last day" do
|
69
|
+
daily = Reservation::Schedule::Daily.new(5, -3, interval("7h", "9:45"))
|
70
|
+
|
71
|
+
events = []
|
72
|
+
daily.generate date("2013-07-12"), events
|
73
|
+
actual = events.map { |e| "#{e.start.prettyd} #{e.finish.pretty}"}.join("\n")
|
74
|
+
actual.should == "Fri,20130712T0700 20130712T0945"
|
49
75
|
end
|
50
76
|
|
51
77
|
it "should generate no events when the date does not match its weekday" do
|
52
|
-
daily = Reservation::Schedule::Daily.new(2)
|
53
|
-
|
54
|
-
|
78
|
+
daily = Reservation::Schedule::Daily.new(2, :all, interval("7h", "9:45"))
|
79
|
+
|
80
|
+
events = []
|
81
|
+
daily.generate date("2013-07-12"), events
|
82
|
+
events.should == []
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should generate no events when the date does not match its nth weekday" do
|
86
|
+
daily = Reservation::Schedule::Daily.new(2, 5, interval("7h", "9:45"))
|
87
|
+
|
88
|
+
events = []
|
89
|
+
daily.generate date("2013-07-12"), events
|
90
|
+
events.should == []
|
91
|
+
end
|
92
|
+
|
93
|
+
it "should generate no events when the date does not match its nth-last weekday" do
|
94
|
+
daily = Reservation::Schedule::Daily.new(2, -1, interval("7h", "9:45"))
|
55
95
|
|
56
96
|
events = []
|
57
97
|
daily.generate date("2013-07-12"), events
|
@@ -56,6 +56,38 @@ Fri,20130719T1000 20130719T1145
|
|
56
56
|
Tue,20130723T0700 20130723T0830"
|
57
57
|
end
|
58
58
|
|
59
|
+
it "should generate events for the fourth-last and second-last friday of each month" do
|
60
|
+
weekly = Reservation::Schedule::Weekly.new [ { "day" => "fri", "start" => "10h", "finish" => "11:45", "nth_of_month" => "-4" },
|
61
|
+
{ "day" => "fri", "start" => "10h", "finish" => "11:45", "nth_of_month" => "-2" } ]
|
62
|
+
|
63
|
+
events = weekly.generate date("2013-01-01"), date("2013-12-31")
|
64
|
+
events.map { |e| "#{e.start.prettyd} #{e.finish.pretty}"}.join("\n").
|
65
|
+
should == "Fri,20130104T1000 20130104T1145
|
66
|
+
Fri,20130118T1000 20130118T1145
|
67
|
+
Fri,20130201T1000 20130201T1145
|
68
|
+
Fri,20130215T1000 20130215T1145
|
69
|
+
Fri,20130308T1000 20130308T1145
|
70
|
+
Fri,20130322T1000 20130322T1145
|
71
|
+
Fri,20130405T1000 20130405T1145
|
72
|
+
Fri,20130419T1000 20130419T1145
|
73
|
+
Fri,20130510T1000 20130510T1145
|
74
|
+
Fri,20130524T1000 20130524T1145
|
75
|
+
Fri,20130607T1000 20130607T1145
|
76
|
+
Fri,20130621T1000 20130621T1145
|
77
|
+
Fri,20130705T1000 20130705T1145
|
78
|
+
Fri,20130719T1000 20130719T1145
|
79
|
+
Fri,20130809T1000 20130809T1145
|
80
|
+
Fri,20130823T1000 20130823T1145
|
81
|
+
Fri,20130906T1000 20130906T1145
|
82
|
+
Fri,20130920T1000 20130920T1145
|
83
|
+
Fri,20131004T1000 20131004T1145
|
84
|
+
Fri,20131018T1000 20131018T1145
|
85
|
+
Fri,20131108T1000 20131108T1145
|
86
|
+
Fri,20131122T1000 20131122T1145
|
87
|
+
Fri,20131206T1000 20131206T1145
|
88
|
+
Fri,20131220T1000 20131220T1145"
|
89
|
+
end
|
90
|
+
|
59
91
|
it "should filter a set of events" do
|
60
92
|
weekly = Reservation::Schedule::Weekly.new [ { "day" => "wed", "start" => "0930", "finish" => "10:30"},
|
61
93
|
{ "day" => "wed", "start" => "18", "finish" => "20" },
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: reservation
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2014-01-21 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
@@ -91,6 +91,22 @@ dependencies:
|
|
91
91
|
- - ! '>='
|
92
92
|
- !ruby/object:Gem::Version
|
93
93
|
version: '0'
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: rspec_numbering_formatter
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
94
110
|
description: A very basic reservation system using ActiveRecord
|
95
111
|
email:
|
96
112
|
- conan@conandalton.net
|
@@ -105,17 +121,22 @@ files:
|
|
105
121
|
- MIT-LICENSE
|
106
122
|
- README.md
|
107
123
|
- Rakefile
|
124
|
+
- lib/core_ext/date.rb
|
108
125
|
- lib/generators/reservation/migration/USAGE
|
109
126
|
- lib/generators/reservation/migration/migration_generator.rb
|
110
127
|
- lib/generators/reservation/migration/templates/migration.rb
|
111
128
|
- lib/reservation.rb
|
129
|
+
- lib/reservation/daily.rb
|
112
130
|
- lib/reservation/event.rb
|
113
131
|
- lib/reservation/event_filter.rb
|
132
|
+
- lib/reservation/hour_minute.rb
|
133
|
+
- lib/reservation/interval.rb
|
114
134
|
- lib/reservation/reservation.rb
|
115
135
|
- lib/reservation/schedule.rb
|
116
136
|
- lib/reservation/scopes.rb
|
117
137
|
- lib/reservation/time_offset.rb
|
118
138
|
- lib/reservation/version.rb
|
139
|
+
- lib/reservation/weekly.rb
|
119
140
|
- lib/tasks/reservation_tasks.rake
|
120
141
|
- reservation.gemspec
|
121
142
|
- spec/dummy/README.rdoc
|
@@ -172,6 +193,7 @@ files:
|
|
172
193
|
- spec/dummy/test/unit/reservation/reservation_test.rb
|
173
194
|
- spec/dummy/test/unit/reservation/time_slot_test.rb
|
174
195
|
- spec/dummy/test/unit/thing_test.rb
|
196
|
+
- spec/models/date_spec.rb
|
175
197
|
- spec/models/event_spec.rb
|
176
198
|
- spec/models/schedule/daily_spec.rb
|
177
199
|
- spec/models/schedule/hour_minute_spec.rb
|
@@ -258,6 +280,7 @@ test_files:
|
|
258
280
|
- spec/dummy/test/unit/reservation/reservation_test.rb
|
259
281
|
- spec/dummy/test/unit/reservation/time_slot_test.rb
|
260
282
|
- spec/dummy/test/unit/thing_test.rb
|
283
|
+
- spec/models/date_spec.rb
|
261
284
|
- spec/models/event_spec.rb
|
262
285
|
- spec/models/schedule/daily_spec.rb
|
263
286
|
- spec/models/schedule/hour_minute_spec.rb
|