From 8ed137f844705e1fc8b79905e86c0d45f8020db9 Mon Sep 17 00:00:00 2001 From: kangazoom Date: Tue, 4 Sep 2018 15:00:42 -0700 Subject: [PATCH 01/36] created booking_system and room initialize vars plus tests --- Guardfile | 3 +-- lib/booking_system.rb | 33 +++++++++++++++++++++++++++++++++ lib/reservation.rb | 8 ++++++++ lib/room.rb | 10 ++++++++++ spec/booking_system_spec.rb | 36 ++++++++++++++++++++++++++++++++++++ spec/reservation_spec.rb | 19 +++++++++++++++++++ spec/room_spec.rb | 22 ++++++++++++++++++++++ spec/spec_helper.rb | 4 +++- 8 files changed, 132 insertions(+), 3 deletions(-) create mode 100644 lib/booking_system.rb create mode 100644 lib/reservation.rb create mode 100644 lib/room.rb create mode 100644 spec/booking_system_spec.rb create mode 100644 spec/reservation_spec.rb create mode 100644 spec/room_spec.rb diff --git a/Guardfile b/Guardfile index 6760f9177..471693a4d 100644 --- a/Guardfile +++ b/Guardfile @@ -1,5 +1,4 @@ -guard :minitest, bundler: false, rubygems: false do - # with Minitest::Spec +guard :minitest, bundler: false, autorun: false, rubygems: false do # with Minitest::Spec watch(%r{^spec/(.*)_spec\.rb$}) watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" } watch(%r{^spec/spec_helper\.rb$}) { 'spec' } diff --git a/lib/booking_system.rb b/lib/booking_system.rb new file mode 100644 index 000000000..f716ad667 --- /dev/null +++ b/lib/booking_system.rb @@ -0,0 +1,33 @@ +require_relative 'room' + +module Hotel + class BookingSystem + attr_accessor :rooms + def initialize() + @rooms = load_rooms() #<-- array of all rooms + end + + def load_rooms() + nums = (1..20).to_a + all_rooms = nums.map { |num| Hotel::Room.new(num)} + + return all_rooms + end + + def list_all_rooms() + + puts "Here is a list of all rooms: " + @rooms.each do |room| + puts room + end + end + + end +end + + +# booking = Hotel::BookingSystem.new() +# rooms_list = booking.load_rooms +# +# puts rooms_list +# puts rooms_list[0].num diff --git a/lib/reservation.rb b/lib/reservation.rb new file mode 100644 index 000000000..946462ccc --- /dev/null +++ b/lib/reservation.rb @@ -0,0 +1,8 @@ +module Hotel + class BookingSystem + attr_accessor :name + def initialize(name) + @name = name + end + end +end diff --git a/lib/room.rb b/lib/room.rb new file mode 100644 index 000000000..3e35c3670 --- /dev/null +++ b/lib/room.rb @@ -0,0 +1,10 @@ +module Hotel + class Room + attr_accessor :num + + def initialize(num) + @num = num + end + + end +end diff --git a/spec/booking_system_spec.rb b/spec/booking_system_spec.rb new file mode 100644 index 000000000..2804eda7c --- /dev/null +++ b/spec/booking_system_spec.rb @@ -0,0 +1,36 @@ +require 'minitest' +require 'minitest/spec' +require 'minitest/autorun' +require 'minitest/reporters' +require 'minitest/pride' + +require_relative '../lib/booking_system' + +Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new + + +describe "BookingSystem class" do + let(:booking) {Hotel::BookingSystem.new()} + let(:rooms_list) {booking.load_rooms()} + + describe "#initialize" do + it "can create a new instance of BookingSystem" do + expect(booking).must_be_kind_of Hotel::BookingSystem + end + + it "can load a list of rooms" do + expect(rooms_list).must_be_kind_of Array + end + + it "accurately loads room info in array" do + first_room = rooms_list[0] + last_room= rooms_list[-1] + + expect(first_room).must_be_kind_of Hotel::Room + expect(first_room.num).must_equal 1 + + expect(last_room).must_be_kind_of Hotel::Room + expect(last_room.num).must_equal 20 +end + end +end diff --git a/spec/reservation_spec.rb b/spec/reservation_spec.rb new file mode 100644 index 000000000..c8265b00a --- /dev/null +++ b/spec/reservation_spec.rb @@ -0,0 +1,19 @@ +require 'minitest' +require 'minitest/spec' +require 'minitest/autorun' +require 'minitest/reporters' +require 'minitest/pride' + +require_relative '../lib/Reservation' + +Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new + + +describe "Reservation" do + it "can create a new instance of hotel" do + name = "Hotel California" + hotel = Hotel.new(name) + + expect(hotel.name).must_equal name + end +end diff --git a/spec/room_spec.rb b/spec/room_spec.rb new file mode 100644 index 000000000..502f3c25c --- /dev/null +++ b/spec/room_spec.rb @@ -0,0 +1,22 @@ +require 'minitest' +require 'minitest/spec' +require 'minitest/autorun' +require 'minitest/reporters' +require 'minitest/pride' + +require_relative '../lib/Room' + +Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new + + +describe "Room" do + describe "#initialize" do + it "can create a new instance of room" do + num = 5 + hotel = Hotel::Room.new(num) + + expect(hotel).must_be_kind_of Hotel::Room + expect(hotel.num).must_equal num + end + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 4d1e3fdc8..0889979f3 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,7 +1,9 @@ require 'minitest' require 'minitest/autorun' require 'minitest/reporters' -# Add simplecov + +require 'simplecov' +SimpleCov.start Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new From 02b9d7082464ce25c7f3b512da32c729da9b1e93 Mon Sep 17 00:00:00 2001 From: kangazoom Date: Tue, 4 Sep 2018 16:03:26 -0700 Subject: [PATCH 02/36] created room class and test + updated booking system class to begin to handle reservations --- lib/booking_system.rb | 21 +++++++++++++++------ lib/reservation.rb | 13 +++++++++---- lib/room.rb | 2 ++ spec/booking_system_spec.rb | 20 ++++++++++++++++++-- spec/reservation_spec.rb | 18 ++++++++++++++---- spec/spec_helper.rb | 4 +++- 6 files changed, 61 insertions(+), 17 deletions(-) diff --git a/lib/booking_system.rb b/lib/booking_system.rb index f716ad667..3914e712c 100644 --- a/lib/booking_system.rb +++ b/lib/booking_system.rb @@ -1,10 +1,12 @@ require_relative 'room' +require_relative 'reservation' module Hotel class BookingSystem - attr_accessor :rooms + attr_accessor :rooms, :reservations def initialize() @rooms = load_rooms() #<-- array of all rooms + @reservations = [] end def load_rooms() @@ -15,11 +17,20 @@ def load_rooms() end def list_all_rooms() + all_rooms_str = "Here is a list of all rooms: \n" - puts "Here is a list of all rooms: " @rooms.each do |room| - puts room + all_rooms_str << "- Room #{room.num} \n" end + + return all_rooms_str + end + + def add_reservation(reservation) + @reservations << reservation + end + + def list_reservations_by_date() end end @@ -27,7 +38,5 @@ def list_all_rooms() # booking = Hotel::BookingSystem.new() -# rooms_list = booking.load_rooms # -# puts rooms_list -# puts rooms_list[0].num +# puts booking.list_all_rooms diff --git a/lib/reservation.rb b/lib/reservation.rb index 946462ccc..392cb9813 100644 --- a/lib/reservation.rb +++ b/lib/reservation.rb @@ -1,8 +1,13 @@ module Hotel - class BookingSystem - attr_accessor :name - def initialize(name) - @name = name + class Reservation + attr_accessor :id, :room_num, :date_start, :date_end, :cost + + def initialize(id, room_num, date_start, date_end, cost=200) + @id = id + @room_num = room_num + @date_start = date_start + @date_end = date_end + @cost = cost end end end diff --git a/lib/room.rb b/lib/room.rb index 3e35c3670..7e9cb15dd 100644 --- a/lib/room.rb +++ b/lib/room.rb @@ -1,3 +1,5 @@ +require 'date' + module Hotel class Room attr_accessor :num diff --git a/spec/booking_system_spec.rb b/spec/booking_system_spec.rb index 2804eda7c..4d011a58f 100644 --- a/spec/booking_system_spec.rb +++ b/spec/booking_system_spec.rb @@ -11,12 +11,15 @@ describe "BookingSystem class" do let(:booking) {Hotel::BookingSystem.new()} - let(:rooms_list) {booking.load_rooms()} describe "#initialize" do it "can create a new instance of BookingSystem" do expect(booking).must_be_kind_of Hotel::BookingSystem end + end + + describe "#load_rooms" do + let(:rooms_list) {booking.load_rooms()} it "can load a list of rooms" do expect(rooms_list).must_be_kind_of Array @@ -31,6 +34,19 @@ expect(last_room).must_be_kind_of Hotel::Room expect(last_room.num).must_equal 20 -end + end + end + + describe "#list_all_rooms" do + let(:all_rooms_str) {booking.list_all_rooms()} + + it "lists all rooms as a string" do + beginning_text = "Here is a list of all rooms:" + room_2 = "Room 2" + + expect(all_rooms_str).must_be_kind_of String + expect(all_rooms_str).must_include beginning_text + expect(all_rooms_str).must_include room_2 + end end end diff --git a/spec/reservation_spec.rb b/spec/reservation_spec.rb index c8265b00a..fe2b9164f 100644 --- a/spec/reservation_spec.rb +++ b/spec/reservation_spec.rb @@ -10,10 +10,20 @@ describe "Reservation" do - it "can create a new instance of hotel" do - name = "Hotel California" - hotel = Hotel.new(name) + # QUESTION: needed for creation: id, room_num, date_start, date_end, cost=200 + # ^^ keyword args? hash input?? + # TODO: test end date AFTER start date + # TODO: test cost as float? + # TODO: test id as any pos int + # TODO: test room_num as 1-20 + let(:start_date) {Time.new(2004, 7, 1)} + let(:end_date) {Time.new(2004, 7, 4)} + let(:reservation) {Hotel::Reservation.new(2, 3, start_date, end_date)} - expect(hotel.name).must_equal name + describe "#initialize" + it "can create a new instance of reservation" do + expect(reservation).must_be_kind_of Hotel::Reservation + expect(reservation.id).must_equal 2 + end end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 0889979f3..746bbc31d 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -7,4 +7,6 @@ Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new -# Require_relative your lib files here! +require_relative '../lib/booking_system' +require_relative '../lib/room' +require_relative '../lib/reservation' From 3275135ac668469f37bb5030573865cac3e8d71e Mon Sep 17 00:00:00 2001 From: kangazoom Date: Tue, 4 Sep 2018 16:24:15 -0700 Subject: [PATCH 03/36] Created Reservation#dates_reserved + tests --- lib/reservation.rb | 15 +++++++++++---- spec/reservation_spec.rb | 25 ++++++++++++++++++++++--- 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/lib/reservation.rb b/lib/reservation.rb index 392cb9813..a0d6342b9 100644 --- a/lib/reservation.rb +++ b/lib/reservation.rb @@ -1,13 +1,20 @@ +require 'time' + module Hotel class Reservation - attr_accessor :id, :room_num, :date_start, :date_end, :cost + attr_accessor :id, :room_num, :start_date, :end_date, :cost - def initialize(id, room_num, date_start, date_end, cost=200) + def initialize(id, room_num, start_date, end_date, cost=200) @id = id @room_num = room_num - @date_start = date_start - @date_end = date_end + @start_date = start_date + @end_date = end_date @cost = cost end + + def dates_reserved() + # don't include the end end_date since that is the checkout date + return (@start_date...@end_date).to_a + end end end diff --git a/spec/reservation_spec.rb b/spec/reservation_spec.rb index fe2b9164f..b1164d8f2 100644 --- a/spec/reservation_spec.rb +++ b/spec/reservation_spec.rb @@ -16,14 +16,33 @@ # TODO: test cost as float? # TODO: test id as any pos int # TODO: test room_num as 1-20 - let(:start_date) {Time.new(2004, 7, 1)} - let(:end_date) {Time.new(2004, 7, 4)} + let(:start_date) {Date.new(2004, 7, 1)} + let(:end_date) {Date.new(2004, 7, 4)} let(:reservation) {Hotel::Reservation.new(2, 3, start_date, end_date)} - describe "#initialize" + describe "#initialize" do it "can create a new instance of reservation" do expect(reservation).must_be_kind_of Hotel::Reservation expect(reservation.id).must_equal 2 end end + + describe "#dates_reserved" do + # TODO: test edge cases like same start/end date + # TODO: error handling for bad start/end dates (above?) + it "returns an array of Time objects" do + + expect(reservation.dates_reserved).must_be_kind_of Array + expect(reservation.dates_reserved()[0]).must_be_kind_of Date + + second_date = Date.new(2004, 7, 2) + expect(reservation.dates_reserved[1]).must_equal second_date + end + it "can list all the dates of a reservation" do + expect(reservation.dates_reserved.length).must_equal 3 + + second_date = Date.new(2004, 7, 2) + expect(reservation.dates_reserved[1]).must_equal second_date + end + end end From 524d46bb946c1d26e0d32787eaa97ac07a3125e0 Mon Sep 17 00:00:00 2001 From: kangazoom Date: Tue, 4 Sep 2018 16:49:25 -0700 Subject: [PATCH 04/36] added BookingSystem methods to create, add, and load reservations. Also added a method to find reservations that match a certain date --- lib/booking_system.rb | 17 ++++++++++++++++- spec/booking_system_spec.rb | 14 ++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/lib/booking_system.rb b/lib/booking_system.rb index 3914e712c..3b46e9fcd 100644 --- a/lib/booking_system.rb +++ b/lib/booking_system.rb @@ -26,11 +26,26 @@ def list_all_rooms() return all_rooms_str end +# QUESTION: ughhhh, inputtt??? this is not DRY + def create_reservation(id, room_num, start_date, end_date, cost=200) + new_reservation = Reservation.new(id, room_num, start_date, end_date, cost) + return new_reservation + end + def add_reservation(reservation) @reservations << reservation end - def list_reservations_by_date() + def load_reservations() + new_reservation = create_reservation() + add_reservation(new_reservation) + return @reservations + end + + + def list_reservations_by_date(date) + #TODO error handling for date as Date object?? + return res_by_date = @reservations.map { |reservation| reservation.date == date } end end diff --git a/spec/booking_system_spec.rb b/spec/booking_system_spec.rb index 4d011a58f..d32d39a3d 100644 --- a/spec/booking_system_spec.rb +++ b/spec/booking_system_spec.rb @@ -49,4 +49,18 @@ expect(all_rooms_str).must_include room_2 end end + + # TODO - below + + describe "#create_reservation" do + end + + describe "#add_reservation" do + end + + describe "#load_reservations" do + end + + describe "#list_reservations_by_date" do + end end From 67da127dcf4766187d0852b044ed00525fbcba87 Mon Sep 17 00:00:00 2001 From: kangazoom Date: Tue, 4 Sep 2018 22:05:24 -0700 Subject: [PATCH 05/36] changed Room#initialize args to hash input + adjusted tests --- lib/booking_system.rb | 12 ++++++++++-- lib/reservation.rb | 7 ++++--- lib/room.rb | 11 ++++++++--- spec/room_spec.rb | 9 ++++++--- 4 files changed, 28 insertions(+), 11 deletions(-) diff --git a/lib/booking_system.rb b/lib/booking_system.rb index 3b46e9fcd..194378295 100644 --- a/lib/booking_system.rb +++ b/lib/booking_system.rb @@ -9,6 +9,7 @@ def initialize() @reservations = [] end +# TODO: maybe separate load class? def load_rooms() nums = (1..20).to_a all_rooms = nums.map { |num| Hotel::Room.new(num)} @@ -27,8 +28,11 @@ def list_all_rooms() end # QUESTION: ughhhh, inputtt??? this is not DRY - def create_reservation(id, room_num, start_date, end_date, cost=200) - new_reservation = Reservation.new(id, room_num, start_date, end_date, cost) + def create_reservation(input) + room = find_room(room_num) + + new_reservation = Reservation.new(input) + new_reservation = Reservation.new(id, room, start_date, end_date, cost) return new_reservation end @@ -48,6 +52,10 @@ def list_reservations_by_date(date) return res_by_date = @reservations.map { |reservation| reservation.date == date } end + def find_room(room_num) + return @rooms.map {|room| room.num == room_num} + end + end end diff --git a/lib/reservation.rb b/lib/reservation.rb index a0d6342b9..26d9745a5 100644 --- a/lib/reservation.rb +++ b/lib/reservation.rb @@ -2,11 +2,11 @@ module Hotel class Reservation - attr_accessor :id, :room_num, :start_date, :end_date, :cost + attr_accessor :id, :room, :start_date, :end_date, :cost - def initialize(id, room_num, start_date, end_date, cost=200) + def initialize(id, room, start_date, end_date, cost=200) @id = id - @room_num = room_num + @room = room # object; not num @start_date = start_date @end_date = end_date @cost = cost @@ -16,5 +16,6 @@ def dates_reserved() # don't include the end end_date since that is the checkout date return (@start_date...@end_date).to_a end + end end diff --git a/lib/room.rb b/lib/room.rb index 7e9cb15dd..5032e5bbf 100644 --- a/lib/room.rb +++ b/lib/room.rb @@ -2,10 +2,15 @@ module Hotel class Room - attr_accessor :num + attr_accessor :num, :reservations - def initialize(num) - @num = num + def initialize(input) + @num = input[:num] + @reservations = [] + end + + def add_reservation(reservation) + @reservations << reservation end end diff --git a/spec/room_spec.rb b/spec/room_spec.rb index 502f3c25c..71ae9f556 100644 --- a/spec/room_spec.rb +++ b/spec/room_spec.rb @@ -12,11 +12,14 @@ describe "Room" do describe "#initialize" do it "can create a new instance of room" do - num = 5 - hotel = Hotel::Room.new(num) + room_hash = { + num: 4 + } + + hotel = Hotel::Room.new(room_hash) expect(hotel).must_be_kind_of Hotel::Room - expect(hotel.num).must_equal num + expect(hotel.num).must_equal room_hash[:num] end end end From 26bab8a30d49632c754057136f63313d763bfb14 Mon Sep 17 00:00:00 2001 From: kangazoom Date: Tue, 4 Sep 2018 22:53:25 -0700 Subject: [PATCH 06/36] Added additional tests and error handling for Room#initialize --- lib/room.rb | 8 ++++++- spec/room_spec.rb | 59 ++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 60 insertions(+), 7 deletions(-) diff --git a/lib/room.rb b/lib/room.rb index 5032e5bbf..34b93f3fd 100644 --- a/lib/room.rb +++ b/lib/room.rb @@ -6,7 +6,13 @@ class Room def initialize(input) @num = input[:num] - @reservations = [] + @reservations = input[:reservations].nil? ? [] : input[:reservations] + + # QUESTION: move up?? + unless (1..20).include? @num + raise ArgumentError, "This is not a valid room number." + end + end def add_reservation(reservation) diff --git a/spec/room_spec.rb b/spec/room_spec.rb index 71ae9f556..2dd6e86da 100644 --- a/spec/room_spec.rb +++ b/spec/room_spec.rb @@ -10,16 +10,63 @@ describe "Room" do + let(:room_hash) {{num: 4}} + let(:room) {Hotel::Room.new(room_hash)} + + describe "#initialize" do it "can create a new instance of room" do - room_hash = { - num: 4 - } - hotel = Hotel::Room.new(room_hash) + expect(room).must_be_kind_of Hotel::Room + expect(room.num).must_equal room_hash[:num] + end - expect(hotel).must_be_kind_of Hotel::Room - expect(hotel.num).must_equal room_hash[:num] + it "has room id as an integer" do + expect(room.num).must_be_kind_of Integer + end + + it "throws an argument error with a bad room num value" do + expect { + Hotel::Room.new(num: 21) + }.must_raise ArgumentError + + expect { + Hotel::Room.new(num: 0) + }.must_raise ArgumentError + end + + it "sets reservations to an empty array if not provided" do + expect(room.reservations).must_be_kind_of Array + expect(room.reservations.length).must_equal 0 end end + +# describe "add_reservation" do +# let(:start_date) {Date.parse("2004, 7, 1")} +# let(:end_date) {Date.parse("2004, 7, 4")} +# let(:reservation_hash) {{ +# id: 2, +# room_num: 4, +# start_date: start_date, +# end_date: end_date, +# }} +# let(:reservation) {Hotel::Reservation.new(reservation_hash)} +# +# it "each item in array is a Reservation instance" do +# .trips.each do |trip| +# expect(trip).must_be_kind_of RideShare::Trip +# end +# end +# +# it "all Reservation instances must have the same passenger's user id" do +# @user.trips.each do |trip| +# expect(trip.passenger.id).must_equal 9 +# end +# end +# it "can add a reservation to a list of reservations" do +# end +# +# it "can add a reservation to a blank list" do +# end +# end end From 62b1ef51239ead981cce25f353d62e25ee30d37d Mon Sep 17 00:00:00 2001 From: kangazoom Date: Tue, 4 Sep 2018 23:20:21 -0700 Subject: [PATCH 07/36] Changed BookingSystem#create_reservation and #add_reservation to accept hash-like input + began similar input-related work on Reservation#initialize --- lib/booking_system.rb | 35 ++++++++++++++++++++++++----------- lib/reservation.rb | 12 ++++++------ lib/room.rb | 1 - 3 files changed, 30 insertions(+), 18 deletions(-) diff --git a/lib/booking_system.rb b/lib/booking_system.rb index 194378295..e7086426f 100644 --- a/lib/booking_system.rb +++ b/lib/booking_system.rb @@ -1,3 +1,5 @@ +require "date" + require_relative 'room' require_relative 'reservation' @@ -27,24 +29,35 @@ def list_all_rooms() return all_rooms_str end -# QUESTION: ughhhh, inputtt??? this is not DRY def create_reservation(input) room = find_room(room_num) + start_date = Date.parse(input[:start_date]) + end_date = Date.parse(input[:end_date]) + + reservation_hash = { + id: input[:id].to_i, + room: room, + start_date: start_date, + end_date: end_date, + cost: input[:cost] #QUESTION: needed?? + } + + new_reservation = Reservation.new(reservation_hash) + #NOTE: add room.change_status??? + room.add_reservation(new_reservation) - new_reservation = Reservation.new(input) - new_reservation = Reservation.new(id, room, start_date, end_date, cost) return new_reservation end - def add_reservation(reservation) - @reservations << reservation + def add_reservation(new_reservation) + @reservations << create_reservation(new_reservation) end - def load_reservations() - new_reservation = create_reservation() - add_reservation(new_reservation) - return @reservations - end + # def load_reservations(input) + # new_reservation = create_reservation() + # add_reservation(new_reservation) + # return @reservations + # end def list_reservations_by_date(date) @@ -53,7 +66,7 @@ def list_reservations_by_date(date) end def find_room(room_num) - return @rooms.map {|room| room.num == room_num} + return @rooms.find {|room| room.num == room_num} end end diff --git a/lib/reservation.rb b/lib/reservation.rb index 26d9745a5..077349c34 100644 --- a/lib/reservation.rb +++ b/lib/reservation.rb @@ -4,12 +4,12 @@ module Hotel class Reservation attr_accessor :id, :room, :start_date, :end_date, :cost - def initialize(id, room, start_date, end_date, cost=200) - @id = id - @room = room # object; not num - @start_date = start_date - @end_date = end_date - @cost = cost + def initialize(input) + @id = input[:id] + @room = input[:room] # object; not num TODO + @start_date = input[:start_date] + @end_date = input[:end_date] + @daily_rate = input[:daily_rate] end def dates_reserved() diff --git a/lib/room.rb b/lib/room.rb index 34b93f3fd..2d5340e3c 100644 --- a/lib/room.rb +++ b/lib/room.rb @@ -8,7 +8,6 @@ def initialize(input) @num = input[:num] @reservations = input[:reservations].nil? ? [] : input[:reservations] - # QUESTION: move up?? unless (1..20).include? @num raise ArgumentError, "This is not a valid room number." end From eb9f6ac025af6320b279611ee8d5a7c4e8040a85 Mon Sep 17 00:00:00 2001 From: kangazoom Date: Wed, 5 Sep 2018 11:57:35 -0700 Subject: [PATCH 08/36] updated BookingSystem tests (var names) and added tests for #find_room and #create_reservation --- lib/booking_system.rb | 8 +++-- spec/booking_system_spec.rb | 58 ++++++++++++++++++++++++++++++------- 2 files changed, 52 insertions(+), 14 deletions(-) diff --git a/lib/booking_system.rb b/lib/booking_system.rb index e7086426f..5323647d5 100644 --- a/lib/booking_system.rb +++ b/lib/booking_system.rb @@ -49,10 +49,12 @@ def create_reservation(input) return new_reservation end - def add_reservation(new_reservation) - @reservations << create_reservation(new_reservation) - end + # QUESTION: NOT NEEDED-- JUST IN RESERVATION? + # def add_reservation(new_reservation) + # @reservations << create_reservation(new_reservation) + # end + # QUESTION: add loading class or hold off? should be blank list at top? # def load_reservations(input) # new_reservation = create_reservation() # add_reservation(new_reservation) diff --git a/spec/booking_system_spec.rb b/spec/booking_system_spec.rb index d32d39a3d..b02900603 100644 --- a/spec/booking_system_spec.rb +++ b/spec/booking_system_spec.rb @@ -10,16 +10,16 @@ describe "BookingSystem class" do - let(:booking) {Hotel::BookingSystem.new()} + let(:booking_system) {Hotel::BookingSystem.new()} describe "#initialize" do it "can create a new instance of BookingSystem" do - expect(booking).must_be_kind_of Hotel::BookingSystem + expect(booking_system).must_be_kind_of Hotel::BookingSystem end end describe "#load_rooms" do - let(:rooms_list) {booking.load_rooms()} + let(:rooms_list) {booking_system.load_rooms()} it "can load a list of rooms" do expect(rooms_list).must_be_kind_of Array @@ -38,7 +38,7 @@ end describe "#list_all_rooms" do - let(:all_rooms_str) {booking.list_all_rooms()} + let(:all_rooms_str) {booking_system.list_all_rooms()} it "lists all rooms as a string" do beginning_text = "Here is a list of all rooms:" @@ -50,17 +50,53 @@ end end - # TODO - below + describe "#find_room" do + let(:room_num) {num: 4} + let(:room_obj) {booking_system.find_room(room_obj)} - describe "#create_reservation" do - end + it "finds room object by room number" + # num = 4 + # room_obj = booking_system.find_room(num) - describe "#add_reservation" do + expect(room_obj).must_be_kind_of Hotel::Room + expect(room_obj.num).must_equal num + end end - describe "#load_reservations" do - end + describe "#create_reservation" do + let(:reservation_hash) {{ + id: "5", + room: room_obj, + start_date: ("2010, 8, 6") + end_date: ("2010, 8, 10") + }} + let(:new_reservation) {Reservation.new(reservation_hash)} + + it "creates a new reservation successfully" do + expect(new_reservation).must_be_kind_of Hotel::Reservation + end + + it "loaded reservation details properly" do + # QUESTION: should i test values or types? in rideshare, seems like mostly type was tested.... + expect(new_reservation.id).must_equal 5 + expect(new_reservation.room.num).must_equal 4 + expect(new_reservation.start_date).must_be_kind_of Date + expect(new_reservation.end_date).must_be_kind_of Date + expect(new_reservation.cost).must_equal 200 - describe "#list_reservations_by_date" do + end end + + # describe "#add_reservation" do + # updated_reservations = booking_system.add_reservation(new_reservation) + # end + + # describe "#load_reservations" do + # end + +# # TODO - i think? +# describe "#list_reservations_by_date" do +# end + + end From d0e3543e944f4a78c01aa8e0907a1a0ea230624f Mon Sep 17 00:00:00 2001 From: kangazoom Date: Wed, 5 Sep 2018 12:05:22 -0700 Subject: [PATCH 09/36] began adding tests for Room#add_reservation --- spec/room_spec.rb | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/spec/room_spec.rb b/spec/room_spec.rb index 2dd6e86da..132c6c3a0 100644 --- a/spec/room_spec.rb +++ b/spec/room_spec.rb @@ -41,22 +41,23 @@ end end -# describe "add_reservation" do -# let(:start_date) {Date.parse("2004, 7, 1")} -# let(:end_date) {Date.parse("2004, 7, 4")} -# let(:reservation_hash) {{ -# id: 2, -# room_num: 4, -# start_date: start_date, -# end_date: end_date, -# }} -# let(:reservation) {Hotel::Reservation.new(reservation_hash)} -# -# it "each item in array is a Reservation instance" do -# .trips.each do |trip| -# expect(trip).must_be_kind_of RideShare::Trip -# end -# end + describe "add_reservation" do + let(:start_date) {Date.parse("2004, 7, 1")} + let(:end_date) {Date.parse("2004, 7, 4")} + let(:reservation_hash_1) {{ + id: 2, + room_num: 4, + start_date: start_date, + end_date: end_date, + }} + let(:reservation_1) {Hotel::Reservation.new(reservation_hash)} + + it "each item in array is a Reservation instance" do + room.add_reservation(reservation_1) + expect(room.reservations[0]).must_be_kind_of Hotel::Reservation + end + end +end # # it "all Reservation instances must have the same passenger's user id" do # @user.trips.each do |trip| From 61d1f0acc0e7cb1ac2cf5407dd5964a6c0c9fd69 Mon Sep 17 00:00:00 2001 From: kangazoom Date: Wed, 5 Sep 2018 12:33:42 -0700 Subject: [PATCH 10/36] fixed bugs in BookingSystem tests; #find_room and #create_reservation --- lib/booking_system.rb | 12 ++++++------ lib/reservation.rb | 6 +++--- spec/booking_system_spec.rb | 22 +++++++++++++-------- spec/reservation_spec.rb | 39 ++++++++++++++++++++----------------- 4 files changed, 44 insertions(+), 35 deletions(-) diff --git a/lib/booking_system.rb b/lib/booking_system.rb index 5323647d5..a5ff8e894 100644 --- a/lib/booking_system.rb +++ b/lib/booking_system.rb @@ -14,7 +14,7 @@ def initialize() # TODO: maybe separate load class? def load_rooms() nums = (1..20).to_a - all_rooms = nums.map { |num| Hotel::Room.new(num)} + all_rooms = nums.map { |num| Hotel::Room.new(num: num)} return all_rooms end @@ -30,15 +30,15 @@ def list_all_rooms() end def create_reservation(input) - room = find_room(room_num) - start_date = Date.parse(input[:start_date]) - end_date = Date.parse(input[:end_date]) + room = find_room(input[:room_num]) + # start_date = input[:start_date] + # end_date = input[:end_date] reservation_hash = { id: input[:id].to_i, room: room, - start_date: start_date, - end_date: end_date, + start_date: input[:start_date], + end_date: input[:end_date], cost: input[:cost] #QUESTION: needed?? } diff --git a/lib/reservation.rb b/lib/reservation.rb index 077349c34..9b3fbd606 100644 --- a/lib/reservation.rb +++ b/lib/reservation.rb @@ -1,4 +1,4 @@ -require 'time' +require 'date' module Hotel class Reservation @@ -7,8 +7,8 @@ class Reservation def initialize(input) @id = input[:id] @room = input[:room] # object; not num TODO - @start_date = input[:start_date] - @end_date = input[:end_date] + @start_date = Date.parse(input[:start_date]) + @end_date = Date.parse(input[:end_date]) @daily_rate = input[:daily_rate] end diff --git a/spec/booking_system_spec.rb b/spec/booking_system_spec.rb index b02900603..17a40c4e1 100644 --- a/spec/booking_system_spec.rb +++ b/spec/booking_system_spec.rb @@ -51,26 +51,32 @@ end describe "#find_room" do - let(:room_num) {num: 4} - let(:room_obj) {booking_system.find_room(room_obj)} + let(:room_num) {4} + let(:room_obj) {booking_system.find_room(room_num)} - it "finds room object by room number" + it "finds room object by room number" do # num = 4 # room_obj = booking_system.find_room(num) + puts room_num + puts room_obj + expect(room_obj).must_be_kind_of Hotel::Room - expect(room_obj.num).must_equal num + expect(room_obj.num).must_equal room_num end end +# TODO: add create reservation method + 2nd input as room_num?? describe "#create_reservation" do + # let(:room_num) {4} + # let(:room_obj) {booking_system.find_room(room_num)} let(:reservation_hash) {{ id: "5", - room: room_obj, - start_date: ("2010, 8, 6") - end_date: ("2010, 8, 10") + room: "10", + start_date: "2010, 8, 6", + end_date: "2010, 8, 10" }} - let(:new_reservation) {Reservation.new(reservation_hash)} + let(:new_reservation) {booking_system.create_reservation(reservation_hash)} it "creates a new reservation successfully" do expect(new_reservation).must_be_kind_of Hotel::Reservation diff --git a/spec/reservation_spec.rb b/spec/reservation_spec.rb index b1164d8f2..529ed5148 100644 --- a/spec/reservation_spec.rb +++ b/spec/reservation_spec.rb @@ -16,6 +16,7 @@ # TODO: test cost as float? # TODO: test id as any pos int # TODO: test room_num as 1-20 + # QUESTION: let vs before/do --> preference and use case diff? let(:start_date) {Date.new(2004, 7, 1)} let(:end_date) {Date.new(2004, 7, 4)} let(:reservation) {Hotel::Reservation.new(2, 3, start_date, end_date)} @@ -27,22 +28,24 @@ end end - describe "#dates_reserved" do - # TODO: test edge cases like same start/end date - # TODO: error handling for bad start/end dates (above?) - it "returns an array of Time objects" do - - expect(reservation.dates_reserved).must_be_kind_of Array - expect(reservation.dates_reserved()[0]).must_be_kind_of Date - - second_date = Date.new(2004, 7, 2) - expect(reservation.dates_reserved[1]).must_equal second_date - end - it "can list all the dates of a reservation" do - expect(reservation.dates_reserved.length).must_equal 3 - - second_date = Date.new(2004, 7, 2) - expect(reservation.dates_reserved[1]).must_equal second_date - end - end +# TODO: go back to this after figuring out all other tests + # describe "#dates_reserved" do + # # TODO: test edge cases like same start/end date + # # TODO: error handling for bad start/end dates (above?) + # it "returns an array of Date objects" do + # + # expect(reservation.dates_reserved).must_be_kind_of Array + # expect(reservation.dates_reserved()[0]).must_be_kind_of Date + # + # second_start_date = ("2004, 7, 2") + # second_end_date = ("2004, 7, 3") + # expect(reservation.dates_reserved[1]).must_equal second_date + # end + # it "can list all the dates of a reservation" do + # expect(reservation.dates_reserved.length).must_equal 3 + # + # second_date = Date.new(2004, 7, 2) + # expect(reservation.dates_reserved[1]).must_equal second_date + # end + # end end From c7d10f0844c36fc4bc67c7d6e82c842df79c2e58 Mon Sep 17 00:00:00 2001 From: kangazoom Date: Wed, 5 Sep 2018 13:55:35 -0700 Subject: [PATCH 11/36] Fixed bugs in BookingSystem tests for #create_reservation --- lib/booking_system.rb | 4 ++-- lib/reservation.rb | 1 + spec/booking_system_spec.rb | 11 ++++------- spec/reservation_spec.rb | 1 + 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/lib/booking_system.rb b/lib/booking_system.rb index a5ff8e894..59a78fbbe 100644 --- a/lib/booking_system.rb +++ b/lib/booking_system.rb @@ -29,6 +29,7 @@ def list_all_rooms() return all_rooms_str end +# QUESTION: is this necessary?? def create_reservation(input) room = find_room(input[:room_num]) # start_date = input[:start_date] @@ -39,7 +40,6 @@ def create_reservation(input) room: room, start_date: input[:start_date], end_date: input[:end_date], - cost: input[:cost] #QUESTION: needed?? } new_reservation = Reservation.new(reservation_hash) @@ -68,7 +68,7 @@ def list_reservations_by_date(date) end def find_room(room_num) - return @rooms.find {|room| room.num == room_num} + return @rooms.find {|room| room.num == room_num.to_i} end end diff --git a/lib/reservation.rb b/lib/reservation.rb index 9b3fbd606..b83e4bcc4 100644 --- a/lib/reservation.rb +++ b/lib/reservation.rb @@ -10,6 +10,7 @@ def initialize(input) @start_date = Date.parse(input[:start_date]) @end_date = Date.parse(input[:end_date]) @daily_rate = input[:daily_rate] + @cost = input[:cost] ? input[:cost] : 200 end def dates_reserved() diff --git a/spec/booking_system_spec.rb b/spec/booking_system_spec.rb index 17a40c4e1..4f9a471c8 100644 --- a/spec/booking_system_spec.rb +++ b/spec/booking_system_spec.rb @@ -58,9 +58,6 @@ # num = 4 # room_obj = booking_system.find_room(num) - puts room_num - puts room_obj - expect(room_obj).must_be_kind_of Hotel::Room expect(room_obj.num).must_equal room_num end @@ -72,9 +69,9 @@ # let(:room_obj) {booking_system.find_room(room_num)} let(:reservation_hash) {{ id: "5", - room: "10", - start_date: "2010, 8, 6", - end_date: "2010, 8, 10" + room_num: "10", + start_date: "2010-8-6", + end_date: "2010-8-10", }} let(:new_reservation) {booking_system.create_reservation(reservation_hash)} @@ -85,7 +82,7 @@ it "loaded reservation details properly" do # QUESTION: should i test values or types? in rideshare, seems like mostly type was tested.... expect(new_reservation.id).must_equal 5 - expect(new_reservation.room.num).must_equal 4 + expect(new_reservation.room.num).must_equal 10 expect(new_reservation.start_date).must_be_kind_of Date expect(new_reservation.end_date).must_be_kind_of Date expect(new_reservation.cost).must_equal 200 diff --git a/spec/reservation_spec.rb b/spec/reservation_spec.rb index 529ed5148..4d7922019 100644 --- a/spec/reservation_spec.rb +++ b/spec/reservation_spec.rb @@ -16,6 +16,7 @@ # TODO: test cost as float? # TODO: test id as any pos int # TODO: test room_num as 1-20 + # TODO: test cost nil or 200 or other value # QUESTION: let vs before/do --> preference and use case diff? let(:start_date) {Date.new(2004, 7, 1)} let(:end_date) {Date.new(2004, 7, 4)} From 85a6c96d0987bdebd38c6263b732c5a5662504e0 Mon Sep 17 00:00:00 2001 From: kangazoom Date: Wed, 5 Sep 2018 14:15:28 -0700 Subject: [PATCH 12/36] added and tested Reservation #dates_reserved and #total_stay_cost --- lib/reservation.rb | 16 +++++++----- spec/booking_system_spec.rb | 2 +- spec/reservation_spec.rb | 51 ++++++++++++++++++++----------------- 3 files changed, 39 insertions(+), 30 deletions(-) diff --git a/lib/reservation.rb b/lib/reservation.rb index b83e4bcc4..6442ae2d7 100644 --- a/lib/reservation.rb +++ b/lib/reservation.rb @@ -2,21 +2,25 @@ module Hotel class Reservation - attr_accessor :id, :room, :start_date, :end_date, :cost + attr_accessor :id, :room, :start_date, :end_date, :daily_rate def initialize(input) - @id = input[:id] - @room = input[:room] # object; not num TODO + @id = input[:id].to_i + @room = input[:room] # num-->obj in BookingSystem create_reservation @start_date = Date.parse(input[:start_date]) @end_date = Date.parse(input[:end_date]) - @daily_rate = input[:daily_rate] - @cost = input[:cost] ? input[:cost] : 200 + @daily_rate = input[:cost] ? input[:cost] : 200 end def dates_reserved() - # don't include the end end_date since that is the checkout date + # don't include end_date since that is the checkout date return (@start_date...@end_date).to_a end + def total_stay_cost() + length_in_days = dates_reserved().length + return @daily_rate * length_in_days + end + end end diff --git a/spec/booking_system_spec.rb b/spec/booking_system_spec.rb index 4f9a471c8..6b05d881f 100644 --- a/spec/booking_system_spec.rb +++ b/spec/booking_system_spec.rb @@ -85,7 +85,7 @@ expect(new_reservation.room.num).must_equal 10 expect(new_reservation.start_date).must_be_kind_of Date expect(new_reservation.end_date).must_be_kind_of Date - expect(new_reservation.cost).must_equal 200 + expect(new_reservation.daily_rate).must_equal 200 end end diff --git a/spec/reservation_spec.rb b/spec/reservation_spec.rb index 4d7922019..2166017f3 100644 --- a/spec/reservation_spec.rb +++ b/spec/reservation_spec.rb @@ -18,9 +18,9 @@ # TODO: test room_num as 1-20 # TODO: test cost nil or 200 or other value # QUESTION: let vs before/do --> preference and use case diff? - let(:start_date) {Date.new(2004, 7, 1)} - let(:end_date) {Date.new(2004, 7, 4)} - let(:reservation) {Hotel::Reservation.new(2, 3, start_date, end_date)} + let(:start_date) {"2004-7-1")} + let(:end_date) {"2004-7-4"} + let(:reservation) {Hotel::Reservation.new("2", "3", start_date, end_date)} describe "#initialize" do it "can create a new instance of reservation" do @@ -29,24 +29,29 @@ end end -# TODO: go back to this after figuring out all other tests - # describe "#dates_reserved" do - # # TODO: test edge cases like same start/end date - # # TODO: error handling for bad start/end dates (above?) - # it "returns an array of Date objects" do - # - # expect(reservation.dates_reserved).must_be_kind_of Array - # expect(reservation.dates_reserved()[0]).must_be_kind_of Date - # - # second_start_date = ("2004, 7, 2") - # second_end_date = ("2004, 7, 3") - # expect(reservation.dates_reserved[1]).must_equal second_date - # end - # it "can list all the dates of a reservation" do - # expect(reservation.dates_reserved.length).must_equal 3 - # - # second_date = Date.new(2004, 7, 2) - # expect(reservation.dates_reserved[1]).must_equal second_date - # end - # end + describe "#dates_reserved" do + # TODO: test edge cases like same start/end date + # TODO: error handling for bad start/end dates (above?) + it "returns an array of Date objects" do + expect(reservation.dates_reserved).must_be_kind_of Array + expect(reservation.dates_reserved[0]).must_be_kind_of Date + end + it "can list all the dates of a reservation" do + expect(reservation.dates_reserved.length).must_equal 3 + + expect(reservation.dates_reserved[0]).must_equal "2004-7-1" + expect(reservation.dates_reserved[1]).must_equal "2004-7-2" + expect(reservation.dates_reserved[2]).must_equal "2004-7-3" + end + end + + describe "#total_stay_cost" do + it "correctly calculates total cost for a reservation" do + rate = 200 + dates = 3 + correct_cost = rate * dates + + expect(reservation.total_stay_cost).must_equal 600 + end + end end From 926a49928b973ef29259292e7fdf37b74abc937d Mon Sep 17 00:00:00 2001 From: kangazoom Date: Wed, 5 Sep 2018 15:39:40 -0700 Subject: [PATCH 13/36] Did a lot of work on tests for Reservation#initialize and #dates_reserved. Also added error handling for invalid end date --- lib/booking_system.rb | 33 +++++++++++++++-- lib/reservation.rb | 14 +++++++ spec/booking_system_spec.rb | 73 +++++++++++++++++++++++++++++++++++-- spec/reservation_spec.rb | 38 ++++++++++++++++--- 4 files changed, 144 insertions(+), 14 deletions(-) diff --git a/lib/booking_system.rb b/lib/booking_system.rb index 59a78fbbe..df5a3c988 100644 --- a/lib/booking_system.rb +++ b/lib/booking_system.rb @@ -43,8 +43,10 @@ def create_reservation(input) } new_reservation = Reservation.new(reservation_hash) - #NOTE: add room.change_status??? + #NOTE: add room.change_status??? should this part go in Res??? + # or should this be split up???? room.add_reservation(new_reservation) + @reservations << new_reservation return new_reservation end @@ -62,11 +64,22 @@ def create_reservation(input) # end - def list_reservations_by_date(date) +# QUESTION: should i be accessing this + def list_reservations_for_date(date) + date = Date.parse(date) #TODO error handling for date as Date object?? - return res_by_date = @reservations.map { |reservation| reservation.date == date } + #TODO what if no dates match? should return nil? + # QUESTION: maybe add one to display by id? + # QUESTION: should room own this??? + matching_res = @reservations.select { |reservation| reservation.dates_reserved.include? date } + + # TODO: combine enumerable with ternary???? --> do in one line??? + return matching_res == [] ? nil : matching_res end + +# QUESTION: should this method be here or in Reservation? +# QUESTION: test nil return if nothing found def find_room(room_num) return @rooms.find {|room| room.num == room_num.to_i} end @@ -76,5 +89,17 @@ def find_room(room_num) # booking = Hotel::BookingSystem.new() +# # +# res_3 = booking.create_reservation({ +# id: "4", +# room_num: "15", +# start_date: "2010-8-4", +# end_date: "2010-8-20", +# }) +# res_2 = booking.create_reservation({id: "1", +# room_num: "20", +# start_date: "2010-8-1", +# end_date: "2010-8-10", +# }) # -# puts booking.list_all_rooms +# p booking.list_reservations_for_date("2010-8-5") diff --git a/lib/reservation.rb b/lib/reservation.rb index 6442ae2d7..8c8471113 100644 --- a/lib/reservation.rb +++ b/lib/reservation.rb @@ -10,6 +10,10 @@ def initialize(input) @start_date = Date.parse(input[:start_date]) @end_date = Date.parse(input[:end_date]) @daily_rate = input[:cost] ? input[:cost] : 200 + + unless @end_date >= @start_date + raise StandardError, "Invalid date range: end date must occur after start date." + end end def dates_reserved() @@ -24,3 +28,13 @@ def total_stay_cost() end end + + +# res = Hotel::Reservation.new({ +# id: "2", +# room_num: "3", +# start_date: "2004-7-1", +# end_date: "2004-7-4"}) +# +# p res.dates_reserved.class +# p res.dates_reserved[0].class diff --git a/spec/booking_system_spec.rb b/spec/booking_system_spec.rb index 6b05d881f..296ae2294 100644 --- a/spec/booking_system_spec.rb +++ b/spec/booking_system_spec.rb @@ -12,9 +12,12 @@ describe "BookingSystem class" do let(:booking_system) {Hotel::BookingSystem.new()} +# TODO test that rooms contains room obj like in load rooms describe "#initialize" do it "can create a new instance of BookingSystem" do expect(booking_system).must_be_kind_of Hotel::BookingSystem + expect(booking_system.rooms).must_be_kind_of Array + expect(booking_system.reservations).must_be_kind_of Array end end @@ -65,6 +68,8 @@ # TODO: add create reservation method + 2nd input as room_num?? describe "#create_reservation" do + # TODO test that it's added to Room + # TODO test that it's added to reservations # let(:room_num) {4} # let(:room_obj) {booking_system.find_room(room_num)} let(:reservation_hash) {{ @@ -79,7 +84,7 @@ expect(new_reservation).must_be_kind_of Hotel::Reservation end - it "loaded reservation details properly" do + it "loads reservation details properly" do # QUESTION: should i test values or types? in rideshare, seems like mostly type was tested.... expect(new_reservation.id).must_equal 5 expect(new_reservation.room.num).must_equal 10 @@ -97,9 +102,69 @@ # describe "#load_reservations" do # end -# # TODO - i think? -# describe "#list_reservations_by_date" do -# end + describe "#list_reservations_for_date" do + before do + + # res_1 = Hotel::Reservation.new({ + # id: "1", + # room_num: "20", + # start_date: "2010-8-1", + # end_date: "2010-8-10", + # }) + # res_2 = Hotel::Reservation.new({ + # id: "2", + # room_num: "19", + # start_date: "2008-5-15", + # end_date: "2010-5-18", + # }) + # res_3 = Hotel::Reservation.new({ + # id: "4", + # room_num: "15", + # start_date: "2009-4-4", + # end_date: "2009-4-10", + # }) + + res_1 = booking_system.create_reservation({ + id: "1", + room_num: "20", + start_date: "2010-8-1", + end_date: "2010-8-10", + }) + res_2 = booking_system.create_reservation({ + id: "2", + room_num: "19", + start_date: "2010-8-15", + end_date: "2010-8-18", + }) + res_3 = booking_system.create_reservation({ + id: "4", + room_num: "15", + start_date: "2010-8-4", + end_date: "2010-8-20", + }) + + @matching_res = booking_system.list_reservations_for_date("2010-8-5") + puts @matching_res + + end + + it "should return an array of Reservation objects" do + expect(@matching_res).must_be_kind_of Array + expect(@matching_res[0]).must_be_kind_of Hotel::Reservation + end + + it "accurately loads Reservation objects for specified date" do + puts @matching_res + expect(@matching_res.length).must_equal 2 + expect(@matching_res[0].id).must_equal 1 + expect(@matching_res[1].id).must_equal 4 + end + + it "returns nil if no Reservations are found for specified date" do + @matching_res = booking_system.list_reservations_for_date("2010-8-30") + expect(@matching_res).must_equal nil + end + end end diff --git a/spec/reservation_spec.rb b/spec/reservation_spec.rb index 2166017f3..4b0bf23bc 100644 --- a/spec/reservation_spec.rb +++ b/spec/reservation_spec.rb @@ -18,15 +18,37 @@ # TODO: test room_num as 1-20 # TODO: test cost nil or 200 or other value # QUESTION: let vs before/do --> preference and use case diff? - let(:start_date) {"2004-7-1")} - let(:end_date) {"2004-7-4"} - let(:reservation) {Hotel::Reservation.new("2", "3", start_date, end_date)} + let(:reservation) {Hotel::Reservation.new({ + id: "2", + room_num: "3", + start_date: "2004-7-1", + end_date: "2004-7-4"})} describe "#initialize" do it "can create a new instance of reservation" do expect(reservation).must_be_kind_of Hotel::Reservation expect(reservation.id).must_equal 2 end + + it "throws a StandardError if end_date occurs before start_date" do + expect { + Hotel::Reservation.new({ + id: "5", + room_num: "8", + start_date: "2009-7-2", + end_date: "2009-7-1" + })}.must_raise StandardError + end + it "can create a reservation with a one-night stay" do + # edge case + one_night_stay = Hotel::Reservation.new({ + id: "66", + room_num: "19", + start_date:"2009-7-29", + end_date: "2009-7-29"}) + expect(one_night_stay).must_be_kind_of Hotel::Reservation + expect(one_night_stay.id).must_equal 66 + end end describe "#dates_reserved" do @@ -39,9 +61,13 @@ it "can list all the dates of a reservation" do expect(reservation.dates_reserved.length).must_equal 3 - expect(reservation.dates_reserved[0]).must_equal "2004-7-1" - expect(reservation.dates_reserved[1]).must_equal "2004-7-2" - expect(reservation.dates_reserved[2]).must_equal "2004-7-3" + date1_s = reservation.dates_reserved[0].strftime('%Y %b %d') + date2_s = reservation.dates_reserved[1].strftime('%Y %b %d') + date3_s = reservation.dates_reserved[2].strftime('%Y %b %d') + + expect(date1_s).must_equal "2004 Jul 01" + expect(date2_s).must_equal "2004 Jul 02" + expect(date3_s).must_equal "2004 Jul 03" end end From 7634b5ac9004ac250cc9c9834ed6d46c0a605c91 Mon Sep 17 00:00:00 2001 From: kangazoom Date: Wed, 5 Sep 2018 17:00:41 -0700 Subject: [PATCH 14/36] saving whatever work i was doing before hotel temp check; i can't remember now :( prob Reservation or BookingSystem --- lib/booking_system.rb | 49 +++++++++++++------ spec/booking_system_spec.rb | 98 +++++++++++++++++++++---------------- 2 files changed, 90 insertions(+), 57 deletions(-) diff --git a/lib/booking_system.rb b/lib/booking_system.rb index df5a3c988..3c2779d76 100644 --- a/lib/booking_system.rb +++ b/lib/booking_system.rb @@ -20,6 +20,7 @@ def load_rooms() end def list_all_rooms() + # return list as a string all_rooms_str = "Here is a list of all rooms: \n" @rooms.each do |room| @@ -30,6 +31,7 @@ def list_all_rooms() end # QUESTION: is this necessary?? +# QUESTION: should I ditch input for date ranges?? def create_reservation(input) room = find_room(input[:room_num]) # start_date = input[:start_date] @@ -65,6 +67,7 @@ def create_reservation(input) # QUESTION: should i be accessing this +# QUESTION: add a pretty to_s for listing reserved dates? def list_reservations_for_date(date) date = Date.parse(date) #TODO error handling for date as Date object?? @@ -84,22 +87,40 @@ def find_room(room_num) return @rooms.find {|room| room.num == room_num.to_i} end + def available_rooms_by_date(start_date, end_date) + # QUESTION: should this be the input?? + # TODO: ugh, not DRY.... + check_date_range = (start_date...end_date).to_a + + @reservations.each do |reservation| + # check for overlap in dates + if !(reservation.date_range & check_date_range) + return reservation.room.num + end + + end + + # TODO URGENT: add rooms to reservation class?? + + + end + end end -# booking = Hotel::BookingSystem.new() -# # -# res_3 = booking.create_reservation({ -# id: "4", -# room_num: "15", -# start_date: "2010-8-4", -# end_date: "2010-8-20", -# }) -# res_2 = booking.create_reservation({id: "1", -# room_num: "20", -# start_date: "2010-8-1", -# end_date: "2010-8-10", -# }) +booking = Hotel::BookingSystem.new() # -# p booking.list_reservations_for_date("2010-8-5") +res_3 = booking.create_reservation({ + id: "4", + room_num: "15", + start_date: "2010-8-4", + end_date: "2010-8-20", + }) +res_2 = booking.create_reservation({id: "1", + room_num: "20", + start_date: "2010-8-1", + end_date: "2010-8-10", + }) + +p booking.available_rooms_by_date("2010-8-5") diff --git a/spec/booking_system_spec.rb b/spec/booking_system_spec.rb index 296ae2294..d45543a70 100644 --- a/spec/booking_system_spec.rb +++ b/spec/booking_system_spec.rb @@ -103,66 +103,78 @@ # end describe "#list_reservations_for_date" do - before do - - # res_1 = Hotel::Reservation.new({ - # id: "1", - # room_num: "20", - # start_date: "2010-8-1", - # end_date: "2010-8-10", - # }) - # res_2 = Hotel::Reservation.new({ - # id: "2", - # room_num: "19", - # start_date: "2008-5-15", - # end_date: "2010-5-18", - # }) - # res_3 = Hotel::Reservation.new({ - # id: "4", - # room_num: "15", - # start_date: "2009-4-4", - # end_date: "2009-4-10", - # }) - - res_1 = booking_system.create_reservation({ + let(:res_1) {booking_system.create_reservation({ id: "1", room_num: "20", start_date: "2010-8-1", - end_date: "2010-8-10", - }) - res_2 = booking_system.create_reservation({ + end_date: "2010-8-10" + })} + + let(:res_2) {booking_system.create_reservation({ id: "2", room_num: "19", start_date: "2010-8-15", - end_date: "2010-8-18", - }) - res_3 = booking_system.create_reservation({ + end_date: "2010-8-18" + })} + + let(:res_3) {booking_system.create_reservation({ id: "4", room_num: "15", start_date: "2010-8-4", - end_date: "2010-8-20", - }) - - @matching_res = booking_system.list_reservations_for_date("2010-8-5") - puts @matching_res - - end + end_date: "2010-8-20" + })} + + let(:matching_res) {booking_system.list_reservations_for_date("2010-8-5")} + # puts @matching_res} + # res_1 = booking_system.create_reservation({ + # id: "1", + # room_num: "20", + # start_date: "2010-8-1", + # end_date: "2010-8-10", + # }) + # res_2 = booking_system.create_reservation({ + # id: "2", + # room_num: "19", + # start_date: "2010-8-15", + # end_date: "2010-8-18", + # }) + # res_3 = booking_system.create_reservation({ + # id: "4", + # room_num: "15", + # start_date: "2010-8-4", + # end_date: "2010-8-20", + # }) + + # @matching_res = booking_system.list_reservations_for_date("2010-8-5") + # puts @matching_res + # end it "should return an array of Reservation objects" do - expect(@matching_res).must_be_kind_of Array - expect(@matching_res[0]).must_be_kind_of Hotel::Reservation + expect(matching_res).must_be_kind_of Array + expect(matching_res[0]).must_be_kind_of Hotel::Reservation end it "accurately loads Reservation objects for specified date" do - puts @matching_res - expect(@matching_res.length).must_equal 2 - expect(@matching_res[0].id).must_equal 1 - expect(@matching_res[1].id).must_equal 4 + expect(matching_res.length).must_equal 2 + expect(matching_res[0].id).must_equal 1 + expect(matching_res[1].id).must_equal 4 end it "returns nil if no Reservations are found for specified date" do - @matching_res = booking_system.list_reservations_for_date("2010-8-30") - expect(@matching_res).must_equal nil + matching_res = booking_system.list_reservations_for_date("2010-8-30") + expect(matching_res).must_equal nil + end + end + + describe "#available_rooms_by_date" do + let(:start_date) {"2010-8-15"} + let(:end_date) {"2010-8-16"} + + it "returns an array of room numbers" do + expect(booking_system.available_rooms_by_date(start_date, end_date)).must_be_kind_of Array + + expect(booking_system.available_rooms_by_date(start_date, end_date)[0]).must_be_kind_of Integer + end end From 307fe1709ea0d6a45c2a9f268689dc05f445615d Mon Sep 17 00:00:00 2001 From: kangazoom Date: Thu, 6 Sep 2018 09:15:55 -0700 Subject: [PATCH 15/36] fixed bug in Room #add_reservation method + test --- lib/room.rb | 1 + spec/room_spec.rb | 10 ++++------ 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/lib/room.rb b/lib/room.rb index 2d5340e3c..0138fc09f 100644 --- a/lib/room.rb +++ b/lib/room.rb @@ -1,4 +1,5 @@ require 'date' +require_relative 'reservation' module Hotel class Room diff --git a/spec/room_spec.rb b/spec/room_spec.rb index 132c6c3a0..e06d80469 100644 --- a/spec/room_spec.rb +++ b/spec/room_spec.rb @@ -42,22 +42,20 @@ end describe "add_reservation" do - let(:start_date) {Date.parse("2004, 7, 1")} - let(:end_date) {Date.parse("2004, 7, 4")} let(:reservation_hash_1) {{ id: 2, room_num: 4, - start_date: start_date, - end_date: end_date, + start_date: "2004-7-1", + end_date: "2004-7-4", }} - let(:reservation_1) {Hotel::Reservation.new(reservation_hash)} + let(:reservation_1) {Hotel::Reservation.new(reservation_hash_1)} it "each item in array is a Reservation instance" do room.add_reservation(reservation_1) expect(room.reservations[0]).must_be_kind_of Hotel::Reservation end end -end + # # it "all Reservation instances must have the same passenger's user id" do # @user.trips.each do |trip| From f82bec928851d4e3a65af3e06bd07f58eefbcb83 Mon Sep 17 00:00:00 2001 From: kangazoom Date: Thu, 6 Sep 2018 23:32:12 -0700 Subject: [PATCH 16/36] Added some more tests for Room regarding @reservations list --- .gitignore | 2 +- lib/reservation.rb | 2 +- lib/room.rb | 2 +- spec/room_spec.rb | 66 +++++++++++++++++++++++++++------------------ spec/spec_helper.rb | 6 ++--- 5 files changed, 46 insertions(+), 32 deletions(-) diff --git a/.gitignore b/.gitignore index 5e1422c9c..932ce5a55 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ *.gem *.rbc /.config -/coverage/ +coverage /InstalledFiles /pkg/ /spec/reports/ diff --git a/lib/reservation.rb b/lib/reservation.rb index 8c8471113..f6582df29 100644 --- a/lib/reservation.rb +++ b/lib/reservation.rb @@ -2,7 +2,7 @@ module Hotel class Reservation - attr_accessor :id, :room, :start_date, :end_date, :daily_rate + attr_reader :id, :room, :start_date, :end_date, :daily_rate def initialize(input) @id = input[:id].to_i diff --git a/lib/room.rb b/lib/room.rb index 0138fc09f..1d96eb360 100644 --- a/lib/room.rb +++ b/lib/room.rb @@ -3,7 +3,7 @@ module Hotel class Room - attr_accessor :num, :reservations + attr_reader :num, :reservations def initialize(input) @num = input[:num] diff --git a/spec/room_spec.rb b/spec/room_spec.rb index e06d80469..8062b55f3 100644 --- a/spec/room_spec.rb +++ b/spec/room_spec.rb @@ -10,15 +10,12 @@ describe "Room" do - let(:room_hash) {{num: 4}} - let(:room) {Hotel::Room.new(room_hash)} - + let(:room) {Hotel::Room.new({num: 4})} describe "#initialize" do it "can create a new instance of room" do - expect(room).must_be_kind_of Hotel::Room - expect(room.num).must_equal room_hash[:num] + expect(room.num).must_equal 4 end it "has room id as an integer" do @@ -42,30 +39,47 @@ end describe "add_reservation" do - let(:reservation_hash_1) {{ - id: 2, - room_num: 4, - start_date: "2004-7-1", - end_date: "2004-7-4", - }} - let(:reservation_1) {Hotel::Reservation.new(reservation_hash_1)} + let(:reservation_1) {Hotel::Reservation.new({ + room: 4, + check_in: "2004-4-1", + check_out: "2004-4-4", + })} + let(:reservation_2) {Hotel::Reservation.new({ + room: 4, + check_in: "2004-6-1", + check_out: "2004-7-4", + })} + let(:reservation_3) {Hotel::Reservation.new({ + room: 4, + check_in: "2004-7-25", + check_out: "2004-7-30", + })} - it "each item in array is a Reservation instance" do + it "can add a Reservation to a blank list" do room.add_reservation(reservation_1) + expect(room.reservations[0]).must_be_kind_of Hotel::Reservation end - end -# -# it "all Reservation instances must have the same passenger's user id" do -# @user.trips.each do |trip| -# expect(trip.passenger.id).must_equal 9 -# end -# end -# it "can add a reservation to a list of reservations" do -# end -# -# it "can add a reservation to a blank list" do -# end -# end + it "each item in array is a Reservation instance" do + room.add_reservation(reservation_1) + room.add_reservation(reservation_2) + room.add_reservation(reservation_3) + + room.reservations.each do |reservation| + expect(reservation).must_be_kind_of Hotel::Reservation + end + end + +# TODO: room num or room obj? + it "each Reservation instance has same room number" do + room.add_reservation(reservation_1) + room.add_reservation(reservation_2) + room.add_reservation(reservation_3) + + room.reservations.each do |reservation| + expect(reservation.room).must_equal 4 + end + end + end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 746bbc31d..8bd0e56e4 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,10 +1,10 @@ +require 'simplecov' +SimpleCov.start + require 'minitest' require 'minitest/autorun' require 'minitest/reporters' -require 'simplecov' -SimpleCov.start - Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new require_relative '../lib/booking_system' From 6a608235c3b4bda5f0198ae36d2db60a2ef597f0 Mon Sep 17 00:00:00 2001 From: kangazoom Date: Fri, 7 Sep 2018 00:10:09 -0700 Subject: [PATCH 17/36] added new date format error handling for proper date format --- lib/reservation.rb | 24 ++++++++++++--------- spec/reservation_spec.rb | 45 +++++++++++++++++++++++++++++++--------- 2 files changed, 49 insertions(+), 20 deletions(-) diff --git a/lib/reservation.rb b/lib/reservation.rb index f6582df29..650f1b143 100644 --- a/lib/reservation.rb +++ b/lib/reservation.rb @@ -2,30 +2,34 @@ module Hotel class Reservation - attr_reader :id, :room, :start_date, :end_date, :daily_rate + attr_reader :id, :room, :check_in, :check_out, :daily_rate def initialize(input) + + unless /\d{4}-\d{1,2}-\d{1,2}/.match(input[:check_in]) && /\d{4}-\d{1,2}-\d{1,2}/.match(input[:check_out]) + raise StandardError, "Improper date format: date must be entered as YYYY-MM-DD." + end + @id = input[:id].to_i - @room = input[:room] # num-->obj in BookingSystem create_reservation - @start_date = Date.parse(input[:start_date]) - @end_date = Date.parse(input[:end_date]) + @room = input[:room] # num-->obj in BookingSystem create_reservation?? + @check_in = Date.parse(input[:check_in]) + @check_out = Date.parse(input[:check_out]) @daily_rate = input[:cost] ? input[:cost] : 200 - unless @end_date >= @start_date + unless @check_out > @check_in raise StandardError, "Invalid date range: end date must occur after start date." end end def dates_reserved() - # don't include end_date since that is the checkout date - return (@start_date...@end_date).to_a + # don't include check out date + return (@check_in...@check_out).to_a end def total_stay_cost() length_in_days = dates_reserved().length return @daily_rate * length_in_days end - end end @@ -33,8 +37,8 @@ def total_stay_cost() # res = Hotel::Reservation.new({ # id: "2", # room_num: "3", -# start_date: "2004-7-1", -# end_date: "2004-7-4"}) +# check_in: "2004,5,6", +# check_out: "2004-7-4"}) # # p res.dates_reserved.class # p res.dates_reserved[0].class diff --git a/spec/reservation_spec.rb b/spec/reservation_spec.rb index 4b0bf23bc..c26f4d4cb 100644 --- a/spec/reservation_spec.rb +++ b/spec/reservation_spec.rb @@ -10,19 +10,17 @@ describe "Reservation" do - # QUESTION: needed for creation: id, room_num, date_start, date_end, cost=200 - # ^^ keyword args? hash input?? + # TODO: test end date AFTER start date # TODO: test cost as float? # TODO: test id as any pos int # TODO: test room_num as 1-20 # TODO: test cost nil or 200 or other value - # QUESTION: let vs before/do --> preference and use case diff? let(:reservation) {Hotel::Reservation.new({ id: "2", room_num: "3", - start_date: "2004-7-1", - end_date: "2004-7-4"})} + check_in: "2004-7-1", + check_out: "2004-7-4"})} describe "#initialize" do it "can create a new instance of reservation" do @@ -30,22 +28,49 @@ expect(reservation.id).must_equal 2 end - it "throws a StandardError if end_date occurs before start_date" do + it "throws a StandardError if fed improper date format for check_in or check_out" do expect { Hotel::Reservation.new({ id: "5", room_num: "8", - start_date: "2009-7-2", - end_date: "2009-7-1" + check_in: "2009,7,2", + check_out: "2009-7-1" + })}.must_raise StandardError + + expect { + Hotel::Reservation.new({ + id: "5", + room_num: "8", + check_in: "2009-7-2", + check_out: "2009,7,1" })}.must_raise StandardError end + + it "throws a StandardError if check_out occurs before or on same day as check_in" do + expect { + Hotel::Reservation.new({ + id: "5", + room_num: "8", + check_in: "2009-7-2", + check_out: "2009-7-1" + })}.must_raise StandardError + + expect { + Hotel::Reservation.new({ + id: "5", + room_num: "8", + check_in: "2009-7-1", + check_out: "2009-7-1" + })}.must_raise StandardError + end + it "can create a reservation with a one-night stay" do # edge case one_night_stay = Hotel::Reservation.new({ id: "66", room_num: "19", - start_date:"2009-7-29", - end_date: "2009-7-29"}) + check_in:"2009-7-29", + check_out: "2009-7-30"}) expect(one_night_stay).must_be_kind_of Hotel::Reservation expect(one_night_stay.id).must_equal 66 end From f50d92381817e3c0997ff4a2b6c1321a70e5404b Mon Sep 17 00:00:00 2001 From: kangazoom Date: Fri, 7 Sep 2018 00:24:59 -0700 Subject: [PATCH 18/36] added tests for Reservation @daily_rate --- lib/reservation.rb | 3 ++- spec/reservation_spec.rb | 36 +++++++++++++++++++++++++++--------- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/lib/reservation.rb b/lib/reservation.rb index 650f1b143..8392669dc 100644 --- a/lib/reservation.rb +++ b/lib/reservation.rb @@ -14,7 +14,7 @@ def initialize(input) @room = input[:room] # num-->obj in BookingSystem create_reservation?? @check_in = Date.parse(input[:check_in]) @check_out = Date.parse(input[:check_out]) - @daily_rate = input[:cost] ? input[:cost] : 200 + @daily_rate = input[:daily_rate] ? input[:daily_rate] : 200 unless @check_out > @check_in raise StandardError, "Invalid date range: end date must occur after start date." @@ -26,6 +26,7 @@ def dates_reserved() return (@check_in...@check_out).to_a end +# QUESTION: daily_rate as a CONSTANT?? def total_stay_cost() length_in_days = dates_reserved().length return @daily_rate * length_in_days diff --git a/spec/reservation_spec.rb b/spec/reservation_spec.rb index c26f4d4cb..313201e95 100644 --- a/spec/reservation_spec.rb +++ b/spec/reservation_spec.rb @@ -11,11 +11,9 @@ describe "Reservation" do - # TODO: test end date AFTER start date - # TODO: test cost as float? - # TODO: test id as any pos int - # TODO: test room_num as 1-20 - # TODO: test cost nil or 200 or other value + # TODO: test id as any pos int? + # TODO: test room_num as 1-20? + let(:reservation) {Hotel::Reservation.new({ id: "2", room_num: "3", @@ -74,22 +72,42 @@ expect(one_night_stay).must_be_kind_of Hotel::Reservation expect(one_night_stay.id).must_equal 66 end + + it "sets daily rate to default value if no value given" do + typical_room = Hotel::Reservation.new({ + id: "66", + room_num: "19", + check_in:"2009-7-29", + check_out: "2009-7-30"}) + + expect(typical_room.daily_rate).must_equal 200 + end + + # QUESTION: do we need error handling for numeric value for daily_rate? + it "can override default value for daily rate" do + rare_room = Hotel::Reservation.new({ + id: "66", + room_num: "19", + check_in:"2009-7-29", + check_out: "2009-7-30", + daily_rate: 500}) + + expect(rare_room.daily_rate).must_equal 500 + end end describe "#dates_reserved" do - # TODO: test edge cases like same start/end date - # TODO: error handling for bad start/end dates (above?) it "returns an array of Date objects" do expect(reservation.dates_reserved).must_be_kind_of Array expect(reservation.dates_reserved[0]).must_be_kind_of Date end - it "can list all the dates of a reservation" do - expect(reservation.dates_reserved.length).must_equal 3 + it "can list all the dates of a reservation" do date1_s = reservation.dates_reserved[0].strftime('%Y %b %d') date2_s = reservation.dates_reserved[1].strftime('%Y %b %d') date3_s = reservation.dates_reserved[2].strftime('%Y %b %d') + expect(reservation.dates_reserved.length).must_equal 3 expect(date1_s).must_equal "2004 Jul 01" expect(date2_s).must_equal "2004 Jul 02" expect(date3_s).must_equal "2004 Jul 03" From 28b5efacb1182e3f1006cee24e749187a6fe4bb4 Mon Sep 17 00:00:00 2001 From: kangazoom Date: Fri, 7 Sep 2018 02:21:15 -0700 Subject: [PATCH 19/36] added skeletons/pseudocode for BookingSystem changes and methods involving dates plus commented questions/todos --- lib/booking_system.rb | 109 +++++++++++++++++++----------------- lib/reservation.rb | 2 +- spec/booking_system_spec.rb | 22 +++++++- 3 files changed, 80 insertions(+), 53 deletions(-) diff --git a/lib/booking_system.rb b/lib/booking_system.rb index 3c2779d76..32447a625 100644 --- a/lib/booking_system.rb +++ b/lib/booking_system.rb @@ -5,13 +5,13 @@ module Hotel class BookingSystem - attr_accessor :rooms, :reservations + attr_reader :rooms, :reservations + def initialize() - @rooms = load_rooms() #<-- array of all rooms + @rooms = load_rooms() #<-- array of all room objects @reservations = [] end -# TODO: maybe separate load class? def load_rooms() nums = (1..20).to_a all_rooms = nums.map { |num| Hotel::Room.new(num: num)} @@ -19,29 +19,21 @@ def load_rooms() return all_rooms end - def list_all_rooms() - # return list as a string - all_rooms_str = "Here is a list of all rooms: \n" + # TODO: maybe use date range instead of start/end? + def create_reservation(start_date, end_date) + id = create_res_id() + rooms = list_avail_rooms_for_range(start_date, end_date) - @rooms.each do |room| - all_rooms_str << "- Room #{room.num} \n" + # QUESTION: AM I DOING THIS RIGHT? + unless rooms != nil + raise StandardError, "No rooms are available for the given date range: #{start_date} - #{end_date}." end - return all_rooms_str - end - -# QUESTION: is this necessary?? -# QUESTION: should I ditch input for date ranges?? - def create_reservation(input) - room = find_room(input[:room_num]) - # start_date = input[:start_date] - # end_date = input[:end_date] - reservation_hash = { - id: input[:id].to_i, - room: room, - start_date: input[:start_date], - end_date: input[:end_date], + id: id, + room: rooms[0], + check_in: start_date, + check_out: end_date, } new_reservation = Reservation.new(reservation_hash) @@ -68,8 +60,8 @@ def create_reservation(input) # QUESTION: should i be accessing this # QUESTION: add a pretty to_s for listing reserved dates? - def list_reservations_for_date(date) - date = Date.parse(date) + def list_reservations_for_date(check_date) + date = Date.parse(check_date) #TODO error handling for date as Date object?? #TODO what if no dates match? should return nil? # QUESTION: maybe add one to display by id? @@ -77,7 +69,7 @@ def list_reservations_for_date(date) matching_res = @reservations.select { |reservation| reservation.dates_reserved.include? date } # TODO: combine enumerable with ternary???? --> do in one line??? - return matching_res == [] ? nil : matching_res + return matching_res.empty? ? nil : matching_res end @@ -87,40 +79,57 @@ def find_room(room_num) return @rooms.find {|room| room.num == room_num.to_i} end - def available_rooms_by_date(start_date, end_date) - # QUESTION: should this be the input?? - # TODO: ugh, not DRY.... - check_date_range = (start_date...end_date).to_a + def create_date_range(start_date, end_date) + return (start_date...end_date).to_a + end - @reservations.each do |reservation| - # check for overlap in dates - if !(reservation.date_range & check_date_range) - return reservation.room.num - end + def overlap?(date_range_1, date_range_2) + return false if (date_range_1 & date_range_2).empty? else return true + end - end + def list_avail_rooms_for_date(check_date) + avail_rooms = @reservations.select { |reservation| !reservation.date_range.include?(check_date) } #==false + # check for no overlap in dates + # if (reservation.date_range & check_date_range).empty? - # TODO URGENT: add rooms to reservation class?? + return avail_rooms.empty? ? nil : avail_rooms + end + + def list_avail_rooms_for_range(start_date, end_date) + check_date_range = create_date_range(start_date, end_date) + + avail_rooms = @reservations.select { |reservation| reservation.room if !overlap?(reservation.date_range, check_date_range)} #==false + + return avail_rooms.empty? ? nil : avail_rooms + # check for no overlap in dates + # if (reservation.date_range & check_date_range).empty? end + def create_res_id() + if @reservations.empty? + return 1 + else + return @reservations.max_by { |reservation| reservation.id}.id + 1 + end + end end end -booking = Hotel::BookingSystem.new() +# booking = Hotel::BookingSystem.new() +# # +# res_3 = booking.create_reservation({ +# id: "4", +# room_num: "15", +# start_date: "2010-8-4", +# end_date: "2010-8-20", +# }) +# res_2 = booking.create_reservation({id: "1", +# room_num: "20", +# start_date: "2010-8-1", +# end_date: "2010-8-10", +# }) # -res_3 = booking.create_reservation({ - id: "4", - room_num: "15", - start_date: "2010-8-4", - end_date: "2010-8-20", - }) -res_2 = booking.create_reservation({id: "1", - room_num: "20", - start_date: "2010-8-1", - end_date: "2010-8-10", - }) - -p booking.available_rooms_by_date("2010-8-5") +# p booking.available_rooms_by_date("2010-8-5") diff --git a/lib/reservation.rb b/lib/reservation.rb index 8392669dc..2d5b085d9 100644 --- a/lib/reservation.rb +++ b/lib/reservation.rb @@ -6,6 +6,7 @@ class Reservation def initialize(input) + # QUESTION: maybe DateRange class can handle all things date-related, including error handling? unless /\d{4}-\d{1,2}-\d{1,2}/.match(input[:check_in]) && /\d{4}-\d{1,2}-\d{1,2}/.match(input[:check_out]) raise StandardError, "Improper date format: date must be entered as YYYY-MM-DD." end @@ -26,7 +27,6 @@ def dates_reserved() return (@check_in...@check_out).to_a end -# QUESTION: daily_rate as a CONSTANT?? def total_stay_cost() length_in_days = dates_reserved().length return @daily_rate * length_in_days diff --git a/spec/booking_system_spec.rb b/spec/booking_system_spec.rb index d45543a70..a08ac9e0a 100644 --- a/spec/booking_system_spec.rb +++ b/spec/booking_system_spec.rb @@ -8,7 +8,8 @@ Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new - +# TODO: fix the order of these methods! +# QUESTION: wave 2 -- Your code should raise an exception when asked to reserve a room that is not available -- huhhh? i thought they book with a date range! describe "BookingSystem class" do let(:booking_system) {Hotel::BookingSystem.new()} @@ -66,8 +67,17 @@ end end +# TODO + describe "#create_date_range" do + end + + # TODO + describe "#overlap?" do + end + # TODO: add create reservation method + 2nd input as room_num?? describe "#create_reservation" do + # TODO: A reservation is allowed start on the same day that another reservation for the same room ends # TODO test that it's added to Room # TODO test that it's added to reservations # let(:room_num) {4} @@ -166,7 +176,7 @@ end end - describe "#available_rooms_by_date" do + describe "#list_avail_rooms_for_date" do let(:start_date) {"2010-8-15"} let(:end_date) {"2010-8-16"} @@ -178,5 +188,13 @@ end end + #TODO + describe "#list_avail_rooms_for_range" do + end + + # TODO + describe "#create_res_id" do + end + end From eeb5e62c19fd3ff514e4dbddd6ebd0aba235b85a Mon Sep 17 00:00:00 2001 From: kangazoom Date: Fri, 7 Sep 2018 10:48:47 -0700 Subject: [PATCH 20/36] Commented out Room class and tests --> first step toward removal --- .DS_Store | Bin 0 -> 6148 bytes lib/booking_system.rb | 10 +-- lib/reservation.rb | 2 +- lib/room.rb | 46 +++++------ spec/booking_system_spec.rb | 12 +-- spec/reservation_spec.rb | 11 +-- spec/room_spec.rb | 161 +++++++++++++++++------------------- spec/spec_helper.rb | 2 +- 8 files changed, 109 insertions(+), 135 deletions(-) create mode 100644 .DS_Store diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..1ad899dbcdc748036dd701eacb0ec11e243703d4 GIT binary patch literal 6148 zcmeHKyJ`bL3>+mc4$`I(2Sbbi#2M3J zT*oXyY@Q(Y!ZDE|1kgGlC+ZoQs7@HV6)|Fx!@~RZ=JlH_u58Z)4k@C?#6Xc7@{2$qaAbO f?f5y0vab1>=e=-D3_9~cC+cUwb&*MdzgFN1-fR_w literal 0 HcmV?d00001 diff --git a/lib/booking_system.rb b/lib/booking_system.rb index 32447a625..de6d90b68 100644 --- a/lib/booking_system.rb +++ b/lib/booking_system.rb @@ -8,15 +8,13 @@ class BookingSystem attr_reader :rooms, :reservations def initialize() - @rooms = load_rooms() #<-- array of all room objects + @rooms = list_rooms() #<-- array of all room objects @reservations = [] end - def load_rooms() - nums = (1..20).to_a - all_rooms = nums.map { |num| Hotel::Room.new(num: num)} - - return all_rooms + def list_rooms() + return (1..20).to_a + # all_rooms = nums.map { |num| Hotel::Room.new(num: num)} end # TODO: maybe use date range instead of start/end? diff --git a/lib/reservation.rb b/lib/reservation.rb index 2d5b085d9..bfca1ca31 100644 --- a/lib/reservation.rb +++ b/lib/reservation.rb @@ -12,7 +12,7 @@ def initialize(input) end @id = input[:id].to_i - @room = input[:room] # num-->obj in BookingSystem create_reservation?? + @room_num = input[:room_num] @check_in = Date.parse(input[:check_in]) @check_out = Date.parse(input[:check_out]) @daily_rate = input[:daily_rate] ? input[:daily_rate] : 200 diff --git a/lib/room.rb b/lib/room.rb index 1d96eb360..bc49a468f 100644 --- a/lib/room.rb +++ b/lib/room.rb @@ -1,23 +1,23 @@ -require 'date' -require_relative 'reservation' - -module Hotel - class Room - attr_reader :num, :reservations - - def initialize(input) - @num = input[:num] - @reservations = input[:reservations].nil? ? [] : input[:reservations] - - unless (1..20).include? @num - raise ArgumentError, "This is not a valid room number." - end - - end - - def add_reservation(reservation) - @reservations << reservation - end - - end -end +# require 'date' +# require_relative 'reservation' +# +# module Hotel +# class Room +# attr_reader :num, :reservations +# +# def initialize(input) +# @num = input[:num] +# @reservations = input[:reservations].nil? ? [] : input[:reservations] +# +# unless (1..20).include? @num +# raise ArgumentError, "This is not a valid room number." +# end +# +# end +# +# def add_reservation(reservation) +# @reservations << reservation +# end +# +# end +# end diff --git a/spec/booking_system_spec.rb b/spec/booking_system_spec.rb index a08ac9e0a..cebb69584 100644 --- a/spec/booking_system_spec.rb +++ b/spec/booking_system_spec.rb @@ -1,12 +1,4 @@ -require 'minitest' -require 'minitest/spec' -require 'minitest/autorun' -require 'minitest/reporters' -require 'minitest/pride' - -require_relative '../lib/booking_system' - -Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new +require_relative 'spec_helper' # TODO: fix the order of these methods! # QUESTION: wave 2 -- Your code should raise an exception when asked to reserve a room that is not available -- huhhh? i thought they book with a date range! @@ -17,6 +9,8 @@ describe "#initialize" do it "can create a new instance of BookingSystem" do expect(booking_system).must_be_kind_of Hotel::BookingSystem + + it "creates accurate attribute types" expect(booking_system.rooms).must_be_kind_of Array expect(booking_system.reservations).must_be_kind_of Array end diff --git a/spec/reservation_spec.rb b/spec/reservation_spec.rb index 313201e95..e91b38c77 100644 --- a/spec/reservation_spec.rb +++ b/spec/reservation_spec.rb @@ -1,13 +1,4 @@ -require 'minitest' -require 'minitest/spec' -require 'minitest/autorun' -require 'minitest/reporters' -require 'minitest/pride' - -require_relative '../lib/Reservation' - -Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new - +require_relative 'spec_helper' describe "Reservation" do diff --git a/spec/room_spec.rb b/spec/room_spec.rb index 8062b55f3..4602524b9 100644 --- a/spec/room_spec.rb +++ b/spec/room_spec.rb @@ -1,85 +1,76 @@ -require 'minitest' -require 'minitest/spec' -require 'minitest/autorun' -require 'minitest/reporters' -require 'minitest/pride' - -require_relative '../lib/Room' - -Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new - - -describe "Room" do - let(:room) {Hotel::Room.new({num: 4})} - - describe "#initialize" do - it "can create a new instance of room" do - expect(room).must_be_kind_of Hotel::Room - expect(room.num).must_equal 4 - end - - it "has room id as an integer" do - expect(room.num).must_be_kind_of Integer - end - - it "throws an argument error with a bad room num value" do - expect { - Hotel::Room.new(num: 21) - }.must_raise ArgumentError - - expect { - Hotel::Room.new(num: 0) - }.must_raise ArgumentError - end - - it "sets reservations to an empty array if not provided" do - expect(room.reservations).must_be_kind_of Array - expect(room.reservations.length).must_equal 0 - end - end - - describe "add_reservation" do - let(:reservation_1) {Hotel::Reservation.new({ - room: 4, - check_in: "2004-4-1", - check_out: "2004-4-4", - })} - let(:reservation_2) {Hotel::Reservation.new({ - room: 4, - check_in: "2004-6-1", - check_out: "2004-7-4", - })} - let(:reservation_3) {Hotel::Reservation.new({ - room: 4, - check_in: "2004-7-25", - check_out: "2004-7-30", - })} - - it "can add a Reservation to a blank list" do - room.add_reservation(reservation_1) - - expect(room.reservations[0]).must_be_kind_of Hotel::Reservation - end - - it "each item in array is a Reservation instance" do - room.add_reservation(reservation_1) - room.add_reservation(reservation_2) - room.add_reservation(reservation_3) - - room.reservations.each do |reservation| - expect(reservation).must_be_kind_of Hotel::Reservation - end - end - -# TODO: room num or room obj? - it "each Reservation instance has same room number" do - room.add_reservation(reservation_1) - room.add_reservation(reservation_2) - room.add_reservation(reservation_3) - - room.reservations.each do |reservation| - expect(reservation.room).must_equal 4 - end - end - end -end +# require_relative 'spec_helper' +# +# describe "Room" do +# let(:room) {Hotel::Room.new({num: 4})} +# +# describe "#initialize" do +# it "can create a new instance of room" do +# expect(room).must_be_kind_of Hotel::Room +# expect(room.num).must_equal 4 +# end +# +# it "has room id as an integer" do +# expect(room.num).must_be_kind_of Integer +# end +# +# it "throws an argument error with a bad room num value" do +# expect { +# Hotel::Room.new(num: 21) +# }.must_raise ArgumentError +# +# expect { +# Hotel::Room.new(num: 0) +# }.must_raise ArgumentError +# end +# +# it "sets reservations to an empty array if not provided" do +# expect(room.reservations).must_be_kind_of Array +# expect(room.reservations.length).must_equal 0 +# end +# end +# +# describe "add_reservation" do +# let(:reservation_1) {Hotel::Reservation.new({ +# room: 4, +# check_in: "2004-4-1", +# check_out: "2004-4-4", +# })} +# let(:reservation_2) {Hotel::Reservation.new({ +# room: 4, +# check_in: "2004-6-1", +# check_out: "2004-7-4", +# })} +# let(:reservation_3) {Hotel::Reservation.new({ +# room: 4, +# check_in: "2004-7-25", +# check_out: "2004-7-30", +# })} +# +# it "can add a Reservation to a blank list" do +# room.add_reservation(reservation_1) +# +# expect(room.reservations[0]).must_be_kind_of Hotel::Reservation +# end +# +# it "each item in array is a Reservation instance" do +# room.add_reservation(reservation_1) +# room.add_reservation(reservation_2) +# room.add_reservation(reservation_3) +# +# room.reservations.each do |reservation| +# expect(reservation).must_be_kind_of Hotel::Reservation +# end +# end +# +# # TODO: room num or room obj? +# it "each Reservation instance has same room number" do +# room.add_reservation(reservation_1) +# room.add_reservation(reservation_2) +# room.add_reservation(reservation_3) +# +# room.reservations.each do |reservation| +# expect(reservation.room).must_equal 4 +# end +# end +# end +# end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 8bd0e56e4..96d5ec85f 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -8,5 +8,5 @@ Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new require_relative '../lib/booking_system' -require_relative '../lib/room' +# require_relative '../lib/room' require_relative '../lib/reservation' From 93dc58bbb60a8f5b432a6510abaa7463f0e0d994 Mon Sep 17 00:00:00 2001 From: kangazoom Date: Fri, 7 Sep 2018 12:12:44 -0700 Subject: [PATCH 21/36] Spruced up tests in BookingSystem (#initialize and #list_all_rooms) --- lib/booking_system.rb | 180 ++++++++++--------- lib/calendar.rb | 0 spec/booking_system_spec.rb | 345 +++++++++++++++++++++--------------- spec/calendar.rb | 0 4 files changed, 291 insertions(+), 234 deletions(-) create mode 100644 lib/calendar.rb create mode 100644 spec/calendar.rb diff --git a/lib/booking_system.rb b/lib/booking_system.rb index de6d90b68..58d81c445 100644 --- a/lib/booking_system.rb +++ b/lib/booking_system.rb @@ -1,6 +1,6 @@ require "date" -require_relative 'room' +# require_relative 'room' require_relative 'reservation' module Hotel @@ -8,110 +8,114 @@ class BookingSystem attr_reader :rooms, :reservations def initialize() - @rooms = list_rooms() #<-- array of all room objects + @rooms = list_all_rooms() #<-- array of all room numbeers @reservations = [] end - def list_rooms() + def list_all_rooms() return (1..20).to_a # all_rooms = nums.map { |num| Hotel::Room.new(num: num)} end - # TODO: maybe use date range instead of start/end? - def create_reservation(start_date, end_date) - id = create_res_id() - rooms = list_avail_rooms_for_range(start_date, end_date) - - # QUESTION: AM I DOING THIS RIGHT? - unless rooms != nil - raise StandardError, "No rooms are available for the given date range: #{start_date} - #{end_date}." - end - - reservation_hash = { - id: id, - room: rooms[0], - check_in: start_date, - check_out: end_date, - } - - new_reservation = Reservation.new(reservation_hash) - #NOTE: add room.change_status??? should this part go in Res??? - # or should this be split up???? - room.add_reservation(new_reservation) - @reservations << new_reservation - - return new_reservation - end - - # QUESTION: NOT NEEDED-- JUST IN RESERVATION? - # def add_reservation(new_reservation) - # @reservations << create_reservation(new_reservation) - # end - - # QUESTION: add loading class or hold off? should be blank list at top? - # def load_reservations(input) - # new_reservation = create_reservation() - # add_reservation(new_reservation) - # return @reservations - # end - - -# QUESTION: should i be accessing this -# QUESTION: add a pretty to_s for listing reserved dates? - def list_reservations_for_date(check_date) - date = Date.parse(check_date) - #TODO error handling for date as Date object?? - #TODO what if no dates match? should return nil? - # QUESTION: maybe add one to display by id? - # QUESTION: should room own this??? - matching_res = @reservations.select { |reservation| reservation.dates_reserved.include? date } - - # TODO: combine enumerable with ternary???? --> do in one line??? - return matching_res.empty? ? nil : matching_res - end - - -# QUESTION: should this method be here or in Reservation? -# QUESTION: test nil return if nothing found - def find_room(room_num) - return @rooms.find {|room| room.num == room_num.to_i} - end - def create_date_range(start_date, end_date) + # TODO: error handling should probably go to cal class (take from reservation plus tests -- 2x) return (start_date...end_date).to_a end - def overlap?(date_range_1, date_range_2) - return false if (date_range_1 & date_range_2).empty? else return true - end - - def list_avail_rooms_for_date(check_date) - avail_rooms = @reservations.select { |reservation| !reservation.date_range.include?(check_date) } #==false - # check for no overlap in dates - # if (reservation.date_range & check_date_range).empty? - - return avail_rooms.empty? ? nil : avail_rooms - - end - - def list_avail_rooms_for_range(start_date, end_date) - check_date_range = create_date_range(start_date, end_date) - - avail_rooms = @reservations.select { |reservation| reservation.room if !overlap?(reservation.date_range, check_date_range)} #==false - - return avail_rooms.empty? ? nil : avail_rooms - # check for no overlap in dates - # if (reservation.date_range & check_date_range).empty? - - end - - def create_res_id() + def generate_res_id() if @reservations.empty? return 1 else return @reservations.max_by { |reservation| reservation.id}.id + 1 end end + + +# # TODO: maybe use date range instead of start/end? +# def create_reservation(start_date, end_date) +# id = create_res_id() +# rooms = list_avail_rooms_for_range(start_date, end_date) +# +# # QUESTION: AM I DOING THIS RIGHT? +# unless rooms != nil +# raise StandardError, "No rooms are available for the given date range: #{start_date} - #{end_date}." +# end +# +# reservation_hash = { +# id: id, +# room: rooms[0], +# check_in: start_date, +# check_out: end_date, +# } +# +# new_reservation = Reservation.new(reservation_hash) +# #NOTE: add room.change_status??? should this part go in Res??? +# # or should this be split up???? +# room.add_reservation(new_reservation) +# @reservations << new_reservation +# +# return new_reservation +# end +# +# # QUESTION: NOT NEEDED-- JUST IN RESERVATION? +# # def add_reservation(new_reservation) +# # @reservations << create_reservation(new_reservation) +# # end +# +# # QUESTION: add loading class or hold off? should be blank list at top? +# # def load_reservations(input) +# # new_reservation = create_reservation() +# # add_reservation(new_reservation) +# # return @reservations +# # end +# +# +# # QUESTION: should i be accessing this +# # QUESTION: add a pretty to_s for listing reserved dates? +# def list_reservations_for_date(check_date) +# date = Date.parse(check_date) +# #TODO error handling for date as Date object?? +# #TODO what if no dates match? should return nil? +# # QUESTION: maybe add one to display by id? +# # QUESTION: should room own this??? +# matching_res = @reservations.select { |reservation| reservation.dates_reserved.include? date } +# +# # TODO: combine enumerable with ternary???? --> do in one line??? +# return matching_res.empty? ? nil : matching_res +# end +# +# +# # QUESTION: should this method be here or in Reservation? +# # QUESTION: test nil return if nothing found +# def find_room(room_num) +# return @rooms.find {|room| room.num == room_num.to_i} +# end +# +# def overlap?(date_range_1, date_range_2) +# return false if (date_range_1 & date_range_2).empty? else return true +# end +# +# def list_avail_rooms_for_date(check_date) +# avail_rooms = @reservations.select { |reservation| !reservation.date_range.include?(check_date) } #==false +# # check for no overlap in dates +# # if (reservation.date_range & check_date_range).empty? +# +# return avail_rooms.empty? ? nil : avail_rooms +# +# end +# +# def list_avail_rooms_for_range(start_date, end_date) +# check_date_range = create_date_range(start_date, end_date) +# +# avail_rooms = @reservations.select { |reservation| reservation.room if !overlap?(reservation.date_range, check_date_range)} #==false +# +# return avail_rooms.empty? ? nil : avail_rooms +# # check for no overlap in dates +# # if (reservation.date_range & check_date_range).empty? +# +# end +# + end end diff --git a/lib/calendar.rb b/lib/calendar.rb new file mode 100644 index 000000000..e69de29bb diff --git a/spec/booking_system_spec.rb b/spec/booking_system_spec.rb index cebb69584..6d79c848d 100644 --- a/spec/booking_system_spec.rb +++ b/spec/booking_system_spec.rb @@ -5,190 +5,243 @@ describe "BookingSystem class" do let(:booking_system) {Hotel::BookingSystem.new()} -# TODO test that rooms contains room obj like in load rooms describe "#initialize" do it "can create a new instance of BookingSystem" do expect(booking_system).must_be_kind_of Hotel::BookingSystem + end - it "creates accurate attribute types" + it "creates accurate attribute types" do expect(booking_system.rooms).must_be_kind_of Array expect(booking_system.reservations).must_be_kind_of Array end end - describe "#load_rooms" do - let(:rooms_list) {booking_system.load_rooms()} + describe "#list_all_rooms" do + let(:rooms_list) {booking_system.list_all_rooms()} it "can load a list of rooms" do expect(rooms_list).must_be_kind_of Array end - it "accurately loads room info in array" do - first_room = rooms_list[0] - last_room= rooms_list[-1] - - expect(first_room).must_be_kind_of Hotel::Room - expect(first_room.num).must_equal 1 - - expect(last_room).must_be_kind_of Hotel::Room - expect(last_room.num).must_equal 20 + it "accurately loads each instance of room as an integer" do + rooms_list.each do |room| + expect(room).must_be_kind_of Integer + end end - end - describe "#list_all_rooms" do - let(:all_rooms_str) {booking_system.list_all_rooms()} - - it "lists all rooms as a string" do - beginning_text = "Here is a list of all rooms:" - room_2 = "Room 2" - - expect(all_rooms_str).must_be_kind_of String - expect(all_rooms_str).must_include beginning_text - expect(all_rooms_str).must_include room_2 + it "accurately describes first room" do + first_room = rooms_list[0] + expect(first_room).must_equal 1 end - end - describe "#find_room" do - let(:room_num) {4} - let(:room_obj) {booking_system.find_room(room_num)} - - it "finds room object by room number" do - # num = 4 - # room_obj = booking_system.find_room(num) - - expect(room_obj).must_be_kind_of Hotel::Room - expect(room_obj.num).must_equal room_num + it "accurately describes last room" do + last_room= rooms_list[-1] + expect(last_room).must_equal 20 end end -# TODO describe "#create_date_range" do - end - - # TODO - describe "#overlap?" do - end - -# TODO: add create reservation method + 2nd input as room_num?? - describe "#create_reservation" do - # TODO: A reservation is allowed start on the same day that another reservation for the same room ends - # TODO test that it's added to Room - # TODO test that it's added to reservations - # let(:room_num) {4} - # let(:room_obj) {booking_system.find_room(room_num)} - let(:reservation_hash) {{ - id: "5", - room_num: "10", - start_date: "2010-8-6", - end_date: "2010-8-10", - }} - let(:new_reservation) {booking_system.create_reservation(reservation_hash)} - - it "creates a new reservation successfully" do - expect(new_reservation).must_be_kind_of Hotel::Reservation + let(:start_date) {Date.parse("07-01-2010")} + let(:end_date) {Date.parse("07-04-2010")} + let(:date_range) {booking_system.create_date_range(start_date, end_date)} + + it "returns an array of Date objects" do + expect(date_range).must_be_kind_of Array + date_range.each do |date| + date.must_be_kind_of Date + end end - it "loads reservation details properly" do - # QUESTION: should i test values or types? in rideshare, seems like mostly type was tested.... - expect(new_reservation.id).must_equal 5 - expect(new_reservation.room.num).must_equal 10 - expect(new_reservation.start_date).must_be_kind_of Date - expect(new_reservation.end_date).must_be_kind_of Date - expect(new_reservation.daily_rate).must_equal 200 + it "accurately returns first Date value" do + expect(date_range[0]).must_equal start_date + end + it "accurately returns last Date value" do + expect(date_range[-1]).must_equal end_date-1 end end - # describe "#add_reservation" do - # updated_reservations = booking_system.add_reservation(new_reservation) - # end - - # describe "#load_reservations" do - # end - - describe "#list_reservations_for_date" do - let(:res_1) {booking_system.create_reservation({ - id: "1", - room_num: "20", - start_date: "2010-8-1", - end_date: "2010-8-10" - })} - - let(:res_2) {booking_system.create_reservation({ - id: "2", - room_num: "19", - start_date: "2010-8-15", - end_date: "2010-8-18" - })} - - let(:res_3) {booking_system.create_reservation({ - id: "4", - room_num: "15", - start_date: "2010-8-4", - end_date: "2010-8-20" - })} - - let(:matching_res) {booking_system.list_reservations_for_date("2010-8-5")} - # puts @matching_res} - # res_1 = booking_system.create_reservation({ - # id: "1", - # room_num: "20", - # start_date: "2010-8-1", - # end_date: "2010-8-10", - # }) - # res_2 = booking_system.create_reservation({ - # id: "2", - # room_num: "19", - # start_date: "2010-8-15", - # end_date: "2010-8-18", - # }) - # res_3 = booking_system.create_reservation({ - # id: "4", - # room_num: "15", - # start_date: "2010-8-4", - # end_date: "2010-8-20", - # }) - - # @matching_res = booking_system.list_reservations_for_date("2010-8-5") - # puts @matching_res - # end - - it "should return an array of Reservation objects" do - expect(matching_res).must_be_kind_of Array - expect(matching_res[0]).must_be_kind_of Hotel::Reservation - end + describe "#generate_res_id" do + let(:first_res) {Reservation.new("08-01-1996", "08-03-1996")} + let(:second_res) {Reservation.new("09-09-1996", "08-13-1996")} + let(:third_res) {Reservation.new("10-01-1996", "10-10-1996")} - it "accurately loads Reservation objects for specified date" do - expect(matching_res.length).must_equal 2 - expect(matching_res[0].id).must_equal 1 - expect(matching_res[1].id).must_equal 4 - end + it "creates the first reservation ID if it's the first reservation in reservations list" do + booking_system.reservations << first_res - it "returns nil if no Reservations are found for specified date" do - matching_res = booking_system.list_reservations_for_date("2010-8-30") - expect(matching_res).must_equal nil + expect(reservations.generate_res_id[0].id).must_equal 1 end - end - describe "#list_avail_rooms_for_date" do - let(:start_date) {"2010-8-15"} - let(:end_date) {"2010-8-16"} + it "can generate accurate IDs when new reservations are added to reservations list" do + booking_system.reservations << first_res + booking_system.reservations << second_res - it "returns an array of room numbers" do - expect(booking_system.available_rooms_by_date(start_date, end_date)).must_be_kind_of Array + expect(reservations.generate_res_id[0].id).must_equal 1 + expect(reservations.generate_res_id[1].id).must_equal 2 - expect(booking_system.available_rooms_by_date(start_date, end_date)[0]).must_be_kind_of Integer + booking_system.reservations << third_res + expect(reservations.generate_res_id[-1].id).must_equal 3 end - end - #TODO - describe "#list_avail_rooms_for_range" do - end - # TODO - describe "#create_res_id" do - end + + end +# +# describe "#list_all_rooms" do +# let(:all_rooms_str) {booking_system.list_all_rooms()} +# +# it "lists all rooms as a string" do +# beginning_text = "Here is a list of all rooms:" +# room_2 = "Room 2" +# +# expect(all_rooms_str).must_be_kind_of String +# expect(all_rooms_str).must_include beginning_text +# expect(all_rooms_str).must_include room_2 +# end +# end +# +# describe "#find_room" do +# let(:room_num) {4} +# let(:room_obj) {booking_system.find_room(room_num)} +# +# it "finds room object by room number" do +# # num = 4 +# # room_obj = booking_system.find_room(num) +# +# expect(room_obj).must_be_kind_of Hotel::Room +# expect(room_obj.num).must_equal room_num +# end +# end +# + +# +# # TODO +# describe "#overlap?" do +# end +# +# # TODO: add create reservation method + 2nd input as room_num?? +# describe "#create_reservation" do +# # TODO: A reservation is allowed start on the same day that another reservation for the same room ends +# # TODO test that it's added to Room +# # TODO test that it's added to reservations +# # let(:room_num) {4} +# # let(:room_obj) {booking_system.find_room(room_num)} +# let(:reservation_hash) {{ +# id: "5", +# room_num: "10", +# start_date: "2010-8-6", +# end_date: "2010-8-10", +# }} +# let(:new_reservation) {booking_system.create_reservation(reservation_hash)} +# +# it "creates a new reservation successfully" do +# expect(new_reservation).must_be_kind_of Hotel::Reservation +# end +# +# it "loads reservation details properly" do +# # QUESTION: should i test values or types? in rideshare, seems like mostly type was tested.... +# expect(new_reservation.id).must_equal 5 +# expect(new_reservation.room.num).must_equal 10 +# expect(new_reservation.start_date).must_be_kind_of Date +# expect(new_reservation.end_date).must_be_kind_of Date +# expect(new_reservation.daily_rate).must_equal 200 +# +# end +# end +# +# # describe "#add_reservation" do +# # updated_reservations = booking_system.add_reservation(new_reservation) +# # end +# +# # describe "#load_reservations" do +# # end +# +# describe "#list_reservations_for_date" do +# let(:res_1) {booking_system.create_reservation({ +# id: "1", +# room_num: "20", +# start_date: "2010-8-1", +# end_date: "2010-8-10" +# })} +# +# let(:res_2) {booking_system.create_reservation({ +# id: "2", +# room_num: "19", +# start_date: "2010-8-15", +# end_date: "2010-8-18" +# })} +# +# let(:res_3) {booking_system.create_reservation({ +# id: "4", +# room_num: "15", +# start_date: "2010-8-4", +# end_date: "2010-8-20" +# })} +# +# let(:matching_res) {booking_system.list_reservations_for_date("2010-8-5")} +# # puts @matching_res} +# # res_1 = booking_system.create_reservation({ +# # id: "1", +# # room_num: "20", +# # start_date: "2010-8-1", +# # end_date: "2010-8-10", +# # }) +# # res_2 = booking_system.create_reservation({ +# # id: "2", +# # room_num: "19", +# # start_date: "2010-8-15", +# # end_date: "2010-8-18", +# # }) +# # res_3 = booking_system.create_reservation({ +# # id: "4", +# # room_num: "15", +# # start_date: "2010-8-4", +# # end_date: "2010-8-20", +# # }) +# +# # @matching_res = booking_system.list_reservations_for_date("2010-8-5") +# # puts @matching_res +# # end +# +# it "should return an array of Reservation objects" do +# expect(matching_res).must_be_kind_of Array +# expect(matching_res[0]).must_be_kind_of Hotel::Reservation +# end +# +# it "accurately loads Reservation objects for specified date" do +# expect(matching_res.length).must_equal 2 +# expect(matching_res[0].id).must_equal 1 +# expect(matching_res[1].id).must_equal 4 +# end +# +# it "returns nil if no Reservations are found for specified date" do +# matching_res = booking_system.list_reservations_for_date("2010-8-30") +# expect(matching_res).must_equal nil +# end +# end +# +# describe "#list_avail_rooms_for_date" do +# let(:start_date) {"2010-8-15"} +# let(:end_date) {"2010-8-16"} +# +# it "returns an array of room numbers" do +# expect(booking_system.available_rooms_by_date(start_date, end_date)).must_be_kind_of Array +# +# expect(booking_system.available_rooms_by_date(start_date, end_date)[0]).must_be_kind_of Integer +# +# end +# end +# +# #TODO +# describe "#list_avail_rooms_for_range" do +# end +# +# # TODO +# describe "#create_res_id" do +# end +# + end diff --git a/spec/calendar.rb b/spec/calendar.rb new file mode 100644 index 000000000..e69de29bb From faf6a0ef3809eca05c46aa1445d290c3ef1214c3 Mon Sep 17 00:00:00 2001 From: kangazoom Date: Sat, 8 Sep 2018 14:53:14 -0700 Subject: [PATCH 22/36] experimenting with Calendar --- lib/booking_system.rb | 24 ++++++------ lib/calendar.rb | 37 ++++++++++++++++++ lib/reservation.rb | 9 +---- spec/booking_system_spec.rb | 78 +++++++++++++++---------------------- spec/calendar.rb | 0 spec/calendar_spec.rb | 66 +++++++++++++++++++++++++++++++ spec/reservation_spec.rb | 67 ++++++++----------------------- spec/spec_helper.rb | 4 +- 8 files changed, 167 insertions(+), 118 deletions(-) delete mode 100644 spec/calendar.rb create mode 100644 spec/calendar_spec.rb diff --git a/lib/booking_system.rb b/lib/booking_system.rb index 58d81c445..129247684 100644 --- a/lib/booking_system.rb +++ b/lib/booking_system.rb @@ -1,6 +1,6 @@ require "date" -# require_relative 'room' +require_relative 'calendar' require_relative 'reservation' module Hotel @@ -17,18 +17,20 @@ def list_all_rooms() # all_rooms = nums.map { |num| Hotel::Room.new(num: num)} end - def create_date_range(start_date, end_date) - # TODO: error handling should probably go to cal class (take from reservation plus tests -- 2x) - return (start_date...end_date).to_a + def construct_cal_checker(start_date:, end_date:) + #QUESTION: initialize this??? + construct_cal_checker = Calendar.new(start_date: start_date, end_date: end_date) + # QUESTION: kwargs? RETURN DATE RANGE OR THE CALENDAR? + # return DateRange.new(start_date, end_date).create_date_range #<-- returns array of Date objects end - def generate_res_id() - if @reservations.empty? - return 1 - else - return @reservations.max_by { |reservation| reservation.id}.id + 1 - end - end + # def generate_res_id() + # if @reservations.empty? + # return 1 + # else + # return @reservations.max_by { |reservation| reservation.id}.id + 1 + # end + # end # # TODO: maybe use date range instead of start/end? diff --git a/lib/calendar.rb b/lib/calendar.rb index e69de29bb..831556fca 100644 --- a/lib/calendar.rb +++ b/lib/calendar.rb @@ -0,0 +1,37 @@ +require 'date' + +module Hotel + class Calendar + attr_reader :start_date, :end_date + + def initialize(start_date:, end_date:) + +# QUESTION: separate error handling into its own method? + unless /\d{4}-\d{1,2}-\d{1,2}/.match(start_date) && /\d{4}-\d{1,2}-\d{1,2}/.match(end_date) + raise StandardError, "Improper date format: date must be entered as YYYY-MM-DD." + end + + @start_date = Date.parse(start_date) + @end_date = Date.parse(end_date) + + unless @start_date < @end_date + raise StandardError, "Invalid date range: end date must occur after start date." + end + end + +# TODO: create date range and check without arrays? + def create_date_range() + # QUESTION: shoudl i just use instance var instead of input local var? + return (@start_date...@end_date).to_a + end + + + + + end +end + +# +# cal = Hotel::Calendar.new(start_date: "1986-07-29", end_date: "1986-07-31") +# +# puts cal diff --git a/lib/reservation.rb b/lib/reservation.rb index bfca1ca31..446dae260 100644 --- a/lib/reservation.rb +++ b/lib/reservation.rb @@ -6,20 +6,13 @@ class Reservation def initialize(input) - # QUESTION: maybe DateRange class can handle all things date-related, including error handling? - unless /\d{4}-\d{1,2}-\d{1,2}/.match(input[:check_in]) && /\d{4}-\d{1,2}-\d{1,2}/.match(input[:check_out]) - raise StandardError, "Improper date format: date must be entered as YYYY-MM-DD." - end - @id = input[:id].to_i @room_num = input[:room_num] + #TODO: date_range CAL instantiate here @check_in = Date.parse(input[:check_in]) @check_out = Date.parse(input[:check_out]) @daily_rate = input[:daily_rate] ? input[:daily_rate] : 200 - unless @check_out > @check_in - raise StandardError, "Invalid date range: end date must occur after start date." - end end def dates_reserved() diff --git a/spec/booking_system_spec.rb b/spec/booking_system_spec.rb index 6d79c848d..b1be0dd0f 100644 --- a/spec/booking_system_spec.rb +++ b/spec/booking_system_spec.rb @@ -40,55 +40,41 @@ end end - describe "#create_date_range" do - let(:start_date) {Date.parse("07-01-2010")} - let(:end_date) {Date.parse("07-04-2010")} - let(:date_range) {booking_system.create_date_range(start_date, end_date)} - - it "returns an array of Date objects" do - expect(date_range).must_be_kind_of Array - date_range.each do |date| - date.must_be_kind_of Date - end - end - - it "accurately returns first Date value" do - expect(date_range[0]).must_equal start_date - end - - it "accurately returns last Date value" do - expect(date_range[-1]).must_equal end_date-1 + describe "#construct_cal" do + # see additional tests in Calendar + it "creates a new instance of Calendar" do + booking_system.construct_cal_checker(start_date: "1990-10-01", end_date: "1990-10-15").must_be_kind_of Hotel::Calendar end end - describe "#generate_res_id" do - let(:first_res) {Reservation.new("08-01-1996", "08-03-1996")} - let(:second_res) {Reservation.new("09-09-1996", "08-13-1996")} - let(:third_res) {Reservation.new("10-01-1996", "10-10-1996")} - - it "creates the first reservation ID if it's the first reservation in reservations list" do - booking_system.reservations << first_res - - expect(reservations.generate_res_id[0].id).must_equal 1 - end - - it "can generate accurate IDs when new reservations are added to reservations list" do - booking_system.reservations << first_res - booking_system.reservations << second_res - - expect(reservations.generate_res_id[0].id).must_equal 1 - expect(reservations.generate_res_id[1].id).must_equal 2 - - booking_system.reservations << third_res - - expect(reservations.generate_res_id[-1].id).must_equal 3 - end - - - - - - end + # describe "#generate_res_id" do + # let(:first_res) {Reservation.new("1996-08-01", "1996-08-03")} + # let(:second_res) {Reservation.new("1996-09-09", "1996-08-13")} + # let(:third_res) {Reservation.new("1996-10-01-", "1996-10-10")} + # + # it "creates the first reservation ID if it's the first reservation in reservations list" do + # booking_system.reservations << first_res + # + # expect(reservations.generate_res_id[0].id).must_equal 1 + # end + # + # it "can generate accurate IDs when new reservations are added to reservations list" do + # booking_system.reservations << first_res + # booking_system.reservations << second_res + # + # expect(reservations.generate_res_id[0].id).must_equal 1 + # expect(reservations.generate_res_id[1].id).must_equal 2 + # + # booking_system.reservations << third_res + # + # expect(reservations.generate_res_id[-1].id).must_equal 3 + # end + + + + + + # end # # describe "#list_all_rooms" do # let(:all_rooms_str) {booking_system.list_all_rooms()} diff --git a/spec/calendar.rb b/spec/calendar.rb deleted file mode 100644 index e69de29bb..000000000 diff --git a/spec/calendar_spec.rb b/spec/calendar_spec.rb new file mode 100644 index 000000000..2ef52404a --- /dev/null +++ b/spec/calendar_spec.rb @@ -0,0 +1,66 @@ +require_relative 'spec_helper' +# require_relative 'calendar' + +# TODO: edge case --> multimonth stay?? +describe "Calendar" do + let(:cal) {Hotel::Calendar.new(start_date: "1986-07-29", end_date: "1986-07-31")} + + describe "#initialize" do + it "can create a new instance of Calendar" do + expect(cal).must_be_kind_of Hotel::Calendar + end + it "correctly loads date attributes" do + expect(cal.start_date).must_be_kind_of Date + expect(cal.start_date.strftime('%Y %b %d')).must_equal "1986 Jul 29" + + expect(cal.end_date).must_be_kind_of Date + expect(cal.end_date.strftime('%Y %b %d')).must_equal "1986 Jul 31" + end + + it "throws a StandardError if fed improper date format for start or end date" do + expect { + Hotel::Calendar.new( + start_date: "2009,7,2", + end_date: "2009-7-1" + )}.must_raise StandardError + + expect { + Hotel::Calendar.new({ + start_date: "2009-7-2", + end_date: "2009,7,1" + })}.must_raise StandardError + end + + it "throws a StandardError if end date occurs before or on same day as start date" do + expect { + Hotel::Calendar.new({ + start_date: "2009-7-2", + end_date: "2009-7-1" + })}.must_raise StandardError + + expect { + Hotel::Calendar.new({ + start_date: "2009-7-1", + end_date: "2009-7-1" + })}.must_raise StandardError + end + end + + describe "#create_date_range" do + it "returns an array of Date objects" do + cal.create_date_range.each do |date| + expect(date).must_be_kind_of Date + end + expect(cal.create_date_range).must_be_kind_of Array + end + + it "can list all the dates within the range" do + date1_s = cal.create_date_range[0].strftime('%Y %b %d') + date2_s = cal.create_date_range[1].strftime('%Y %b %d') + + expect(cal.create_date_range.length).must_equal 2 + expect(date1_s).must_equal "1986 Jul 29" + expect(date2_s).must_equal "1986 Jul 30" + end + end +end diff --git a/spec/reservation_spec.rb b/spec/reservation_spec.rb index e91b38c77..7ba8b4ea9 100644 --- a/spec/reservation_spec.rb +++ b/spec/reservation_spec.rb @@ -17,42 +17,6 @@ expect(reservation.id).must_equal 2 end - it "throws a StandardError if fed improper date format for check_in or check_out" do - expect { - Hotel::Reservation.new({ - id: "5", - room_num: "8", - check_in: "2009,7,2", - check_out: "2009-7-1" - })}.must_raise StandardError - - expect { - Hotel::Reservation.new({ - id: "5", - room_num: "8", - check_in: "2009-7-2", - check_out: "2009,7,1" - })}.must_raise StandardError - end - - it "throws a StandardError if check_out occurs before or on same day as check_in" do - expect { - Hotel::Reservation.new({ - id: "5", - room_num: "8", - check_in: "2009-7-2", - check_out: "2009-7-1" - })}.must_raise StandardError - - expect { - Hotel::Reservation.new({ - id: "5", - room_num: "8", - check_in: "2009-7-1", - check_out: "2009-7-1" - })}.must_raise StandardError - end - it "can create a reservation with a one-night stay" do # edge case one_night_stay = Hotel::Reservation.new({ @@ -88,21 +52,22 @@ end describe "#dates_reserved" do - it "returns an array of Date objects" do - expect(reservation.dates_reserved).must_be_kind_of Array - expect(reservation.dates_reserved[0]).must_be_kind_of Date - end - - it "can list all the dates of a reservation" do - date1_s = reservation.dates_reserved[0].strftime('%Y %b %d') - date2_s = reservation.dates_reserved[1].strftime('%Y %b %d') - date3_s = reservation.dates_reserved[2].strftime('%Y %b %d') - - expect(reservation.dates_reserved.length).must_equal 3 - expect(date1_s).must_equal "2004 Jul 01" - expect(date2_s).must_equal "2004 Jul 02" - expect(date3_s).must_equal "2004 Jul 03" - end + # NOTE: tests in cal?? + # it "returns an array of Date objects" do + # expect(reservation.dates_reserved).must_be_kind_of Array + # expect(reservation.dates_reserved[0]).must_be_kind_of Date + # end + # + # it "can list all the dates of a reservation" do + # date1_s = reservation.dates_reserved[0].strftime('%Y %b %d') + # date2_s = reservation.dates_reserved[1].strftime('%Y %b %d') + # date3_s = reservation.dates_reserved[2].strftime('%Y %b %d') + # + # expect(reservation.dates_reserved.length).must_equal 3 + # expect(date1_s).must_equal "2004 Jul 01" + # expect(date2_s).must_equal "2004 Jul 02" + # expect(date3_s).must_equal "2004 Jul 03" + # end end describe "#total_stay_cost" do diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 96d5ec85f..67f86b8eb 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -7,6 +7,6 @@ Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new -require_relative '../lib/booking_system' -# require_relative '../lib/room' +require_relative '../lib/calendar' require_relative '../lib/reservation' +require_relative '../lib/booking_system' From 2cd102385843ed067b1230ef354845e9e3cdc85a Mon Sep 17 00:00:00 2001 From: kangazoom Date: Sat, 8 Sep 2018 15:23:59 -0700 Subject: [PATCH 23/36] Added inheritance to Reservation from Calendar and changed hash initialization to kwargs --- lib/booking_system.rb | 19 ++++++------- lib/calendar.rb | 19 +++++++------ lib/reservation.rb | 34 +++++++++++----------- spec/booking_system_spec.rb | 56 +++++++++++++++++-------------------- spec/calendar_spec.rb | 26 ++++++++--------- spec/reservation_spec.rb | 16 +++++------ 6 files changed, 83 insertions(+), 87 deletions(-) diff --git a/lib/booking_system.rb b/lib/booking_system.rb index 129247684..3424e195e 100644 --- a/lib/booking_system.rb +++ b/lib/booking_system.rb @@ -18,19 +18,16 @@ def list_all_rooms() end def construct_cal_checker(start_date:, end_date:) - #QUESTION: initialize this??? - construct_cal_checker = Calendar.new(start_date: start_date, end_date: end_date) - # QUESTION: kwargs? RETURN DATE RANGE OR THE CALENDAR? - # return DateRange.new(start_date, end_date).create_date_range #<-- returns array of Date objects + return Calendar.new(start_date: start_date, end_date: end_date) end - # def generate_res_id() - # if @reservations.empty? - # return 1 - # else - # return @reservations.max_by { |reservation| reservation.id}.id + 1 - # end - # end + def generate_res_id() + if @reservations.empty? + return 1 + else + return @reservations.max_by { |reservation| reservation.id}.id + 1 + end + end # # TODO: maybe use date range instead of start/end? diff --git a/lib/calendar.rb b/lib/calendar.rb index 831556fca..c791b469e 100644 --- a/lib/calendar.rb +++ b/lib/calendar.rb @@ -2,19 +2,20 @@ module Hotel class Calendar - attr_reader :start_date, :end_date + attr_reader :check_in, :check_out - def initialize(start_date:, end_date:) + def initialize(check_in:, check_out:) -# QUESTION: separate error handling into its own method? - unless /\d{4}-\d{1,2}-\d{1,2}/.match(start_date) && /\d{4}-\d{1,2}-\d{1,2}/.match(end_date) +# QUESTION: separate error handling into its own method? YES +# ^^ also if check_out is nil --> just look at one date + unless /\d{4}-\d{1,2}-\d{1,2}/.match(check_in) && /\d{4}-\d{1,2}-\d{1,2}/.match(check_out) raise StandardError, "Improper date format: date must be entered as YYYY-MM-DD." end - @start_date = Date.parse(start_date) - @end_date = Date.parse(end_date) + @check_in = Date.parse(check_in) + @check_out = Date.parse(check_out) - unless @start_date < @end_date + unless @check_in < @check_out raise StandardError, "Invalid date range: end date must occur after start date." end end @@ -22,7 +23,7 @@ def initialize(start_date:, end_date:) # TODO: create date range and check without arrays? def create_date_range() # QUESTION: shoudl i just use instance var instead of input local var? - return (@start_date...@end_date).to_a + return (@check_in...@check_out).to_a end @@ -32,6 +33,6 @@ def create_date_range() end # -# cal = Hotel::Calendar.new(start_date: "1986-07-29", end_date: "1986-07-31") +# cal = Hotel::Calendar.new(check_in: "1986-07-29", check_out: "1986-07-31") # # puts cal diff --git a/lib/reservation.rb b/lib/reservation.rb index 446dae260..ed8492d63 100644 --- a/lib/reservation.rb +++ b/lib/reservation.rb @@ -1,17 +1,19 @@ require 'date' +require_relative 'calendar' module Hotel - class Reservation - attr_reader :id, :room, :check_in, :check_out, :daily_rate + class Reservation < Calendar + attr_reader :id, :room, :daily_rate - def initialize(input) + def initialize(check_in:, check_out:, id:, room_num:, daily_rate:200) + super(check_in: check_in, check_out: check_out) - @id = input[:id].to_i - @room_num = input[:room_num] + @id = id.to_i + @room_num = room_num.to_i #TODO: date_range CAL instantiate here - @check_in = Date.parse(input[:check_in]) - @check_out = Date.parse(input[:check_out]) - @daily_rate = input[:daily_rate] ? input[:daily_rate] : 200 + # @check_in = Date.parse(input[:check_in]) + # @check_out = Date.parse(input[:check_out]) + @daily_rate = daily_rate.to_f end @@ -28,11 +30,11 @@ def total_stay_cost() end -# res = Hotel::Reservation.new({ -# id: "2", -# room_num: "3", -# check_in: "2004,5,6", -# check_out: "2004-7-4"}) -# -# p res.dates_reserved.class -# p res.dates_reserved[0].class +res = Hotel::Reservation.new( + id: "2", + room_num: "3", + check_in: "2004-5-6", + check_out: "2004-7-4") + +p res.create_date_range +p res.create_date_range.class diff --git a/spec/booking_system_spec.rb b/spec/booking_system_spec.rb index b1be0dd0f..8adbfb2b9 100644 --- a/spec/booking_system_spec.rb +++ b/spec/booking_system_spec.rb @@ -40,41 +40,37 @@ end end - describe "#construct_cal" do - # see additional tests in Calendar + describe "#construct_cal_checker" do + # see additional constructor tests in Calendar it "creates a new instance of Calendar" do booking_system.construct_cal_checker(start_date: "1990-10-01", end_date: "1990-10-15").must_be_kind_of Hotel::Calendar + #TODO: check for endd_date as nil? end end - # describe "#generate_res_id" do - # let(:first_res) {Reservation.new("1996-08-01", "1996-08-03")} - # let(:second_res) {Reservation.new("1996-09-09", "1996-08-13")} - # let(:third_res) {Reservation.new("1996-10-01-", "1996-10-10")} - # - # it "creates the first reservation ID if it's the first reservation in reservations list" do - # booking_system.reservations << first_res - # - # expect(reservations.generate_res_id[0].id).must_equal 1 - # end - # - # it "can generate accurate IDs when new reservations are added to reservations list" do - # booking_system.reservations << first_res - # booking_system.reservations << second_res - # - # expect(reservations.generate_res_id[0].id).must_equal 1 - # expect(reservations.generate_res_id[1].id).must_equal 2 - # - # booking_system.reservations << third_res - # - # expect(reservations.generate_res_id[-1].id).must_equal 3 - # end - - - - - - # end + describe "#generate_res_id" do + let(:first_res) {Reservation.new("1996-08-01", "1996-08-03")} + let(:second_res) {Reservation.new("1996-09-09", "1996-08-13")} + let(:third_res) {Reservation.new("1996-10-01-", "1996-10-10")} + + it "creates the first reservation ID if it's the first reservation in reservations list" do + booking_system.reservations << first_res + + expect(reservations.generate_res_id[0].id).must_equal 1 + end + + it "can generate accurate IDs when new reservations are added to reservations list" do + booking_system.reservations << first_res + booking_system.reservations << second_res + + expect(reservations.generate_res_id[0].id).must_equal 1 + expect(reservations.generate_res_id[1].id).must_equal 2 + + booking_system.reservations << third_res + + expect(reservations.generate_res_id[-1].id).must_equal 3 + end + end # # describe "#list_all_rooms" do # let(:all_rooms_str) {booking_system.list_all_rooms()} diff --git a/spec/calendar_spec.rb b/spec/calendar_spec.rb index 2ef52404a..c44bc5987 100644 --- a/spec/calendar_spec.rb +++ b/spec/calendar_spec.rb @@ -3,45 +3,45 @@ # TODO: edge case --> multimonth stay?? describe "Calendar" do - let(:cal) {Hotel::Calendar.new(start_date: "1986-07-29", end_date: "1986-07-31")} + let(:cal) {Hotel::Calendar.new(check_in: "1986-07-29", check_out: "1986-07-31")} describe "#initialize" do it "can create a new instance of Calendar" do expect(cal).must_be_kind_of Hotel::Calendar end it "correctly loads date attributes" do - expect(cal.start_date).must_be_kind_of Date - expect(cal.start_date.strftime('%Y %b %d')).must_equal "1986 Jul 29" + expect(cal.check_in).must_be_kind_of Date + expect(cal.check_in.strftime('%Y %b %d')).must_equal "1986 Jul 29" - expect(cal.end_date).must_be_kind_of Date - expect(cal.end_date.strftime('%Y %b %d')).must_equal "1986 Jul 31" + expect(cal.check_out).must_be_kind_of Date + expect(cal.check_out.strftime('%Y %b %d')).must_equal "1986 Jul 31" end it "throws a StandardError if fed improper date format for start or end date" do expect { Hotel::Calendar.new( - start_date: "2009,7,2", - end_date: "2009-7-1" + check_in: "2009,7,2", + check_out: "2009-7-1" )}.must_raise StandardError expect { Hotel::Calendar.new({ - start_date: "2009-7-2", - end_date: "2009,7,1" + check_in: "2009-7-2", + check_out: "2009,7,1" })}.must_raise StandardError end it "throws a StandardError if end date occurs before or on same day as start date" do expect { Hotel::Calendar.new({ - start_date: "2009-7-2", - end_date: "2009-7-1" + check_in: "2009-7-2", + check_out: "2009-7-1" })}.must_raise StandardError expect { Hotel::Calendar.new({ - start_date: "2009-7-1", - end_date: "2009-7-1" + check_in: "2009-7-1", + check_out: "2009-7-1" })}.must_raise StandardError end end diff --git a/spec/reservation_spec.rb b/spec/reservation_spec.rb index 7ba8b4ea9..16465cfae 100644 --- a/spec/reservation_spec.rb +++ b/spec/reservation_spec.rb @@ -5,11 +5,11 @@ # TODO: test id as any pos int? # TODO: test room_num as 1-20? - let(:reservation) {Hotel::Reservation.new({ + let(:reservation) {Hotel::Reservation.new( id: "2", room_num: "3", check_in: "2004-7-1", - check_out: "2004-7-4"})} + check_out: "2004-7-4")} describe "#initialize" do it "can create a new instance of reservation" do @@ -19,33 +19,33 @@ it "can create a reservation with a one-night stay" do # edge case - one_night_stay = Hotel::Reservation.new({ + one_night_stay = Hotel::Reservation.new( id: "66", room_num: "19", check_in:"2009-7-29", - check_out: "2009-7-30"}) + check_out: "2009-7-30") expect(one_night_stay).must_be_kind_of Hotel::Reservation expect(one_night_stay.id).must_equal 66 end it "sets daily rate to default value if no value given" do - typical_room = Hotel::Reservation.new({ + typical_room = Hotel::Reservation.new( id: "66", room_num: "19", check_in:"2009-7-29", - check_out: "2009-7-30"}) + check_out: "2009-7-30") expect(typical_room.daily_rate).must_equal 200 end # QUESTION: do we need error handling for numeric value for daily_rate? it "can override default value for daily rate" do - rare_room = Hotel::Reservation.new({ + rare_room = Hotel::Reservation.new( id: "66", room_num: "19", check_in:"2009-7-29", check_out: "2009-7-30", - daily_rate: 500}) + daily_rate: 500) expect(rare_room.daily_rate).must_equal 500 end From 9178b35dabfde4885efc5a72035ec5f34dfe45e1 Mon Sep 17 00:00:00 2001 From: kangazoom Date: Sat, 8 Sep 2018 16:52:15 -0700 Subject: [PATCH 24/36] added #overlap to Calendar and wrote a bunch of tests for nominal and edge cases woo --- lib/booking_system.rb | 12 ++-- lib/calendar.rb | 18 ++++-- lib/reservation.rb | 18 +++--- spec/booking_system_spec.rb | 32 ++++++----- spec/calendar_spec.rb | 106 +++++++++++++++++++++++++++++++----- 5 files changed, 135 insertions(+), 51 deletions(-) diff --git a/lib/booking_system.rb b/lib/booking_system.rb index 3424e195e..c8f254aed 100644 --- a/lib/booking_system.rb +++ b/lib/booking_system.rb @@ -14,11 +14,10 @@ def initialize() def list_all_rooms() return (1..20).to_a - # all_rooms = nums.map { |num| Hotel::Room.new(num: num)} end - def construct_cal_checker(start_date:, end_date:) - return Calendar.new(start_date: start_date, end_date: end_date) + def construct_cal_checker(check_in:, check_out:) + return Calendar.new(check_in: check_in, check_out: check_out) end def generate_res_id() @@ -90,10 +89,6 @@ def generate_res_id() # return @rooms.find {|room| room.num == room_num.to_i} # end # -# def overlap?(date_range_1, date_range_2) -# return false if (date_range_1 & date_range_2).empty? else return true -# end -# # def list_avail_rooms_for_date(check_date) # avail_rooms = @reservations.select { |reservation| !reservation.date_range.include?(check_date) } #==false # # check for no overlap in dates @@ -119,7 +114,8 @@ def generate_res_id() end -# booking = Hotel::BookingSystem.new() +booking = Hotel::BookingSystem.new() +puts booking.reservations.empty? # # # res_3 = booking.create_reservation({ # id: "4", diff --git a/lib/calendar.rb b/lib/calendar.rb index c791b469e..4f438a3bc 100644 --- a/lib/calendar.rb +++ b/lib/calendar.rb @@ -7,7 +7,7 @@ class Calendar def initialize(check_in:, check_out:) # QUESTION: separate error handling into its own method? YES -# ^^ also if check_out is nil --> just look at one date +# ^^ also if check_out is nil --> just look at one date unless /\d{4}-\d{1,2}-\d{1,2}/.match(check_in) && /\d{4}-\d{1,2}-\d{1,2}/.match(check_out) raise StandardError, "Improper date format: date must be entered as YYYY-MM-DD." end @@ -21,9 +21,17 @@ def initialize(check_in:, check_out:) end # TODO: create date range and check without arrays? - def create_date_range() - # QUESTION: shoudl i just use instance var instead of input local var? - return (@check_in...@check_out).to_a + # def create_date_range() + # # QUESTION: shoudl i just use instance var instead of input local var? + # return (@check_in...@check_out).to_a + # end + + def overlap?(other_dates) # param: Calendar obj + if !(other_dates.check_in <= @check_out-1) || !(other_dates.check_out-1 >= @check_in) + return false + else + return true + end end @@ -35,4 +43,4 @@ def create_date_range() # # cal = Hotel::Calendar.new(check_in: "1986-07-29", check_out: "1986-07-31") # -# puts cal +# puts cal.check_in diff --git a/lib/reservation.rb b/lib/reservation.rb index ed8492d63..7740b4a90 100644 --- a/lib/reservation.rb +++ b/lib/reservation.rb @@ -5,7 +5,7 @@ module Hotel class Reservation < Calendar attr_reader :id, :room, :daily_rate - def initialize(check_in:, check_out:, id:, room_num:, daily_rate:200) + def initialize(check_in:, check_out:, id:, room_num:, daily_rate: 200) super(check_in: check_in, check_out: check_out) @id = id.to_i @@ -30,11 +30,11 @@ def total_stay_cost() end -res = Hotel::Reservation.new( - id: "2", - room_num: "3", - check_in: "2004-5-6", - check_out: "2004-7-4") - -p res.create_date_range -p res.create_date_range.class +# res = Hotel::Reservation.new( +# id: "2", +# room_num: "3", +# check_in: "2004-5-6", +# check_out: "2004-7-4") +# +# p res.create_date_range +# p res.create_date_range.class diff --git a/spec/booking_system_spec.rb b/spec/booking_system_spec.rb index 8adbfb2b9..694b1a8ac 100644 --- a/spec/booking_system_spec.rb +++ b/spec/booking_system_spec.rb @@ -14,6 +14,8 @@ expect(booking_system.rooms).must_be_kind_of Array expect(booking_system.reservations).must_be_kind_of Array end + + #TODO: can add new reservations successfully? or elsewhere do this?? end describe "#list_all_rooms" do @@ -43,32 +45,34 @@ describe "#construct_cal_checker" do # see additional constructor tests in Calendar it "creates a new instance of Calendar" do - booking_system.construct_cal_checker(start_date: "1990-10-01", end_date: "1990-10-15").must_be_kind_of Hotel::Calendar + booking_system.construct_cal_checker(check_in: "1990-10-01", check_out: "1990-10-15").must_be_kind_of Hotel::Calendar #TODO: check for endd_date as nil? end end describe "#generate_res_id" do - let(:first_res) {Reservation.new("1996-08-01", "1996-08-03")} - let(:second_res) {Reservation.new("1996-09-09", "1996-08-13")} - let(:third_res) {Reservation.new("1996-10-01-", "1996-10-10")} - it "creates the first reservation ID if it's the first reservation in reservations list" do - booking_system.reservations << first_res - - expect(reservations.generate_res_id[0].id).must_equal 1 + let(:second_res) {Hotel::Reservation.new(id: 2, room_num: 19, check_in: "1996-09-09", check_out: "1996-08-13")} + let(:third_res) {Hotel::Reservation.new(id: 3, room_num: 20, check_in: "1996-10-01-", check_out: "1996-10-10")} + + it "can create ID for first reservation ID instance" do + new_id = booking_system.generate_res_id() + new_res = Hotel::Reservation.new(id: new_id, room_num: 16, check_in: "1996-08-01", check_out: "1996-08-03") + + booking_system.reservations << new_res + + expect(booking_system.reservations[0].id).must_equal 1 end it "can generate accurate IDs when new reservations are added to reservations list" do + first_res = Hotel::Reservation.new(id: 10, room_num: 19, check_in: "1996-09-09", check_out: "1996-09-13") booking_system.reservations << first_res - booking_system.reservations << second_res - expect(reservations.generate_res_id[0].id).must_equal 1 - expect(reservations.generate_res_id[1].id).must_equal 2 - - booking_system.reservations << third_res + new_id = booking_system.generate_res_id() + second_res = Hotel::Reservation.new(id: new_id, room_num: 20, check_in: "1996-10-01", check_out: "1996-10-10") + booking_system.reservations << second_res - expect(reservations.generate_res_id[-1].id).must_equal 3 + expect(booking_system.reservations[1].id).must_equal 11 end end # diff --git a/spec/calendar_spec.rb b/spec/calendar_spec.rb index c44bc5987..9edaa9c00 100644 --- a/spec/calendar_spec.rb +++ b/spec/calendar_spec.rb @@ -3,7 +3,7 @@ # TODO: edge case --> multimonth stay?? describe "Calendar" do - let(:cal) {Hotel::Calendar.new(check_in: "1986-07-29", check_out: "1986-07-31")} + let(:cal) {Hotel::Calendar.new(check_in: "1986-07-20", check_out: "1986-07-29")} describe "#initialize" do it "can create a new instance of Calendar" do @@ -11,10 +11,10 @@ end it "correctly loads date attributes" do expect(cal.check_in).must_be_kind_of Date - expect(cal.check_in.strftime('%Y %b %d')).must_equal "1986 Jul 29" + expect(cal.check_in.strftime('%Y %b %d')).must_equal "1986 Jul 20" expect(cal.check_out).must_be_kind_of Date - expect(cal.check_out.strftime('%Y %b %d')).must_equal "1986 Jul 31" + expect(cal.check_out.strftime('%Y %b %d')).must_equal "1986 Jul 29" end it "throws a StandardError if fed improper date format for start or end date" do @@ -46,21 +46,97 @@ end end - describe "#create_date_range" do - it "returns an array of Date objects" do - cal.create_date_range.each do |date| - expect(date).must_be_kind_of Date - end - expect(cal.create_date_range).must_be_kind_of Array + # describe "#create_date_range" do + # it "returns an array of Date objects" do + # cal.create_date_range.each do |date| + # expect(date).must_be_kind_of Date + # end + # expect(cal.create_date_range).must_be_kind_of Array + # end + # + # it "can list first and last dates within range" do + # date1_s = cal.create_date_range[0].strftime('%Y %b %d') + # date2_s = cal.create_date_range[-1].strftime('%Y %b %d') + # + # expect(cal.create_date_range.length).must_equal 9 + # expect(date1_s).must_equal "1986 Jul 20" + # expect(date2_s).must_equal "1986 Jul 29" + # end + # end + + describe "#overlap?" do + it "returns false for no overlap: other dates begin and end before reserved dates" do + other_dates = Hotel::Calendar.new(check_in: "1986-07-01", check_out: "1986-07-15") + + dates_overlap = cal.overlap?(other_dates) + + expect(dates_overlap).must_equal false + end + + it "returns false for no overlap: other dates begin and end after reserved dates" do + other_dates = Hotel::Calendar.new(check_in: "1986-07-30", check_out: "1986-07-31") + + dates_overlap = cal.overlap?(other_dates) + + expect(dates_overlap).must_equal false + end + + it "returns false for no overlap: other dates begin during reserved dates' check out date" do + # edge case + other_dates = Hotel::Calendar.new(check_in: "1986-07-29", check_out: "1986-07-31") + + dates_overlap = cal.overlap?(other_dates) + + expect(dates_overlap).must_equal false + end + + it "returns false for no overlap: other dates end during reserved dates' check in date" do + # edge case + other_dates = Hotel::Calendar.new(check_in: "1986-07-15", check_out: "1986-07-20") + + dates_overlap = cal.overlap?(other_dates) + + expect(dates_overlap).must_equal false + end + + it "returns true if dates overlap: other dates begin and end beyond reserved dates range" do + other_dates = Hotel::Calendar.new(check_in: "1986-07-01", check_out: "1986-07-31") + + dates_overlap = cal.overlap?(other_dates) + + expect(dates_overlap).must_equal true + end + + it "returns true if dates overlap: other dates are fully contained within reserved dates" do + other_dates = Hotel::Calendar.new(check_in: "1986-07-25", check_out: "1986-07-28") + + dates_overlap = cal.overlap?(other_dates) + + expect(dates_overlap).must_equal true + end + + it "returns true if dates overlap: other dates begin before but end during reserved dates" do + other_dates = Hotel::Calendar.new(check_in: "1986-07-10", check_out: "1986-07-28") + + dates_overlap = cal.overlap?(other_dates) + + expect(dates_overlap).must_equal true end - it "can list all the dates within the range" do - date1_s = cal.create_date_range[0].strftime('%Y %b %d') - date2_s = cal.create_date_range[1].strftime('%Y %b %d') + it "returns true if dates overlap: other dates begin during but end after reserved dates" do + other_dates = Hotel::Calendar.new(check_in: "1986-07-25", check_out: "1986-07-31") - expect(cal.create_date_range.length).must_equal 2 - expect(date1_s).must_equal "1986 Jul 29" - expect(date2_s).must_equal "1986 Jul 30" + dates_overlap = cal.overlap?(other_dates) + + expect(dates_overlap).must_equal true end + + + + end + + + + end From 49b4efaa38f524a86cde578fe3354b97e1cc50a4 Mon Sep 17 00:00:00 2001 From: kangazoom Date: Sun, 9 Sep 2018 16:18:14 -0700 Subject: [PATCH 25/36] added has_date? to Calendar and used it to list reservations by date in BookingSystem --- lib/booking_system.rb | 22 ++--- lib/calendar.rb | 23 ++++-- spec/booking_system_spec.rb | 158 +++++++++++++++--------------------- spec/calendar_spec.rb | 51 ++++++++++++ 4 files changed, 142 insertions(+), 112 deletions(-) diff --git a/lib/booking_system.rb b/lib/booking_system.rb index c8f254aed..fe9df7726 100644 --- a/lib/booking_system.rb +++ b/lib/booking_system.rb @@ -28,6 +28,15 @@ def generate_res_id() end end + def list_res_for_date(check_date) + matching_res = @reservations.select { |reservation| reservation.has_date?(check_date) } #==false + # check for no overlap in dates + # if (reservation.date_range & check_date_range).empty? + + return matching_res.empty? ? nil : matching_res + + end + # # TODO: maybe use date range instead of start/end? # def create_reservation(start_date, end_date) @@ -89,14 +98,7 @@ def generate_res_id() # return @rooms.find {|room| room.num == room_num.to_i} # end # -# def list_avail_rooms_for_date(check_date) -# avail_rooms = @reservations.select { |reservation| !reservation.date_range.include?(check_date) } #==false -# # check for no overlap in dates -# # if (reservation.date_range & check_date_range).empty? -# -# return avail_rooms.empty? ? nil : avail_rooms -# -# end + # # def list_avail_rooms_for_range(start_date, end_date) # check_date_range = create_date_range(start_date, end_date) @@ -114,8 +116,8 @@ def generate_res_id() end -booking = Hotel::BookingSystem.new() -puts booking.reservations.empty? +# booking = Hotel::BookingSystem.new() +# puts booking.reservations.empty? # # # res_3 = booking.create_reservation({ # id: "4", diff --git a/lib/calendar.rb b/lib/calendar.rb index 4f438a3bc..8fd877894 100644 --- a/lib/calendar.rb +++ b/lib/calendar.rb @@ -26,16 +26,23 @@ def initialize(check_in:, check_out:) # return (@check_in...@check_out).to_a # end - def overlap?(other_dates) # param: Calendar obj - if !(other_dates.check_in <= @check_out-1) || !(other_dates.check_out-1 >= @check_in) - return false - else - return true - end - end - + def has_date?(other_date) + other_date = Date.parse(other_date) + if (other_date >= @check_in) && (other_date <= @check_out - 1) + return true + else + return false + end + end + def overlap?(other_dates) # param: Calendar obj + if !(other_dates.check_in <= @check_out-1) || !(other_dates.check_out-1 >= @check_in) + return false + else + return true + end + end end end diff --git a/spec/booking_system_spec.rb b/spec/booking_system_spec.rb index 694b1a8ac..c00b58f4a 100644 --- a/spec/booking_system_spec.rb +++ b/spec/booking_system_spec.rb @@ -75,39 +75,71 @@ expect(booking_system.reservations[1].id).must_equal 11 end end -# -# describe "#list_all_rooms" do -# let(:all_rooms_str) {booking_system.list_all_rooms()} -# -# it "lists all rooms as a string" do -# beginning_text = "Here is a list of all rooms:" -# room_2 = "Room 2" -# -# expect(all_rooms_str).must_be_kind_of String -# expect(all_rooms_str).must_include beginning_text -# expect(all_rooms_str).must_include room_2 -# end -# end -# -# describe "#find_room" do -# let(:room_num) {4} -# let(:room_obj) {booking_system.find_room(room_num)} -# -# it "finds room object by room number" do -# # num = 4 -# # room_obj = booking_system.find_room(num) -# -# expect(room_obj).must_be_kind_of Hotel::Room -# expect(room_obj.num).must_equal room_num -# end -# end -# + # describe "#find_room" do + # skip + # let(:room_num) {4} + # let(:room_obj) {booking_system.find_room(room_num)} + # + # it "finds room object by room number" do + # # num = 4 + # # room_obj = booking_system.find_room(num) + # + # expect(room_obj).must_be_kind_of Hotel::Room + # expect(room_obj.num).must_equal room_num + # end + # end + + describe "#list_res_for_date" do + let(:res_1) {Hotel::Reservation.new( + id: "1", + room_num: "20", + check_in: "2010-8-1", + check_out: "2010-8-10" + )} + + let(:res_2) {Hotel::Reservation.new( + id: "2", + room_num: "19", + check_in: "2010-8-15", + check_out: "2010-8-18" + )} + + let(:res_3) {Hotel::Reservation.new( + id: "4", + room_num: "15", + check_in: "2010-8-4", + check_out: "2010-8-20" + )} + + let(:matching_res) {booking_system.list_res_for_date("2010-8-5")} + + it "should return an array of Reservation objects" do + + booking_system.reservations.push(res_1, res_2, res_3) + + expect(matching_res).must_be_kind_of Array + expect(matching_res[0]).must_be_kind_of Hotel::Reservation + end + + it "accurately loads Reservation objects for specified date" do + booking_system.reservations.push(res_1, res_2, res_3) + + expect(matching_res.length).must_equal 2 + expect(matching_res[0].id).must_equal 1 + expect(matching_res[1].id).must_equal 4 + end + + it "returns nil if no Reservations are found for specified date" do + booking_system.reservations.push(res_1, res_2, res_3) + + matching_res = booking_system.list_res_for_date("2010-8-30") + expect(matching_res).must_equal nil + end + end # -# # TODO -# describe "#overlap?" do -# end -# + + # # TODO: add create reservation method + 2nd input as room_num?? # describe "#create_reservation" do # # TODO: A reservation is allowed start on the same day that another reservation for the same room ends @@ -145,69 +177,7 @@ # # describe "#load_reservations" do # # end # -# describe "#list_reservations_for_date" do -# let(:res_1) {booking_system.create_reservation({ -# id: "1", -# room_num: "20", -# start_date: "2010-8-1", -# end_date: "2010-8-10" -# })} -# -# let(:res_2) {booking_system.create_reservation({ -# id: "2", -# room_num: "19", -# start_date: "2010-8-15", -# end_date: "2010-8-18" -# })} -# -# let(:res_3) {booking_system.create_reservation({ -# id: "4", -# room_num: "15", -# start_date: "2010-8-4", -# end_date: "2010-8-20" -# })} -# -# let(:matching_res) {booking_system.list_reservations_for_date("2010-8-5")} -# # puts @matching_res} -# # res_1 = booking_system.create_reservation({ -# # id: "1", -# # room_num: "20", -# # start_date: "2010-8-1", -# # end_date: "2010-8-10", -# # }) -# # res_2 = booking_system.create_reservation({ -# # id: "2", -# # room_num: "19", -# # start_date: "2010-8-15", -# # end_date: "2010-8-18", -# # }) -# # res_3 = booking_system.create_reservation({ -# # id: "4", -# # room_num: "15", -# # start_date: "2010-8-4", -# # end_date: "2010-8-20", -# # }) -# -# # @matching_res = booking_system.list_reservations_for_date("2010-8-5") -# # puts @matching_res -# # end -# -# it "should return an array of Reservation objects" do -# expect(matching_res).must_be_kind_of Array -# expect(matching_res[0]).must_be_kind_of Hotel::Reservation -# end -# -# it "accurately loads Reservation objects for specified date" do -# expect(matching_res.length).must_equal 2 -# expect(matching_res[0].id).must_equal 1 -# expect(matching_res[1].id).must_equal 4 -# end -# -# it "returns nil if no Reservations are found for specified date" do -# matching_res = booking_system.list_reservations_for_date("2010-8-30") -# expect(matching_res).must_equal nil -# end -# end + # # describe "#list_avail_rooms_for_date" do # let(:start_date) {"2010-8-15"} diff --git a/spec/calendar_spec.rb b/spec/calendar_spec.rb index 9edaa9c00..7d09799f6 100644 --- a/spec/calendar_spec.rb +++ b/spec/calendar_spec.rb @@ -64,6 +64,57 @@ # end # end + describe "#has_date?" do + it "returns true if other date is between check in and check out dates: in the middle" do + other_date = "1986-07-25" + + has_date = cal.has_date?(other_date) + + expect(has_date).must_equal true + end + + it "returns true if other date is between check in and check out dates: on check in date" do + other_date = "1986-07-20" + + has_date = cal.has_date?(other_date) + + expect(has_date).must_equal true + end + + it "returns true if other date is between check in and check out dates: on day before check out" do + other_date = "1986-07-28" + + has_date = cal.has_date?(other_date) + + expect(has_date).must_equal true + end + + it "returns false if other date is outside of check in and check out dates: before check in date" do + other_date = "1986-07-15" + + has_date = cal.has_date?(other_date) + + expect(has_date).must_equal false + end + + it "returns false if other date is outside of check in and check out dates: after check out date" do + other_date = "1986-07-31" + + has_date = cal.has_date?(other_date) + + expect(has_date).must_equal false + end + + it "returns false if other date is outside of check in and check out dates: on check out date" do + # edge case + other_date = "1986-07-29" + + has_date = cal.has_date?(other_date) + + expect(has_date).must_equal false + end + end + describe "#overlap?" do it "returns false for no overlap: other dates begin and end before reserved dates" do other_dates = Hotel::Calendar.new(check_in: "1986-07-01", check_out: "1986-07-15") From c6f1445a79fd934720efa57cb3a62372be81d538 Mon Sep 17 00:00:00 2001 From: kangazoom Date: Sun, 9 Sep 2018 17:25:02 -0700 Subject: [PATCH 26/36] Rewrote BookingSystem #list_available_rooms_for_range to pass all tests --- lib/booking_system.rb | 43 ++++++++++----------- lib/reservation.rb | 2 +- spec/booking_system_spec.rb | 74 ++++++++++++++++++++++++++----------- 3 files changed, 74 insertions(+), 45 deletions(-) diff --git a/lib/booking_system.rb b/lib/booking_system.rb index fe9df7726..2d2835a80 100644 --- a/lib/booking_system.rb +++ b/lib/booking_system.rb @@ -30,13 +30,18 @@ def generate_res_id() def list_res_for_date(check_date) matching_res = @reservations.select { |reservation| reservation.has_date?(check_date) } #==false - # check for no overlap in dates - # if (reservation.date_range & check_date_range).empty? return matching_res.empty? ? nil : matching_res end + def list_avail_rooms_for_range(check_in:, check_out:) + date_range = construct_cal_checker(check_in: check_in, check_out: check_out) + + avail_rooms = @reservations.select { |reservation| !reservation.overlap?(date_range) }.map { |reservation| reservation.room_num } + + return avail_rooms.empty? ? nil : avail_rooms + end # # TODO: maybe use date range instead of start/end? # def create_reservation(start_date, end_date) @@ -100,16 +105,7 @@ def list_res_for_date(check_date) # # -# def list_avail_rooms_for_range(start_date, end_date) -# check_date_range = create_date_range(start_date, end_date) -# -# avail_rooms = @reservations.select { |reservation| reservation.room if !overlap?(reservation.date_range, check_date_range)} #==false -# -# return avail_rooms.empty? ? nil : avail_rooms -# # check for no overlap in dates -# # if (reservation.date_range & check_date_range).empty? -# -# end + # end @@ -117,18 +113,19 @@ def list_res_for_date(check_date) # booking = Hotel::BookingSystem.new() -# puts booking.reservations.empty? -# # -# res_3 = booking.create_reservation({ +# +# res_3 = Hotel::Reservation.new( # id: "4", # room_num: "15", -# start_date: "2010-8-4", -# end_date: "2010-8-20", -# }) -# res_2 = booking.create_reservation({id: "1", +# check_in: "2010-8-4", +# check_out: "2010-8-20", +# ) +# res_2 = Hotel::Reservation.new(id: "1", # room_num: "20", -# start_date: "2010-8-1", -# end_date: "2010-8-10", -# }) +# check_in: "2010-8-1", +# check_out: "2010-8-10", +# ) +# +# booking.reservations.push(res_2, res_3) # -# p booking.available_rooms_by_date("2010-8-5") +# p booking.list_avail_rooms_for_range(check_in: "2010-10-15", check_out: "2010-10-26") diff --git a/lib/reservation.rb b/lib/reservation.rb index 7740b4a90..983a4ed41 100644 --- a/lib/reservation.rb +++ b/lib/reservation.rb @@ -3,7 +3,7 @@ module Hotel class Reservation < Calendar - attr_reader :id, :room, :daily_rate + attr_reader :id, :room_num, :daily_rate def initialize(check_in:, check_out:, id:, room_num:, daily_rate: 200) super(check_in: check_in, check_out: check_out) diff --git a/spec/booking_system_spec.rb b/spec/booking_system_spec.rb index c00b58f4a..37f94e64f 100644 --- a/spec/booking_system_spec.rb +++ b/spec/booking_system_spec.rb @@ -91,6 +91,7 @@ # end describe "#list_res_for_date" do + # see Calendar#has_date? for additional tests let(:res_1) {Hotel::Reservation.new( id: "1", room_num: "20", @@ -134,11 +135,59 @@ booking_system.reservations.push(res_1, res_2, res_3) matching_res = booking_system.list_res_for_date("2010-8-30") - expect(matching_res).must_equal nil + expect(matching_res).must_be_nil end end -# + describe "#list_avail_rooms_for_range" do + # see Calendar#overlap? for additonal tests + let(:res_1) {Hotel::Reservation.new( + id: "1", + room_num: "20", + check_in: "2010-8-1", + check_out: "2010-8-10" + )} + + let(:res_2) {Hotel::Reservation.new( + id: "2", + room_num: "19", + check_in: "2010-8-15", + check_out: "2010-8-18" + )} + + let(:res_3) {Hotel::Reservation.new( + id: "4", + room_num: "15", + check_in: "2010-8-4", + check_out: "2010-8-20" + )} + it "returns an array of room numbers if rooms are available" do + booking_system.reservations.push(res_1, res_2, res_3) + + avail_rooms = booking_system.list_avail_rooms_for_range(check_in: "2010-10-15", check_out: "2010-10-26") + + expect(avail_rooms).must_be_kind_of Array + expect(avail_rooms[0]).must_be_kind_of Integer + end + + it "accurately returns a list of available rooms by number if rooms are available" do + booking_system.reservations.push(res_1, res_2, res_3) + + avail_rooms = booking_system.list_avail_rooms_for_range(check_in: "2010-8-19", check_out: "2010-10-26") + + expect(avail_rooms.length).must_equal 2 + expect(avail_rooms[0]).must_equal 20 + expect(avail_rooms[1]).must_equal 19 + end + + it "returns nil if no rooms are available" do + booking_system.reservations.push(res_1, res_2, res_3) + + avail_rooms = booking_system.list_avail_rooms_for_range(check_in: "2010-8-1", check_out: "2010-8-20") + + expect(avail_rooms).must_be_nil + end + end # # TODO: add create reservation method + 2nd input as room_num?? # describe "#create_reservation" do @@ -179,25 +228,8 @@ # # -# describe "#list_avail_rooms_for_date" do -# let(:start_date) {"2010-8-15"} -# let(:end_date) {"2010-8-16"} -# -# it "returns an array of room numbers" do -# expect(booking_system.available_rooms_by_date(start_date, end_date)).must_be_kind_of Array -# -# expect(booking_system.available_rooms_by_date(start_date, end_date)[0]).must_be_kind_of Integer -# -# end -# end -# -# #TODO -# describe "#list_avail_rooms_for_range" do -# end -# -# # TODO -# describe "#create_res_id" do -# end + + # end From be7358594ff1bc5929373e4a3bc2d000840bb142 Mon Sep 17 00:00:00 2001 From: kangazoom Date: Sun, 9 Sep 2018 19:00:43 -0700 Subject: [PATCH 27/36] revamped BookingSystem #create_reservation to pass all tests --- lib/booking_system.rb | 105 ++++++++++---------------- spec/booking_system_spec.rb | 143 +++++++++++++++++++++--------------- 2 files changed, 125 insertions(+), 123 deletions(-) diff --git a/lib/booking_system.rb b/lib/booking_system.rb index 2d2835a80..74e55ce80 100644 --- a/lib/booking_system.rb +++ b/lib/booking_system.rb @@ -38,63 +38,49 @@ def list_res_for_date(check_date) def list_avail_rooms_for_range(check_in:, check_out:) date_range = construct_cal_checker(check_in: check_in, check_out: check_out) - avail_rooms = @reservations.select { |reservation| !reservation.overlap?(date_range) }.map { |reservation| reservation.room_num } + booked_rooms = @reservations.select { |reservation| reservation.overlap?(date_range) }.map { |reservation| reservation.room_num } + + avail_rooms = @rooms - booked_rooms return avail_rooms.empty? ? nil : avail_rooms end -# # TODO: maybe use date range instead of start/end? -# def create_reservation(start_date, end_date) -# id = create_res_id() -# rooms = list_avail_rooms_for_range(start_date, end_date) -# -# # QUESTION: AM I DOING THIS RIGHT? -# unless rooms != nil -# raise StandardError, "No rooms are available for the given date range: #{start_date} - #{end_date}." -# end -# -# reservation_hash = { -# id: id, -# room: rooms[0], -# check_in: start_date, -# check_out: end_date, -# } -# -# new_reservation = Reservation.new(reservation_hash) -# #NOTE: add room.change_status??? should this part go in Res??? -# # or should this be split up???? -# room.add_reservation(new_reservation) -# @reservations << new_reservation -# -# return new_reservation -# end + def create_reservation(check_in:, check_out:) + id = generate_res_id() #<-- create new reservation id + avail_rooms = list_avail_rooms_for_range(check_in: check_in, check_out: check_out) #<-- grab first available room + + if avail_rooms.nil? + raise StandardError, "No rooms are available for the given date range: #{check_in} - #{check_out}." + else + avail_room = avail_rooms[0] + end + + + + # reservation_hash = { + # id: id, + # room: rooms[0], + # check_in: start_date, + # check_out: end_date, + # } + + new_reservation = Hotel::Reservation.new( + id: id, + room_num: avail_room, + check_in: check_in, + check_out: check_out) + + # QUESTION: do i realy need to make dates an obj?? + @reservations << new_reservation + + return new_reservation + end # # # QUESTION: NOT NEEDED-- JUST IN RESERVATION? # # def add_reservation(new_reservation) # # @reservations << create_reservation(new_reservation) # # end # -# # QUESTION: add loading class or hold off? should be blank list at top? -# # def load_reservations(input) -# # new_reservation = create_reservation() -# # add_reservation(new_reservation) -# # return @reservations -# # end -# -# -# # QUESTION: should i be accessing this -# # QUESTION: add a pretty to_s for listing reserved dates? -# def list_reservations_for_date(check_date) -# date = Date.parse(check_date) -# #TODO error handling for date as Date object?? -# #TODO what if no dates match? should return nil? -# # QUESTION: maybe add one to display by id? -# # QUESTION: should room own this??? -# matching_res = @reservations.select { |reservation| reservation.dates_reserved.include? date } -# -# # TODO: combine enumerable with ternary???? --> do in one line??? -# return matching_res.empty? ? nil : matching_res -# end # # # # QUESTION: should this method be here or in Reservation? @@ -102,11 +88,6 @@ def list_avail_rooms_for_range(check_in:, check_out:) # def find_room(room_num) # return @rooms.find {|room| room.num == room_num.to_i} # end -# - -# - -# end end @@ -114,18 +95,12 @@ def list_avail_rooms_for_range(check_in:, check_out:) # booking = Hotel::BookingSystem.new() # -# res_3 = Hotel::Reservation.new( -# id: "4", -# room_num: "15", -# check_in: "2010-8-4", -# check_out: "2010-8-20", -# ) -# res_2 = Hotel::Reservation.new(id: "1", -# room_num: "20", -# check_in: "2010-8-1", -# check_out: "2010-8-10", -# ) +# p booking.reservations # -# booking.reservations.push(res_2, res_3) +# res_1 = booking.create_reservation(check_in: "1992-10-15", check_out: "1992-10-25") +# res_2 = booking.create_reservation(check_in: "1992-11-15", check_out: "1992-11-25") +# # res_3 = booking_system.create_reservation(check_in: "1992-10-15", check_out: "1992-10-25") # -# p booking.list_avail_rooms_for_range(check_in: "2010-10-15", check_out: "2010-10-26") +# p booking.list_avail_rooms_for_range(check_in: "1992-10-15", check_out: "1992-10-25") + + # booking.reservations.push(res_2, res_3) diff --git a/spec/booking_system_spec.rb b/spec/booking_system_spec.rb index 37f94e64f..a97b140ae 100644 --- a/spec/booking_system_spec.rb +++ b/spec/booking_system_spec.rb @@ -143,24 +143,25 @@ # see Calendar#overlap? for additonal tests let(:res_1) {Hotel::Reservation.new( id: "1", - room_num: "20", - check_in: "2010-8-1", - check_out: "2010-8-10" + room_num: "18", + check_in: "2010-6-15", + check_out: "2010-6-20" )} let(:res_2) {Hotel::Reservation.new( id: "2", room_num: "19", - check_in: "2010-8-15", - check_out: "2010-8-18" + check_in: "2010-7-15", + check_out: "2010-7-20" )} let(:res_3) {Hotel::Reservation.new( - id: "4", - room_num: "15", - check_in: "2010-8-4", + id: "3", + room_num: "20", + check_in: "2010-8-15", check_out: "2010-8-20" )} + it "returns an array of room numbers if rooms are available" do booking_system.reservations.push(res_1, res_2, res_3) @@ -173,63 +174,89 @@ it "accurately returns a list of available rooms by number if rooms are available" do booking_system.reservations.push(res_1, res_2, res_3) - avail_rooms = booking_system.list_avail_rooms_for_range(check_in: "2010-8-19", check_out: "2010-10-26") + all_rooms = booking_system.rooms + + booked_rooms = [19, 20] + + avail_rooms = booking_system.list_avail_rooms_for_range(check_in: "2010-7-1", check_out: "2010-8-30") - expect(avail_rooms.length).must_equal 2 - expect(avail_rooms[0]).must_equal 20 - expect(avail_rooms[1]).must_equal 19 + expect(avail_rooms.length).must_equal 18 + expect(avail_rooms).must_equal (all_rooms - booked_rooms) end - it "returns nil if no rooms are available" do - booking_system.reservations.push(res_1, res_2, res_3) + # it "returns nil if no rooms are available" do + # TODO:hoooww? + # booking_system.rooms -= (1..17).to_a + # booking_system.reservations.push(res_1, res_2, res_3) + # + # avail_rooms = booking_system.list_avail_rooms_for_range(check_in: "2010-6-1", check_out: "2010-9-1") + # + # expect(avail_rooms).must_be_nil + # end - avail_rooms = booking_system.list_avail_rooms_for_range(check_in: "2010-8-1", check_out: "2010-8-20") + it "returns all rooms available if there are no reservations" do + #edge case + avail_rooms = booking_system.list_avail_rooms_for_range(check_in: "2010-8-1", check_out: "2010-8-20") + + all_rooms = (1..20).to_a + + expect(avail_rooms).must_equal all_rooms + + end + end + +# TODO: add create reservation method + 2nd input as room_num?? + describe "#create_reservation" do + # TODO: A reservation is allowed start on the same day that another reservation for the same room ends + # TODO test that it's added to Room + # TODO test that it's added to reservations + # let(:room_num) {4} + # let(:room_obj) {booking_system.find_room(room_num)} + + it "creates a new reservation successfully with correct data types" do + res_1 = booking_system.create_reservation(check_in: "1992-10-15", check_out: "1992-10-25") + + expect(res_1).must_be_kind_of Hotel::Reservation + expect(res_1.id).must_be_kind_of Integer + expect(res_1.room_num).must_be_kind_of Integer + expect(res_1.check_in).must_be_kind_of Date + expect(res_1.check_out).must_be_kind_of Date + end + + it "accurately adds information to first reservation made" do + res_1 = booking_system.create_reservation(check_in: "1992-10-15", check_out: "1992-10-25") + + expect(res_1.id).must_equal 1 + expect(res_1.room_num).must_equal 1 + expect(res_1.check_in.strftime('%Y %b %d')).must_equal "1992 Oct 15" + expect(res_1.check_out.strftime('%Y %b %d')).must_equal "1992 Oct 25" + end + + it "ignores reservations for the same room room but on other dates" do + res_1 = booking_system.create_reservation(check_in: "1992-10-15", check_out: "1992-10-25") + res_2 = booking_system.create_reservation(check_in: "1992-11-15", check_out: "1992-11-25") + + expect(res_2.id).must_equal 2 + expect(res_2.room_num).must_equal 1 + expect(res_2.check_in.strftime('%Y %b %d')).must_equal "1992 Nov 15" + expect(res_2.check_out.strftime('%Y %b %d')).must_equal "1992 Nov 25" + end - expect(avail_rooms).must_be_nil + it "selects the next available room if reservation dates conflict with other reservations" do + res_1 = booking_system.create_reservation(check_in: "1992-10-15", check_out: "1992-10-25") + res_2 = booking_system.create_reservation(check_in: "1992-11-15", check_out: "1992-11-25") + res_3 = booking_system.create_reservation(check_in: "1992-10-15", check_out: "1992-10-25") + p res_1 + p res_2 + p res_3 + p booking_system.reservations + + expect(res_3.id).must_equal 3 + expect(res_3.room_num).must_equal 2 + expect(res_3.check_in.strftime('%Y %b %d')).must_equal "1992 Oct 15" + expect(res_3.check_out.strftime('%Y %b %d')).must_equal "1992 Oct 25" end end -# # TODO: add create reservation method + 2nd input as room_num?? -# describe "#create_reservation" do -# # TODO: A reservation is allowed start on the same day that another reservation for the same room ends -# # TODO test that it's added to Room -# # TODO test that it's added to reservations -# # let(:room_num) {4} -# # let(:room_obj) {booking_system.find_room(room_num)} -# let(:reservation_hash) {{ -# id: "5", -# room_num: "10", -# start_date: "2010-8-6", -# end_date: "2010-8-10", -# }} -# let(:new_reservation) {booking_system.create_reservation(reservation_hash)} -# -# it "creates a new reservation successfully" do -# expect(new_reservation).must_be_kind_of Hotel::Reservation -# end -# -# it "loads reservation details properly" do -# # QUESTION: should i test values or types? in rideshare, seems like mostly type was tested.... -# expect(new_reservation.id).must_equal 5 -# expect(new_reservation.room.num).must_equal 10 -# expect(new_reservation.start_date).must_be_kind_of Date -# expect(new_reservation.end_date).must_be_kind_of Date -# expect(new_reservation.daily_rate).must_equal 200 -# -# end -# end -# -# # describe "#add_reservation" do -# # updated_reservations = booking_system.add_reservation(new_reservation) -# # end -# -# # describe "#load_reservations" do -# # end -# - -# - - -# end From e714797984544b882bdd07b39d1c81d106ee67a7 Mon Sep 17 00:00:00 2001 From: kangazoom Date: Sun, 9 Sep 2018 22:54:41 -0700 Subject: [PATCH 28/36] Added RoomBlock class and a few tests plus cost calculating functionality --- lib/reservation.rb | 11 +--- lib/room_block.rb | 46 +++++++++++++ spec/calendar_spec.rb | 20 +----- spec/reservation_spec.rb | 21 +----- spec/room_block_spec.rb | 135 +++++++++++++++++++++++++++++++++++++++ spec/spec_helper.rb | 1 + 6 files changed, 185 insertions(+), 49 deletions(-) create mode 100644 lib/room_block.rb create mode 100644 spec/room_block_spec.rb diff --git a/lib/reservation.rb b/lib/reservation.rb index 983a4ed41..c160d2e51 100644 --- a/lib/reservation.rb +++ b/lib/reservation.rb @@ -1,4 +1,3 @@ -require 'date' require_relative 'calendar' module Hotel @@ -10,20 +9,12 @@ def initialize(check_in:, check_out:, id:, room_num:, daily_rate: 200) @id = id.to_i @room_num = room_num.to_i - #TODO: date_range CAL instantiate here - # @check_in = Date.parse(input[:check_in]) - # @check_out = Date.parse(input[:check_out]) @daily_rate = daily_rate.to_f end - def dates_reserved() - # don't include check out date - return (@check_in...@check_out).to_a - end - def total_stay_cost() - length_in_days = dates_reserved().length + length_in_days = @check_out - @check_in return @daily_rate * length_in_days end end diff --git a/lib/room_block.rb b/lib/room_block.rb new file mode 100644 index 000000000..9330c6670 --- /dev/null +++ b/lib/room_block.rb @@ -0,0 +1,46 @@ +require_relative 'reservation' + +module Hotel + class RoomBlock < Reservation + attr_reader :block_size, :discount, :room_nums + + def initialize(id:, daily_rate: 200, check_in:, check_out:, discount:0, room_nums:) + super(id: id, daily_rate: daily_rate, check_in: check_in, check_out: check_out, room_num: room_num) # QUESTION: do i need to specify daily_rate??? + + unless !room_nums.empty? + raise StandardError, "Room blocks cannot be empty!" + end + + @discount = discount/100.to_f + @room_nums = room_nums # array + @block_size = room_nums.length # must be <= 5 + + unless @block_size <= 5 && @block_size > 1 + raise StandardError, "Room blocks must hold at least two rooms and at most five. You entered #{block_size} rooms." + end + + end + + def discounted_rate() + return @daily_rate * (1-@discount) + end + + def total_stay_cost_room() + length_in_days = @check_out - @check_in + return discounted_rate() * length_in_days + end + + def total_stay_cost_block() + return total_stay_cost_room() * @block_size + end + end +end + + +# block = Hotel::RoomBlock.new( +# id: "2", +# room_nums: [1,2,3], +# check_in: "2004-7-1", +# check_out: "2004-7-4") +# +# p block.daily_rate diff --git a/spec/calendar_spec.rb b/spec/calendar_spec.rb index 7d09799f6..5e8ed5f7d 100644 --- a/spec/calendar_spec.rb +++ b/spec/calendar_spec.rb @@ -46,24 +46,6 @@ end end - # describe "#create_date_range" do - # it "returns an array of Date objects" do - # cal.create_date_range.each do |date| - # expect(date).must_be_kind_of Date - # end - # expect(cal.create_date_range).must_be_kind_of Array - # end - # - # it "can list first and last dates within range" do - # date1_s = cal.create_date_range[0].strftime('%Y %b %d') - # date2_s = cal.create_date_range[-1].strftime('%Y %b %d') - # - # expect(cal.create_date_range.length).must_equal 9 - # expect(date1_s).must_equal "1986 Jul 20" - # expect(date2_s).must_equal "1986 Jul 29" - # end - # end - describe "#has_date?" do it "returns true if other date is between check in and check out dates: in the middle" do other_date = "1986-07-25" @@ -104,7 +86,7 @@ expect(has_date).must_equal false end - + it "returns false if other date is outside of check in and check out dates: on check out date" do # edge case other_date = "1986-07-29" diff --git a/spec/reservation_spec.rb b/spec/reservation_spec.rb index 16465cfae..dac7b3fff 100644 --- a/spec/reservation_spec.rb +++ b/spec/reservation_spec.rb @@ -51,28 +51,9 @@ end end - describe "#dates_reserved" do - # NOTE: tests in cal?? - # it "returns an array of Date objects" do - # expect(reservation.dates_reserved).must_be_kind_of Array - # expect(reservation.dates_reserved[0]).must_be_kind_of Date - # end - # - # it "can list all the dates of a reservation" do - # date1_s = reservation.dates_reserved[0].strftime('%Y %b %d') - # date2_s = reservation.dates_reserved[1].strftime('%Y %b %d') - # date3_s = reservation.dates_reserved[2].strftime('%Y %b %d') - # - # expect(reservation.dates_reserved.length).must_equal 3 - # expect(date1_s).must_equal "2004 Jul 01" - # expect(date2_s).must_equal "2004 Jul 02" - # expect(date3_s).must_equal "2004 Jul 03" - # end - end - describe "#total_stay_cost" do it "correctly calculates total cost for a reservation" do - rate = 200 + rate = reservation.daily_rate dates = 3 correct_cost = rate * dates diff --git a/spec/room_block_spec.rb b/spec/room_block_spec.rb new file mode 100644 index 000000000..dde95892e --- /dev/null +++ b/spec/room_block_spec.rb @@ -0,0 +1,135 @@ +require_relative 'spec_helper' + +describe "RoomBlock" do + + let(:block) {Hotel::RoomBlock.new( + id: "2", + room_nums: [1,2,3,4,5], + check_in: "2004-7-1", + check_out: "2004-7-4")} + + describe "#initialize" do + it "can create a new instance of RoomBlock" do + expect(block).must_be_kind_of Hotel::RoomBlock + expect(block.id).must_equal 2 + end + + it "throws an error for an empty list of rooms" do + expect { + Hotel::RoomBlock.new( + id: "2", + room_nums: [], + check_in: "2004-7-1", + check_out: "2004-7-4")}.must_raise StandardError + end + + it "throws an error for a single room" do + expect { + Hotel::RoomBlock.new( + id: "2", + room_nums: [1], + check_in: "2004-7-1", + check_out: "2004-7-4")}.must_raise StandardError + end + + it "throws an error for too many rooms" do + expect { + Hotel::RoomBlock.new( + id: "2", + room_nums: [1,2,3,4,5,6], + check_in: "2004-7-1", + check_out: "2004-7-4")}.must_raise StandardError + end + + it "can create a room block with a one-night stay" do + # edge case + one_night_stay = Hotel::RoomBlock.new( + id: "66", + room_nums: [1,2,3], + check_in:"2009-7-29", + check_out: "2009-7-30") + expect(one_night_stay).must_be_kind_of Hotel::RoomBlock + expect(one_night_stay.id).must_equal 66 + end + + it "sets daily rate to default value if no value given" do + expect(block.daily_rate).must_equal 200 + end + + it "sets discount to default value if no value given" do + expect(block.discount).must_equal 0 + end + + it "can override daily rate's default value" do + expensive_stay = Hotel::RoomBlock.new( + id: "66", + room_nums: [1,2,3], + check_in:"2009-5-15", + check_out: "2009-7-30", + daily_rate: 500) + + expect(expensive_stay.daily_rate).must_equal 500 + end + end + + describe "#discounted_rate" do + it "accurately calculates discounted rate" do + block_room = Hotel::RoomBlock.new( + id: "66", + room_nums: [1,2,3], + check_in:"2009-7-29", + check_out: "2009-7-30", + discount: 20) + + expect(block_room.discounted_rate).must_equal 160 + end + end + + describe "#total_stay_cost_room" do + it "accurately calculates the total cost for one room within the block" do + block_room = Hotel::RoomBlock.new( + id: "66", + room_nums: [1,2,3], + check_in:"2009-7-29", + check_out: "2009-7-30") + + expect(block_room.total_stay_cost_room).must_equal 200.0 + end + end + + describe "#total_stay_cost_block" do + it "accurately calculates the total cost for one room within the block" do + entire_block = Hotel::RoomBlock.new( + id: "66", + room_nums: [1,2,3], + check_in:"2009-7-29", + check_out: "2009-7-30") + + expect(entire_block.total_stay_cost_block).must_equal 600 + end + end + # end + + # # QUESTION: do we need error handling for numeric value for daily_rate? + # it "can override default value for daily rate" do + # rare_room = Hotel::RoomBlock.new( + # id: "66", + # room_num: "19", + # check_in:"2009-7-29", + # check_out: "2009-7-30", + # daily_rate: 500) + # + # expect(rare_room.daily_rate).must_equal 500 + # end + # end + + # describe "#total_stay_cost" do + # it "correctly calculates total cost for a reservation" do + # rate = reservation.daily_rate + # dates = 3 + # correct_cost = rate * dates + # + # expect(reservation.total_stay_cost).must_equal 600 + # end + # end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 67f86b8eb..9bec37e96 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -9,4 +9,5 @@ require_relative '../lib/calendar' require_relative '../lib/reservation' +require_relative '../lib/room_block' require_relative '../lib/booking_system' From 0519f8e7c5a5babbe242d5805706fdc55809fb64 Mon Sep 17 00:00:00 2001 From: kangazoom Date: Sun, 9 Sep 2018 23:40:54 -0700 Subject: [PATCH 29/36] Added a block id generator to BookingSystem --- lib/booking_system.rb | 38 +++++++++++++++++++++++++++++++------ lib/room_block.rb | 12 ++++++------ spec/booking_system_spec.rb | 31 ++++++++++++++++++++++++++++++ spec/room_block_spec.rb | 18 +++++++++--------- 4 files changed, 78 insertions(+), 21 deletions(-) diff --git a/lib/booking_system.rb b/lib/booking_system.rb index 74e55ce80..1c7ab4d69 100644 --- a/lib/booking_system.rb +++ b/lib/booking_system.rb @@ -5,11 +5,12 @@ module Hotel class BookingSystem - attr_reader :rooms, :reservations + attr_reader :rooms, :reservations, :room_blocks def initialize() @rooms = list_all_rooms() #<-- array of all room numbeers @reservations = [] + @room_blocks = [] end def list_all_rooms() @@ -28,6 +29,14 @@ def generate_res_id() end end + def generate_block_id() + if @room_blocks.empty? + return 1 + else + return @room_blocks.max_by { |block| block.id}.id + 1 + end + end + def list_res_for_date(check_date) matching_res = @reservations.select { |reservation| reservation.has_date?(check_date) } #==false @@ -75,11 +84,28 @@ def create_reservation(check_in:, check_out:) return new_reservation end -# -# # QUESTION: NOT NEEDED-- JUST IN RESERVATION? -# # def add_reservation(new_reservation) -# # @reservations << create_reservation(new_reservation) -# # end + + # def create_room_block(check_in:, check_out:, :block_size) + # date_range = construct_cal_checker(check_in: check_in, check_out: check_out) + # + # avail_rooms = list_avail_rooms_for_range(date_range) + # + # if avail_rooms.length > block_size + # raise StandardError, "Not enough rooms available." + # end + # + # block_size.times do + # room_block = Hotel::Reservation.new(check_in: check_in, check_out: check_out).map { |res| res } + # end + # + # id = generate_block_id() + # + # new_room_block = Hotel::RoomBlock(id: id, check_in: check_in, check_out: check_out, reservations: room_block) + # + # @room_blocks << new_room_block + # + # end + # end # # # diff --git a/lib/room_block.rb b/lib/room_block.rb index 9330c6670..d02e53231 100644 --- a/lib/room_block.rb +++ b/lib/room_block.rb @@ -2,18 +2,18 @@ module Hotel class RoomBlock < Reservation - attr_reader :block_size, :discount, :room_nums + attr_reader :block_size, :discount, :reservations - def initialize(id:, daily_rate: 200, check_in:, check_out:, discount:0, room_nums:) + def initialize(id:, daily_rate: 200, check_in:, check_out:, discount:0, reservations:) super(id: id, daily_rate: daily_rate, check_in: check_in, check_out: check_out, room_num: room_num) # QUESTION: do i need to specify daily_rate??? - unless !room_nums.empty? + unless !reservations.empty? raise StandardError, "Room blocks cannot be empty!" end @discount = discount/100.to_f - @room_nums = room_nums # array - @block_size = room_nums.length # must be <= 5 + @reservations = [] + @block_size = reservations.length # must be <= 5 unless @block_size <= 5 && @block_size > 1 raise StandardError, "Room blocks must hold at least two rooms and at most five. You entered #{block_size} rooms." @@ -39,7 +39,7 @@ def total_stay_cost_block() # block = Hotel::RoomBlock.new( # id: "2", -# room_nums: [1,2,3], +# reservations: [1,2,3], # check_in: "2004-7-1", # check_out: "2004-7-4") # diff --git a/spec/booking_system_spec.rb b/spec/booking_system_spec.rb index a97b140ae..bfa170420 100644 --- a/spec/booking_system_spec.rb +++ b/spec/booking_system_spec.rb @@ -76,6 +76,32 @@ end end + describe "#generate_block_id" do + # NOTE: here and in roomblock, i got tired and didn't do res but instead ints in array + let(:block_1) {Hotel::RoomBlock.new(id: 2, reservations: [1,2,3], check_in: "1996-09-09", check_out: "1996-08-13")} + let(:block_2) {Hotel::RoomBlock.new(id: 3, reservations: [1,2,3], check_in: "1996-10-01-", check_out: "1996-10-10")} + + it "can create ID for first room block ID instance" do + new_id = booking_system.generate_block_id() + new_block = Hotel::RoomBlock.new(id: new_id, reservations: [1,2,3], check_in: "1996-08-01", check_out: "1996-08-03") + + booking_system.room_blocks << new_block + + expect(booking_system.room_blocks[0].id).must_equal 1 + end + + it "can generate accurate IDs when new reservations are added to reservations list" do + first_block = Hotel::RoomBlock.new(id: 10, reservations: [1,2,3], check_in: "1996-09-09", check_out: "1996-09-13") + booking_system.room_blocks << first_block + + new_id = booking_system.generate_block_id() + second_block= Hotel::RoomBlock.new(id: new_id, reservations: [1,2,3], check_in: "1996-10-01", check_out: "1996-10-10") + booking_system.room_blocks << second_block + + expect(booking_system.room_blocks[1].id).must_equal 11 + end + end + # describe "#find_room" do # skip # let(:room_num) {4} @@ -258,5 +284,10 @@ end end + describe "#create_room_block" do + it "creates a block of rooms" do + expect() + end + end end diff --git a/spec/room_block_spec.rb b/spec/room_block_spec.rb index dde95892e..bf47d4b92 100644 --- a/spec/room_block_spec.rb +++ b/spec/room_block_spec.rb @@ -4,7 +4,7 @@ let(:block) {Hotel::RoomBlock.new( id: "2", - room_nums: [1,2,3,4,5], + reservations: [1,2,3,4,5], check_in: "2004-7-1", check_out: "2004-7-4")} @@ -18,7 +18,7 @@ expect { Hotel::RoomBlock.new( id: "2", - room_nums: [], + reservations: [], check_in: "2004-7-1", check_out: "2004-7-4")}.must_raise StandardError end @@ -27,7 +27,7 @@ expect { Hotel::RoomBlock.new( id: "2", - room_nums: [1], + reservations: [1], check_in: "2004-7-1", check_out: "2004-7-4")}.must_raise StandardError end @@ -36,7 +36,7 @@ expect { Hotel::RoomBlock.new( id: "2", - room_nums: [1,2,3,4,5,6], + reservations: [1,2,3,4,5,6], check_in: "2004-7-1", check_out: "2004-7-4")}.must_raise StandardError end @@ -45,7 +45,7 @@ # edge case one_night_stay = Hotel::RoomBlock.new( id: "66", - room_nums: [1,2,3], + reservations: [1,2,3], check_in:"2009-7-29", check_out: "2009-7-30") expect(one_night_stay).must_be_kind_of Hotel::RoomBlock @@ -63,7 +63,7 @@ it "can override daily rate's default value" do expensive_stay = Hotel::RoomBlock.new( id: "66", - room_nums: [1,2,3], + reservations: [1,2,3], check_in:"2009-5-15", check_out: "2009-7-30", daily_rate: 500) @@ -76,7 +76,7 @@ it "accurately calculates discounted rate" do block_room = Hotel::RoomBlock.new( id: "66", - room_nums: [1,2,3], + reservations: [1,2,3], check_in:"2009-7-29", check_out: "2009-7-30", discount: 20) @@ -89,7 +89,7 @@ it "accurately calculates the total cost for one room within the block" do block_room = Hotel::RoomBlock.new( id: "66", - room_nums: [1,2,3], + reservations: [1,2,3], check_in:"2009-7-29", check_out: "2009-7-30") @@ -101,7 +101,7 @@ it "accurately calculates the total cost for one room within the block" do entire_block = Hotel::RoomBlock.new( id: "66", - room_nums: [1,2,3], + reservations: [1,2,3], check_in:"2009-7-29", check_out: "2009-7-30") From b336c0f70b50165fb0225c069b0ab98fb248b0db Mon Sep 17 00:00:00 2001 From: kangazoom Date: Mon, 10 Sep 2018 00:16:23 -0700 Subject: [PATCH 30/36] created ability to make a room block in BookingSystem --- lib/booking_system.rb | 44 +++++++++++++++++++------------------ lib/room_block.rb | 12 +++++----- spec/booking_system_spec.rb | 42 ++++++++++++++--------------------- spec/room_block_spec.rb | 18 +++++++-------- 4 files changed, 54 insertions(+), 62 deletions(-) diff --git a/lib/booking_system.rb b/lib/booking_system.rb index 1c7ab4d69..214feacc2 100644 --- a/lib/booking_system.rb +++ b/lib/booking_system.rb @@ -2,6 +2,7 @@ require_relative 'calendar' require_relative 'reservation' +require_relative 'room_block' module Hotel class BookingSystem @@ -85,27 +86,21 @@ def create_reservation(check_in:, check_out:) return new_reservation end - # def create_room_block(check_in:, check_out:, :block_size) - # date_range = construct_cal_checker(check_in: check_in, check_out: check_out) - # - # avail_rooms = list_avail_rooms_for_range(date_range) - # - # if avail_rooms.length > block_size - # raise StandardError, "Not enough rooms available." - # end - # - # block_size.times do - # room_block = Hotel::Reservation.new(check_in: check_in, check_out: check_out).map { |res| res } - # end - # - # id = generate_block_id() - # - # new_room_block = Hotel::RoomBlock(id: id, check_in: check_in, check_out: check_out, reservations: room_block) - # - # @room_blocks << new_room_block - # - # end - # end + def create_room_block(check_in:, check_out:, block_size:) + avail_rooms = list_avail_rooms_for_range(check_in: check_in, check_out: check_out) + + unless avail_rooms.length > block_size + raise StandardError, "Not enough rooms available." + end + + hold_rooms = avail_rooms[0..block_size-1] + id = generate_block_id() + + new_room_block = Hotel::RoomBlock.new(id: id, check_in: check_in, check_out: check_out, rooms: hold_rooms) + + @room_blocks << new_room_block + return new_room_block + end # # # @@ -130,3 +125,10 @@ def create_reservation(check_in:, check_out:) # p booking.list_avail_rooms_for_range(check_in: "1992-10-15", check_out: "1992-10-25") # booking.reservations.push(res_2, res_3) + # block = booking.create_room_block( + # check_in: "1990-01-01", + # check_out: "1990-01-15", + # block_size: 2 + # ) + # + # p block diff --git a/lib/room_block.rb b/lib/room_block.rb index d02e53231..2b7825b16 100644 --- a/lib/room_block.rb +++ b/lib/room_block.rb @@ -2,18 +2,18 @@ module Hotel class RoomBlock < Reservation - attr_reader :block_size, :discount, :reservations + attr_reader :block_size, :discount, :rooms - def initialize(id:, daily_rate: 200, check_in:, check_out:, discount:0, reservations:) + def initialize(id:, daily_rate: 200, check_in:, check_out:, discount:0, rooms:[]) super(id: id, daily_rate: daily_rate, check_in: check_in, check_out: check_out, room_num: room_num) # QUESTION: do i need to specify daily_rate??? - unless !reservations.empty? + unless !rooms.empty? raise StandardError, "Room blocks cannot be empty!" end @discount = discount/100.to_f - @reservations = [] - @block_size = reservations.length # must be <= 5 + @rooms = rooms # array of ints + @block_size = rooms.length unless @block_size <= 5 && @block_size > 1 raise StandardError, "Room blocks must hold at least two rooms and at most five. You entered #{block_size} rooms." @@ -39,7 +39,7 @@ def total_stay_cost_block() # block = Hotel::RoomBlock.new( # id: "2", -# reservations: [1,2,3], +# rooms: [1,2,3], # check_in: "2004-7-1", # check_out: "2004-7-4") # diff --git a/spec/booking_system_spec.rb b/spec/booking_system_spec.rb index bfa170420..4ffdcda7f 100644 --- a/spec/booking_system_spec.rb +++ b/spec/booking_system_spec.rb @@ -78,44 +78,30 @@ describe "#generate_block_id" do # NOTE: here and in roomblock, i got tired and didn't do res but instead ints in array - let(:block_1) {Hotel::RoomBlock.new(id: 2, reservations: [1,2,3], check_in: "1996-09-09", check_out: "1996-08-13")} - let(:block_2) {Hotel::RoomBlock.new(id: 3, reservations: [1,2,3], check_in: "1996-10-01-", check_out: "1996-10-10")} + let(:block_1) {Hotel::RoomBlock.new(id: 2, rooms: [1,2,3], check_in: "1996-09-09", check_out: "1996-08-13")} + let(:block_2) {Hotel::RoomBlock.new(id: 3, rooms: [1,2,3], check_in: "1996-10-01-", check_out: "1996-10-10")} it "can create ID for first room block ID instance" do new_id = booking_system.generate_block_id() - new_block = Hotel::RoomBlock.new(id: new_id, reservations: [1,2,3], check_in: "1996-08-01", check_out: "1996-08-03") + new_block = Hotel::RoomBlock.new(id: new_id, rooms: [1,2,3], check_in: "1996-08-01", check_out: "1996-08-03") booking_system.room_blocks << new_block expect(booking_system.room_blocks[0].id).must_equal 1 end - it "can generate accurate IDs when new reservations are added to reservations list" do - first_block = Hotel::RoomBlock.new(id: 10, reservations: [1,2,3], check_in: "1996-09-09", check_out: "1996-09-13") + it "can generate accurate IDs when new rooms are added to rooms list" do + first_block = Hotel::RoomBlock.new(id: 10, rooms: [1,2,3], check_in: "1996-09-09", check_out: "1996-09-13") booking_system.room_blocks << first_block new_id = booking_system.generate_block_id() - second_block= Hotel::RoomBlock.new(id: new_id, reservations: [1,2,3], check_in: "1996-10-01", check_out: "1996-10-10") + second_block= Hotel::RoomBlock.new(id: new_id, rooms: [1,2,3], check_in: "1996-10-01", check_out: "1996-10-10") booking_system.room_blocks << second_block expect(booking_system.room_blocks[1].id).must_equal 11 end end - # describe "#find_room" do - # skip - # let(:room_num) {4} - # let(:room_obj) {booking_system.find_room(room_num)} - # - # it "finds room object by room number" do - # # num = 4 - # # room_obj = booking_system.find_room(num) - # - # expect(room_obj).must_be_kind_of Hotel::Room - # expect(room_obj.num).must_equal room_num - # end - # end - describe "#list_res_for_date" do # see Calendar#has_date? for additional tests let(:res_1) {Hotel::Reservation.new( @@ -272,10 +258,6 @@ res_1 = booking_system.create_reservation(check_in: "1992-10-15", check_out: "1992-10-25") res_2 = booking_system.create_reservation(check_in: "1992-11-15", check_out: "1992-11-25") res_3 = booking_system.create_reservation(check_in: "1992-10-15", check_out: "1992-10-25") - p res_1 - p res_2 - p res_3 - p booking_system.reservations expect(res_3.id).must_equal 3 expect(res_3.room_num).must_equal 2 @@ -285,9 +267,17 @@ end describe "#create_room_block" do - it "creates a block of rooms" do + let(:room_block) {booking_system.create_room_block( + check_in: "1990-01-01", + check_out: "1990-01-15", + block_size: 2 + )} - expect() + it "creates a block using room numbers" do + expect(room_block).must_be_kind_of Hotel::RoomBlock + expect(room_block.rooms).must_be_kind_of Array + expect(room_block.rooms.length).must_equal 2 + expect(room_block.rooms[0]).must_be_kind_of Integer end end end diff --git a/spec/room_block_spec.rb b/spec/room_block_spec.rb index bf47d4b92..3b5c6ec67 100644 --- a/spec/room_block_spec.rb +++ b/spec/room_block_spec.rb @@ -4,7 +4,7 @@ let(:block) {Hotel::RoomBlock.new( id: "2", - reservations: [1,2,3,4,5], + rooms: [1,2,3,4,5], check_in: "2004-7-1", check_out: "2004-7-4")} @@ -18,7 +18,7 @@ expect { Hotel::RoomBlock.new( id: "2", - reservations: [], + rooms: [], check_in: "2004-7-1", check_out: "2004-7-4")}.must_raise StandardError end @@ -27,7 +27,7 @@ expect { Hotel::RoomBlock.new( id: "2", - reservations: [1], + rooms: [1], check_in: "2004-7-1", check_out: "2004-7-4")}.must_raise StandardError end @@ -36,7 +36,7 @@ expect { Hotel::RoomBlock.new( id: "2", - reservations: [1,2,3,4,5,6], + rooms: [1,2,3,4,5,6], check_in: "2004-7-1", check_out: "2004-7-4")}.must_raise StandardError end @@ -45,7 +45,7 @@ # edge case one_night_stay = Hotel::RoomBlock.new( id: "66", - reservations: [1,2,3], + rooms: [1,2,3], check_in:"2009-7-29", check_out: "2009-7-30") expect(one_night_stay).must_be_kind_of Hotel::RoomBlock @@ -63,7 +63,7 @@ it "can override daily rate's default value" do expensive_stay = Hotel::RoomBlock.new( id: "66", - reservations: [1,2,3], + rooms: [1,2,3], check_in:"2009-5-15", check_out: "2009-7-30", daily_rate: 500) @@ -76,7 +76,7 @@ it "accurately calculates discounted rate" do block_room = Hotel::RoomBlock.new( id: "66", - reservations: [1,2,3], + rooms: [1,2,3], check_in:"2009-7-29", check_out: "2009-7-30", discount: 20) @@ -89,7 +89,7 @@ it "accurately calculates the total cost for one room within the block" do block_room = Hotel::RoomBlock.new( id: "66", - reservations: [1,2,3], + rooms: [1,2,3], check_in:"2009-7-29", check_out: "2009-7-30") @@ -101,7 +101,7 @@ it "accurately calculates the total cost for one room within the block" do entire_block = Hotel::RoomBlock.new( id: "66", - reservations: [1,2,3], + rooms: [1,2,3], check_in:"2009-7-29", check_out: "2009-7-30") From 2f30c193ca4ab8a8fbae6062ba4488fca10805e7 Mon Sep 17 00:00:00 2001 From: kangazoom Date: Mon, 10 Sep 2018 03:25:58 -0700 Subject: [PATCH 31/36] tinkered around more in BookingSystem to make RoomBlock a reality --- lib/booking_system.rb | 66 +++++++++++++++++--------------- lib/room.rb | 23 ----------- lib/room_block.rb | 12 +++++- spec/booking_system_spec.rb | 41 +++++++++++++++----- spec/room_block_spec.rb | 14 +++++++ spec/room_spec.rb | 76 ------------------------------------- 6 files changed, 91 insertions(+), 141 deletions(-) delete mode 100644 lib/room.rb delete mode 100644 spec/room_spec.rb diff --git a/lib/booking_system.rb b/lib/booking_system.rb index 214feacc2..ef8626d61 100644 --- a/lib/booking_system.rb +++ b/lib/booking_system.rb @@ -48,9 +48,17 @@ def list_res_for_date(check_date) def list_avail_rooms_for_range(check_in:, check_out:) date_range = construct_cal_checker(check_in: check_in, check_out: check_out) - booked_rooms = @reservations.select { |reservation| reservation.overlap?(date_range) }.map { |reservation| reservation.room_num } + booked_rooms = @reservations.select { |reservation| reservation.overlap?(date_range) }.map { |reservation| reservation.room_num } - avail_rooms = @rooms - booked_rooms + avail_rooms = @rooms - booked_rooms + + held_rooms = @room_blocks.select { |block| block.overlap?(date_range) }.map {|block| block.rooms} + + if !held_rooms.empty? + held_rooms = held_rooms[0] + end + + avail_rooms -= held_rooms return avail_rooms.empty? ? nil : avail_rooms end @@ -65,15 +73,6 @@ def create_reservation(check_in:, check_out:) avail_room = avail_rooms[0] end - - - # reservation_hash = { - # id: id, - # room: rooms[0], - # check_in: start_date, - # check_out: end_date, - # } - new_reservation = Hotel::Reservation.new( id: id, room_num: avail_room, @@ -89,8 +88,10 @@ def create_reservation(check_in:, check_out:) def create_room_block(check_in:, check_out:, block_size:) avail_rooms = list_avail_rooms_for_range(check_in: check_in, check_out: check_out) - unless avail_rooms.length > block_size - raise StandardError, "Not enough rooms available." + if avail_rooms.nil? || avail_rooms.length < block_size + raise StandardError, "Not enough rooms are available for the given date range: #{check_in} - #{check_out}." + else + avail_room = avail_rooms[0] end hold_rooms = avail_rooms[0..block_size-1] @@ -102,10 +103,6 @@ def create_room_block(check_in:, check_out:, block_size:) return new_room_block end # -# -# -# # QUESTION: should this method be here or in Reservation? -# # QUESTION: test nil return if nothing found # def find_room(room_num) # return @rooms.find {|room| room.num == room_num.to_i} # end @@ -113,22 +110,29 @@ def create_room_block(check_in:, check_out:, block_size:) end end - +# # booking = Hotel::BookingSystem.new() +# # +# block = Hotel::RoomBlock.new(id: 1, check_in: "1970-03-04", check_out: "1992-12-15", rooms: [1,2,3]) +# booking.room_blocks << block # -# p booking.reservations +# p booking.list_avail_rooms_for_range(check_in: "1970-03-01", check_out: "1970-03-07") # -# res_1 = booking.create_reservation(check_in: "1992-10-15", check_out: "1992-10-25") -# res_2 = booking.create_reservation(check_in: "1992-11-15", check_out: "1992-11-25") -# # res_3 = booking_system.create_reservation(check_in: "1992-10-15", check_out: "1992-10-25") +# p booking.reservations # -# p booking.list_avail_rooms_for_range(check_in: "1992-10-15", check_out: "1992-10-25") +# res_1 = Hotel::Reservation.new(id: 1, room_num: 1, check_in: "1992-10-15", check_out: "1992-10-25") +# res_2 = Hotel::Reservation.new(id: 2, room_num:2, check_in: "1992-11-15", check_out: "1992-11-25") +# res_3 = Hotel::Reservation.new(id: 3, room_num: 3, check_in: "1992-10-15", check_out: "1992-10-25") + +# booking.reservations.push(res_1, res_2, res_3) - # booking.reservations.push(res_2, res_3) - # block = booking.create_room_block( - # check_in: "1990-01-01", - # check_out: "1990-01-15", - # block_size: 2 - # ) - # - # p block +# p booking.list_avail_rooms_for_range(check_in: "1992-10-15", check_out: "1992-10-25") +# # +# booking.reservations.push(res_2, res_3) +# block = booking.new( +# check_in: "1990-01-01", +# check_out: "1990-01-15", +# block_size: 2 +# ) +# +# p diff --git a/lib/room.rb b/lib/room.rb deleted file mode 100644 index bc49a468f..000000000 --- a/lib/room.rb +++ /dev/null @@ -1,23 +0,0 @@ -# require 'date' -# require_relative 'reservation' -# -# module Hotel -# class Room -# attr_reader :num, :reservations -# -# def initialize(input) -# @num = input[:num] -# @reservations = input[:reservations].nil? ? [] : input[:reservations] -# -# unless (1..20).include? @num -# raise ArgumentError, "This is not a valid room number." -# end -# -# end -# -# def add_reservation(reservation) -# @reservations << reservation -# end -# -# end -# end diff --git a/lib/room_block.rb b/lib/room_block.rb index 2b7825b16..5992ad91a 100644 --- a/lib/room_block.rb +++ b/lib/room_block.rb @@ -2,9 +2,9 @@ module Hotel class RoomBlock < Reservation - attr_reader :block_size, :discount, :rooms + attr_reader :block_size, :discount, :rooms, :status - def initialize(id:, daily_rate: 200, check_in:, check_out:, discount:0, rooms:[]) + def initialize(id:, daily_rate: 200, check_in:, check_out:, discount:0, rooms:[], status: :available) super(id: id, daily_rate: daily_rate, check_in: check_in, check_out: check_out, room_num: room_num) # QUESTION: do i need to specify daily_rate??? unless !rooms.empty? @@ -13,12 +13,20 @@ def initialize(id:, daily_rate: 200, check_in:, check_out:, discount:0, rooms:[] @discount = discount/100.to_f @rooms = rooms # array of ints + @status = status @block_size = rooms.length unless @block_size <= 5 && @block_size > 1 raise StandardError, "Room blocks must hold at least two rooms and at most five. You entered #{block_size} rooms." end + end + def show_status() + rooms_hash = {} + rooms.each do |room| + rooms_hash[room.to_s] = @status + end + return rooms_hash end def discounted_rate() diff --git a/spec/booking_system_spec.rb b/spec/booking_system_spec.rb index 4ffdcda7f..0410dbf15 100644 --- a/spec/booking_system_spec.rb +++ b/spec/booking_system_spec.rb @@ -196,15 +196,18 @@ expect(avail_rooms).must_equal (all_rooms - booked_rooms) end - # it "returns nil if no rooms are available" do - # TODO:hoooww? - # booking_system.rooms -= (1..17).to_a - # booking_system.reservations.push(res_1, res_2, res_3) - # - # avail_rooms = booking_system.list_avail_rooms_for_range(check_in: "2010-6-1", check_out: "2010-9-1") - # - # expect(avail_rooms).must_be_nil - # end + it "returns nil if no rooms are available" do + 20.times do |i| + res = Hotel::Reservation.new(id:1, room_num: i+1, check_in: "1999-1-1", check_out: "1999-12-31") + booking_system.reservations << res + end + + all_rooms = booking_system.rooms + + avail_rooms = booking_system.list_avail_rooms_for_range(check_in: "1999-6-1", check_out: "1999-7-1") + + expect(avail_rooms).must_be_nil + end it "returns all rooms available if there are no reservations" do #edge case @@ -215,6 +218,18 @@ expect(avail_rooms).must_equal all_rooms end + + it "can take rooms in room blocks into account" do + block = Hotel::RoomBlock.new(id: 1, check_in: "1970-03-04", check_out: "1970-03-15", rooms: [1,2,3]) + booking_system.room_blocks << block + + all_rooms = (1..20).to_a + booked_rooms = block.rooms + + avail_rooms = booking_system.list_avail_rooms_for_range(check_in: "1970-03-01", check_out: "1970-03-07") + + expect(avail_rooms).must_equal all_rooms - booked_rooms + end end # TODO: add create reservation method + 2nd input as room_num?? @@ -279,5 +294,13 @@ expect(room_block.rooms.length).must_equal 2 expect(room_block.rooms[0]).must_be_kind_of Integer end + + it "accurately adds information to first room block made" do + + expect(room_block.id).must_equal 1 + expect(room_block.rooms.length).must_equal 2 + expect(room_block.check_in.strftime('%Y %b %d')).must_equal "1990 Jan 01" + expect(room_block.check_out.strftime('%Y %b %d')).must_equal "1990 Jan 15" + end end end diff --git a/spec/room_block_spec.rb b/spec/room_block_spec.rb index 3b5c6ec67..d4b2561bb 100644 --- a/spec/room_block_spec.rb +++ b/spec/room_block_spec.rb @@ -85,6 +85,20 @@ end end + describe "#show_status" do + it "returns a hash" do + expect(block.show_status).must_be_kind_of Hash + end + + it "correctly returns first and last values, thanks to Ruby's ordered hashes" do + expect(block.show_status.keys[0]).must_equal "1" + expect(block.show_status.values[0]).must_equal :available + + expect(block.show_status.keys[-1]).must_equal "5" + expect(block.show_status.values[-1]).must_equal :available + end + end + describe "#total_stay_cost_room" do it "accurately calculates the total cost for one room within the block" do block_room = Hotel::RoomBlock.new( diff --git a/spec/room_spec.rb b/spec/room_spec.rb deleted file mode 100644 index 4602524b9..000000000 --- a/spec/room_spec.rb +++ /dev/null @@ -1,76 +0,0 @@ -# require_relative 'spec_helper' -# -# describe "Room" do -# let(:room) {Hotel::Room.new({num: 4})} -# -# describe "#initialize" do -# it "can create a new instance of room" do -# expect(room).must_be_kind_of Hotel::Room -# expect(room.num).must_equal 4 -# end -# -# it "has room id as an integer" do -# expect(room.num).must_be_kind_of Integer -# end -# -# it "throws an argument error with a bad room num value" do -# expect { -# Hotel::Room.new(num: 21) -# }.must_raise ArgumentError -# -# expect { -# Hotel::Room.new(num: 0) -# }.must_raise ArgumentError -# end -# -# it "sets reservations to an empty array if not provided" do -# expect(room.reservations).must_be_kind_of Array -# expect(room.reservations.length).must_equal 0 -# end -# end -# -# describe "add_reservation" do -# let(:reservation_1) {Hotel::Reservation.new({ -# room: 4, -# check_in: "2004-4-1", -# check_out: "2004-4-4", -# })} -# let(:reservation_2) {Hotel::Reservation.new({ -# room: 4, -# check_in: "2004-6-1", -# check_out: "2004-7-4", -# })} -# let(:reservation_3) {Hotel::Reservation.new({ -# room: 4, -# check_in: "2004-7-25", -# check_out: "2004-7-30", -# })} -# -# it "can add a Reservation to a blank list" do -# room.add_reservation(reservation_1) -# -# expect(room.reservations[0]).must_be_kind_of Hotel::Reservation -# end -# -# it "each item in array is a Reservation instance" do -# room.add_reservation(reservation_1) -# room.add_reservation(reservation_2) -# room.add_reservation(reservation_3) -# -# room.reservations.each do |reservation| -# expect(reservation).must_be_kind_of Hotel::Reservation -# end -# end -# -# # TODO: room num or room obj? -# it "each Reservation instance has same room number" do -# room.add_reservation(reservation_1) -# room.add_reservation(reservation_2) -# room.add_reservation(reservation_3) -# -# room.reservations.each do |reservation| -# expect(reservation.room).must_equal 4 -# end -# end -# end -# end From 0b7d7d241c126bc78e93edda547ea6db11d6ddc3 Mon Sep 17 00:00:00 2001 From: kangazoom Date: Mon, 10 Sep 2018 06:24:50 -0700 Subject: [PATCH 32/36] combed through my code and added todo+question comments to refactors.txt --- lib/booking_system.rb | 38 ++------------------ lib/calendar.rb | 15 -------- lib/reservation.rb | 10 ------ lib/room_block.rb | 13 ++----- refactors.txt | 21 +++++++++++ spec/booking_system_spec.rb | 42 +++++++++++++--------- spec/calendar_spec.rb | 11 +----- spec/reservation_spec.rb | 11 +++--- spec/room_block_spec.rb | 69 ++++++++++++------------------------- 9 files changed, 79 insertions(+), 151 deletions(-) create mode 100644 refactors.txt diff --git a/lib/booking_system.rb b/lib/booking_system.rb index ef8626d61..1ff912afb 100644 --- a/lib/booking_system.rb +++ b/lib/booking_system.rb @@ -39,10 +39,9 @@ def generate_block_id() end def list_res_for_date(check_date) - matching_res = @reservations.select { |reservation| reservation.has_date?(check_date) } #==false + matching_res = @reservations.select { |reservation| reservation.has_date?(check_date) } return matching_res.empty? ? nil : matching_res - end def list_avail_rooms_for_range(check_in:, check_out:) @@ -55,7 +54,7 @@ def list_avail_rooms_for_range(check_in:, check_out:) held_rooms = @room_blocks.select { |block| block.overlap?(date_range) }.map {|block| block.rooms} if !held_rooms.empty? - held_rooms = held_rooms[0] + held_rooms = held_rooms[0] # list within a list end avail_rooms -= held_rooms @@ -79,7 +78,6 @@ def create_reservation(check_in:, check_out:) check_in: check_in, check_out: check_out) - # QUESTION: do i realy need to make dates an obj?? @reservations << new_reservation return new_reservation @@ -102,37 +100,5 @@ def create_room_block(check_in:, check_out:, block_size:) @room_blocks << new_room_block return new_room_block end -# -# def find_room(room_num) -# return @rooms.find {|room| room.num == room_num.to_i} -# end - end end - -# -# booking = Hotel::BookingSystem.new() -# # -# block = Hotel::RoomBlock.new(id: 1, check_in: "1970-03-04", check_out: "1992-12-15", rooms: [1,2,3]) -# booking.room_blocks << block -# -# p booking.list_avail_rooms_for_range(check_in: "1970-03-01", check_out: "1970-03-07") -# -# p booking.reservations -# -# res_1 = Hotel::Reservation.new(id: 1, room_num: 1, check_in: "1992-10-15", check_out: "1992-10-25") -# res_2 = Hotel::Reservation.new(id: 2, room_num:2, check_in: "1992-11-15", check_out: "1992-11-25") -# res_3 = Hotel::Reservation.new(id: 3, room_num: 3, check_in: "1992-10-15", check_out: "1992-10-25") - -# booking.reservations.push(res_1, res_2, res_3) - -# p booking.list_avail_rooms_for_range(check_in: "1992-10-15", check_out: "1992-10-25") -# # -# booking.reservations.push(res_2, res_3) -# block = booking.new( -# check_in: "1990-01-01", -# check_out: "1990-01-15", -# block_size: 2 -# ) -# -# p diff --git a/lib/calendar.rb b/lib/calendar.rb index 8fd877894..8e939521d 100644 --- a/lib/calendar.rb +++ b/lib/calendar.rb @@ -6,8 +6,6 @@ class Calendar def initialize(check_in:, check_out:) -# QUESTION: separate error handling into its own method? YES -# ^^ also if check_out is nil --> just look at one date unless /\d{4}-\d{1,2}-\d{1,2}/.match(check_in) && /\d{4}-\d{1,2}-\d{1,2}/.match(check_out) raise StandardError, "Improper date format: date must be entered as YYYY-MM-DD." end @@ -20,13 +18,6 @@ def initialize(check_in:, check_out:) end end -# TODO: create date range and check without arrays? - # def create_date_range() - # # QUESTION: shoudl i just use instance var instead of input local var? - # return (@check_in...@check_out).to_a - # end - - def has_date?(other_date) other_date = Date.parse(other_date) if (other_date >= @check_in) && (other_date <= @check_out - 1) @@ -43,11 +34,5 @@ def overlap?(other_dates) # param: Calendar obj return true end end - end end - -# -# cal = Hotel::Calendar.new(check_in: "1986-07-29", check_out: "1986-07-31") -# -# puts cal.check_in diff --git a/lib/reservation.rb b/lib/reservation.rb index c160d2e51..3fb327374 100644 --- a/lib/reservation.rb +++ b/lib/reservation.rb @@ -19,13 +19,3 @@ def total_stay_cost() end end end - - -# res = Hotel::Reservation.new( -# id: "2", -# room_num: "3", -# check_in: "2004-5-6", -# check_out: "2004-7-4") -# -# p res.create_date_range -# p res.create_date_range.class diff --git a/lib/room_block.rb b/lib/room_block.rb index 5992ad91a..84e1e9160 100644 --- a/lib/room_block.rb +++ b/lib/room_block.rb @@ -5,7 +5,7 @@ class RoomBlock < Reservation attr_reader :block_size, :discount, :rooms, :status def initialize(id:, daily_rate: 200, check_in:, check_out:, discount:0, rooms:[], status: :available) - super(id: id, daily_rate: daily_rate, check_in: check_in, check_out: check_out, room_num: room_num) # QUESTION: do i need to specify daily_rate??? + super(id: id, daily_rate: daily_rate, check_in: check_in, check_out: check_out, room_num: room_num) unless !rooms.empty? raise StandardError, "Room blocks cannot be empty!" @@ -23,7 +23,7 @@ def initialize(id:, daily_rate: 200, check_in:, check_out:, discount:0, rooms:[] def show_status() rooms_hash = {} - rooms.each do |room| + @rooms.each do |room| rooms_hash[room.to_s] = @status end return rooms_hash @@ -43,12 +43,3 @@ def total_stay_cost_block() end end end - - -# block = Hotel::RoomBlock.new( -# id: "2", -# rooms: [1,2,3], -# check_in: "2004-7-1", -# check_out: "2004-7-4") -# -# p block.daily_rate diff --git a/refactors.txt b/refactors.txt new file mode 100644 index 000000000..c0379eae0 --- /dev/null +++ b/refactors.txt @@ -0,0 +1,21 @@ +Calendar +- add separate eror handling method or class +- spec: add more edge cases: multi month stay? +- in #overlap? maybe we don't need the object (so remove BookingSystem#construct_cal_checker and change date_range checks back to check_in, check_out + +Reservation +- add hundredths place rounding for money +- make @daily_rate a constant? + +RoomBlock +- maybe RoomBlock shouldn't inherit from Reservation b/c I don't use the instance var @room_num in RoomBlock -- but got errors when I didn't include it in super() in initialize() +- like Calendar, this class also has a lot of error handling going on --> split into methods or a class? +- add more functionality (didn't finish wave 3), like maybe check whether a given room number exists within the block? + +BookingSystem +- spec: #initialize: maybe here see if new reservations and room blocks can be added to @reservations and @room_blocks??? Not sure if this is the right place to test that. +- spec: check in #initialize that list_all_rooms() worked +- spec: more testing for #create_reservation?: reject same start-day overlaps, check to see if res are added to @reservations (here?) + +Overall +- Finish Wave 3 diff --git a/spec/booking_system_spec.rb b/spec/booking_system_spec.rb index 0410dbf15..e7ea6caf0 100644 --- a/spec/booking_system_spec.rb +++ b/spec/booking_system_spec.rb @@ -1,7 +1,5 @@ require_relative 'spec_helper' -# TODO: fix the order of these methods! -# QUESTION: wave 2 -- Your code should raise an exception when asked to reserve a room that is not available -- huhhh? i thought they book with a date range! describe "BookingSystem class" do let(:booking_system) {Hotel::BookingSystem.new()} @@ -14,8 +12,6 @@ expect(booking_system.rooms).must_be_kind_of Array expect(booking_system.reservations).must_be_kind_of Array end - - #TODO: can add new reservations successfully? or elsewhere do this?? end describe "#list_all_rooms" do @@ -46,12 +42,10 @@ # see additional constructor tests in Calendar it "creates a new instance of Calendar" do booking_system.construct_cal_checker(check_in: "1990-10-01", check_out: "1990-10-15").must_be_kind_of Hotel::Calendar - #TODO: check for endd_date as nil? end end describe "#generate_res_id" do - let(:second_res) {Hotel::Reservation.new(id: 2, room_num: 19, check_in: "1996-09-09", check_out: "1996-08-13")} let(:third_res) {Hotel::Reservation.new(id: 3, room_num: 20, check_in: "1996-10-01-", check_out: "1996-10-10")} @@ -77,7 +71,6 @@ end describe "#generate_block_id" do - # NOTE: here and in roomblock, i got tired and didn't do res but instead ints in array let(:block_1) {Hotel::RoomBlock.new(id: 2, rooms: [1,2,3], check_in: "1996-09-09", check_out: "1996-08-13")} let(:block_2) {Hotel::RoomBlock.new(id: 3, rooms: [1,2,3], check_in: "1996-10-01-", check_out: "1996-10-10")} @@ -90,7 +83,7 @@ expect(booking_system.room_blocks[0].id).must_equal 1 end - it "can generate accurate IDs when new rooms are added to rooms list" do + it "can generate accurate IDs when new blocks are added to block list" do first_block = Hotel::RoomBlock.new(id: 10, rooms: [1,2,3], check_in: "1996-09-09", check_out: "1996-09-13") booking_system.room_blocks << first_block @@ -128,7 +121,6 @@ let(:matching_res) {booking_system.list_res_for_date("2010-8-5")} it "should return an array of Reservation objects" do - booking_system.reservations.push(res_1, res_2, res_3) expect(matching_res).must_be_kind_of Array @@ -216,7 +208,6 @@ all_rooms = (1..20).to_a expect(avail_rooms).must_equal all_rooms - end it "can take rooms in room blocks into account" do @@ -232,13 +223,18 @@ end end -# TODO: add create reservation method + 2nd input as room_num?? describe "#create_reservation" do - # TODO: A reservation is allowed start on the same day that another reservation for the same room ends - # TODO test that it's added to Room - # TODO test that it's added to reservations - # let(:room_num) {4} - # let(:room_obj) {booking_system.find_room(room_num)} + it "throws an error when no rooms are available for a given date range" do + 20.times do |i| + res = Hotel::Reservation.new(id:1, room_num: i+1, check_in: "1999-1-1", check_out: "1999-12-31") + booking_system.reservations << res + end + + expect { + booking_system.create_reservation( + check_in: "1999-7-1", + check_out: "1999-7-4")}.must_raise StandardError + end it "creates a new reservation successfully with correct data types" do res_1 = booking_system.create_reservation(check_in: "1992-10-15", check_out: "1992-10-25") @@ -288,6 +284,19 @@ block_size: 2 )} + it "throws an error when no rooms are available for a given date range" do + 20.times do |i| + res = Hotel::Reservation.new(id:1, room_num: i+1, check_in: "1999-1-1", check_out: "1999-12-31") + booking_system.reservations << res + end + + expect { + booking_system.create_room_block( + block_size: 4, + check_in: "1999-7-1", + check_out: "1999-7-4")}.must_raise StandardError + end + it "creates a block using room numbers" do expect(room_block).must_be_kind_of Hotel::RoomBlock expect(room_block.rooms).must_be_kind_of Array @@ -296,7 +305,6 @@ end it "accurately adds information to first room block made" do - expect(room_block.id).must_equal 1 expect(room_block.rooms.length).must_equal 2 expect(room_block.check_in.strftime('%Y %b %d')).must_equal "1990 Jan 01" diff --git a/spec/calendar_spec.rb b/spec/calendar_spec.rb index 5e8ed5f7d..b3226e49b 100644 --- a/spec/calendar_spec.rb +++ b/spec/calendar_spec.rb @@ -1,7 +1,5 @@ require_relative 'spec_helper' -# require_relative 'calendar' -# TODO: edge case --> multimonth stay?? describe "Calendar" do let(:cal) {Hotel::Calendar.new(check_in: "1986-07-20", check_out: "1986-07-29")} @@ -9,6 +7,7 @@ it "can create a new instance of Calendar" do expect(cal).must_be_kind_of Hotel::Calendar end + it "correctly loads date attributes" do expect(cal.check_in).must_be_kind_of Date expect(cal.check_in.strftime('%Y %b %d')).must_equal "1986 Jul 20" @@ -163,13 +162,5 @@ expect(dates_overlap).must_equal true end - - - - end - - - - end diff --git a/spec/reservation_spec.rb b/spec/reservation_spec.rb index dac7b3fff..dcacb5d60 100644 --- a/spec/reservation_spec.rb +++ b/spec/reservation_spec.rb @@ -2,9 +2,6 @@ describe "Reservation" do - # TODO: test id as any pos int? - # TODO: test room_num as 1-20? - let(:reservation) {Hotel::Reservation.new( id: "2", room_num: "3", @@ -14,7 +11,12 @@ describe "#initialize" do it "can create a new instance of reservation" do expect(reservation).must_be_kind_of Hotel::Reservation - expect(reservation.id).must_equal 2 + end + + it "correctly loads the initialized datatypes" do + expect(reservation.id).must_be_kind_of Integer + expect(reservation.room_num).must_be_kind_of Integer + expect(reservation.daily_rate).must_be_kind_of Float end it "can create a reservation with a one-night stay" do @@ -38,7 +40,6 @@ expect(typical_room.daily_rate).must_equal 200 end - # QUESTION: do we need error handling for numeric value for daily_rate? it "can override default value for daily rate" do rare_room = Hotel::Reservation.new( id: "66", diff --git a/spec/room_block_spec.rb b/spec/room_block_spec.rb index d4b2561bb..d7f706636 100644 --- a/spec/room_block_spec.rb +++ b/spec/room_block_spec.rb @@ -1,7 +1,6 @@ require_relative 'spec_helper' describe "RoomBlock" do - let(:block) {Hotel::RoomBlock.new( id: "2", rooms: [1,2,3,4,5], @@ -72,19 +71,6 @@ end end - describe "#discounted_rate" do - it "accurately calculates discounted rate" do - block_room = Hotel::RoomBlock.new( - id: "66", - rooms: [1,2,3], - check_in:"2009-7-29", - check_out: "2009-7-30", - discount: 20) - - expect(block_room.discounted_rate).must_equal 160 - end - end - describe "#show_status" do it "returns a hash" do expect(block.show_status).must_be_kind_of Hash @@ -99,6 +85,19 @@ end end + describe "#discounted_rate" do + it "accurately calculates discounted rate" do + block_room = Hotel::RoomBlock.new( + id: "66", + rooms: [1,2,3], + check_in:"2009-7-29", + check_out: "2009-7-30", + discount: 20) + + expect(block_room.discounted_rate).must_equal 160 + end + end + describe "#total_stay_cost_room" do it "accurately calculates the total cost for one room within the block" do block_room = Hotel::RoomBlock.new( @@ -111,39 +110,15 @@ end end - describe "#total_stay_cost_block" do - it "accurately calculates the total cost for one room within the block" do - entire_block = Hotel::RoomBlock.new( - id: "66", - rooms: [1,2,3], - check_in:"2009-7-29", - check_out: "2009-7-30") + describe "#total_stay_cost_block" do + it "accurately calculates the total cost for one entire block" do + entire_block = Hotel::RoomBlock.new( + id: "66", + rooms: [1,2,3], + check_in:"2009-7-29", + check_out: "2009-7-30") - expect(entire_block.total_stay_cost_block).must_equal 600 - end + expect(entire_block.total_stay_cost_block).must_equal 600 end - # end - - # # QUESTION: do we need error handling for numeric value for daily_rate? - # it "can override default value for daily rate" do - # rare_room = Hotel::RoomBlock.new( - # id: "66", - # room_num: "19", - # check_in:"2009-7-29", - # check_out: "2009-7-30", - # daily_rate: 500) - # - # expect(rare_room.daily_rate).must_equal 500 - # end - # end - - # describe "#total_stay_cost" do - # it "correctly calculates total cost for a reservation" do - # rate = reservation.daily_rate - # dates = 3 - # correct_cost = rate * dates - # - # expect(reservation.total_stay_cost).must_equal 600 - # end - # end + end end From 2d48f683fa1c00bfb2d63c34d315debb59ec1beb Mon Sep 17 00:00:00 2001 From: kangazoom Date: Sat, 29 Sep 2018 17:56:12 -0700 Subject: [PATCH 33/36] answered design activity questions --- design-activity.md | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 design-activity.md diff --git a/design-activity.md b/design-activity.md new file mode 100644 index 000000000..8eb0f9814 --- /dev/null +++ b/design-activity.md @@ -0,0 +1,37 @@ +**What classes does each implementation include? Are the lists the same?** +They each include ```CartEntry```, ```ShoppingCart```, and ```Order```. The lists are the same. + +**Write down a sentence to describe each class.** +```CartEntry``` is in charge of each item placed into the cart (quantity+price). +```ShoppingCart``` is in charge of all the items placed into the cart (as an array). +```Order``` is in charge of finalizing all pricing details for all the items in the cart. + +**How do the classes relate to each other? It might be helpful to draw a diagram on a whiteboard or piece of paper.** +Each cart item is instantiated via ```CartEntry```. When we instantiate ```Order```, we also instantiate a new instance of ```ShoppingCart``` within the constructor. I imagine in the driver code, we would pass in ```CartEntry``` items to ```Order.cart```when instantiating ```Order```. SO ```ShoppingCart``` has many ```CartEntry``` items -- and ```Order``` has one ```ShoppingCart``` (along with its many ```CartEntry``` items) + +**What data does each class store? How (if at all) does this differ between the two implementations?** +In both, ```CartEntry``` stores ```@unit_price``` and ```@quantity``` of each item. In both, ```ShoppingCart``` stores ```@entries``` (as an array). In both, ```Order``` stores ```@cart``` (an instance of ```ShoppingCart```). There are no differences in state between the two. + +**What methods does each class have? How (if at all) does this differ between the two implementations?** +```CartEntry``` +Implementation A: nothing beyond the constructor. +Implementation B: ```price```, which returns the price for each item entry. +```ShoppingCart``` +Implementation A: nothing beyond the constructor. +Implementation B: ```price```, which returns the subtotal for the entire cart. +```Order``` +Both have ```total_price```, which calculates the total price for the cart, including the sales tax. + +**Consider the Order#total_price method. In each implementation:** +* **Is logic to compute the price delegated to "lower level" classes like ShoppingCart and CartEntry, or is it retained in Order?** +In Implementation A, the logic is relegated only to ```Order```. In Implementation B, the pricing is built in the "lower level" classes first before ```Order``` completes the final calculation. +* **Does total_price directly manipulate the instance variables of other classes?** +In Implementation A, ```total_price``` directly manipulates ```CartEntry```'s instance variables (like ```@price```). +In Implementation B, ```total_price``` only interacts with ```ShoppingCart```'s methods. + +**If we decide items are cheaper if bought in bulk, how would this change the code? Which implementation is easier to modify?** +We would need to change the code in ```CartEntry``` to add a discount for bulk items (likely an optional parameter) and a way to determine if ```quantity``` meets the threshold for the bulk item discount (likely through a conditional). Implementation B would be easier to modify, since you'd really only need to make an edit in one place (```CartEntry```), whereas more work would be needed in Implementation A since it doesn't know anything about a discount or bulk quantity criteria yet those influence the pricing for each item (which Implementation A's ```Order``` directly references). +**Which implementation better adheres to the single responsibility principle?** +Implementation B. ```Order``` in Implementation A does too much work and knows too much about ```CartEntry``` in particular. +***Bonus question once you've read Metz ch. 3: Which implementation is more loosely coupled?** +Implementation B (see above). From 1ec67305b045e297d91ea4f3da8aa01ab946bd25 Mon Sep 17 00:00:00 2001 From: kangazoom Date: Sat, 29 Sep 2018 17:58:21 -0700 Subject: [PATCH 34/36] fixed spacing in markdown file --- design-activity.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/design-activity.md b/design-activity.md index 8eb0f9814..4c698a996 100644 --- a/design-activity.md +++ b/design-activity.md @@ -31,7 +31,9 @@ In Implementation B, ```total_price``` only interacts with ```ShoppingCart```'s **If we decide items are cheaper if bought in bulk, how would this change the code? Which implementation is easier to modify?** We would need to change the code in ```CartEntry``` to add a discount for bulk items (likely an optional parameter) and a way to determine if ```quantity``` meets the threshold for the bulk item discount (likely through a conditional). Implementation B would be easier to modify, since you'd really only need to make an edit in one place (```CartEntry```), whereas more work would be needed in Implementation A since it doesn't know anything about a discount or bulk quantity criteria yet those influence the pricing for each item (which Implementation A's ```Order``` directly references). + **Which implementation better adheres to the single responsibility principle?** Implementation B. ```Order``` in Implementation A does too much work and knows too much about ```CartEntry``` in particular. + ***Bonus question once you've read Metz ch. 3: Which implementation is more loosely coupled?** Implementation B (see above). From c6007776aa6b1a5243ac79f28dc5e9ae518fca0c Mon Sep 17 00:00:00 2001 From: kangazoom Date: Mon, 1 Oct 2018 00:59:59 -0700 Subject: [PATCH 35/36] added method to Calendar to calculate nights reserved; edited Reservation so it can interact with this method --- design-activity.md | 3 + lib/calendar.rb | 4 + lib/reservation.rb | 3 +- spec/calendar_spec.rb | 217 ++++++++++++++++++++++-------------------- 4 files changed, 120 insertions(+), 107 deletions(-) diff --git a/design-activity.md b/design-activity.md index 4c698a996..693009ac3 100644 --- a/design-activity.md +++ b/design-activity.md @@ -37,3 +37,6 @@ Implementation B. ```Order``` in Implementation A does too much work and knows t ***Bonus question once you've read Metz ch. 3: Which implementation is more loosely coupled?** Implementation B (see above). + +Activity +- I will add a method to my Calendar class to calculate the number of nights reserved. Right now, this is something I calculate in Reservation in the total_stay_cost method. But because it is date-related, I think I should move it to Calendar. And then I can use it in Reservation since it inherits from Calendar. diff --git a/lib/calendar.rb b/lib/calendar.rb index 8e939521d..a363d2cdb 100644 --- a/lib/calendar.rb +++ b/lib/calendar.rb @@ -34,5 +34,9 @@ def overlap?(other_dates) # param: Calendar obj return true end end + + def nights_reserved() + return @check_out - @check_in + end end end diff --git a/lib/reservation.rb b/lib/reservation.rb index 3fb327374..51fc0ac25 100644 --- a/lib/reservation.rb +++ b/lib/reservation.rb @@ -14,8 +14,7 @@ def initialize(check_in:, check_out:, id:, room_num:, daily_rate: 200) end def total_stay_cost() - length_in_days = @check_out - @check_in - return @daily_rate * length_in_days + return @daily_rate * nights_reserved end end end diff --git a/spec/calendar_spec.rb b/spec/calendar_spec.rb index b3226e49b..339a57985 100644 --- a/spec/calendar_spec.rb +++ b/spec/calendar_spec.rb @@ -1,7 +1,7 @@ require_relative 'spec_helper' describe "Calendar" do - let(:cal) {Hotel::Calendar.new(check_in: "1986-07-20", check_out: "1986-07-29")} + let(:cal) {Hotel::Calendar.new(check_in: "1986-07-20", check_out: "1986-07-29")} describe "#initialize" do it "can create a new instance of Calendar" do @@ -17,150 +17,157 @@ end it "throws a StandardError if fed improper date format for start or end date" do - expect { - Hotel::Calendar.new( - check_in: "2009,7,2", - check_out: "2009-7-1" - )}.must_raise StandardError - - expect { - Hotel::Calendar.new({ - check_in: "2009-7-2", - check_out: "2009,7,1" - })}.must_raise StandardError - end + expect { + Hotel::Calendar.new( + check_in: "2009,7,2", + check_out: "2009-7-1" + )}.must_raise StandardError - it "throws a StandardError if end date occurs before or on same day as start date" do - expect { - Hotel::Calendar.new({ - check_in: "2009-7-2", - check_out: "2009-7-1" - })}.must_raise StandardError - - expect { - Hotel::Calendar.new({ - check_in: "2009-7-1", - check_out: "2009-7-1" - })}.must_raise StandardError - end - end + expect { + Hotel::Calendar.new({ + check_in: "2009-7-2", + check_out: "2009,7,1" + })}.must_raise StandardError + end - describe "#has_date?" do - it "returns true if other date is between check in and check out dates: in the middle" do - other_date = "1986-07-25" + it "throws a StandardError if end date occurs before or on same day as start date" do + expect { + Hotel::Calendar.new({ + check_in: "2009-7-2", + check_out: "2009-7-1" + })}.must_raise StandardError - has_date = cal.has_date?(other_date) + expect { + Hotel::Calendar.new({ + check_in: "2009-7-1", + check_out: "2009-7-1" + })}.must_raise StandardError + end + end - expect(has_date).must_equal true - end + describe "#has_date?" do + it "returns true if other date is between check in and check out dates: in the middle" do + other_date = "1986-07-25" - it "returns true if other date is between check in and check out dates: on check in date" do - other_date = "1986-07-20" + has_date = cal.has_date?(other_date) - has_date = cal.has_date?(other_date) + expect(has_date).must_equal true + end - expect(has_date).must_equal true - end + it "returns true if other date is between check in and check out dates: on check in date" do + other_date = "1986-07-20" - it "returns true if other date is between check in and check out dates: on day before check out" do - other_date = "1986-07-28" + has_date = cal.has_date?(other_date) - has_date = cal.has_date?(other_date) + expect(has_date).must_equal true + end - expect(has_date).must_equal true - end + it "returns true if other date is between check in and check out dates: on day before check out" do + other_date = "1986-07-28" - it "returns false if other date is outside of check in and check out dates: before check in date" do - other_date = "1986-07-15" + has_date = cal.has_date?(other_date) - has_date = cal.has_date?(other_date) + expect(has_date).must_equal true + end - expect(has_date).must_equal false - end + it "returns false if other date is outside of check in and check out dates: before check in date" do + other_date = "1986-07-15" - it "returns false if other date is outside of check in and check out dates: after check out date" do - other_date = "1986-07-31" + has_date = cal.has_date?(other_date) - has_date = cal.has_date?(other_date) + expect(has_date).must_equal false + end - expect(has_date).must_equal false - end + it "returns false if other date is outside of check in and check out dates: after check out date" do + other_date = "1986-07-31" - it "returns false if other date is outside of check in and check out dates: on check out date" do - # edge case - other_date = "1986-07-29" + has_date = cal.has_date?(other_date) - has_date = cal.has_date?(other_date) + expect(has_date).must_equal false + end - expect(has_date).must_equal false - end - end + it "returns false if other date is outside of check in and check out dates: on check out date" do + # edge case + other_date = "1986-07-29" - describe "#overlap?" do - it "returns false for no overlap: other dates begin and end before reserved dates" do - other_dates = Hotel::Calendar.new(check_in: "1986-07-01", check_out: "1986-07-15") + has_date = cal.has_date?(other_date) - dates_overlap = cal.overlap?(other_dates) + expect(has_date).must_equal false + end + end - expect(dates_overlap).must_equal false - end + describe "#overlap?" do + it "returns false for no overlap: other dates begin and end before reserved dates" do + other_dates = Hotel::Calendar.new(check_in: "1986-07-01", check_out: "1986-07-15") - it "returns false for no overlap: other dates begin and end after reserved dates" do - other_dates = Hotel::Calendar.new(check_in: "1986-07-30", check_out: "1986-07-31") + dates_overlap = cal.overlap?(other_dates) - dates_overlap = cal.overlap?(other_dates) + expect(dates_overlap).must_equal false + end - expect(dates_overlap).must_equal false - end + it "returns false for no overlap: other dates begin and end after reserved dates" do + other_dates = Hotel::Calendar.new(check_in: "1986-07-30", check_out: "1986-07-31") - it "returns false for no overlap: other dates begin during reserved dates' check out date" do - # edge case - other_dates = Hotel::Calendar.new(check_in: "1986-07-29", check_out: "1986-07-31") + dates_overlap = cal.overlap?(other_dates) - dates_overlap = cal.overlap?(other_dates) + expect(dates_overlap).must_equal false + end - expect(dates_overlap).must_equal false - end + it "returns false for no overlap: other dates begin during reserved dates' check out date" do + # edge case + other_dates = Hotel::Calendar.new(check_in: "1986-07-29", check_out: "1986-07-31") - it "returns false for no overlap: other dates end during reserved dates' check in date" do - # edge case - other_dates = Hotel::Calendar.new(check_in: "1986-07-15", check_out: "1986-07-20") + dates_overlap = cal.overlap?(other_dates) - dates_overlap = cal.overlap?(other_dates) + expect(dates_overlap).must_equal false + end - expect(dates_overlap).must_equal false - end + it "returns false for no overlap: other dates end during reserved dates' check in date" do + # edge case + other_dates = Hotel::Calendar.new(check_in: "1986-07-15", check_out: "1986-07-20") - it "returns true if dates overlap: other dates begin and end beyond reserved dates range" do - other_dates = Hotel::Calendar.new(check_in: "1986-07-01", check_out: "1986-07-31") + dates_overlap = cal.overlap?(other_dates) - dates_overlap = cal.overlap?(other_dates) + expect(dates_overlap).must_equal false + end - expect(dates_overlap).must_equal true - end + it "returns true if dates overlap: other dates begin and end beyond reserved dates range" do + other_dates = Hotel::Calendar.new(check_in: "1986-07-01", check_out: "1986-07-31") - it "returns true if dates overlap: other dates are fully contained within reserved dates" do - other_dates = Hotel::Calendar.new(check_in: "1986-07-25", check_out: "1986-07-28") + dates_overlap = cal.overlap?(other_dates) - dates_overlap = cal.overlap?(other_dates) + expect(dates_overlap).must_equal true + end - expect(dates_overlap).must_equal true - end + it "returns true if dates overlap: other dates are fully contained within reserved dates" do + other_dates = Hotel::Calendar.new(check_in: "1986-07-25", check_out: "1986-07-28") - it "returns true if dates overlap: other dates begin before but end during reserved dates" do - other_dates = Hotel::Calendar.new(check_in: "1986-07-10", check_out: "1986-07-28") + dates_overlap = cal.overlap?(other_dates) - dates_overlap = cal.overlap?(other_dates) + expect(dates_overlap).must_equal true + end - expect(dates_overlap).must_equal true - end + it "returns true if dates overlap: other dates begin before but end during reserved dates" do + other_dates = Hotel::Calendar.new(check_in: "1986-07-10", check_out: "1986-07-28") - it "returns true if dates overlap: other dates begin during but end after reserved dates" do - other_dates = Hotel::Calendar.new(check_in: "1986-07-25", check_out: "1986-07-31") + dates_overlap = cal.overlap?(other_dates) - dates_overlap = cal.overlap?(other_dates) + expect(dates_overlap).must_equal true + end - expect(dates_overlap).must_equal true - end - end -end + it "returns true if dates overlap: other dates begin during but end after reserved dates" do + other_dates = Hotel::Calendar.new(check_in: "1986-07-25", check_out: "1986-07-31") + + dates_overlap = cal.overlap?(other_dates) + + expect(dates_overlap).must_equal true + end + end + + describe "#nights_reserved" do + it "returns the number of nights reserved" do + num_nights = cal.check_out - cal.check_in + expect(num_nights).must_equal 9 + end + end + end From a4889223349667f5327a9eda17888db3a2ca9f83 Mon Sep 17 00:00:00 2001 From: kangazoom Date: Mon, 1 Oct 2018 01:12:59 -0700 Subject: [PATCH 36/36] edited RoomBlock #total_stay_cost_room to incorporate Calendar's #nights_reserved --- design-activity.md | 2 +- lib/room_block.rb | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/design-activity.md b/design-activity.md index 693009ac3..ad85ce5dc 100644 --- a/design-activity.md +++ b/design-activity.md @@ -39,4 +39,4 @@ Implementation B. ```Order``` in Implementation A does too much work and knows t Implementation B (see above). Activity -- I will add a method to my Calendar class to calculate the number of nights reserved. Right now, this is something I calculate in Reservation in the total_stay_cost method. But because it is date-related, I think I should move it to Calendar. And then I can use it in Reservation since it inherits from Calendar. +- I will add a method to my Calendar class to calculate the number of nights reserved. Right now, this is something I calculate in Reservation in #total_stay_cost. But because it is date-related, I think I should move it to Calendar. And then I can interact with it in Reservation. I can also interact with it in the RoomBlock class since I calculate costs there. diff --git a/lib/room_block.rb b/lib/room_block.rb index 84e1e9160..a682ebabe 100644 --- a/lib/room_block.rb +++ b/lib/room_block.rb @@ -34,8 +34,7 @@ def discounted_rate() end def total_stay_cost_room() - length_in_days = @check_out - @check_in - return discounted_rate() * length_in_days + return discounted_rate() * nights_reserved end def total_stay_cost_block()