Skip to content
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
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
Empty file added lib/block.rb
Empty file.
128 changes: 128 additions & 0 deletions lib/booker.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
require "date"

require_relative "room"
require_relative "reservation"
require_relative "block"

module Hotel
class Booker
attr_reader :inventory, :rooms, :reservations

def initialize(inventory:)
@inventory = inventory
@rooms = []
@reservations = []

if @inventory.class != Integer

Choose a reason for hiding this comment

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

This error checking should go ahead of the assignment to @inventory

raise ArgumentError, "inventory has to be an integer"
elsif @inventory < 1
raise ArgumentError, "inventory can't be less than 1"
else
n = 1
@inventory.times do
@rooms << Hotel::Room.new(number: n)
n += 1
end

end

end

def all_rooms

Choose a reason for hiding this comment

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

How is this different than the rooms reader method.

return @rooms
end

def available_rooms(check_in:, check_out:)
start_date = Date.parse(check_in.to_s)
end_date = Date.parse(check_out.to_s)
available_rooms = []

availability = 0
@rooms.each do |room|
if room.bookings == nil
available_rooms << room

else
no_overlap = 0
room.bookings.each do |booking|
if end_date <= booking.check_in || start_date >= booking.check_out
no_overlap += 1
end
end

if no_overlap == room.bookings.length
available_rooms << room
availability += 1
end
end
end

if availability == 0
raise ArgumentError, "There are no available room"
else
return available_rooms
end

end

def make_reservation(check_in:, check_out:)
start_date = Date.parse(check_in.to_s)
end_date = Date.parse(check_out.to_s)

@rooms.each do |room|

if room.bookings.length == 0
new_reservation = Reservation.new(check_in: start_date, check_out: end_date, room: room)
room_bookings << new_reservation
return new_reservation

else
no_overlap = 0
room.bookings.each do |booking|

if end_date <= booking.check_in || start_date >= booking.check_out
no_overlap += 1
end

if no_overlap == room.bookings.length
new_reservation = Reservation.new(check_in: start_date, check_out: end_date, room: room)
room.bookings << new_reservation
return new_reservation
else
raise ArgumentError, "There are no available rooms for this date range"
end

end

end

end

end

def search_reservation(date:)
search_date = Date.parse(date.to_s)
search_result = []

@rooms.each do |room|

if room.bookings.length != 0
room.bookings.each do |booking|

if search_date.between?(booking.check_in, booking.check_out) == true
search_result << booking
end

end

end

end

return search_result

end

end

end
29 changes: 29 additions & 0 deletions lib/reservation.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
require "date"

require_relative "room"
require_relative "booker"
require_relative "block"

module Hotel
class Reservation
attr_reader :check_in, :check_out, :total_cost, :room

def initialize(check_in:, check_out:, room: nil)
@check_in = Date.parse(check_in.to_s)
@check_out = Date.parse(check_out.to_s)
@total_cost = (@check_out - @check_in).to_i * 200
@room = room || nil

if @check_out <= @check_in
raise ArgumentError, "End time can't be earlier than or equal to start time"
end

end

def total_cost
return @total_cost
end

end

end
27 changes: 27 additions & 0 deletions lib/room.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
require "date"

require_relative "reservation"
require_relative "booker"
require_relative "block"

module Hotel
class Room
attr_reader :number, :bookings

def initialize(number:, booking: nil)
@number = number
@bookings = booking || []

if @number.class != Integer
raise ArgumentError, "room number must be an interger"
elsif @number < 1
raise ArgumentError, "room number can not be less than 1"
end

end

# would create a add_room method if the hotel would expand rooms in the future

end

end
7 changes: 7 additions & 0 deletions refactors.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Simplify "make_reservation" method for Booker by utilizing its "available_room" method
Research Date gem ~ current code requires user input in string for "check_in" & "check_out"
Update all syntax from "instance_variable_get" to "." in all files
Update test files to reach 100% code coverage
Finish Wave_3 (& additional enhancement as time allows)
Remove "@reservations" from Booker if no longer useful/necessary for the design
Keep practicing and get really comfortable with VS code debugging tool, guard, and SimpleCov
Empty file added test/block_test.rb
Empty file.
165 changes: 165 additions & 0 deletions test/booker_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
require_relative "test_helper"

describe "Booker class" do

describe "Booker initialization" do

it "throws argument erros for invalid inventory input" do
expect{Hotel::Booker.new(inventory: '20')}.must_raise ArgumentError
expect{Hotel::Booker.new(inventory: 0)}.must_raise ArgumentError
end

before do
@new_booker = Hotel::Booker.new(inventory: 20)
end

it "is an instance of Booker" do
expect(@new_booker).must_be_kind_of Hotel::Booker
end

it "has an empty array for reservations" do
expect(@new_booker.reservations).must_be_kind_of Array
expect(@new_booker.reservations.length).must_equal 0
end

it "has an array of Room instances matching with the inventory number" do
expect(@new_booker.rooms).must_be_kind_of Array
expect(@new_booker.rooms.first).must_be_kind_of Hotel::Room
expect(@new_booker.rooms.last).must_be_kind_of Hotel::Room
expect(@new_booker.rooms.length).must_equal 20
end

end

describe "all_rooms method" do

Choose a reason for hiding this comment

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

I like this inventory feature, but your hotel was supposed to have 20 rooms.

it "must return an array of Room instances matching with the inventory number" do
expect(Hotel::Booker.new(inventory: 33).all_rooms).must_be_kind_of Array
expect(Hotel::Booker.new(inventory: 33).all_rooms.first).must_be_kind_of Hotel::Room
expect(Hotel::Booker.new(inventory: 33).all_rooms.last).must_be_kind_of Hotel:: Room
expect(Hotel::Booker.new(inventory: 33).all_rooms.length).must_equal 33
end

end

describe "available_rooms method" do
before do
@new_booker = Hotel::Booker.new(inventory: 2)
end

it "throws ArgumentError for invalid check_in and check_out dates" do
expect{ @new_booker.make_reservation(check_in: "2019-09-01", check_out: "2019-09-01") }.must_raise ArgumentError
expect{ @new_booker.make_reservation(check_in: "2019-09-02", check_out: "2019-09-01") }.must_raise ArgumentError
end

it "throws ArgumentError when there is no available rooms during the given date range" do
rooms = @new_booker.rooms
rooms[0].bookings << Hotel::Reservation.new(check_in: "2019-09-01", check_out: "2019-09-04", room: 1)

Choose a reason for hiding this comment

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

Consider storing the dates in variables so it is clear what you are testing.

Suggested change
rooms[0].bookings << Hotel::Reservation.new(check_in: "2019-09-01", check_out: "2019-09-04", room: 1)
check_in_date = "2019-09-01"
check_out_date = "2019-09-04"

rooms[1].bookings << Hotel::Reservation.new(check_in: "2019-09-02", check_out: "2019-09-05", room: 2)

expect{ @new_booker.make_reservation(check_in: "2019-09-02", check_out: "2019-09-04") }.must_raise ArgumentError
expect{ @new_booker.make_reservation(check_in: "2019-09-01", check_out: "2019-09-05") }.must_raise ArgumentError
expect{ @new_booker.make_reservation(check_in: "2019-08-30", check_out: "2019-09-03") }.must_raise ArgumentError
expect{ @new_booker.make_reservation(check_in: "2019-09-03", check_out: "2019-09-07") }.must_raise ArgumentError
end

it "will add room with no bookings to the avaliable rooms search result" do
search = @new_booker.available_rooms(check_in: "2019-09-08", check_out: "2019-09-09")
expect(search.length).must_equal 2
end

it "returns an array of all Room instances avaliable during the given date range" do
rooms = @new_booker.rooms
rooms[0].bookings << Hotel::Reservation.new(check_in: "2019-09-01", check_out: "2019-09-04", room: 1)
rooms[1].bookings << Hotel::Reservation.new(check_in: "2019-09-02", check_out: "2019-09-05", room: 2)

search_1 = @new_booker.available_rooms(check_in: "2019-09-04", check_out: "2019-09-07")
search_2 = @new_booker.available_rooms(check_in: "2019-08-30", check_out: "2019-09-01")

expect(search_1).must_be_kind_of Array
expect(search_2).must_be_kind_of Array

expect(search_1.length).must_equal 1
expect(search_2.length).must_equal 2

expect(search_1[0]).must_be_kind_of Hotel::Room
expect(search_2.first).must_be_kind_of Hotel::Room
expect(search_2.last).must_be_kind_of Hotel::Room
end

end

describe "make_reservation method" do

Choose a reason for hiding this comment

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

Nice, comprehensive tests.

before do
@new_booker = Hotel::Booker.new(inventory: 2)
end

it "throws ArgumentError for invalid check_in and check_out dates" do
expect{ @new_booker.make_reservation(check_in: "2019-09-01", check_out: "2019-09-01") }.must_raise ArgumentError
expect{ @new_booker.make_reservation(check_in: "2019-09-02", check_out: "2019-09-01") }.must_raise ArgumentError
end

it "throws ArgumentError when there is no available rooms during the given date range" do
rooms = @new_booker.rooms
rooms[0].bookings << Hotel::Reservation.new(check_in: "2019-09-01", check_out: "2019-09-04", room: 1)
rooms[1].bookings << Hotel::Reservation.new(check_in: "2019-09-02", check_out: "2019-09-05", room: 2)

expect{ @new_booker.make_reservation(check_in: "2019-09-02", check_out: "2019-09-04") }.must_raise ArgumentError
expect{ @new_booker.make_reservation(check_in: "2019-09-01", check_out: "2019-09-05") }.must_raise ArgumentError
expect{ @new_booker.make_reservation(check_in: "2019-08-30", check_out: "2019-09-03") }.must_raise ArgumentError
expect{ @new_booker.make_reservation(check_in: "2019-09-03", check_out: "2019-09-07") }.must_raise ArgumentError
end

it "creats a Resveration instance with the correct Room instance(s)" do
rooms = @new_booker.rooms
rooms[0].bookings << Hotel::Reservation.new(check_in: "2019-09-01", check_out: "2019-09-04", room: 1)
rooms[1].bookings << Hotel::Reservation.new(check_in: "2019-09-02", check_out: "2019-09-05", room: 2)
new_reservation = @new_booker.make_reservation(check_in: "2019-09-04", check_out: "2019-09-07")
reserved_room = new_reservation.room
updated_room_bookings = reserved_room.bookings

expect(new_reservation).must_be_kind_of Hotel::Reservation
expect(reserved_room.number).must_equal 1
expect(updated_room_bookings.length).must_equal 2

end

end

describe "search_reservation method" do
before do
@new_booker = Hotel::Booker.new(inventory: 2)
end

it "throws ArgumentError when there is no available rooms during the given date range" do
rooms = @new_booker.rooms
rooms[0].bookings << Hotel::Reservation.new(check_in: "2019-09-07", check_out: "2019-09-08", room: 1)
rooms[1].bookings << Hotel::Reservation.new(check_in: "2019-09-08", check_out: "2019-09-09", room: 2)

expect{ @new_booker.make_reservation(check_in: "2019-09-02", check_out: "2019-09-08") }.must_raise ArgumentError

end

it "creates an array of all reservations on that date" do
rooms = @new_booker.rooms
rooms[0].bookings << Hotel::Reservation.new(check_in: "2019-10-20", check_out: "2019-10-25", room: 1)
rooms[1].bookings << Hotel::Reservation.new(check_in: "2019-09-30", check_out: "2019-10-20", room: 2)
result_1 = @new_booker.search_reservation(date: '2019-10-03')
result_2 = @new_booker.search_reservation(date: '2019-10-20')
result_3 = @new_booker.search_reservation(date: '2019-10-26')

expect(result_1).must_be_kind_of Array
expect(result_2).must_be_kind_of Array
expect(result_3).must_be_kind_of Array

expect(result_1.length).must_equal 1
expect(result_2.length).must_equal 2
expect(result_3.length).must_equal 0

expect(result_1[0]).must_be_kind_of Hotel::Reservation
expect(result_2[1]).must_be_kind_of Hotel::Reservation
end

end

end

5 changes: 5 additions & 0 deletions test/coverage/.last_run.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"result": {
"covered_percent": 100.0
}
}
7 changes: 7 additions & 0 deletions test/coverage/.resultset.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"MiniTest": {
"coverage": {
},
"timestamp": 1567911677
}
}
Empty file.
Loading