Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Karinna Iniguez - Hotel - Octos #34

Open
wants to merge 20 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
ef50e2c
Add directories, Rakefile, Coverage directory, and room production an…
karinnainiguez Mar 5, 2018
595cb25
Add spec file and production file for reservation class
karinnainiguez Mar 5, 2018
051489b
Add spec and production files for booking class
karinnainiguez Mar 5, 2018
8df9ae7
Add tests and functionality for Room#number method
karinnainiguez Mar 5, 2018
33647b2
Tests for Room#number passing
karinnainiguez Mar 5, 2018
a7717bc
Add tests and functionality for Room#price
karinnainiguez Mar 5, 2018
e84bbd7
Add tests for Booking class. An admin can access the list of all the…
karinnainiguez Mar 5, 2018
7fdc841
Add reservation and booking tests for initalize methods. Add functio…
karinnainiguez Mar 6, 2018
11b42ad
Add tests and functionality room#reserve and room#reserved? methods.
karinnainiguez Mar 6, 2018
41e3e7a
Change reservations. Room is now a required argument and must be ins…
karinnainiguez Mar 6, 2018
dc7b4ad
Pass tests requiring reservation to have a room instance as argument
karinnainiguez Mar 6, 2018
c1f7940
Add helper methods to validate dates and validate stays in reservatio…
karinnainiguez Mar 6, 2018
f699e43
Add loader class for helper methods used in all classes and have each…
karinnainiguez Mar 6, 2018
bc6d77f
Add tests for Booking#reserve method and add functionality including …
karinnainiguez Mar 8, 2018
7e28235
Adding filter to remove specs from coverage
karinnainiguez Mar 8, 2018
5415673
Add tests and functionality for Reservation#total_cost method and hel…
karinnainiguez Mar 8, 2018
78ff624
Change loader class to more appropriate name. New name is Validate cl…
karinnainiguez Mar 12, 2018
e3eb848
remove unused files for block class. Program not using that class af…
karinnainiguez Mar 12, 2018
2226e78
removing file
karinnainiguez Mar 12, 2018
9ad17c0
Refactor
karinnainiguez Mar 12, 2018
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
9 changes: 9 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
require 'rake/testtask'

Rake::TestTask.new do |t|
t.libs = ["lib"]
t.warning = true
t.test_files = FileList['specs/*_spec.rb']
end

task default: :test
78 changes: 78 additions & 0 deletions lib/booking.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
require 'set'
require_relative 'validate'
require_relative 'reservation'
require_relative 'room'

module Hotel
class Booking < Validate

NUM_OF_ROOMS = 20

attr_reader :rooms, :reservations

def initialize
@rooms = []
@reservations = []
@blocks = []
create_rooms
end # initialize

def create_rooms
NUM_OF_ROOMS.times do |i|
data = {number: i+1}
@rooms << Room.new(data)
end
end # create_rooms

def room_by_num(num)
@rooms.find do |room|
room.number == num
end
end


def rooms_by_day(date, block: nil)
date = validate_date(date)
@rooms.reject do |room|
room.reserved?(date) && room.blocked?(date)
end
end

def rooms_by_range(start_date, end_date, block: nil)
start_date = validate_date(start_date)
end_date = validate_date(end_date)
date_set = Set.new(start_date...end_date)

avail_array = @rooms.reject do |room|
date_set.intersect? room.reserved.to_set
end

if block
avail_array = avail_array.reject do |room|
date_set.intersect? room.booked[block].to_set
end
end

return avail_array
end


def reserve(data)
start_date = validate_date(data[:start_date])
end_date = validate_date(data[:end_date])
available_rooms = rooms_by_range(start_date, end_date, block: data[:block])
if available_rooms.length == 0
raise ArgumentError.new("Sorry, we do not have a room available at this time")
else
room = available_rooms.sample
end

reservation = Reservation.new(start_date: start_date, end_date: end_date, room: room)
@reservations << reservation
room.reserve(start_date, end_date, block: data[:block])
return reservation
end


end # Class Booking
end # Module Hotel
39 changes: 39 additions & 0 deletions lib/reservation.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@

require_relative 'validate'
require_relative 'room'

module Hotel
class Reservation < Validate

BLOCK_DISCOUNT = 0.20

attr_reader :start_date, :end_date, :room

def initialize(data)
if data[:room].class != Room
raise ArgumentError.new("Must enter room to be reserved")
end
@room = data[:room]

@start_date = validate_date(data[:start_date])
@end_date = validate_date(data[:end_date])
validate_stay(@start_date, @end_date)

# OPTIONAL
@block = data[:block] # NIL if not provided
end

def total_cost
cost = stay_length * @room.price
if @block
cost *= BLOCK_DISCOUNT
end
return cost
end

def stay_length
@end_date - @start_date
end

end # Class Reservation
end # Module Hotel
60 changes: 60 additions & 0 deletions lib/room.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@

require_relative 'validate'
require 'date'

module Hotel
class Room < Validate

attr_reader :number, :reserved, :blocked
attr_accessor :price

def initialize(data)
if data[:number] == nil || data[:number].class != Integer || data[:number] < 1
raise ArgumentError.new("Rooms must have a positive integer for room number. Received #{number}")
end
@number = data[:number]
@price = data[:price].to_f ||= 200.00
@reserved = []
@blocked = {}
end

def reserved?(date)
date = validate_date(date)
if @reserved.include?(date)
return true
else
return false
end
end

def reserve(start_date, end_date, block: nil)
start_date = validate_date(start_date)
end_date = validate_date(end_date)
validate_stay(start_date, end_date)
stay = end_date - start_date

stay.to_i.times do |index|
@reserved << start_date + index
end
end

def blocked?(date)

Choose a reason for hiding this comment

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

Methods that end in the ? should return true or false

date = validate_date(date)
existing_blocks = @blocked.find do |name, dates|
dates.include?(date)
end
return existing_blocks.keys
end

def block(date, name)
date = validate_date(date)
if @blocked[name]
@blocked[name] << date
else
@blocked[name] = [date]
end
end


end # Class Room
end # Module Hotel
35 changes: 35 additions & 0 deletions lib/validate.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
require 'date'
module Hotel
class Validate

OLDEST_RES_DATE = Date.new(1900, 01, 01)
NEWEST_RES_DATE = Date.new(3999, 12, 31)

def validate_date(entry)
if entry.class == String
entry = Date.strptime(entry, '%m/%d/%Y')
if entry.class != Date || entry < OLDEST_RES_DATE || entry > NEWEST_RES_DATE
raise ArgumentError.new("Invalid date. Please enter MM/DD/YYYY Received #{entry}")
end
elsif entry.class == Date
if entry < OLDEST_RES_DATE || entry > NEWEST_RES_DATE
raise ArgumentError.new("Date: Invalid date. Received #{entry}")
end
else
raise ArgumentError.new("Other: Invalid date. Received #{entry}")
end
return entry
end

def validate_stay(beginning, ending)
beginning = validate_date(beginning)
ending = validate_date(ending)
if beginning > ending
raise ArgumentError.new("Start date cannot be after end date")
end
return (ending - beginning).to_i
end

end # class loader

end # module Hotel
111 changes: 111 additions & 0 deletions specs/booking_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
require_relative 'spec_helper'

describe "Booking Class" do

describe "#initialize" do

it "can be created" do
result = Hotel::Booking.new
result.must_be_kind_of Hotel::Booking
end

it "has a rooms array" do
booking = Hotel::Booking.new
booking.rooms.must_be_kind_of Array
end

it "has collection of 20 rooms" do
booking = Hotel::Booking.new
booking.rooms.length.must_equal 20
booking.rooms.each do |room|
room.must_be_kind_of Hotel::Room
end
end

end # initialize

describe "#room_by_num" do

before do
@booking = Hotel::Booking.new
end

it "returns an instance of room" do
result = @booking.room_by_num(12)
result.must_be_kind_of Hotel::Room
end

it "returns nil if room does not exist" do
result = @booking.room_by_num(67)
result.must_be_nil
end

it "returns nil if invalid argument given" do
result = @booking.room_by_num("Some String")
result.must_be_nil
end

end # room_by_num

describe "#reserve" do

it "returns a reservation with start date and end date." do
book = Hotel::Booking.new
start = Date.new(2018, 04, 02)

result = book.reserve(start_date: start, end_date: start + 3)
result.must_be_kind_of Hotel::Reservation
end

it "updates the reservations array" do
book = Hotel::Booking.new
before = book.reservations.length
book.reserve(start_date: "05/02/2018", end_date: "05/08/2018")
after = book.reservations.length
after.must_equal before + 1
book.reservations[0].must_be_kind_of Hotel::Reservation
end

it "raises an error if no available rooms" do
book = Hotel::Booking.new
20.times do
book.reserve(start_date: "06/01/2018", end_date: "06/03/2018")
end
proc {
book.reserve(start_date: "06/01/2018", end_date: "06/03/2018")
}.must_raise ArgumentError
end

it "raises an error if incorrect date information is given" do
book = Hotel::Booking.new
proc {
book.reserve(start_date: "August 29th", end_date: "09/30/2018")
}.must_raise ArgumentError
end

it "raises an error if no start date or end date is given" do
book = Hotel::Booking.new
proc {
book.reserve(end_date: "09/30/2018")
}.must_raise ArgumentError

proc {
book.reserve(start_date: "09/30/2018")
}.must_raise ArgumentError

proc {
book.reserve()
}.must_raise ArgumentError
end

it "raises an error if end date is before start date" do
book = Hotel::Booking.new
proc {
book.reserve(start_date: "11/01/2018", end_date: "09/30/2018")
}.must_raise ArgumentError
end


end # reserve

end # Booking Class
Loading