Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
36dcc6d
initial commit
dnguye2 Mar 2, 2020
daee191
foundational scaffolding for wave 1
dnguye2 Mar 3, 2020
cf0eaa1
night method for date range calculated
dnguye2 Mar 3, 2020
b63e5d0
strings allowed as inputs for dates
dnguye2 Mar 3, 2020
941f30c
psuedocode to plan out design of class methods
dnguye2 Mar 4, 2020
2aada82
added method to parse end and start dates
dnguye2 Mar 5, 2020
cbf14a5
changed reservation to inherit date_range
dnguye2 Mar 5, 2020
3247f98
added tests for valid dates for reservation class
dnguye2 Mar 5, 2020
6e32941
set up array of room hashes for hotel controller
dnguye2 Mar 5, 2020
7e143e1
added test to confirm list of 20 rooms by "rooms"
dnguye2 Mar 5, 2020
f9232f5
made rooms an instance variable
dnguye2 Mar 5, 2020
5e6a73c
pseudocode for hotelcontroller methods
dnguye2 Mar 6, 2020
6063db3
improved date_range test coverage 42% -> 96.5%
dnguye2 Mar 6, 2020
d8119f1
removed room as attribute for reservation class
dnguye2 Mar 6, 2020
5bb518f
list of reserverations(date) method and tests made
dnguye2 Mar 6, 2020
f9ffebf
psuedocode for reservations_by_room method
dnguye2 Mar 6, 2020
ac8bce3
added tests to create for reservations method
dnguye2 Mar 6, 2020
d91a6e4
psuedocode for wave 2 available rooms method
dnguye2 Mar 6, 2020
c0d894c
removed parsing dates method, not needed
dnguye2 Mar 6, 2020
c4fbb79
removed tests for parsing date, not needed anymore
dnguye2 Mar 6, 2020
77d5638
removed date parsing methods, not needed
dnguye2 Mar 6, 2020
2e2c815
fixed tests to deal with date objects only
dnguye2 Mar 6, 2020
39791ed
before block @date Δ parsed Date to Date object
dnguye2 Mar 6, 2020
c865285
cleaned up code and unneccessary comments
dnguye2 Mar 6, 2020
7721424
added more tests for reservation method
dnguye2 Mar 7, 2020
f82c3f7
simplified reservation class, removed validation
dnguye2 Mar 7, 2020
57cecf0
improved test coverage for reserve room method
dnguye2 Mar 7, 2020
ef1b19c
fixed valid_room_inputs array
dnguye2 Mar 7, 2020
cc53ee0
reservation lookup by room and date completed
dnguye2 Mar 7, 2020
e1a7e6d
filled out tests for overlap method
dnguye2 Mar 8, 2020
d47e981
overlap method completed
dnguye2 Mar 8, 2020
f23f13e
made tests for date range include? method
dnguye2 Mar 8, 2020
81baca6
added and completed include? method
dnguye2 Mar 8, 2020
c9306ee
available rooms method tested and created
dnguye2 Mar 8, 2020
1c583e4
reserve_room method updated
dnguye2 Mar 9, 2020
445555e
reserve_room method completed
dnguye2 Mar 9, 2020
ffb0766
finalized tests and cleaned up code
dnguye2 Mar 9, 2020
8509bb4
refactor.txt file
dnguye2 Mar 9, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions lib/date_range.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
require_relative 'date_range'

module Hotel
class DateRange
attr_accessor :start_date, :end_date

def initialize(start_date, end_date)
difference = end_date - start_date

if difference == 0
raise ArgumentError, "Cannot have 0 length date range"
elsif difference < 0
raise ArgumentError, "Cannot have negative length for a date range"
else
@start_date = start_date
@end_date = end_date
end

@start_date = start_date
@end_date = end_date
end

def overlap?(range)
if (range.start_date) == @end_date || (range.end_date) == @start_date
return false
elsif @start_date.between?(range.start_date, range.end_date) && @end_date.between?(range.start_date, range.end_date)
return true
elsif (range.start_date).between?(@start_date, @end_date)
return true
elsif @start_date.between?(range.start_date, range.end_date)
return true
elsif @end_date.between?(range.start_date, range.end_date)
return true
else
return false
end
end

def include?(date)
if date > @end_date || date == @end_date || date < @start_date
return false
end
return true
end

def nights
nights = (end_date - start_date) - 1
end
end
end
96 changes: 96 additions & 0 deletions lib/hotel_manager.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
require_relative 'date_range'

module Hotel
class HotelController
# Wave 1
attr_reader :rooms
def rooms
@rooms = []
20.times do |i|
@rooms << {(("room#{i+1}").to_sym) => []}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see that @rooms is setup as an array of hashes. For future reference, this would have been much easier to work with simply as a hash, where the key to each item in the has is the room number and the value is the array of reservations.

end

return @rooms
end

def reserve_room(start_date, end_date)
available_rooms = available_rooms(start_date, end_date)

if available_rooms.empty?
raise ArgumentError.new, "No available rooms for this date range."
else
# at random choose from available rooms
chosen_room = (available_rooms.sample.to_sym)
room_index = (((chosen_room.to_s).match('[0-9]')[0]).to_i) - 1

# add reservation to master room list (@rooms)
reserved_room = Hotel::DateRange.new(start_date, end_date)
reserved = Hotel::Reservation.new(reserved_room.start_date, reserved_room.end_date)
@rooms[room_index][chosen_room] << reserved

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If @rooms were updated to match what I've noted in the comment above, there wouldn't be a need to index into the data structure twice like it's done here.

end

return @rooms
end

def reservations(date)
reservation_list = []

@rooms.each do |room|
room.each_value do |reservation|
reservation.each do |reservation_instance|
if date.between?(reservation_instance.start_date, reservation_instance.end_date)
reservation_list << reservation_instance
end
end
end
end

return reservation_list
end

# method to lookup reservations by room and date
def reservations_by_room(room, date)
valid_room_inputs = []
20.times do |i|
valid_room_inputs << ("room#{i+1}").to_sym
end

unless valid_room_inputs.include?(room)
raise ArgumentError.new("Not a valid room")
end

room_index = (((room.to_s).match('[0-9]')[0]).to_i) - 1
reservation_list = []

@rooms[room_index][room].each do |reservation_instance|
if date.between?(reservation_instance.start_date, reservation_instance.end_date)
reservation_list << reservation_instance
end
end

return reservation_list
end

# Wave 2
def available_rooms(start_date, end_date)
unavailable_rooms = []
available_rooms = @rooms.map { |room| (room.keys).join }

test_range = Hotel::DateRange.new(start_date, end_date)

@rooms.each do |room|
room.each_value do |reservation|
reservation.each do |reservation_instance|
reservation_range = Hotel::DateRange.new(reservation_instance.start_date, reservation_instance.end_date)
if reservation_range.overlap?(test_range) == true
unavailable_rooms << (room.keys).join
end
end
end
end

available_rooms = available_rooms - unavailable_rooms
return available_rooms
end
end
end
16 changes: 16 additions & 0 deletions lib/reservation.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
require_relative 'date_range'

module Hotel
class Reservation
attr_reader :start_date, :end_date
def initialize(start_date, end_date)
@start_date = start_date
@end_date = end_date
end

def cost
cost = (@end_date - @start_date) * 200
return cost
end
end
end
3 changes: 3 additions & 0 deletions refactor.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
- fix reserve_room method
- change room hash structure access
- attempt wave 3
158 changes: 158 additions & 0 deletions test/date_range_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
require_relative "test_helper"

describe Hotel::DateRange do
describe "constructor" do
before do
start_date = Date.new(2017, 01, 01)
end_date = start_date + 3

@range = Hotel::DateRange.new(start_date, end_date)
end

it "can be initialized with two dates" do
start_date = Date.new(2017, 01, 01)
end_date = start_date + 3
expect(@range.start_date).must_equal start_date
expect(@range.end_date).must_equal end_date
end

it "is set up for specific attributes and data types" do
expect(@range.start_date).must_be_kind_of Date
expect(@range.end_date).must_be_kind_of Date
end

it "is an an error for negative-length ranges" do
start_date = Date.new(2017, 02, 01)
end_date = Date.new(2017, 01, 01)

expect{Hotel::DateRange.new(start_date, end_date)}.must_raise ArgumentError, "Cannot have negative length for a date range"
end

it "is an error to create a 0-length range" do
start_date = Date.new(2017, 01, 01)
end_date = Date.new(2017, 01, 01)

expect{(Hotel::DateRange.new(start_date, end_date))}.must_raise ArgumentError, "Cannot have 0 length date range"
end

end

describe "overlap?" do
before do
start_date = Date.new(2017, 01, 01)
end_date = start_date + 3

@range = Hotel::DateRange.new(start_date, end_date)
end

it "returns true for the same range" do
start_date = @range.start_date
end_date = @range.end_date
test_range = Hotel::DateRange.new(start_date, end_date)

expect(@range.overlap?(test_range)).must_equal true
end

it "returns true for a contained range" do
start_date = @range.start_date + 1
end_date = @range.end_date - 1
test_range = Hotel::DateRange.new(start_date, end_date)

expect(@range.overlap?(test_range)).must_equal true
end

it "returns true for a range that overlaps in front" do
start_date = @range.start_date - 1
end_date = @range.end_date - 1
test_range = Hotel::DateRange.new(start_date, end_date)

expect(@range.overlap?(test_range)).must_equal true
end

it "returns true for a range that overlaps in the back" do
start_date = @range.start_date + 1
end_date = @range.end_date + 1
test_range = Hotel::DateRange.new(start_date, end_date)

expect(@range.overlap?(test_range)).must_equal true
end

it "returns true for a containing range" do
start_date = @range.start_date - 1
end_date = @range.end_date + 1
test_range = Hotel::DateRange.new(start_date, end_date)

expect(@range.overlap?(test_range)).must_equal true
end

it "returns false for a range starting on the end_date date" do
start_date = @range.end_date
end_date = @range.end_date + 4
test_range = Hotel::DateRange.new(start_date, end_date)

expect(@range.overlap?(test_range)).must_equal false
end

it "returns false for a range ending on the start_date date" do
start_date = @range.start_date - 4
end_date = @range.start_date
test_range = Hotel::DateRange.new(start_date, end_date)

expect(@range.overlap?(test_range)).must_equal false
end

it "returns false for a range completely before" do
start_date = @range.start_date - 5
end_date = @range.start_date - 3
test_range = Hotel::DateRange.new(start_date, end_date)

expect(@range.overlap?(test_range)).must_equal false
end

it "returns false for a date completely after" do
start_date = @range.end_date + 1
end_date = @range.end_date + 3
test_range = Hotel::DateRange.new(start_date, end_date)

expect(@range.overlap?(test_range)).must_equal false
end

end

describe "include?" do
before do
start_date = Date.new(2017, 01, 01)
end_date = start_date + 3

@range = Hotel::DateRange.new(start_date, end_date)
end

it "returns false if the date is clearly out" do
date = @range.end_date + 1
date_2 = @range.start_date - 1
expect(@range.include?(date)).must_equal false
expect(@range.include?(date_2)).must_equal false
end

it "returns true for dates within the range" do
date = @range.end_date - 2
expect(@range.include?(date)).must_equal true
end

it "returns false for the end_date date" do
date = @range.end_date
expect(@range.include?(date)).must_equal false
end
end

describe "nights" do
it "returns the correct number of nights" do
start_date = Date.new(2017, 01, 01)
end_date = start_date + 4

range = Hotel::DateRange.new(start_date, end_date)

expect(range.nights).must_equal 3
end
end
end
Loading