From 35f4197f42d3ce703bd13b7127e4a65e63bbedba Mon Sep 17 00:00:00 2001 From: Victoria Garcia Date: Mon, 5 Mar 2018 13:18:38 -0800 Subject: [PATCH 01/51] Initial batch of documents, including lib and spec files for hotel, room, and reservation, as well as the spec_helper and Rakefile, aade for the project. No real content besides require statements for basic gems and documents. --- Rakefile | 9 +++++++++ lib/hotel.rb | 4 ++++ lib/reservation.rb | 4 ++++ lib/room.rb | 4 ++++ specs/hotel_spec.rb | 2 ++ specs/reservation_spec.rb | 2 ++ specs/room_spec.rb | 2 ++ specs/spec_helper.rb | 13 +++++++++++++ 8 files changed, 40 insertions(+) create mode 100644 Rakefile create mode 100644 lib/hotel.rb create mode 100644 lib/reservation.rb create mode 100644 lib/room.rb create mode 100644 specs/hotel_spec.rb create mode 100644 specs/reservation_spec.rb create mode 100644 specs/room_spec.rb create mode 100644 specs/spec_helper.rb diff --git a/Rakefile b/Rakefile new file mode 100644 index 000000000..deb52f2cd --- /dev/null +++ b/Rakefile @@ -0,0 +1,9 @@ +require 'rake/testtask' + +Rake::TestTask.new do |t| + t.libs = ["lib"] + t.warning = true + t.test_files = FileList['specs/*_spec.rb'] +end + +task default: :test diff --git a/lib/hotel.rb b/lib/hotel.rb new file mode 100644 index 000000000..0878a844d --- /dev/null +++ b/lib/hotel.rb @@ -0,0 +1,4 @@ +require 'date' + +require_relative 'reservation' +require_relative 'room' diff --git a/lib/reservation.rb b/lib/reservation.rb new file mode 100644 index 000000000..9a1b7c18a --- /dev/null +++ b/lib/reservation.rb @@ -0,0 +1,4 @@ +require 'date' + +require_relative 'room' +require_relative 'hotel' diff --git a/lib/room.rb b/lib/room.rb new file mode 100644 index 000000000..4df3afc7c --- /dev/null +++ b/lib/room.rb @@ -0,0 +1,4 @@ +require 'date' + +require_relative 'reservation' +require_relative 'hotel' diff --git a/specs/hotel_spec.rb b/specs/hotel_spec.rb new file mode 100644 index 000000000..8334ea95d --- /dev/null +++ b/specs/hotel_spec.rb @@ -0,0 +1,2 @@ +require 'date' +require_relative 'spec_helper' diff --git a/specs/reservation_spec.rb b/specs/reservation_spec.rb new file mode 100644 index 000000000..8334ea95d --- /dev/null +++ b/specs/reservation_spec.rb @@ -0,0 +1,2 @@ +require 'date' +require_relative 'spec_helper' diff --git a/specs/room_spec.rb b/specs/room_spec.rb new file mode 100644 index 000000000..8334ea95d --- /dev/null +++ b/specs/room_spec.rb @@ -0,0 +1,2 @@ +require 'date' +require_relative 'spec_helper' diff --git a/specs/spec_helper.rb b/specs/spec_helper.rb new file mode 100644 index 000000000..ba2a28431 --- /dev/null +++ b/specs/spec_helper.rb @@ -0,0 +1,13 @@ +require 'simplecov' +SimpleCov.start + +require 'date' +require 'minitest' +require 'minitest/autorun' +require 'minitest/reporters' + +Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new + +require_relative '../lib/hotel' +require_relative '../lib/reservation' +require_relative '../lib/room' From 95d867cd538c3416436b38a8d9f5c4f78b2fb45c Mon Sep 17 00:00:00 2001 From: Victoria Garcia Date: Mon, 5 Mar 2018 15:39:20 -0800 Subject: [PATCH 02/51] Tests for Reservation class written and failing/error-ing in the desired ways. --- .DS_Store | Bin 0 -> 6148 bytes lib/front_desk.rb | 14 +++++ lib/hotel.rb | 4 -- lib/reservation.rb | 19 ++++++- lib/room.rb | 12 ++++- specs/{hotel_spec.rb => front_desk_spec.rb} | 3 ++ specs/reservation_spec.rb | 56 ++++++++++++++++++++ specs/room_spec.rb | 3 ++ specs/spec_helper.rb | 2 +- 9 files changed, 105 insertions(+), 8 deletions(-) create mode 100644 .DS_Store create mode 100644 lib/front_desk.rb delete mode 100644 lib/hotel.rb rename specs/{hotel_spec.rb => front_desk_spec.rb} (56%) diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..fc73fea78b2e414e9d7acb6cdbcacfb6258d9daa GIT binary patch literal 6148 zcmeHKyK2Kg5S)!2Fr;yr@_r$Ia2V$c@&mzkih#fYkzQ54E1%}s2f;=N(xeHquse67 z-8(deRtvy(pQk5a3t&Tc#FvM;`E&P~-4)|#e#UV)oX-Q7xSu625MH~&fOi~D<8}Rr z54_=s@tR&ZM6?u;0#ZN4!@ic&xdNP!;({QJ=8j=gY7j86wci~z(n z=`gNimLN7Kh`n%1Btx?-C1$DBh+$byzExf?oD#Df7B};py4h+%vACUli*#5|RFncz z;8uZEZnxh5pXm$p|80?WQa}p)D+O%5f7$Q&O4VCuFXz3s(O>DF^G$c-I!YL#9TTG+ hbK~v!F_JQ``I^sr;glHV Date: Mon, 5 Mar 2018 16:15:43 -0800 Subject: [PATCH 03/51] within reservation, assign_id method is working, even though it involves a class variable. But we'll see how long that lasts\! --- lib/reservation.rb | 21 ++++++++++++++++++--- specs/reservation_spec.rb | 16 +++++++++++----- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/lib/reservation.rb b/lib/reservation.rb index 368f3f861..e8604f32f 100644 --- a/lib/reservation.rb +++ b/lib/reservation.rb @@ -7,13 +7,28 @@ module Hotel class Reservation attr_accessor :id, :start_date, :end_date + @@last_id_base = 0 + def initialize(start_date, end_date) - @id = :id - @start_date = start_date - @end_date = end_date + @id = assign_id + @start_date = DateTime.parse(start_date) + @end_date = DateTime.parse(end_date) end def calculate_cumulative_price end + + def assign_id + new_id_base = (@@last_id_base + 1).to_s + @@last_id_base += 1 + zeroes_needed = 8 - new_id_base.length + leading_zero_array = [] + zeroes_needed.times do + leading_zero_array << "0" + end + leading_zero_block = leading_zero_array.join + new_id = leading_zero_block.concat(new_id_base) + return new_id + end end end diff --git a/specs/reservation_spec.rb b/specs/reservation_spec.rb index 56f4f0f67..3e133a438 100644 --- a/specs/reservation_spec.rb +++ b/specs/reservation_spec.rb @@ -5,6 +5,9 @@ before do @reservation_0_nominal = Hotel::Reservation.new('10th Jun 3013', '16th Jun 3013') + @reservation_1_id_check = Hotel::Reservation.new('1st Oct 3080', '4th Oct 3080') + @reservation_2_id_check = Hotel::Reservation.new('1st Nov 3081', '4th Nov 3081') + @reservation_3_id_check = Hotel::Reservation.new('1st Dec 3082', '5th Dec 3082') end describe "initialize" do @@ -34,10 +37,6 @@ end it "has a unique, six-digit ID number that is one higher than the next-highest ID number" do - @reservation_1_id_check = Hotel::Reservation.new('1st Oct 3080', '4th Oct 3080') - @reservation_2_id_check = Hotel::Reservation.new('1st Nov 3081', '4th Nov 3081') - @reservation_3_id_check = Hotel::Reservation.new('1st Dec 3082', '5th Dec 3082') - @reservation_2_id_check.id.to_i.must_equal 1 + @reservation_1_id_check.id.to_i @reservation_3_id_check.id.to_i.must_equal 2 + @reservation_1_id_check.id.to_i end @@ -48,11 +47,18 @@ it "returns a float rounded to two decimal places" do @reservation_0_nominal.calculate_cumulative_price.must_be_kind_of Float - @reservation_0_nominal.calculate_cumulative_price.must_match /^\d+\.\d{2}$/ + @reservation_0_nominal.calculate_cumulative_price.to_s.must_match /^\d+\.\d{2}$/ end it "accurately returns the product of the room's per-day price and the length (in days) of the reservation" do @reservation_0_nominal.calculate_cumulative_price.must_be_within_delta 600.00, 0.003 end + + describe "assign_id" do + it "creates an eight-digit id" do + @reservation_0_nominal.id.to_s.must_match /^\d{8}$/ + + end + end end end From b4b658592b174eac9f7678565cd65ba465ae7895 Mon Sep 17 00:00:00 2001 From: Victoria Garcia Date: Mon, 5 Mar 2018 16:57:48 -0800 Subject: [PATCH 04/51] Reseration Class is passing all tests, except for the 'calculate_price' test, which I am thinking of putting in a different class, and which, in any case, is dependant on the as-yet-nonexistant Room class. --- lib/reservation.rb | 21 +++++++++++++-------- specs/reservation_spec.rb | 32 +++++++++++++++----------------- 2 files changed, 28 insertions(+), 25 deletions(-) diff --git a/lib/reservation.rb b/lib/reservation.rb index e8604f32f..8dc9af06c 100644 --- a/lib/reservation.rb +++ b/lib/reservation.rb @@ -1,33 +1,38 @@ require 'date' +require 'pry' # require_relative 'room' # require_relative 'front_desk' + module Hotel class Reservation attr_accessor :id, :start_date, :end_date @@last_id_base = 0 + #36000 seconds is ten hours. This figure was arrived at by taking the most likely check-out time (10:00 am) and determining the number of seconds since the change of date at midnight. The putative customer could change this easily, depending on their needs. + MIN_RES_IN_SEC = 36000 + def initialize(start_date, end_date) @id = assign_id @start_date = DateTime.parse(start_date) @end_date = DateTime.parse(end_date) - end - def calculate_cumulative_price + if (@start_date.to_time.to_i - @end_date.to_time.to_i) > MIN_RES_IN_SEC || @start_date.to_time.to_i < Time.now.to_i + raise StandardError.new("A reservation's end date must come after its start date.") + end end + # def calculate_cumulative_price + # end + def assign_id new_id_base = (@@last_id_base + 1).to_s @@last_id_base += 1 zeroes_needed = 8 - new_id_base.length - leading_zero_array = [] - zeroes_needed.times do - leading_zero_array << "0" - end - leading_zero_block = leading_zero_array.join - new_id = leading_zero_block.concat(new_id_base) + leading_zero_array = (1..zeroes_needed).collect {"0"} + new_id = leading_zero_array.join.concat(new_id_base) return new_id end end diff --git a/specs/reservation_spec.rb b/specs/reservation_spec.rb index 3e133a438..b80cf7044 100644 --- a/specs/reservation_spec.rb +++ b/specs/reservation_spec.rb @@ -35,30 +35,28 @@ early_end = '1st May 3075' proc{ Hotel::Reservation.new(late_start, early_end) }.must_raise StandardError end - - it "has a unique, six-digit ID number that is one higher than the next-highest ID number" do - @reservation_2_id_check.id.to_i.must_equal 1 + @reservation_1_id_check.id.to_i - @reservation_3_id_check.id.to_i.must_equal 2 + @reservation_1_id_check.id.to_i - end - end - describe "calculate_cumulative_price" do - - it "returns a float rounded to two decimal places" do - @reservation_0_nominal.calculate_cumulative_price.must_be_kind_of Float - @reservation_0_nominal.calculate_cumulative_price.to_s.must_match /^\d+\.\d{2}$/ - end - - it "accurately returns the product of the room's per-day price and the length (in days) of the reservation" do - @reservation_0_nominal.calculate_cumulative_price.must_be_within_delta 600.00, 0.003 - end + # describe "calculate_cumulative_price" do + # it "returns a float rounded to two decimal places" do + # @reservation_0_nominal.calculate_cumulative_price.must_be_kind_of Float + # @reservation_0_nominal.calculate_cumulative_price.to_s.must_match /^\d+\.\d{2}$/ + # end + # + # it "accurately returns the product of the room's per-day price and the length (in days) of the reservation" do + # @reservation_0_nominal.calculate_cumulative_price.must_be_within_delta 600.00, 0.003 + # end + # end describe "assign_id" do it "creates an eight-digit id" do @reservation_0_nominal.id.to_s.must_match /^\d{8}$/ + @reservation_3_id_check.id.to_s.must_match /^\d{8}$/ + end + it "generates an ID number that is one higher than the next-highest ID number" do + @reservation_2_id_check.id.to_i.must_equal 1 + @reservation_1_id_check.id.to_i + @reservation_3_id_check.id.to_i.must_equal 2 + @reservation_1_id_check.id.to_i end end - end end From 73776cada464b0e683998f46dafa3b79791e237a Mon Sep 17 00:00:00 2001 From: Victoria Garcia Date: Mon, 5 Mar 2018 20:33:54 -0800 Subject: [PATCH 05/51] After consideration, price calculation methods added to reservation class. Tests written and failing in the desired way. --- lib/reservation.rb | 24 ++++++++++---- specs/reservation_spec.rb | 66 +++++++++++++++++++++++++-------------- 2 files changed, 61 insertions(+), 29 deletions(-) diff --git a/lib/reservation.rb b/lib/reservation.rb index 8dc9af06c..a24699613 100644 --- a/lib/reservation.rb +++ b/lib/reservation.rb @@ -7,26 +7,30 @@ module Hotel class Reservation - attr_accessor :id, :start_date, :end_date + attr_accessor :start_date, :end_date + attr_reader :id, :total_nights, :total_reservation_cost @@last_id_base = 0 - #36000 seconds is ten hours. This figure was arrived at by taking the most likely check-out time (10:00 am) and determining the number of seconds since the change of date at midnight. The putative customer could change this easily, depending on their needs. + # The constant below, MIN_RES_IN_SEC, is the length of the minimum reservation, in seconds. This figure was arrived at by calculating the number of seconds between an early-but-common check-out time (10:00 am) and the change of date at midnight. The putative customer could, of course, change this to whatever they wanted. MIN_RES_IN_SEC = 36000 + #Since all rooms are identical, and we haven't been given any parameters for price variation, it makes sense to assign a default price for the moment. If the customer needs more options or granularity here, that cna be implemented later + PER_NIGHT_PRICE = 100.00 + def initialize(start_date, end_date) @id = assign_id @start_date = DateTime.parse(start_date) @end_date = DateTime.parse(end_date) + @total_nights = calculate_total_nights + @total_reservation_cost = calculate_reservation_price + if (@start_date.to_time.to_i - @end_date.to_time.to_i) > MIN_RES_IN_SEC || @start_date.to_time.to_i < Time.now.to_i - raise StandardError.new("A reservation's end date must come after its start date.") + raise StandardError.new("A reservation's end date must come after its start date, and it must be at least one night long.") end end - # def calculate_cumulative_price - # end - def assign_id new_id_base = (@@last_id_base + 1).to_s @@last_id_base += 1 @@ -35,5 +39,13 @@ def assign_id new_id = leading_zero_array.join.concat(new_id_base) return new_id end + + def calculate_total_nights + (@start_date.to_date - @end_date.to_date).to_i + end + + def calculate_reservation_price + (@total_nights * PER_NIGHT_PRICE).round(2) + end end end diff --git a/specs/reservation_spec.rb b/specs/reservation_spec.rb index b80cf7044..5e0b40c86 100644 --- a/specs/reservation_spec.rb +++ b/specs/reservation_spec.rb @@ -4,24 +4,24 @@ describe "Reservation class" do before do - @reservation_0_nominal = Hotel::Reservation.new('10th Jun 3013', '16th Jun 3013') - @reservation_1_id_check = Hotel::Reservation.new('1st Oct 3080', '4th Oct 3080') - @reservation_2_id_check = Hotel::Reservation.new('1st Nov 3081', '4th Nov 3081') - @reservation_3_id_check = Hotel::Reservation.new('1st Dec 3082', '5th Dec 3082') + @reservation_0_nominal_6n = Hotel::Reservation.new('10th Jun 3013', '16th Jun 3013') + @reservation_1_1n = Hotel::Reservation.new('1st Oct 3080', '2nd Oct 3080') + @reservation_2_2n = Hotel::Reservation.new('1st Nov 3081', '3rd Nov 3081') + @reservation_3_35n = Hotel::Reservation.new('1st Dec 3082', '5th Jan 3083') end describe "initialize" do it "is an instance of Reservation" do - @reservation_0_nominal.must_be_instance_of Hotel::Reservation + @reservation_0_nominal_6n.must_be_instance_of Hotel::Reservation end it "has a start date that is an instance of Ruby's Date class" do - @reservation_0_nominal.start_date.must_be_instance_of DateTime + @reservation_0_nominal_6n.start_date.must_be_instance_of DateTime end it "has an end date that is an instance of Ruby's Date class" do - @reservation_0_nominal.end_date.must_be_instance_of DateTime + @reservation_0_nominal_6n.end_date.must_be_instance_of DateTime end it "Raises an error if the start date comes before the date of instantiation" do @@ -32,31 +32,51 @@ it "raises an error if the end date is not at least one day after the end date" do late_start = '3rd May 3075' - early_end = '1st May 3075' + early_end = '3rd May 3075' proc{ Hotel::Reservation.new(late_start, early_end) }.must_raise StandardError end end - # describe "calculate_cumulative_price" do - # it "returns a float rounded to two decimal places" do - # @reservation_0_nominal.calculate_cumulative_price.must_be_kind_of Float - # @reservation_0_nominal.calculate_cumulative_price.to_s.must_match /^\d+\.\d{2}$/ - # end - # - # it "accurately returns the product of the room's per-day price and the length (in days) of the reservation" do - # @reservation_0_nominal.calculate_cumulative_price.must_be_within_delta 600.00, 0.003 - # end - # end - describe "assign_id" do it "creates an eight-digit id" do - @reservation_0_nominal.id.to_s.must_match /^\d{8}$/ - @reservation_3_id_check.id.to_s.must_match /^\d{8}$/ + @reservation_0_nominal_6n.id.to_s.must_match /^\d{8}$/ + @reservation_3_35n.id.to_s.must_match /^\d{8}$/ end it "generates an ID number that is one higher than the next-highest ID number" do - @reservation_2_id_check.id.to_i.must_equal 1 + @reservation_1_id_check.id.to_i - @reservation_3_id_check.id.to_i.must_equal 2 + @reservation_1_id_check.id.to_i + @reservation_2_2n.id.to_i.must_equal 1 + @reservation_1_1n.id.to_i + @reservation_3_35n.id.to_i.must_equal 2 + @reservation_1_1n.id.to_i + end + end + + describe "calculate_total_nights" do + before do + @r_0_nominal_nights = @reservation_0_nominal_6n.calculate_total_nights + end + it "returns an integer" do + @r_0_nominal_nights.must_be_kind_of Integer + end + it "correctly calculates the length of a nominal stay" do + @r_0_nominal_nights.must_equal 6 + end + it "correctly calculates the length of a stay that begins in one year and ends in another" do + @reservation_3_35n.calculate_total_nights.must_equal 35 + end + it "correctly calculates teh length of a stay that is one night long" do + @reservation_1_1n.calculate_total_nights.must_equal 1 + end + end + + describe "calculate_reservation_price" do + it "returns a float rounded to two decimal places" do + @reservation_0_nominal_6n.calculate_reservation_price.must_be_kind_of Float + @reservation_0_nominal_6n.calculate_reservation_price.to_s.must_match /^\d+\.\d{2}$/ + end + + it "accurately returns the product of the room's per-day price and the length (in days) of the reservation" do + @reservation_0_nominal_6n.calculate_reservation_price.must_be_within_delta 600.00, 0.003 + @reservation_1_1n.calculate_reservation_price.must_be_within_delta 100.00, 0.003 + @reservation_3_35n.calculate_reservation_price.must_be_within_delta 3500.00, 0.003 end end end From 4349a6931e0cf57bc61549e6e765fc07554f1bd8 Mon Sep 17 00:00:00 2001 From: Victoria Garcia Date: Mon, 5 Mar 2018 21:08:34 -0800 Subject: [PATCH 06/51] total calculation method in Reservation is now passing all tests. --- lib/reservation.rb | 7 ++++--- specs/reservation_spec.rb | 3 ++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/reservation.rb b/lib/reservation.rb index a24699613..8055502dd 100644 --- a/lib/reservation.rb +++ b/lib/reservation.rb @@ -26,7 +26,7 @@ def initialize(start_date, end_date) @total_reservation_cost = calculate_reservation_price - if (@start_date.to_time.to_i - @end_date.to_time.to_i) > MIN_RES_IN_SEC || @start_date.to_time.to_i < Time.now.to_i + if (@end_date.to_time.to_i - @start_date.to_time.to_i) < MIN_RES_IN_SEC || @start_date.to_time.to_i < Time.now.to_i raise StandardError.new("A reservation's end date must come after its start date, and it must be at least one night long.") end end @@ -41,11 +41,12 @@ def assign_id end def calculate_total_nights - (@start_date.to_date - @end_date.to_date).to_i + (@end_date.to_date - @start_date.to_date).to_i end def calculate_reservation_price - (@total_nights * PER_NIGHT_PRICE).round(2) + #I know this isn't exactly best practice for dealing with real-world currency. But since we haven't covered that yet and this isn't the real world, this is what I'm going with. + (@total_nights * PER_NIGHT_PRICE).round(2) end end end diff --git a/specs/reservation_spec.rb b/specs/reservation_spec.rb index 5e0b40c86..eec83db54 100644 --- a/specs/reservation_spec.rb +++ b/specs/reservation_spec.rb @@ -1,4 +1,5 @@ require 'date' +require 'pry' require_relative 'spec_helper' describe "Reservation class" do @@ -70,7 +71,7 @@ describe "calculate_reservation_price" do it "returns a float rounded to two decimal places" do @reservation_0_nominal_6n.calculate_reservation_price.must_be_kind_of Float - @reservation_0_nominal_6n.calculate_reservation_price.to_s.must_match /^\d+\.\d{2}$/ + @reservation_0_nominal_6n.calculate_reservation_price.to_s.must_match /^\d+\.\d{1,2}$/ end it "accurately returns the product of the room's per-day price and the length (in days) of the reservation" do From bc418d2913b89d480c62f8e649b16f4f5deaa93a Mon Sep 17 00:00:00 2001 From: Victoria Garcia Date: Tue, 6 Mar 2018 15:09:22 -0800 Subject: [PATCH 07/51] A bunch of tests stubbed for the Room class. --- specs/room_spec.rb | 62 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/specs/room_spec.rb b/specs/room_spec.rb index 673875f20..a591062b1 100644 --- a/specs/room_spec.rb +++ b/specs/room_spec.rb @@ -2,4 +2,66 @@ require_relative 'spec_helper' describe "Room class" do + before do + @room_300 = Hotel::Room.new("300") + ) + end + describe "initialize(room_number)" do + it "must have a room number encoded as a symbol" do + @room_300.room_number.must_be_kind_of Symbol + end + it "must accurately report its own room number" do + @room_300.room_number.must_equal :300 + end + it "must store its reservations in an array" do + @room_300.reservations.must_be_kind_of Array + end + end + + describe "report_all_reservations" do + + it "returns a complete collection of reservations for the room" do + end + + it "returns nil when a room has no present or pending reservations" do + end + + it "performs properly when the room is reserved on the same day the method is called" do + end + end + + describe "report_availability(date)" do + + it "accurately reports reservations when run for the current day" do + end + + it "accurately reports reservations for a future date" do + end + + it "accurately reports reservations for a date in the past" do + end + end + + describe "can_accept_reservation?(reservation)" do + + it "returns true if the proposed reservation does not conflict with an existing reservation" do + end + + it "returns false if the proposed reservation conflicts with an existing reservation" do + end + + it "accepts a reservation when the start date is the same as the date of the request, assuming no other conflicts" do + end + + it "rejects a reservation when the start date is the same as the date of the request, if the only conflict is for that day" do + end + + end + + describe "add_reservation(reservation)" do + it "must add itself to the room's collection of reservations" do + end + + it "must add the dates of the reservation to the room's collection of unavailable dates" + end end From 0b24d319754df838dd688954ce46c349c2ef4dfb Mon Sep 17 00:00:00 2001 From: Victoria Garcia Date: Tue, 6 Mar 2018 15:24:26 -0800 Subject: [PATCH 08/51] More tests stubbed for the Room class. It is a stubby kind of day. --- specs/room_spec.rb | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/specs/room_spec.rb b/specs/room_spec.rb index a591062b1..f3eedb251 100644 --- a/specs/room_spec.rb +++ b/specs/room_spec.rb @@ -5,6 +5,10 @@ before do @room_300 = Hotel::Room.new("300") ) + @reservation_n_nominal_6n = Hotel::Reservation.new('10th Jun 3013', '16th Jun 3013') + @reservation_1_follows_n_directly = Hotel::Reservation.new('16th Oct 3013', '2nd Nov 3013') + @reservation_2_overlaps_n_beginning = Hotel::Reservation.new('8th Jun 3013', '11th Jun 3013') + @reservation_3_overlaps_n_end = Hotel::Reservation.new('15th Jun 3013', '5th Jul 3013') end describe "initialize(room_number)" do it "must have a room number encoded as a symbol" do @@ -53,9 +57,15 @@ it "accepts a reservation when the start date is the same as the date of the request, assuming no other conflicts" do end - it "rejects a reservation when the start date is the same as the date of the request, if the only conflict is for that day" do + it "accepts a reservation that begins the same day another reservation ends, assuming no other conflicts" do end + it "accepts a reservation when its start date, the date of the request, and the end date of another reservation are all the same, assuming o other conflicts" do + end + + it "rejects a reservation that begins the same date as the date of the request, if another conflict exists" do + end + end describe "add_reservation(reservation)" do From ac02b879e2d91c6b1636645e045518b5c9f9f1b4 Mon Sep 17 00:00:00 2001 From: Victoria Garcia Date: Tue, 6 Mar 2018 16:26:21 -0800 Subject: [PATCH 09/51] Some more test-ish stuff for Room, including variables that hold DateTime-parsable values for 'right now', 'two days from now', and 'two days ago'. Don't know if I REALLY need these, but I spec-ed out some tests that will benefit from them being available. So yaaaay. --- lib/room.rb | 9 ++++++--- specs/room_spec.rb | 33 +++++++++++++++++++++++++-------- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/lib/room.rb b/lib/room.rb index eaa66416a..17c5764fb 100644 --- a/lib/room.rb +++ b/lib/room.rb @@ -5,10 +5,13 @@ module Hotel class Room - attr_reader - attr_accessor + attr_reader :room_number + attr_accessor :reservations :dates_unavailable - def initialize + def initialize(room_number) + @room_number = :room_number + @reservations = [] + @dates_unavailable = [] end end end diff --git a/specs/room_spec.rb b/specs/room_spec.rb index f3eedb251..be2170efc 100644 --- a/specs/room_spec.rb +++ b/specs/room_spec.rb @@ -3,12 +3,20 @@ describe "Room class" do before do - @room_300 = Hotel::Room.new("300") - ) - @reservation_n_nominal_6n = Hotel::Reservation.new('10th Jun 3013', '16th Jun 3013') - @reservation_1_follows_n_directly = Hotel::Reservation.new('16th Oct 3013', '2nd Nov 3013') - @reservation_2_overlaps_n_beginning = Hotel::Reservation.new('8th Jun 3013', '11th Jun 3013') - @reservation_3_overlaps_n_end = Hotel::Reservation.new('15th Jun 3013', '5th Jul 3013') + + right_now = Time.now.to_s + two_days_ago = Time.at(Time.now.to_i - 172800).to_s + two_days_from_now = Time.at(Time.now.to_i + 172800).to_s + + @room_300_nominal = Hotel::Room.new("300") + @room_400_no_res = Hotel::Room.new("400") + + @reservation_n1_nominal = Hotel::Reservation.new('10th Jun 3013', '16th Jun 3013') + @reservation_1_follows_n1_directly = Hotel::Reservation.new('16th Oct 3013', '2nd Nov 3013') + @reservation_2_overlaps_n1_beginning = Hotel::Reservation.new('8th Jun 3013', '11th Jun 3013') + @reservation_3_overlaps_n1_end = Hotel::Reservation.new('15th Jun 3013', '5th Jul 3013') + @reservation_n2_nominal = Hotel::Reservation.new('10th Jun 3014', '16th Jun 3014') + @reservation_n3_nominal = Hotel::Reservation.new('10th Oct 3015', '9th Dec 3015') end describe "initialize(room_number)" do it "must have a room number encoded as a symbol" do @@ -25,12 +33,21 @@ describe "report_all_reservations" do it "returns a complete collection of reservations for the room" do + all_nominal_reservations = [@reservation_n1_nominal, @reservation_n2_nominal, @reservation_n3_nominal] + @room_300.reservations = all_nominal_reservations + @room_300.report_all_reservations.must_equal all_nominal_reservations end it "returns nil when a room has no present or pending reservations" do + @room_400_no_res.report_alL_reservations.must_be_nil + end + + it "performs properly when the room has a reservation that ends on the day on which the method is called" do + end - it "performs properly when the room is reserved on the same day the method is called" do + it "performs properly when the room has a reservation that ends on the day on which the method is called" do + end end @@ -64,7 +81,7 @@ end it "rejects a reservation that begins the same date as the date of the request, if another conflict exists" do - end + end end From c5d831eaeb09e6df14661e051f8d215db706bb55 Mon Sep 17 00:00:00 2001 From: Victoria Garcia Date: Thu, 8 Mar 2018 00:45:14 -0800 Subject: [PATCH 10/51] got the first bit of my crazy-ass date system to start throwing a reasonable number of fails and errors instead of a blizzard of them. Calling that progress. (Amazing progress, actually.) Now, going to put that shizz to bed. I can troubleshoot the rest in the morning. THIS WILL WORK GDI. --- lib/reservation.rb | 35 +++++++++++++++-- lib/room.rb | 5 +-- specs/reservation_spec.rb | 82 ++++++++++++++++++++++++++++++++++++--- specs/room_spec.rb | 18 +++++---- 4 files changed, 121 insertions(+), 19 deletions(-) diff --git a/lib/reservation.rb b/lib/reservation.rb index 8055502dd..c2f205557 100644 --- a/lib/reservation.rb +++ b/lib/reservation.rb @@ -8,7 +8,7 @@ module Hotel class Reservation attr_accessor :start_date, :end_date - attr_reader :id, :total_nights, :total_reservation_cost + attr_reader :id, :days_booked_am_and_pm, :total_nights, :total_reservation_cost @@last_id_base = 0 @@ -22,11 +22,13 @@ def initialize(start_date, end_date) @id = assign_id @start_date = DateTime.parse(start_date) @end_date = DateTime.parse(end_date) + @days_booked_am_and_pm = days_with_am_and_pm_occupation @total_nights = calculate_total_nights @total_reservation_cost = calculate_reservation_price - - if (@end_date.to_time.to_i - @start_date.to_time.to_i) < MIN_RES_IN_SEC || @start_date.to_time.to_i < Time.now.to_i + #THIS IS GOOD, BUT IT EFFS UP YOUR ABILITY TO TEST CERTAIN SHIT. MAYBE PUT THE VALIDATION MEASURE FOR START-DATES IN THE PAST IN FrontDesk??? OR RESCUE?? + ## Commenting out the req about not starting reservations in the past--- for now. + if (@end_date.to_time.to_i - @start_date.to_time.to_i) < MIN_RES_IN_SEC #|| @start_date.to_time.to_i < Time.now.to_i raise StandardError.new("A reservation's end date must come after its start date, and it must be at least one night long.") end end @@ -44,6 +46,33 @@ def calculate_total_nights (@end_date.to_date - @start_date.to_date).to_i end + def days_with_am_and_pm_occupation + first_key = @start_date.jd.to_s + last_key = @end_date.jd.to_s + start_and_end_days = { + first_key => { + :am => false, + :pm => true + }, + last_key => { + :am => true, + :pm => false + } + } + intervening_span = (last_key.to_i - first_key.to_i - 1) + mid_keys_array = [] + while intervening_span > 0 + mid_key = (first_key.to_i + intervening_span).to_s + mid_keys_array << mid_key + intervening_span -= 1 + end + full_days_in_use = {} + unless mid_keys_array.empty? + full_days_in_use = mid_keys_array.map {|day| [day, {:am => true, :pm => true}] } + end + all_days_in_use = start_and_end_days.merge(full_days_in_use.to_h) + end + def calculate_reservation_price #I know this isn't exactly best practice for dealing with real-world currency. But since we haven't covered that yet and this isn't the real world, this is what I'm going with. (@total_nights * PER_NIGHT_PRICE).round(2) diff --git a/lib/room.rb b/lib/room.rb index 17c5764fb..c3f30876a 100644 --- a/lib/room.rb +++ b/lib/room.rb @@ -5,11 +5,10 @@ module Hotel class Room - attr_reader :room_number - attr_accessor :reservations :dates_unavailable + attr_accessor :room_number, :reservations, :dates_unavailable def initialize(room_number) - @room_number = :room_number + @room_number = room_number @reservations = [] @dates_unavailable = [] end diff --git a/specs/reservation_spec.rb b/specs/reservation_spec.rb index eec83db54..5cdc5d6c9 100644 --- a/specs/reservation_spec.rb +++ b/specs/reservation_spec.rb @@ -25,11 +25,12 @@ @reservation_0_nominal_6n.end_date.must_be_instance_of DateTime end - it "Raises an error if the start date comes before the date of instantiation" do - too_early_start = '1st Feb 1975' - acceptible_end = '2nd Feb 3080' - proc{ Hotel::Reservation.new(too_early_start, acceptible_end) }.must_raise StandardError - end + # Note: COMMENTING THIS OUT FOR NOW. WILL PROBABLY move this functionality to FrontDesk. + # it "Raises an error if the start date comes before the date of instantiation" do + # too_early_start = '1st Feb 1975' + # acceptible_end = '2nd Feb 3080' + # proc{ Hotel::Reservation.new(too_early_start, acceptible_end) }.must_raise StandardError + # end it "raises an error if the end date is not at least one day after the end date" do late_start = '3rd May 3075' @@ -50,6 +51,77 @@ end end + describe "days_with_am_and_pm_occupation" do + + before do + @nominal_understand_days = @reservation_0_nominal_6n.days_with_am_and_pm_occupation + @start_date_hash = @nominal_understand_days.fetch(@reservation_0_nominal_6n.start_date.jd.to_s) + @end_date_hash = @nominal_understand_days.fetch(@reservation_0_nominal_6n.end_date.jd.to_s) + end + + it "returns a hash" do + @nominal_understand_days.must_be_kind_of Hash + end + + it "contains a key-value pair for each day of the reservation" do + @nominal_understand_days.count.must_equal 7 + end + + it "must be composed of key-value pairs in which all the keys are Julian dates in string form" do + @nominal_understand_days.each_key.must_be_kind_of String + @nominal_understand_days.each_key.must_match /^24[56]\d{4}$/ + end + + it "must be composed of key-value pairs in which all the values are hashes" do + @nominal_understand_days.each_value.must_be_instance_of Hash + end + + it "must be composed of key-value pairs in which the value is a hash which contains two keys, :am and :pm" do + @nominal_understand_days.each_value.count.must_equal 2 + @nominal_understand_days.each_value.has_key?(:am).must_equal true + @nominal_understand_days.each_value.has_key?(:pm).must_equal true + end + + it "must contain a key-value pair for the start date in which the key is the start date, and the value is a 2-item hash, wherein the :am key's value is 'false' and the :pm key's value is 'true'" do + + @nominal_understand_days.has_key?(@reservation_0_nominal_6n.start_date.jd.to_s).must_equal true + @start_date_hash.count.must_equal 1 + @start_date_hash[1].fetch(:am).must_equal false + @start_date_hash[1].fetch(:pm).must_equal true + end + + + it "must contain a key-value pair for the end date in which the key is the end date, and the value is a 2-item hash, wherein which the :am key's value is 'true' and the :pm key's value is 'false'" do + + @nominal_understand_days.has_key?(@reservation_0_nominal_6n.end_date.jd.to_s).must_equal true + @end_date_hash.count.must_equal 1 + @end_date_hash[1].fetch(:am).must_equal true + @end_date_hash[1].fetch(:pm).must_equal false + end + + it "must include a hash for each FULL DAY (i.e, non-starting or ending day) of the reservation in which the value contains exactly two key-value pairs, one with a key of :am, and one with a key of :pm, and both with a value of 'true'" do + test_copy_nominal_understand_1 = @nominal_understand_days.dup + no_start_test = (test_copy_nominal_understand_1.delete(@reservation_0_nominal_6n.start_date.jd.to_s)).dup + no_start_or_end_test = (no_start_test.delete(@reservation_0_nominal_6n.end_date.jd.to_s)).dup + first_res_day_julian = @reservation_0_nominal_6n.start_date.jd.to_i + last_res_day_julian = @reservation_0_nominal_6n.end_date.jd.to_i + if last_res_day_julian - first_res_day_julian > 1 + value_array = [] + no_start_or_end_test.each do |full_day| + value_array = [] + full_day.value.each_value{|value| value_array << value} + value_array.must_equal [true, true] + end + key_array = [] + no_start_or_end_test.each_key {|key| key_array << key} + key_array.sort! + key_array.each_with_index do |key, index| + (key.to_i + index + 1).must_equal (first_res_day_julian + index + 1) + end + end + end + end + describe "calculate_total_nights" do before do @r_0_nominal_nights = @reservation_0_nominal_6n.calculate_total_nights diff --git a/specs/room_spec.rb b/specs/room_spec.rb index be2170efc..b4a140958 100644 --- a/specs/room_spec.rb +++ b/specs/room_spec.rb @@ -1,4 +1,5 @@ require 'date' +require 'pry' require_relative 'spec_helper' describe "Room class" do @@ -19,14 +20,14 @@ @reservation_n3_nominal = Hotel::Reservation.new('10th Oct 3015', '9th Dec 3015') end describe "initialize(room_number)" do - it "must have a room number encoded as a symbol" do - @room_300.room_number.must_be_kind_of Symbol + it "must have a room number encoded as a string" do + @room_300_nominal.room_number.must_be_kind_of String end it "must accurately report its own room number" do - @room_300.room_number.must_equal :300 + @room_300_nominal.room_number.must_equal "300" end it "must store its reservations in an array" do - @room_300.reservations.must_be_kind_of Array + @room_300_nominal.reservations.must_be_kind_of Array end end @@ -34,8 +35,8 @@ it "returns a complete collection of reservations for the room" do all_nominal_reservations = [@reservation_n1_nominal, @reservation_n2_nominal, @reservation_n3_nominal] - @room_300.reservations = all_nominal_reservations - @room_300.report_all_reservations.must_equal all_nominal_reservations + @room_300_nominal.reservations = all_nominal_reservations + @room_300_nominal.report_all_reservations.must_equal all_nominal_reservations end it "returns nil when a room has no present or pending reservations" do @@ -43,6 +44,7 @@ end it "performs properly when the room has a reservation that ends on the day on which the method is called" do + @reservation_ending_today = Hotel::Reservation.new(two_days_ago, right_now) end @@ -82,13 +84,13 @@ it "rejects a reservation that begins the same date as the date of the request, if another conflict exists" do end - end describe "add_reservation(reservation)" do it "must add itself to the room's collection of reservations" do end - it "must add the dates of the reservation to the room's collection of unavailable dates" + it "must add the dates of the reservation to the room's collection of unavailable dates" do end + end end From 43f620962efcf07285e9647cc65561978f5a34ae Mon Sep 17 00:00:00 2001 From: Victoria Garcia Date: Thu, 8 Mar 2018 03:18:51 -0800 Subject: [PATCH 11/51] My stars and garters but all the freaking tests for the freaking date generation scheme in Reservation are actually passing. Zounds. --- lib/room.rb | 2 ++ specs/reservation_spec.rb | 63 +++++++++++++++++++-------------------- specs/room_spec.rb | 48 ++++++++++++++--------------- 3 files changed, 57 insertions(+), 56 deletions(-) diff --git a/lib/room.rb b/lib/room.rb index c3f30876a..fb8c36a2b 100644 --- a/lib/room.rb +++ b/lib/room.rb @@ -12,5 +12,7 @@ def initialize(room_number) @reservations = [] @dates_unavailable = [] end + def report_all_reservations + end end end diff --git a/specs/reservation_spec.rb b/specs/reservation_spec.rb index 5cdc5d6c9..fe8fd5139 100644 --- a/specs/reservation_spec.rb +++ b/specs/reservation_spec.rb @@ -55,7 +55,7 @@ before do @nominal_understand_days = @reservation_0_nominal_6n.days_with_am_and_pm_occupation - @start_date_hash = @nominal_understand_days.fetch(@reservation_0_nominal_6n.start_date.jd.to_s) + @end_date_hash = @nominal_understand_days.fetch(@reservation_0_nominal_6n.end_date.jd.to_s) end @@ -68,57 +68,56 @@ end it "must be composed of key-value pairs in which all the keys are Julian dates in string form" do - @nominal_understand_days.each_key.must_be_kind_of String - @nominal_understand_days.each_key.must_match /^24[56]\d{4}$/ + @nominal_understand_days.each do |k, v| + k.must_be_kind_of String + #must_match /^24[56]\d{4}$/ + end end it "must be composed of key-value pairs in which all the values are hashes" do - @nominal_understand_days.each_value.must_be_instance_of Hash + @nominal_understand_days.each do |k, v| + v.must_be_kind_of Hash + end end it "must be composed of key-value pairs in which the value is a hash which contains two keys, :am and :pm" do - @nominal_understand_days.each_value.count.must_equal 2 - @nominal_understand_days.each_value.has_key?(:am).must_equal true - @nominal_understand_days.each_value.has_key?(:pm).must_equal true + @nominal_understand_days.each do |k, v| + v.length.must_equal 2 + v.has_key?(:am).must_equal true + v.has_key?(:pm).must_equal true + end + # + # _value.count.must_equal 2 + # @nominal_understand_days.each_value.has_key?(:am).must_equal true + # @nominal_understand_days.each_value.has_key?(:pm).must_equal true end it "must contain a key-value pair for the start date in which the key is the start date, and the value is a 2-item hash, wherein the :am key's value is 'false' and the :pm key's value is 'true'" do + start_date_am_pm_availability = @nominal_understand_days.assoc(@reservation_0_nominal_6n.start_date.jd.to_s) + @nominal_understand_days.has_key?(@reservation_0_nominal_6n.start_date.jd.to_s).must_equal true - @start_date_hash.count.must_equal 1 - @start_date_hash[1].fetch(:am).must_equal false - @start_date_hash[1].fetch(:pm).must_equal true + start_date_am_pm_availability[1].length.must_equal 2 + start_date_am_pm_availability[1][:am].must_equal false + start_date_am_pm_availability[1][:pm].must_equal true end it "must contain a key-value pair for the end date in which the key is the end date, and the value is a 2-item hash, wherein which the :am key's value is 'true' and the :pm key's value is 'false'" do + end_date_am_pm_availability = @nominal_understand_days.assoc(@reservation_0_nominal_6n.end_date.jd.to_s) @nominal_understand_days.has_key?(@reservation_0_nominal_6n.end_date.jd.to_s).must_equal true - @end_date_hash.count.must_equal 1 - @end_date_hash[1].fetch(:am).must_equal true - @end_date_hash[1].fetch(:pm).must_equal false + # end_date_hash.count.must_equal 1 + end_date_am_pm_availability[1].length.must_equal 2 + end_date_am_pm_availability[1][:am].must_equal true + end_date_am_pm_availability[1][:pm].must_equal false end - it "must include a hash for each FULL DAY (i.e, non-starting or ending day) of the reservation in which the value contains exactly two key-value pairs, one with a key of :am, and one with a key of :pm, and both with a value of 'true'" do + it "must include a hash for each FULL DAY (i.e, non-starting or ending day) of the reservation, in which the values for :am and :pm are both 'true'" do + test_copy_nominal_understand_1 = @nominal_understand_days.dup - no_start_test = (test_copy_nominal_understand_1.delete(@reservation_0_nominal_6n.start_date.jd.to_s)).dup - no_start_or_end_test = (no_start_test.delete(@reservation_0_nominal_6n.end_date.jd.to_s)).dup - first_res_day_julian = @reservation_0_nominal_6n.start_date.jd.to_i - last_res_day_julian = @reservation_0_nominal_6n.end_date.jd.to_i - if last_res_day_julian - first_res_day_julian > 1 - value_array = [] - no_start_or_end_test.each do |full_day| - value_array = [] - full_day.value.each_value{|value| value_array << value} - value_array.must_equal [true, true] - end - key_array = [] - no_start_or_end_test.each_key {|key| key_array << key} - key_array.sort! - key_array.each_with_index do |key, index| - (key.to_i + index + 1).must_equal (first_res_day_julian + index + 1) - end - end + no_start_or_end_days = test_copy_nominal_understand_1.reject {|k, v| k == @reservation_0_nominal_6n.start_date.jd.to_s || k == @reservation_0_nominal_6n.end_date.jd.to_s} + no_start_or_end_days.values.each {|value| value.each { |k, v| v.must_equal true}} end end diff --git a/specs/room_spec.rb b/specs/room_spec.rb index b4a140958..4ede60b35 100644 --- a/specs/room_spec.rb +++ b/specs/room_spec.rb @@ -5,9 +5,9 @@ describe "Room class" do before do - right_now = Time.now.to_s - two_days_ago = Time.at(Time.now.to_i - 172800).to_s - two_days_from_now = Time.at(Time.now.to_i + 172800).to_s + @right_now = Time.now.to_s + @two_days_ago = Time.at(Time.now.to_i - 172800).to_s + @two_days_from_now = Time.at(Time.now.to_i + 172800).to_s @room_300_nominal = Hotel::Room.new("300") @room_400_no_res = Hotel::Room.new("400") @@ -31,27 +31,27 @@ end end - describe "report_all_reservations" do - - it "returns a complete collection of reservations for the room" do - all_nominal_reservations = [@reservation_n1_nominal, @reservation_n2_nominal, @reservation_n3_nominal] - @room_300_nominal.reservations = all_nominal_reservations - @room_300_nominal.report_all_reservations.must_equal all_nominal_reservations - end - - it "returns nil when a room has no present or pending reservations" do - @room_400_no_res.report_alL_reservations.must_be_nil - end - - it "performs properly when the room has a reservation that ends on the day on which the method is called" do - @reservation_ending_today = Hotel::Reservation.new(two_days_ago, right_now) - - end - - it "performs properly when the room has a reservation that ends on the day on which the method is called" do - - end - end + # describe "report_all_reservations" do + # + # it "returns a complete collection of reservations for the room" do + # all_nominal_reservations = [@reservation_n1_nominal, @reservation_n2_nominal, @reservation_n3_nominal] + # @room_300_nominal.reservations = all_nominal_reservations + # @room_300_nominal.report_all_reservations.must_equal all_nominal_reservations + # end + # + # it "returns nil when a room has no present or pending reservations" do + # @room_400_no_res.report_all_reservations.must_be_nil + # end + # + # it "performs properly when the room has a reservation that ends on the day on which the method is called" do + # @reservation_ending_today = Hotel::Reservation.new(@two_days_ago, @right_now) + # + # end + # + # it "performs properly when the room has a reservation that ends on the day on which the method is called" do + # + # end + # end describe "report_availability(date)" do From 77ea867712b90c8e7faaa13cf82df38ad6ba6ac7 Mon Sep 17 00:00:00 2001 From: Victoria Garcia Date: Fri, 9 Mar 2018 14:02:27 -0800 Subject: [PATCH 12/51] Beginning of the room-level lookup system now underway. --- lib/room.rb | 18 ++++++++++++++++++ specs/reservation_spec.rb | 9 +++------ 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/lib/room.rb b/lib/room.rb index fb8c36a2b..5adb34acd 100644 --- a/lib/room.rb +++ b/lib/room.rb @@ -12,7 +12,25 @@ def initialize(room_number) @reservations = [] @dates_unavailable = [] end + def report_all_reservations end + + def report_reservations_for_day(date_julian) + reservation_acceptable = true + unless @dates_unavailable.empty? + dates_unavailable.each do |date| + if reservation.days_booked_am_and_pm.keys.include?(date) + unless ( date[1][:am] == false ^ reservation.days_booked_am_and_pm[date][1][:am] == false) && (date[1][:pm] == false ^ reservation.days_booked_am_and_pm[1][:pm] == false ) + reservation_acceptable = false + end + end + end + end + return reservation_acceptable + end + + def add_reservation(reservation_acceptable?, reservation) + end end end diff --git a/specs/reservation_spec.rb b/specs/reservation_spec.rb index fe8fd5139..d0d666150 100644 --- a/specs/reservation_spec.rb +++ b/specs/reservation_spec.rb @@ -70,7 +70,8 @@ it "must be composed of key-value pairs in which all the keys are Julian dates in string form" do @nominal_understand_days.each do |k, v| k.must_be_kind_of String - #must_match /^24[56]\d{4}$/ + # Conversion note: This test uses a hard-coded seven-date range that starts with Junee 10, 3013 + k.must_match /^2821\d{3}$/ end end @@ -86,10 +87,6 @@ v.has_key?(:am).must_equal true v.has_key?(:pm).must_equal true end - # - # _value.count.must_equal 2 - # @nominal_understand_days.each_value.has_key?(:am).must_equal true - # @nominal_understand_days.each_value.has_key?(:pm).must_equal true end it "must contain a key-value pair for the start date in which the key is the start date, and the value is a 2-item hash, wherein the :am key's value is 'false' and the :pm key's value is 'true'" do @@ -134,7 +131,7 @@ it "correctly calculates the length of a stay that begins in one year and ends in another" do @reservation_3_35n.calculate_total_nights.must_equal 35 end - it "correctly calculates teh length of a stay that is one night long" do + it "correctly calculates the length of a stay that is one night long" do @reservation_1_1n.calculate_total_nights.must_equal 1 end end From 3c5f7ee422f4b00f747ee3c04b6b65626bcc8bd1 Mon Sep 17 00:00:00 2001 From: Victoria Garcia Date: Fri, 9 Mar 2018 14:54:00 -0800 Subject: [PATCH 13/51] A few minor comments in the Reservation class and spec. Got my crazy multipart conditional in Room to run without breaking the room.spec doc, yay me. --- lib/reservation.rb | 10 ++++++++ lib/room.rb | 29 ++++++++++++++++++++--- specs/front_desk_spec.rb | 8 +++++++ specs/reservation_spec.rb | 7 +----- specs/room_spec.rb | 49 +++++++++++++++++++-------------------- 5 files changed, 69 insertions(+), 34 deletions(-) diff --git a/lib/reservation.rb b/lib/reservation.rb index c2f205557..da5244966 100644 --- a/lib/reservation.rb +++ b/lib/reservation.rb @@ -47,6 +47,16 @@ def calculate_total_nights end def days_with_am_and_pm_occupation + # This creates a hash of hashes for the dates within a reservation. For + # each date, the key of the base hash is the date in Julian. The value of + # that hash is a second hash with two key-value pairs, the key of the + # first being :am, and the key of the second being :pm. The values of these + # can be either true or false. + + # For a date in the middle of the hash, the :am and :pm keys will both have + # the value true. For the start date of a reservation, the :am key will + # have the value false, and the :pm key will have the value true. + # The end-date will have a value of true for its :am key and false for its :pm key. first_key = @start_date.jd.to_s last_key = @end_date.jd.to_s start_and_end_days = { diff --git a/lib/room.rb b/lib/room.rb index 5adb34acd..5692a57a5 100644 --- a/lib/room.rb +++ b/lib/room.rb @@ -14,14 +14,34 @@ def initialize(room_number) end def report_all_reservations + all_reservations = nil + unless @reservations.empty? + all_reservations = @reservations + end + return all_reservations end def report_reservations_for_day(date_julian) + end + + def can_accept_reservation?(reservation) reservation_acceptable = true unless @dates_unavailable.empty? dates_unavailable.each do |date| if reservation.days_booked_am_and_pm.keys.include?(date) - unless ( date[1][:am] == false ^ reservation.days_booked_am_and_pm[date][1][:am] == false) && (date[1][:pm] == false ^ reservation.days_booked_am_and_pm[1][:pm] == false ) + am_conflict = nil + pm_conflict = nil + if (date[1][:am] == false) ^ (reservation.days_booked_am_and_pm[date][1][:am] == false) + am_conflict = false + else + am_conflict = true + end + if ( date[1][:pm] == false ) ^ ( reservation.days_booked_am_and_pm[1][:pm] == false ) + pm_conflict = false + else + pm_conflict = true + end + unless am_conflict == false && pm_conflict == false reservation_acceptable = false end end @@ -30,7 +50,10 @@ def report_reservations_for_day(date_julian) return reservation_acceptable end - def add_reservation(reservation_acceptable?, reservation) - end + # def add_reservation(reservation_acceptable?, reservation) + # if can_accept_reservation(reservation) == true + # else #Make an error or something + # end + # end end end diff --git a/specs/front_desk_spec.rb b/specs/front_desk_spec.rb index 4943da820..6d5441505 100644 --- a/specs/front_desk_spec.rb +++ b/specs/front_desk_spec.rb @@ -3,3 +3,11 @@ describe "FrontDesk class" do end + + +# Note: COMMENTING THIS OUT FOR NOW. WILL PROBABLY move this functionality to FrontDesk. +# it "Raises an error if the start date comes before the date of instantiation" do +# too_early_start = '1st Feb 1975' +# acceptible_end = '2nd Feb 3080' +# proc{ Hotel::Reservation.new(too_early_start, acceptible_end) }.must_raise StandardError +# end diff --git a/specs/reservation_spec.rb b/specs/reservation_spec.rb index d0d666150..195617ffb 100644 --- a/specs/reservation_spec.rb +++ b/specs/reservation_spec.rb @@ -25,12 +25,7 @@ @reservation_0_nominal_6n.end_date.must_be_instance_of DateTime end - # Note: COMMENTING THIS OUT FOR NOW. WILL PROBABLY move this functionality to FrontDesk. - # it "Raises an error if the start date comes before the date of instantiation" do - # too_early_start = '1st Feb 1975' - # acceptible_end = '2nd Feb 3080' - # proc{ Hotel::Reservation.new(too_early_start, acceptible_end) }.must_raise StandardError - # end + it "raises an error if the end date is not at least one day after the end date" do late_start = '3rd May 3075' diff --git a/specs/room_spec.rb b/specs/room_spec.rb index 4ede60b35..8f976e9cd 100644 --- a/specs/room_spec.rb +++ b/specs/room_spec.rb @@ -31,38 +31,37 @@ end end - # describe "report_all_reservations" do - # - # it "returns a complete collection of reservations for the room" do - # all_nominal_reservations = [@reservation_n1_nominal, @reservation_n2_nominal, @reservation_n3_nominal] - # @room_300_nominal.reservations = all_nominal_reservations - # @room_300_nominal.report_all_reservations.must_equal all_nominal_reservations - # end - # - # it "returns nil when a room has no present or pending reservations" do - # @room_400_no_res.report_all_reservations.must_be_nil - # end - # - # it "performs properly when the room has a reservation that ends on the day on which the method is called" do - # @reservation_ending_today = Hotel::Reservation.new(@two_days_ago, @right_now) - # - # end - # - # it "performs properly when the room has a reservation that ends on the day on which the method is called" do - # - # end - # end + describe "report_reservations_for_day(date_julian)" do - describe "report_availability(date)" do + #THIS IS WHERE AN IMPORTANT HANDSHAKE BETWEEN RESERVATION AND ROOM NEEDS TO HAPPEN. + it "returns a complete collection of reservations for the room" do + all_nominal_reservations = [@reservation_n1_nominal, @reservation_n2_nominal, @reservation_n3_nominal] + @room_300_nominal.reservations = all_nominal_reservations + @room_300_nominal.report_all_reservations.must_equal all_nominal_reservations + end + + it "returns nil when a room has no present or pending reservations" do + @room_400_no_res.report_all_reservations.must_be_nil + end + + it "performs properly when the room has a reservation that ends on the day on which the method is called" do + @reservation_ending_today = Hotel::Reservation.new(@two_days_ago, @right_now) + + end + + it "performs properly when the room has a reservation that ends on the day on which the method is called" do - it "accurately reports reservations when run for the current day" do end + end - it "accurately reports reservations for a future date" do + describe "report_availability(date)" do + + it "accurately reports reservations when run for a single day" do end - it "accurately reports reservations for a date in the past" do + it "accurately reports reservations for a range of days" do end + end describe "can_accept_reservation?(reservation)" do From 52baa85dff98d317d81e0070af9d804d739e1efb Mon Sep 17 00:00:00 2001 From: Victoria Garcia Date: Fri, 9 Mar 2018 16:27:15 -0800 Subject: [PATCH 14/51] basic functionality for 'add reservation' working in room, with tests passing. now need to add bells and/or whistles for dealing with start and end dates. --- lib/reservation.rb | 4 ++-- lib/room.rb | 27 +++++++++++++++++++-------- specs/room_spec.rb | 43 ++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 61 insertions(+), 13 deletions(-) diff --git a/lib/reservation.rb b/lib/reservation.rb index da5244966..64f5b5afd 100644 --- a/lib/reservation.rb +++ b/lib/reservation.rb @@ -7,8 +7,8 @@ module Hotel class Reservation - attr_accessor :start_date, :end_date - attr_reader :id, :days_booked_am_and_pm, :total_nights, :total_reservation_cost + attr_accessor :start_date, :end_date, :days_booked_am_and_pm + attr_reader :id, :total_nights, :total_reservation_cost @@last_id_base = 0 diff --git a/lib/room.rb b/lib/room.rb index 5692a57a5..2b7119c67 100644 --- a/lib/room.rb +++ b/lib/room.rb @@ -10,7 +10,7 @@ class Room def initialize(room_number) @room_number = room_number @reservations = [] - @dates_unavailable = [] + @dates_unavailable = {} end def report_all_reservations @@ -22,12 +22,15 @@ def report_all_reservations end def report_reservations_for_day(date_julian) + # THIS NEEDS TO BE TESTED AFTER THE RESERVATION-ADDING MECHANICS GO IN, BECAUSE IT WILL READ FROM 'Dates Unavailable.' end def can_accept_reservation?(reservation) - reservation_acceptable = true + reservation_acceptable = {:accept => true, :resolve_conflict => false} + resolve_date_conflict = [] unless @dates_unavailable.empty? dates_unavailable.each do |date| + # Note: I originally had the am/pm conflict checking written as a single, long, one-line thing, but that made minitest loose its mind, so now it's in all these little chunks. if reservation.days_booked_am_and_pm.keys.include?(date) am_conflict = nil pm_conflict = nil @@ -42,18 +45,26 @@ def can_accept_reservation?(reservation) pm_conflict = true end unless am_conflict == false && pm_conflict == false - reservation_acceptable = false + reservation_acceptable = {:accept => false, :resolve_conflict => nil} + else + resolve_date_conflict << date end end end + reservation_accetable = {:accept => true, :resolve_conflict => resolve_date_conflict} end return reservation_acceptable end - # def add_reservation(reservation_acceptable?, reservation) - # if can_accept_reservation(reservation) == true - # else #Make an error or something - # end - # end + def add_reservation(new_reservation) + #PROCESS NOTES: THink I'm going to write this method, then add in the rejection mechanics, even tough the rejection mechanics are already kind of there. The commented-out if/else business below will be retrofitted on. + # if can_accept_reservation(reservation) == true + # else #Make an error or something + # end + @reservations << new_reservation + @dates_unavailable.merge!(new_reservation.days_booked_am_and_pm) + + + end end end diff --git a/specs/room_spec.rb b/specs/room_spec.rb index 8f976e9cd..aee43d00d 100644 --- a/specs/room_spec.rb +++ b/specs/room_spec.rb @@ -31,7 +31,7 @@ end end - describe "report_reservations_for_day(date_julian)" do + describe "report_all_reservations" do #THIS IS WHERE AN IMPORTANT HANDSHAKE BETWEEN RESERVATION AND ROOM NEEDS TO HAPPEN. it "returns a complete collection of reservations for the room" do @@ -54,7 +54,7 @@ end end - describe "report_availability(date)" do + describe "report_availability_for_day(date_julian)" do it "accurately reports reservations when run for a single day" do end @@ -85,11 +85,48 @@ end end - describe "add_reservation(reservation)" do + describe "add_reservation(new_reservation)" do + + it "must add itself to the room's collection of reservations" do + + @room_300_nominal.reservations << @reservation_n1_nominal + before_reservations = @room_300_nominal.reservations.dup + before_count = before_reservations.count + @room_300_nominal.add_reservation(@reservation_n2_nominal) + + # The two assertions below just test the test + before_reservations.must_include @reservation_n1_nominal + before_count.must_equal 1 + + @room_300_nominal.reservations.count.must_equal 2 + @room_300_nominal.reservations.must_include @reservation_n1_nominal + @room_300_nominal.reservations.must_include @reservation_n2_nominal + end + + it "performs properly if a room has no other pending reservations" do + + before_reservations = @room_400_no_res.reservations.dup + @room_400_no_res.add_reservation(@reservation_n3_nominal) + + #The assertion below just tests the test + before_reservations.must_be_empty + + @room_400_no_res.reservations.count.must_equal 1 + @room_400_no_res.reservations.must_include @reservation_n3_nominal + end it "must add the dates of the reservation to the room's collection of unavailable dates" do + + before_unavailables = @room_300_nominal.dates_unavailable.dup + before_unavailables.count.must_equal 0 + + @room_300_nominal.add_reservation(@reservation_n1_nominal) + @room_300_nominal.dates_unavailable.count.must_equal 7 + @room_300_nominal.dates_unavailable.keys.must_include "2821697" + end + end end From 52cdb0ce5452cad51f8cd4cac752ac3ccba84bf2 Mon Sep 17 00:00:00 2001 From: Victoria Garcia Date: Fri, 9 Mar 2018 18:28:21 -0800 Subject: [PATCH 15/51] tests for conflict-checking mechanism in room are failing in the desired way. --- lib/room.rb | 50 ++++++++++++---------- specs/room_spec.rb | 104 +++++++++++++++++++++++++++++++++++++-------- 2 files changed, 115 insertions(+), 39 deletions(-) diff --git a/lib/room.rb b/lib/room.rb index 2b7119c67..8c0a3016a 100644 --- a/lib/room.rb +++ b/lib/room.rb @@ -29,29 +29,37 @@ def can_accept_reservation?(reservation) reservation_acceptable = {:accept => true, :resolve_conflict => false} resolve_date_conflict = [] unless @dates_unavailable.empty? - dates_unavailable.each do |date| - # Note: I originally had the am/pm conflict checking written as a single, long, one-line thing, but that made minitest loose its mind, so now it's in all these little chunks. - if reservation.days_booked_am_and_pm.keys.include?(date) - am_conflict = nil - pm_conflict = nil - if (date[1][:am] == false) ^ (reservation.days_booked_am_and_pm[date][1][:am] == false) - am_conflict = false - else - am_conflict = true - end - if ( date[1][:pm] == false ) ^ ( reservation.days_booked_am_and_pm[1][:pm] == false ) - pm_conflict = false - else - pm_conflict = true - end - unless am_conflict == false && pm_conflict == false - reservation_acceptable = {:accept => false, :resolve_conflict => nil} - else - resolve_date_conflict << date + unless reservation_acceptable[:accept] == false + dates_unavailable.each do |date| + # Note: I originally had the am/pm conflict checking written as a single, long, one-line thing, but that made minitest loose its mind, so now it's in all these little chunks. + if reservation.days_booked_am_and_pm.keys.include?(date) + am_conflict = nil + pm_conflict = nil + if (date[1][:am] == false) ^ (reservation.days_booked_am_and_pm[date][1][:am] == false) + am_conflict = false + else + am_conflict = true + end + if ( date[1][:pm] == false ) ^ ( reservation.days_booked_am_and_pm[1][:pm] == false ) + pm_conflict = false + else + pm_conflict = true + end + unless am_conflict == false && pm_conflict == false + reservation_acceptable = {:accept => false, :resolve_conflict => false} + else + resolve_date_conflict << date + end end end end - reservation_accetable = {:accept => true, :resolve_conflict => resolve_date_conflict} + end + unless reservation_acceptable[:accept] == false + if resolve_date_conflict.any? + reservation_acceptable[:resolve_conflict] = resolve_date_conflict + else + reservation_acceptable[:resolve_conflict] = false + end end return reservation_acceptable end @@ -63,8 +71,6 @@ def add_reservation(new_reservation) # end @reservations << new_reservation @dates_unavailable.merge!(new_reservation.days_booked_am_and_pm) - - end end end diff --git a/specs/room_spec.rb b/specs/room_spec.rb index aee43d00d..4397e3879 100644 --- a/specs/room_spec.rb +++ b/specs/room_spec.rb @@ -11,13 +11,22 @@ @room_300_nominal = Hotel::Room.new("300") @room_400_no_res = Hotel::Room.new("400") + @room_500_misc_tests = Hotel::Room.new("500") @reservation_n1_nominal = Hotel::Reservation.new('10th Jun 3013', '16th Jun 3013') + @reservation_n2_nominal = Hotel::Reservation.new('10th Jun 3014', '16th Jun 3014') + @reservation_n3_nominal = Hotel::Reservation.new('10th Oct 3015', '9th Dec 3015') + + @reservation_0_precedes_n1_directly = Hotel::Reservation.new('5th Jun 3013', '10th Jun 3013') @reservation_1_follows_n1_directly = Hotel::Reservation.new('16th Oct 3013', '2nd Nov 3013') @reservation_2_overlaps_n1_beginning = Hotel::Reservation.new('8th Jun 3013', '11th Jun 3013') @reservation_3_overlaps_n1_end = Hotel::Reservation.new('15th Jun 3013', '5th Jul 3013') - @reservation_n2_nominal = Hotel::Reservation.new('10th Jun 3014', '16th Jun 3014') - @reservation_n3_nominal = Hotel::Reservation.new('10th Oct 3015', '9th Dec 3015') + @reservation_4_overlaps_n1_precedes_n2 = Hotel::Reservation.new('14th Jun 3013', '10th Jun 3014') + @reservation_5_follows_n1_precedes_n2 = Hotel::Reservation.new('16th Jun 3013', '10th Jun 3014') + + @reservation_a_single_night = Hotel::Reservation.new('1st Nov 3013', '2nd Nov 3013') + @reservation_b_single_night = Hotel::Reservation.new('1st Nov 3013', '2nd Nov 3013') + end describe "initialize(room_number)" do it "must have a room number encoded as a string" do @@ -44,14 +53,6 @@ @room_400_no_res.report_all_reservations.must_be_nil end - it "performs properly when the room has a reservation that ends on the day on which the method is called" do - @reservation_ending_today = Hotel::Reservation.new(@two_days_ago, @right_now) - - end - - it "performs properly when the room has a reservation that ends on the day on which the method is called" do - - end end describe "report_availability_for_day(date_julian)" do @@ -66,22 +67,92 @@ describe "can_accept_reservation?(reservation)" do - it "returns true if the proposed reservation does not conflict with an existing reservation" do + before do + @room_300_nominal.add_reservation(@reservation_n1_nominal) + end + + it "returns the value '{:accept => true, :resolve_conflict => false}' if the proposed reservation does not conflict with or share a starting/ending date with an existing reservation" do + + acceptability_result = @room_300_nominal.can_accept_reservation?(@reservation_n2_nominal) + + acceptability_result[:accept].must_equal true + acceptability_result[:resolve_conflict].must_equal true + + end + + it "gives a value {:accept => false, :resolve_conflict => false} for a new reservation that has a whole-day conflict with an existing reservation " do + + early_conflict_result = @room_300_nominal.can_accept_reservation?(@reservation_2_overlaps_n1_beginning) + late_conflict_result = @room_300_nominal.can_accept_reservation?(@reservation_3_overlaps_n1_end) + + early_conflict_result[:accept].must_equal false + early_conflict_result[:resolve_conflict].must_equal false + + late_conflict_result[:accept].must_equal false + late_conflict_result[:resolve_conflict].must_equal false end - it "returns false if the proposed reservation conflicts with an existing reservation" do + it "gives a value {:accept => false, :resolve_conflict => false} for a one-night reservation that conflicts with an existing one-night reservation" do + + @room_500_misc_tests.add_reservation(@reservation_a_single_night) + single_day_conf_result = @room_500_misc_tests.can_accept_reservation?(@reservation_b_single_night) + + single_day_conf_result[:accept].must_equal false + single_day_conf_result[:resolve_conflict].must_equal false + end - it "accepts a reservation when the start date is the same as the date of the request, assuming no other conflicts" do + it "gives a value {:accept => false, :resolve_conflict => false} when there is an acceptable start-and-end conflict with one existing reservation, and a full-day conflict with another reservation" do + + @room_300_nominal.add_reservation(@reservation_n2_nominal) + + acceptible_and_not_result = @room_300_nominal.can_accept_reservation?(@reservation_4_overlaps_n1_precedes_n2) + + acceptible_and_not_result[:accept].must_equal false + acceptible_and_not_result[:resolve_conflict].must_equal false + end - it "accepts a reservation that begins the same day another reservation ends, assuming no other conflicts" do + it "gives a value of {:accept => true, :resolve_conflict => [foo1], where foo1 is a hash of the date of the start-date/end-date overlap, when a proposed reservation starts on the day an existing reservation ends" do + + follows_result = @room_300_nominal.can_accept_reservation?(@reservation_1_follows_n1_directly) + + follows_result[:accept].must_equal true + follows_result[:resolve_conflict].must_be_kind_of Array + follows_result[:resolve_conflict].count.must_equal 1 + follows_result[:resolve_conflict][0].must_be_kind_of Hash + # Note: This number is the date of the start-end overlap, respresented as a Julian date in string form. + follows_result[:resolve_conflict][0][0].must_equal "2821701" + end - it "accepts a reservation when its start date, the date of the request, and the end date of another reservation are all the same, assuming o other conflicts" do + it "gives a value of {:accept => true, :resolve_conflict => [foo1], where foo1 is a hash of the date of the start-date/end-date overlap, when a proposed reservation ends on the day an existing reservation starts" do + + precedes_result = @room_300_nominal.can_accept_reservation?(@reservation_0_precedes_n1_directly) + + precedes_result[:accept].must_equal true + precedes_result[:resolve_conflict].must_be_kind_of Array + precedes_result[:resolve_conflict].count.must_equal 1 + precedes_result[:resolve_conflict][0].must_be_kind_of Hash + # Note: This number is the date of the start-end overlap, respresented as a Julian date in string form. + follows_result[:resolve_conflict][0][0].must_equal "2821695" + end - it "rejects a reservation that begins the same date as the date of the request, if another conflict exists" do + it "gives a value of {:accept => false, :resolve_conflict => [foo1, foo2], where foo1 and foo2 are hashes of the dates of the start-date/end-date overlaps, when a proposed reservation starts on the day an existing reservation ends, and ends on the day an existing reservation starts" do + + @room_300_nominal.add_reservation(@reservation_n2_nominal) + in_middle_result = @room_300_nominal.can_accept_reservation?(@reservation_5_follows_n1_precedes_n2) + + in_middle_result[:accept].must_equal true + in_middle_result[:resolve_conflict].must_be_kind_of Array + in_middle_result[:resolve_conflict].count.must_equal 2 + in_middle_result[:resolve_conflict][0].must_be_kind_of Hash + # Note: This number is the date of the first start-end overlap, respresented as a Julian date in string form. + in_middle_result[:resolve_conflict][0][0].must_equal "2821701" + in_middle_result[:resolve_conflict][1].must_be_kind_of Hash + # Note: This number is the date of the second start-end overlap, respresented as a Julian date in string form. + in_middle_result[:resolve_conflict][1][0].must_equal "2822060" end end @@ -125,7 +196,6 @@ @room_300_nominal.add_reservation(@reservation_n1_nominal) @room_300_nominal.dates_unavailable.count.must_equal 7 @room_300_nominal.dates_unavailable.keys.must_include "2821697" - end end From fa8d67fafd8b562a234e16a4183730601aaaa524 Mon Sep 17 00:00:00 2001 From: Victoria Garcia Date: Fri, 9 Mar 2018 19:20:47 -0800 Subject: [PATCH 16/51] a whole bunch of the tests for the conflict-checking machinery are now passing. --- lib/room.rb | 23 ++++++++++++++--- specs/room_spec.rb | 61 +++++++++++++++++++++++----------------------- 2 files changed, 50 insertions(+), 34 deletions(-) diff --git a/lib/room.rb b/lib/room.rb index 8c0a3016a..5b7271f33 100644 --- a/lib/room.rb +++ b/lib/room.rb @@ -1,4 +1,5 @@ require 'date' +require 'pry' require_relative 'reservation' require_relative 'front_desk' @@ -29,38 +30,52 @@ def can_accept_reservation?(reservation) reservation_acceptable = {:accept => true, :resolve_conflict => false} resolve_date_conflict = [] unless @dates_unavailable.empty? + puts "unless at 33" unless reservation_acceptable[:accept] == false - dates_unavailable.each do |date| + puts "unless at 35" + @dates_unavailable.each do |booked_date| # Note: I originally had the am/pm conflict checking written as a single, long, one-line thing, but that made minitest loose its mind, so now it's in all these little chunks. - if reservation.days_booked_am_and_pm.keys.include?(date) + date = booked_date + if reservation.days_booked_am_and_pm.keys.include?(date[0]) am_conflict = nil pm_conflict = nil - if (date[1][:am] == false) ^ (reservation.days_booked_am_and_pm[date][1][:am] == false) + puts "if at 42" + if (date[1][:am] == false) ^ (reservation.days_booked_am_and_pm[date[0]][:am] == false) am_conflict = false + puts "if at 45" else am_conflict = true + puts "else at 46" end - if ( date[1][:pm] == false ) ^ ( reservation.days_booked_am_and_pm[1][:pm] == false ) + if (date[1][:pm] == false) ^ (reservation.days_booked_am_and_pm[date[0]][:pm] == false) pm_conflict = false + puts "if at 52" else pm_conflict = true + puts "else at 53" end unless am_conflict == false && pm_conflict == false reservation_acceptable = {:accept => false, :resolve_conflict => false} + puts "unless at 59" else resolve_date_conflict << date + puts "else at 62" end end end end end unless reservation_acceptable[:accept] == false + puts "unless at 69" if resolve_date_conflict.any? reservation_acceptable[:resolve_conflict] = resolve_date_conflict + puts "if at 72" else reservation_acceptable[:resolve_conflict] = false + puts "else at 75" end end + puts "end at 78" return reservation_acceptable end diff --git a/specs/room_spec.rb b/specs/room_spec.rb index 4397e3879..ff7458ec8 100644 --- a/specs/room_spec.rb +++ b/specs/room_spec.rb @@ -76,7 +76,7 @@ acceptability_result = @room_300_nominal.can_accept_reservation?(@reservation_n2_nominal) acceptability_result[:accept].must_equal true - acceptability_result[:resolve_conflict].must_equal true + acceptability_result[:resolve_conflict].must_equal false end @@ -85,6 +85,7 @@ early_conflict_result = @room_300_nominal.can_accept_reservation?(@reservation_2_overlaps_n1_beginning) late_conflict_result = @room_300_nominal.can_accept_reservation?(@reservation_3_overlaps_n1_end) + early_conflict_result[:accept].must_equal false early_conflict_result[:resolve_conflict].must_equal false @@ -125,35 +126,35 @@ follows_result[:resolve_conflict][0][0].must_equal "2821701" end - - it "gives a value of {:accept => true, :resolve_conflict => [foo1], where foo1 is a hash of the date of the start-date/end-date overlap, when a proposed reservation ends on the day an existing reservation starts" do - - precedes_result = @room_300_nominal.can_accept_reservation?(@reservation_0_precedes_n1_directly) - - precedes_result[:accept].must_equal true - precedes_result[:resolve_conflict].must_be_kind_of Array - precedes_result[:resolve_conflict].count.must_equal 1 - precedes_result[:resolve_conflict][0].must_be_kind_of Hash - # Note: This number is the date of the start-end overlap, respresented as a Julian date in string form. - follows_result[:resolve_conflict][0][0].must_equal "2821695" - - end - - it "gives a value of {:accept => false, :resolve_conflict => [foo1, foo2], where foo1 and foo2 are hashes of the dates of the start-date/end-date overlaps, when a proposed reservation starts on the day an existing reservation ends, and ends on the day an existing reservation starts" do - - @room_300_nominal.add_reservation(@reservation_n2_nominal) - in_middle_result = @room_300_nominal.can_accept_reservation?(@reservation_5_follows_n1_precedes_n2) - - in_middle_result[:accept].must_equal true - in_middle_result[:resolve_conflict].must_be_kind_of Array - in_middle_result[:resolve_conflict].count.must_equal 2 - in_middle_result[:resolve_conflict][0].must_be_kind_of Hash - # Note: This number is the date of the first start-end overlap, respresented as a Julian date in string form. - in_middle_result[:resolve_conflict][0][0].must_equal "2821701" - in_middle_result[:resolve_conflict][1].must_be_kind_of Hash - # Note: This number is the date of the second start-end overlap, respresented as a Julian date in string form. - in_middle_result[:resolve_conflict][1][0].must_equal "2822060" - end + # + # it "gives a value of {:accept => true, :resolve_conflict => [foo1], where foo1 is a hash of the date of the start-date/end-date overlap, when a proposed reservation ends on the day an existing reservation starts" do + # + # precedes_result = @room_300_nominal.can_accept_reservation?(@reservation_0_precedes_n1_directly) + # + # precedes_result[:accept].must_equal true + # precedes_result[:resolve_conflict].must_be_kind_of Array + # precedes_result[:resolve_conflict].count.must_equal 1 + # precedes_result[:resolve_conflict][0].must_be_kind_of Hash + # # Note: This number is the date of the start-end overlap, respresented as a Julian date in string form. + # follows_result[:resolve_conflict][0][0].must_equal "2821695" + # + # end + # + # it "gives a value of {:accept => false, :resolve_conflict => [foo1, foo2], where foo1 and foo2 are hashes of the dates of the start-date/end-date overlaps, when a proposed reservation starts on the day an existing reservation ends, and ends on the day an existing reservation starts" do + # + # @room_300_nominal.add_reservation(@reservation_n2_nominal) + # in_middle_result = @room_300_nominal.can_accept_reservation?(@reservation_5_follows_n1_precedes_n2) + # + # in_middle_result[:accept].must_equal true + # in_middle_result[:resolve_conflict].must_be_kind_of Array + # in_middle_result[:resolve_conflict].count.must_equal 2 + # in_middle_result[:resolve_conflict][0].must_be_kind_of Hash + # # Note: This number is the date of the first start-end overlap, respresented as a Julian date in string form. + # in_middle_result[:resolve_conflict][0][0].must_equal "2821701" + # in_middle_result[:resolve_conflict][1].must_be_kind_of Hash + # # Note: This number is the date of the second start-end overlap, respresented as a Julian date in string form. + # in_middle_result[:resolve_conflict][1][0].must_equal "2822060" + # end end describe "add_reservation(new_reservation)" do From b0e3aa377a975087657d152c1f155103ece4b01d Mon Sep 17 00:00:00 2001 From: Victoria Garcia Date: Fri, 9 Mar 2018 20:16:30 -0800 Subject: [PATCH 17/51] closer to functional with the conflict-checking mechanism. One more major test green. --- lib/room.rb | 3 +- specs/room_spec.rb | 74 ++++++++++++++++++++++---------------------- specs/spec_helper.rb | 1 + 3 files changed, 40 insertions(+), 38 deletions(-) diff --git a/lib/room.rb b/lib/room.rb index 5b7271f33..b24707f63 100644 --- a/lib/room.rb +++ b/lib/room.rb @@ -58,7 +58,8 @@ def can_accept_reservation?(reservation) reservation_acceptable = {:accept => false, :resolve_conflict => false} puts "unless at 59" else - resolve_date_conflict << date + conflicted_date_hash = {booked_date[0] => booked_date[1]} + resolve_date_conflict << conflicted_date_hash puts "else at 62" end end diff --git a/specs/room_spec.rb b/specs/room_spec.rb index ff7458ec8..6225eed51 100644 --- a/specs/room_spec.rb +++ b/specs/room_spec.rb @@ -18,7 +18,7 @@ @reservation_n3_nominal = Hotel::Reservation.new('10th Oct 3015', '9th Dec 3015') @reservation_0_precedes_n1_directly = Hotel::Reservation.new('5th Jun 3013', '10th Jun 3013') - @reservation_1_follows_n1_directly = Hotel::Reservation.new('16th Oct 3013', '2nd Nov 3013') + @reservation_1_follows_n1_directly = Hotel::Reservation.new('16th Jun 3013', '2nd Jul 3013') @reservation_2_overlaps_n1_beginning = Hotel::Reservation.new('8th Jun 3013', '11th Jun 3013') @reservation_3_overlaps_n1_end = Hotel::Reservation.new('15th Jun 3013', '5th Jul 3013') @reservation_4_overlaps_n1_precedes_n2 = Hotel::Reservation.new('14th Jun 3013', '10th Jun 3014') @@ -71,7 +71,7 @@ @room_300_nominal.add_reservation(@reservation_n1_nominal) end - it "returns the value '{:accept => true, :resolve_conflict => false}' if the proposed reservation does not conflict with or share a starting/ending date with an existing reservation" do + xit "returns the value '{:accept => true, :resolve_conflict => false}' if the proposed reservation does not conflict with or share a starting/ending date with an existing reservation" do acceptability_result = @room_300_nominal.can_accept_reservation?(@reservation_n2_nominal) @@ -80,7 +80,7 @@ end - it "gives a value {:accept => false, :resolve_conflict => false} for a new reservation that has a whole-day conflict with an existing reservation " do + xit "gives a value {:accept => false, :resolve_conflict => false} for a new reservation that has a whole-day conflict with an existing reservation " do early_conflict_result = @room_300_nominal.can_accept_reservation?(@reservation_2_overlaps_n1_beginning) late_conflict_result = @room_300_nominal.can_accept_reservation?(@reservation_3_overlaps_n1_end) @@ -93,7 +93,7 @@ late_conflict_result[:resolve_conflict].must_equal false end - it "gives a value {:accept => false, :resolve_conflict => false} for a one-night reservation that conflicts with an existing one-night reservation" do + xit "gives a value {:accept => false, :resolve_conflict => false} for a one-night reservation that conflicts with an existing one-night reservation" do @room_500_misc_tests.add_reservation(@reservation_a_single_night) single_day_conf_result = @room_500_misc_tests.can_accept_reservation?(@reservation_b_single_night) @@ -103,7 +103,7 @@ end - it "gives a value {:accept => false, :resolve_conflict => false} when there is an acceptable start-and-end conflict with one existing reservation, and a full-day conflict with another reservation" do + xit "gives a value {:accept => false, :resolve_conflict => false} when there is an acceptable start-and-end conflict with one existing reservation, and a full-day conflict with another reservation" do @room_300_nominal.add_reservation(@reservation_n2_nominal) @@ -123,38 +123,38 @@ follows_result[:resolve_conflict].count.must_equal 1 follows_result[:resolve_conflict][0].must_be_kind_of Hash # Note: This number is the date of the start-end overlap, respresented as a Julian date in string form. - follows_result[:resolve_conflict][0][0].must_equal "2821701" - - end - # - # it "gives a value of {:accept => true, :resolve_conflict => [foo1], where foo1 is a hash of the date of the start-date/end-date overlap, when a proposed reservation ends on the day an existing reservation starts" do - # - # precedes_result = @room_300_nominal.can_accept_reservation?(@reservation_0_precedes_n1_directly) - # - # precedes_result[:accept].must_equal true - # precedes_result[:resolve_conflict].must_be_kind_of Array - # precedes_result[:resolve_conflict].count.must_equal 1 - # precedes_result[:resolve_conflict][0].must_be_kind_of Hash - # # Note: This number is the date of the start-end overlap, respresented as a Julian date in string form. - # follows_result[:resolve_conflict][0][0].must_equal "2821695" - # - # end - # - # it "gives a value of {:accept => false, :resolve_conflict => [foo1, foo2], where foo1 and foo2 are hashes of the dates of the start-date/end-date overlaps, when a proposed reservation starts on the day an existing reservation ends, and ends on the day an existing reservation starts" do - # - # @room_300_nominal.add_reservation(@reservation_n2_nominal) - # in_middle_result = @room_300_nominal.can_accept_reservation?(@reservation_5_follows_n1_precedes_n2) - # - # in_middle_result[:accept].must_equal true - # in_middle_result[:resolve_conflict].must_be_kind_of Array - # in_middle_result[:resolve_conflict].count.must_equal 2 - # in_middle_result[:resolve_conflict][0].must_be_kind_of Hash - # # Note: This number is the date of the first start-end overlap, respresented as a Julian date in string form. - # in_middle_result[:resolve_conflict][0][0].must_equal "2821701" - # in_middle_result[:resolve_conflict][1].must_be_kind_of Hash - # # Note: This number is the date of the second start-end overlap, respresented as a Julian date in string form. - # in_middle_result[:resolve_conflict][1][0].must_equal "2822060" - # end + follows_result[:resolve_conflict][0].keys.must_include "2821702" + + end + + xit "gives a value of {:accept => true, :resolve_conflict => [foo1], where foo1 is a hash of the date of the start-date/end-date overlap, when a proposed reservation ends on the day an existing reservation starts" do + + precedes_result = @room_300_nominal.can_accept_reservation?(@reservation_0_precedes_n1_directly) + + precedes_result[:accept].must_equal true + precedes_result[:resolve_conflict].must_be_kind_of Array + precedes_result[:resolve_conflict].count.must_equal 1 + precedes_result[:resolve_conflict][0].must_be_kind_of Hash + # Note: This number is the date of the start-end overlap, respresented as a Julian date in string form. + follows_result[:resolve_conflict][0][0].must_equal "2821695" + + end + + xit "gives a value of {:accept => false, :resolve_conflict => [foo1, foo2], where foo1 and foo2 are hashes of the dates of the start-date/end-date overlaps, when a proposed reservation starts on the day an existing reservation ends, and ends on the day an existing reservation starts" do + + @room_300_nominal.add_reservation(@reservation_n2_nominal) + in_middle_result = @room_300_nominal.can_accept_reservation?(@reservation_5_follows_n1_precedes_n2) + + in_middle_result[:accept].must_equal true + in_middle_result[:resolve_conflict].must_be_kind_of Array + in_middle_result[:resolve_conflict].count.must_equal 2 + in_middle_result[:resolve_conflict][0].must_be_kind_of Hash + # Note: This number is the date of the first start-end overlap, respresented as a Julian date in string form. + in_middle_result[:resolve_conflict][0][0].must_equal "2821701" + in_middle_result[:resolve_conflict][1].must_be_kind_of Hash + # Note: This number is the date of the second start-end overlap, respresented as a Julian date in string form. + in_middle_result[:resolve_conflict][1][0].must_equal "2822060" + end end describe "add_reservation(new_reservation)" do diff --git a/specs/spec_helper.rb b/specs/spec_helper.rb index 12195a700..ed1ccc2a3 100644 --- a/specs/spec_helper.rb +++ b/specs/spec_helper.rb @@ -3,6 +3,7 @@ require 'date' require 'minitest' +require 'minitest/skip_dsl' require 'minitest/autorun' require 'minitest/reporters' From aaf782fd22610bbeed8f978123c31e84c521c1a6 Mon Sep 17 00:00:00 2001 From: Victoria Garcia Date: Fri, 9 Mar 2018 20:30:12 -0800 Subject: [PATCH 18/51] all tests passing for the conflict-checking system in Room. Also, added the kind of skips I like to the spec helper doc. --- specs/room_spec.rb | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/specs/room_spec.rb b/specs/room_spec.rb index 6225eed51..c8c625c5b 100644 --- a/specs/room_spec.rb +++ b/specs/room_spec.rb @@ -71,7 +71,7 @@ @room_300_nominal.add_reservation(@reservation_n1_nominal) end - xit "returns the value '{:accept => true, :resolve_conflict => false}' if the proposed reservation does not conflict with or share a starting/ending date with an existing reservation" do + it "returns the value '{:accept => true, :resolve_conflict => false}' if the proposed reservation does not conflict with or share a starting/ending date with an existing reservation" do acceptability_result = @room_300_nominal.can_accept_reservation?(@reservation_n2_nominal) @@ -80,7 +80,7 @@ end - xit "gives a value {:accept => false, :resolve_conflict => false} for a new reservation that has a whole-day conflict with an existing reservation " do + it "gives a value {:accept => false, :resolve_conflict => false} for a new reservation that has a whole-day conflict with an existing reservation " do early_conflict_result = @room_300_nominal.can_accept_reservation?(@reservation_2_overlaps_n1_beginning) late_conflict_result = @room_300_nominal.can_accept_reservation?(@reservation_3_overlaps_n1_end) @@ -93,7 +93,7 @@ late_conflict_result[:resolve_conflict].must_equal false end - xit "gives a value {:accept => false, :resolve_conflict => false} for a one-night reservation that conflicts with an existing one-night reservation" do + it "gives a value {:accept => false, :resolve_conflict => false} for a one-night reservation that conflicts with an existing one-night reservation" do @room_500_misc_tests.add_reservation(@reservation_a_single_night) single_day_conf_result = @room_500_misc_tests.can_accept_reservation?(@reservation_b_single_night) @@ -103,7 +103,7 @@ end - xit "gives a value {:accept => false, :resolve_conflict => false} when there is an acceptable start-and-end conflict with one existing reservation, and a full-day conflict with another reservation" do + it "gives a value {:accept => false, :resolve_conflict => false} when there is an acceptable start-and-end conflict with one existing reservation, and a full-day conflict with another reservation" do @room_300_nominal.add_reservation(@reservation_n2_nominal) @@ -127,7 +127,7 @@ end - xit "gives a value of {:accept => true, :resolve_conflict => [foo1], where foo1 is a hash of the date of the start-date/end-date overlap, when a proposed reservation ends on the day an existing reservation starts" do + it "gives a value of {:accept => true, :resolve_conflict => [foo1], where foo1 is a hash of the date of the start-date/end-date overlap, when a proposed reservation ends on the day an existing reservation starts" do precedes_result = @room_300_nominal.can_accept_reservation?(@reservation_0_precedes_n1_directly) @@ -136,11 +136,11 @@ precedes_result[:resolve_conflict].count.must_equal 1 precedes_result[:resolve_conflict][0].must_be_kind_of Hash # Note: This number is the date of the start-end overlap, respresented as a Julian date in string form. - follows_result[:resolve_conflict][0][0].must_equal "2821695" + precedes_result[:resolve_conflict][0].keys.must_include "2821696" end - xit "gives a value of {:accept => false, :resolve_conflict => [foo1, foo2], where foo1 and foo2 are hashes of the dates of the start-date/end-date overlaps, when a proposed reservation starts on the day an existing reservation ends, and ends on the day an existing reservation starts" do + it "gives a value of {:accept => false, :resolve_conflict => [foo1, foo2], where foo1 and foo2 are hashes of the dates of the start-date/end-date overlaps, when a proposed reservation starts on the day an existing reservation ends, and ends on the day an existing reservation starts" do @room_300_nominal.add_reservation(@reservation_n2_nominal) in_middle_result = @room_300_nominal.can_accept_reservation?(@reservation_5_follows_n1_precedes_n2) @@ -150,10 +150,10 @@ in_middle_result[:resolve_conflict].count.must_equal 2 in_middle_result[:resolve_conflict][0].must_be_kind_of Hash # Note: This number is the date of the first start-end overlap, respresented as a Julian date in string form. - in_middle_result[:resolve_conflict][0][0].must_equal "2821701" + in_middle_result[:resolve_conflict][0].keys.must_include "2821702" in_middle_result[:resolve_conflict][1].must_be_kind_of Hash # Note: This number is the date of the second start-end overlap, respresented as a Julian date in string form. - in_middle_result[:resolve_conflict][1][0].must_equal "2822060" + in_middle_result[:resolve_conflict][1].keys.must_include "2822061" end end From 3a173528ef80e73d61cf40bafd972acbacb06f9f Mon Sep 17 00:00:00 2001 From: Victoria Garcia Date: Fri, 9 Mar 2018 21:10:31 -0800 Subject: [PATCH 19/51] tests for date conflict resolution helper method written and failing properly. --- lib/room.rb | 11 --------- specs/room_spec.rb | 56 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 11 deletions(-) diff --git a/lib/room.rb b/lib/room.rb index b24707f63..87f51e5cd 100644 --- a/lib/room.rb +++ b/lib/room.rb @@ -39,44 +39,33 @@ def can_accept_reservation?(reservation) if reservation.days_booked_am_and_pm.keys.include?(date[0]) am_conflict = nil pm_conflict = nil - puts "if at 42" if (date[1][:am] == false) ^ (reservation.days_booked_am_and_pm[date[0]][:am] == false) am_conflict = false - puts "if at 45" else am_conflict = true - puts "else at 46" end if (date[1][:pm] == false) ^ (reservation.days_booked_am_and_pm[date[0]][:pm] == false) pm_conflict = false - puts "if at 52" else pm_conflict = true - puts "else at 53" end unless am_conflict == false && pm_conflict == false reservation_acceptable = {:accept => false, :resolve_conflict => false} - puts "unless at 59" else conflicted_date_hash = {booked_date[0] => booked_date[1]} resolve_date_conflict << conflicted_date_hash - puts "else at 62" end end end end end unless reservation_acceptable[:accept] == false - puts "unless at 69" if resolve_date_conflict.any? reservation_acceptable[:resolve_conflict] = resolve_date_conflict - puts "if at 72" else reservation_acceptable[:resolve_conflict] = false - puts "else at 75" end end - puts "end at 78" return reservation_acceptable end diff --git a/specs/room_spec.rb b/specs/room_spec.rb index c8c625c5b..78dece2d4 100644 --- a/specs/room_spec.rb +++ b/specs/room_spec.rb @@ -12,6 +12,7 @@ @room_300_nominal = Hotel::Room.new("300") @room_400_no_res = Hotel::Room.new("400") @room_500_misc_tests = Hotel::Room.new("500") + @room_600_misc_tests = Hotel::Room.new("600") @reservation_n1_nominal = Hotel::Reservation.new('10th Jun 3013', '16th Jun 3013') @reservation_n2_nominal = Hotel::Reservation.new('10th Jun 3014', '16th Jun 3014') @@ -157,6 +158,61 @@ end end + describe "resolve_date_conflict(conflict_array)" do + + before do + @conflict_array_1 = [ + { "28281899" => + { :am => false, :pm => true } + } + ] + + @conflict_array_2 = [ + {"28281802" => + { :am => false, :pm => true } + }, + + {"28281807" => + { :am => true, :pm => false } + } + ] + @conf_res_output_array_1 = @room_500_misc_tests.resolve_date_conflict(@conflict_array_1) + + @conf_res_output_array_2 = @room_600_misc_tests.resolve_date_conflict(@conflict_array_2) + + @times_all_true_hash = {:am => true, :pm => true} + end + + it "outputs an array that is the same length as its input array" do + before_length_1 = @conflict_array_1.length + before_length_2 = @conflict_array_2.length + + @conf_res_output_array_1.length.must_equal before_length_1 + @conf_res_output_array_2.length.must_equal before_length_2 + end + + it "outputs an array of date-hashes that have the same keys (Julian dates in string form) as its input-hashes" do + + @conflict_array_1[0].keys.must_equal @conf_res_output_array_1[0].keys + + @conflict_array_2[0].keys.must_equal + @conf_res_output_array_2[0].keys + + @conflict_array_2[1].keys.must_equal + @conf_res_output_array_2[1].keys + + end + + it "outputs an array that contains one or more date-hashes, where the key of each is a Julian date in string form, and the value is a hash of two hashes, with keys :am and :pm, and a value of true for each" do + + @conflict_array_1[0].values.must_equal @times_all_true_hash + + @conflict_array_2[0].values.must_equal @times_all_true_hash + + @conflict_array_2[1].values.must_equal @times_all_true_hash + + end + end describe "add_reservation(new_reservation)" do From 27704ae78777fe1607ba73c85463985b299d5d8a Mon Sep 17 00:00:00 2001 From: Victoria Garcia Date: Fri, 9 Mar 2018 21:58:08 -0800 Subject: [PATCH 20/51] all tests for conflict resolution helper method are passing. --- lib/room.rb | 6 ++++-- specs/room_spec.rb | 20 +++++++++----------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/lib/room.rb b/lib/room.rb index 87f51e5cd..a77d8ea70 100644 --- a/lib/room.rb +++ b/lib/room.rb @@ -30,9 +30,7 @@ def can_accept_reservation?(reservation) reservation_acceptable = {:accept => true, :resolve_conflict => false} resolve_date_conflict = [] unless @dates_unavailable.empty? - puts "unless at 33" unless reservation_acceptable[:accept] == false - puts "unless at 35" @dates_unavailable.each do |booked_date| # Note: I originally had the am/pm conflict checking written as a single, long, one-line thing, but that made minitest loose its mind, so now it's in all these little chunks. date = booked_date @@ -68,6 +66,10 @@ def can_accept_reservation?(reservation) end return reservation_acceptable end + def fix_conflicting_date(conflict_array) + output_array = conflict_array.map {|d| {d.keys[0] => {:am => true, :pm => true}}} + return output_array + end def add_reservation(new_reservation) #PROCESS NOTES: THink I'm going to write this method, then add in the rejection mechanics, even tough the rejection mechanics are already kind of there. The commented-out if/else business below will be retrofitted on. diff --git a/specs/room_spec.rb b/specs/room_spec.rb index 78dece2d4..cad20c94c 100644 --- a/specs/room_spec.rb +++ b/specs/room_spec.rb @@ -158,7 +158,7 @@ end end - describe "resolve_date_conflict(conflict_array)" do + describe "fix_conflicting_date(conflict_array)" do before do @conflict_array_1 = [ @@ -176,9 +176,9 @@ { :am => true, :pm => false } } ] - @conf_res_output_array_1 = @room_500_misc_tests.resolve_date_conflict(@conflict_array_1) + @conf_res_output_array_1 = @room_500_misc_tests.fix_conflicting_date(@conflict_array_1) - @conf_res_output_array_2 = @room_600_misc_tests.resolve_date_conflict(@conflict_array_2) + @conf_res_output_array_2 = @room_600_misc_tests.fix_conflicting_date(@conflict_array_2) @times_all_true_hash = {:am => true, :pm => true} end @@ -193,23 +193,21 @@ it "outputs an array of date-hashes that have the same keys (Julian dates in string form) as its input-hashes" do - @conflict_array_1[0].keys.must_equal @conf_res_output_array_1[0].keys + @conf_res_output_array_1[0].keys.must_equal @conflict_array_1[0].keys - @conflict_array_2[0].keys.must_equal - @conf_res_output_array_2[0].keys + @conflict_array_2[0].keys.must_equal @conflict_array_2[0].keys - @conflict_array_2[1].keys.must_equal - @conf_res_output_array_2[1].keys + @conf_res_output_array_2[1].keys.must_equal @conflict_array_2[1].keys end it "outputs an array that contains one or more date-hashes, where the key of each is a Julian date in string form, and the value is a hash of two hashes, with keys :am and :pm, and a value of true for each" do - @conflict_array_1[0].values.must_equal @times_all_true_hash + @conf_res_output_array_1[0].values[0].must_equal @times_all_true_hash - @conflict_array_2[0].values.must_equal @times_all_true_hash + @conf_res_output_array_2[0].values[0].must_equal @times_all_true_hash - @conflict_array_2[1].values.must_equal @times_all_true_hash + @conf_res_output_array_2[1].values[0].must_equal @times_all_true_hash end end From 0658e5eec010f1028079ea8eda8811eb2316b068 Mon Sep 17 00:00:00 2001 From: Victoria Garcia Date: Fri, 9 Mar 2018 23:33:50 -0800 Subject: [PATCH 21/51] all the conflict-oriented machinery for Room is now passing all its tests. --- lib/room.rb | 20 +++++++++++++++----- specs/room_spec.rb | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/lib/room.rb b/lib/room.rb index a77d8ea70..4a3f14633 100644 --- a/lib/room.rb +++ b/lib/room.rb @@ -73,11 +73,21 @@ def fix_conflicting_date(conflict_array) def add_reservation(new_reservation) #PROCESS NOTES: THink I'm going to write this method, then add in the rejection mechanics, even tough the rejection mechanics are already kind of there. The commented-out if/else business below will be retrofitted on. - # if can_accept_reservation(reservation) == true - # else #Make an error or something - # end - @reservations << new_reservation - @dates_unavailable.merge!(new_reservation.days_booked_am_and_pm) + + adding_instructions = can_accept_reservation?(new_reservation) + if adding_instructions[:accept] == false + raise StandardError.new ("You are trying to add a reservation that conflicts with a pre-existing reservation") + else + @reservations << new_reservation + @dates_unavailable.merge!(new_reservation.days_booked_am_and_pm) + end + dates_with_conflicts_fixed = nil + if adding_instructions[:resolve_conflict].kind_of? Array + dates_with_conflicts_fixed = fix_conflicting_date(adding_instructions[:resolve_conflict]) + # binding.pry + dates_with_conflicts_fixed.each {|date| @dates_unavailable.merge!(date)} + # binding.pry + end end end end diff --git a/specs/room_spec.rb b/specs/room_spec.rb index cad20c94c..cf036c033 100644 --- a/specs/room_spec.rb +++ b/specs/room_spec.rb @@ -253,5 +253,38 @@ @room_300_nominal.dates_unavailable.keys.must_include "2821697" end + it "raises a standard error if an attempt is made to add a reservation that conflicts with an existing reservation" do + + #Note -- at this time, my plan is actually for this to happen in FrontDesk, but all the machinery is present to make this happen here as well, so maybe I'll just go ahead and do this? + @room_300_nominal.add_reservation(@reservation_n1_nominal) + + proc{ @room_300_nominal.add_reservation(@reservation_2_overlaps_n1_beginning)}.must_raise StandardError + + + end + + it "creates a date hash with values of true for both :am and :pm for any date on which a (non-conflicting) new reservation's start or end date falls on the start or end date of a pre-existing reservation and logs it in the room's @dates_unavailable hash. " do + + @room_300_nominal.add_reservation(@reservation_n1_nominal) + room_before_booked = @room_300_nominal.dates_unavailable.dup + new_res_before_dates = @reservation_1_follows_n1_directly.days_booked_am_and_pm.dup + + # The assertions below just test the test. + room_before_booked.count.must_equal 7 + new_res_before_dates.count.must_equal 17 + room_before_booked["2821702"][:pm].must_equal false + new_res_before_dates["2821702"][:am].must_equal false + + @room_300_nominal.add_reservation(@reservation_1_follows_n1_directly) + dates_after_adding_and_conf_res = @room_300_nominal.dates_unavailable.dup + + dates_after_adding_and_conf_res.count.must_equal 23 + dates_after_adding_and_conf_res["2821702"][:am].must_equal true + dates_after_adding_and_conf_res["2821702"][:pm].must_equal true + + end + + + end end From 93b04631e5a0f6993d9aea24cf727d4ea33c70bc Mon Sep 17 00:00:00 2001 From: Victoria Garcia Date: Fri, 9 Mar 2018 23:57:31 -0800 Subject: [PATCH 22/51] tests for reporting method written and failing/erroring appropriately. --- lib/room.rb | 1 - specs/room_spec.rb | 16 ++++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/lib/room.rb b/lib/room.rb index 4a3f14633..2dbe13d62 100644 --- a/lib/room.rb +++ b/lib/room.rb @@ -72,7 +72,6 @@ def fix_conflicting_date(conflict_array) end def add_reservation(new_reservation) - #PROCESS NOTES: THink I'm going to write this method, then add in the rejection mechanics, even tough the rejection mechanics are already kind of there. The commented-out if/else business below will be retrofitted on. adding_instructions = can_accept_reservation?(new_reservation) if adding_instructions[:accept] == false diff --git a/specs/room_spec.rb b/specs/room_spec.rb index cf036c033..594c90540 100644 --- a/specs/room_spec.rb +++ b/specs/room_spec.rb @@ -56,14 +56,22 @@ end - describe "report_availability_for_day(date_julian)" do + describe "report_reservations_for_day(date_julian)" do it "accurately reports reservations when run for a single day" do - end + @room_300_nominal.add_reservation(@reservation_n1_nominal) + @room_300_nominal.add_reservation(@reservation_1_follows_n1_directly) + + jun_10_reservations = @room_300_nominal.report_reservations_for_day("2821702") + june_10_reservations.length.must_equal 2 + june_10_reservations.must_be_kind_of Array + june_10_reservations.must_inlude @reservation_n1_nominal + june_10_reservations.must_include @reservation_1_follows_n1_directly - it "accurately reports reservations for a range of days" do end + + end describe "can_accept_reservation?(reservation)" do @@ -243,7 +251,7 @@ end - it "must add the dates of the reservation to the room's collection of unavailable dates" do + it "adds the dates of the reservation to the room's collection of unavailable dates" do before_unavailables = @room_300_nominal.dates_unavailable.dup before_unavailables.count.must_equal 0 From 83c8cb65f6f798dd5d21b2fe8cb4ed4847397366 Mon Sep 17 00:00:00 2001 From: Victoria Garcia Date: Sat, 10 Mar 2018 00:07:12 -0800 Subject: [PATCH 23/51] last functionality added to Room class. Tests passing. --- lib/room.rb | 7 ++++++- specs/room_spec.rb | 8 ++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/lib/room.rb b/lib/room.rb index 2dbe13d62..3c06c86cc 100644 --- a/lib/room.rb +++ b/lib/room.rb @@ -23,8 +23,13 @@ def report_all_reservations end def report_reservations_for_day(date_julian) - # THIS NEEDS TO BE TESTED AFTER THE RESERVATION-ADDING MECHANICS GO IN, BECAUSE IT WILL READ FROM 'Dates Unavailable.' + resvs_for_day = @reservations.find_all {|reservation| reservation.days_booked_am_and_pm[date_julian]} end + # + # + # def self.find(query_id) + # found_order = Grocery::Order.all.find {|order_instance| order_instance.id == query_id} + # return found_order def can_accept_reservation?(reservation) reservation_acceptable = {:accept => true, :resolve_conflict => false} diff --git a/specs/room_spec.rb b/specs/room_spec.rb index 594c90540..838ccba37 100644 --- a/specs/room_spec.rb +++ b/specs/room_spec.rb @@ -63,10 +63,10 @@ @room_300_nominal.add_reservation(@reservation_1_follows_n1_directly) jun_10_reservations = @room_300_nominal.report_reservations_for_day("2821702") - june_10_reservations.length.must_equal 2 - june_10_reservations.must_be_kind_of Array - june_10_reservations.must_inlude @reservation_n1_nominal - june_10_reservations.must_include @reservation_1_follows_n1_directly + jun_10_reservations.length.must_equal 2 + jun_10_reservations.must_be_kind_of Array + jun_10_reservations.must_include @reservation_n1_nominal + jun_10_reservations.must_include @reservation_1_follows_n1_directly end From 05e25d0671fb5f6dea3d7a843f35dfc9a7487dbd Mon Sep 17 00:00:00 2001 From: Victoria Garcia Date: Sat, 10 Mar 2018 00:21:50 -0800 Subject: [PATCH 24/51] wrote a couple more tests for Room. all functionality for Room, including reporting, is now in place. All tests passing. --- lib/room.rb | 5 +++++ specs/room_spec.rb | 30 ++++++++++++++++++++++++------ 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/lib/room.rb b/lib/room.rb index 3c06c86cc..6b0fa7cb0 100644 --- a/lib/room.rb +++ b/lib/room.rb @@ -23,7 +23,12 @@ def report_all_reservations end def report_reservations_for_day(date_julian) + report = nil resvs_for_day = @reservations.find_all {|reservation| reservation.days_booked_am_and_pm[date_julian]} + if resvs_for_day.any? + report = resvs_for_day + end + return report end # # diff --git a/specs/room_spec.rb b/specs/room_spec.rb index 838ccba37..d89e3fe51 100644 --- a/specs/room_spec.rb +++ b/specs/room_spec.rb @@ -57,20 +57,38 @@ end describe "report_reservations_for_day(date_julian)" do + before do - it "accurately reports reservations when run for a single day" do @room_300_nominal.add_reservation(@reservation_n1_nominal) @room_300_nominal.add_reservation(@reservation_1_follows_n1_directly) - jun_10_reservations = @room_300_nominal.report_reservations_for_day("2821702") - jun_10_reservations.length.must_equal 2 - jun_10_reservations.must_be_kind_of Array - jun_10_reservations.must_include @reservation_n1_nominal - jun_10_reservations.must_include @reservation_1_follows_n1_directly + end + + it "accurately reports reservations for a day on which there is a single reservation" do + + jun_12_reservations = @room_300_nominal.report_reservations_for_day("2821698") + jun_12_reservations.must_be_kind_of Array + jun_12_reservations.length.must_equal 1 + jun_12_reservations.must_include @reservation_n1_nominal + end + + it "accurately reports reservations when run for a day on which one reservation begins and another ends" do + + jun_16_reservations = @room_300_nominal.report_reservations_for_day("2821702") + jun_16_reservations.length.must_equal 2 + jun_16_reservations.must_be_kind_of Array + jun_16_reservations.must_include @reservation_n1_nominal + jun_16_reservations.must_include @reservation_1_follows_n1_directly end + it "returns nil if a room has no reservations for a given day." do + + xmas_3075_reservations = @room_300_nominal.report_reservations_for_day("2844539") + xmas_3075_reservations.must_be_nil + + end end From 661cb71f02951381a230a4c29a599d1e02f4484b Mon Sep 17 00:00:00 2001 From: Victoria Garcia Date: Sat, 10 Mar 2018 16:51:46 -0800 Subject: [PATCH 25/51] stubbed a whole lot of stuff for FrontDesk. --- lib/front_desk.rb | 44 +++++++++++++++++++++++++++++++++++++- lib/reservation.rb | 10 ++++++++- lib/room.rb | 10 ++++----- specs/front_desk_spec.rb | 46 ++++++++++++++++++++++++++++++++++++++++ specs/room_spec.rb | 12 +++++------ 5 files changed, 108 insertions(+), 14 deletions(-) diff --git a/lib/front_desk.rb b/lib/front_desk.rb index 3224fb03c..326f5d832 100644 --- a/lib/front_desk.rb +++ b/lib/front_desk.rb @@ -1,14 +1,56 @@ require 'date' +require 'pry' require_relative 'reservation' require_relative 'room' module Hotel class FrontDesk - attr_reader + attr_reader :rooms_basic, :rooms_block attr_accessor + TOTAL_ROOMS_IN_FACILITY = 20 + BASE_RATE = 200.00 + MINIMUM_RES_IN_SECONDS = 36000 + def initialize + @rooms_basic = generate_rooms + @rooms_block + end + + def generate_rooms + end + + def report_all_rooms + end + + def create_reservation_basic(start_date_juli, end_date_juli) + end + + def report_reservation_price(id) + end + + def report_all_reservations_day(date_julian) + end + + def report_all_reservations_room(room) end + + def report_all_availabile_rooms(start_dt_julian, end_dt_julian) + end + + def check_availability_for_block(stt_dt_jln, end_dt_jln) + end + + def create_room_block(block_size, block_discount) + end + + def report_available_block_rooms(start_julian, end_julian) + end + + def create_reservation_block(start_date_jul, end_date_jul) + end + + end end diff --git a/lib/reservation.rb b/lib/reservation.rb index 64f5b5afd..3b26eafba 100644 --- a/lib/reservation.rb +++ b/lib/reservation.rb @@ -18,16 +18,19 @@ class Reservation #Since all rooms are identical, and we haven't been given any parameters for price variation, it makes sense to assign a default price for the moment. If the customer needs more options or granularity here, that cna be implemented later PER_NIGHT_PRICE = 100.00 - def initialize(start_date, end_date) + def initialize(start_date, end_date ) @id = assign_id @start_date = DateTime.parse(start_date) @end_date = DateTime.parse(end_date) + #@hotel_room_id = hotel_room_id @days_booked_am_and_pm = days_with_am_and_pm_occupation @total_nights = calculate_total_nights @total_reservation_cost = calculate_reservation_price #THIS IS GOOD, BUT IT EFFS UP YOUR ABILITY TO TEST CERTAIN SHIT. MAYBE PUT THE VALIDATION MEASURE FOR START-DATES IN THE PAST IN FrontDesk??? OR RESCUE?? ## Commenting out the req about not starting reservations in the past--- for now. + + ## GOING TO HAVE THIS LOOK UP THE MIN_RES_IN_SEC on the room to which it is being assigned, using the room numer ID. YASS. if (@end_date.to_time.to_i - @start_date.to_time.to_i) < MIN_RES_IN_SEC #|| @start_date.to_time.to_i < Time.now.to_i raise StandardError.new("A reservation's end date must come after its start date, and it must be at least one night long.") end @@ -85,6 +88,11 @@ def days_with_am_and_pm_occupation def calculate_reservation_price #I know this isn't exactly best practice for dealing with real-world currency. But since we haven't covered that yet and this isn't the real world, this is what I'm going with. + + #OK, SO WHAT THIS IS ACTUALLY GOING TO DO IS: + # LOOK UP THE ROOM TO WHICH IT AS ASSIGNED USING HOTEL_ROOM_ID + # FIND THE PRICE AND DISCOUNT OF THAT ROOM + # APPLY THEM HERE. (@total_nights * PER_NIGHT_PRICE).round(2) end end diff --git a/lib/room.rb b/lib/room.rb index 6b0fa7cb0..5c82c0ec8 100644 --- a/lib/room.rb +++ b/lib/room.rb @@ -6,7 +6,8 @@ module Hotel class Room - attr_accessor :room_number, :reservations, :dates_unavailable + attr_reader :room_number + attr_accessor :reservations, :dates_unavailable def initialize(room_number) @room_number = room_number @@ -30,11 +31,6 @@ def report_reservations_for_day(date_julian) end return report end - # - # - # def self.find(query_id) - # found_order = Grocery::Order.all.find {|order_instance| order_instance.id == query_id} - # return found_order def can_accept_reservation?(reservation) reservation_acceptable = {:accept => true, :resolve_conflict => false} @@ -76,6 +72,8 @@ def can_accept_reservation?(reservation) end return reservation_acceptable end + + def fix_conflicting_date(conflict_array) output_array = conflict_array.map {|d| {d.keys[0] => {:am => true, :pm => true}}} return output_array diff --git a/specs/front_desk_spec.rb b/specs/front_desk_spec.rb index 6d5441505..e9de260ee 100644 --- a/specs/front_desk_spec.rb +++ b/specs/front_desk_spec.rb @@ -2,9 +2,55 @@ require_relative 'spec_helper' describe "FrontDesk class" do + + describe "initialize" do + end + + describe "generate_rooms" do + end + + describe "report_all_rooms" do + end + + describe "create_reservation_basic(start_date_juli, end_date_juli)" do + end + + describe "report_reservation_price(id)" do + end + + describe "report_all_reservations_day(date_julian)" do + end + + describe "report_all_reservations_room(room)" do + end + + describe "report_all_available_rooms(start_dt_julian, end_dt_julian)" do + end + + describe "check_availability_for_block" do + end + + describe "create_room_block(block_size, block_discount)" do + end + + describe "report_available_block_rooms" do + end + + describe "create_reservation_block(start_date_jul, end_date_jul)" do + end end + + + + + + + + + + # Note: COMMENTING THIS OUT FOR NOW. WILL PROBABLY move this functionality to FrontDesk. # it "Raises an error if the start date comes before the date of instantiation" do # too_early_start = '1st Feb 1975' diff --git a/specs/room_spec.rb b/specs/room_spec.rb index d89e3fe51..912e92bb6 100644 --- a/specs/room_spec.rb +++ b/specs/room_spec.rb @@ -43,7 +43,6 @@ describe "report_all_reservations" do - #THIS IS WHERE AN IMPORTANT HANDSHAKE BETWEEN RESERVATION AND ROOM NEEDS TO HAPPEN. it "returns a complete collection of reservations for the room" do all_nominal_reservations = [@reservation_n1_nominal, @reservation_n2_nominal, @reservation_n3_nominal] @room_300_nominal.reservations = all_nominal_reservations @@ -61,6 +60,7 @@ @room_300_nominal.add_reservation(@reservation_n1_nominal) @room_300_nominal.add_reservation(@reservation_1_follows_n1_directly) + @room_300_nominal.add_reservation(@reservation_n3_nominal) end @@ -70,6 +70,7 @@ jun_12_reservations.must_be_kind_of Array jun_12_reservations.length.must_equal 1 jun_12_reservations.must_include @reservation_n1_nominal + end it "accurately reports reservations when run for a day on which one reservation begins and another ends" do @@ -89,7 +90,6 @@ xmas_3075_reservations.must_be_nil end - end describe "can_accept_reservation?(reservation)" do @@ -167,7 +167,7 @@ end - it "gives a value of {:accept => false, :resolve_conflict => [foo1, foo2], where foo1 and foo2 are hashes of the dates of the start-date/end-date overlaps, when a proposed reservation starts on the day an existing reservation ends, and ends on the day an existing reservation starts" do + it "gives a value of {:accept => false, :resolve_conflict => [foo1, foo2], where foo1 and foo2 are hashes of the dates of acceptable start-date/end-date overlaps, when a proposed reservation begins on the day an existing reservation ends, and ends on the day an existing reservation begins" do @room_300_nominal.add_reservation(@reservation_n2_nominal) in_middle_result = @room_300_nominal.can_accept_reservation?(@reservation_5_follows_n1_precedes_n2) @@ -176,9 +176,11 @@ in_middle_result[:resolve_conflict].must_be_kind_of Array in_middle_result[:resolve_conflict].count.must_equal 2 in_middle_result[:resolve_conflict][0].must_be_kind_of Hash + # Note: This number is the date of the first start-end overlap, respresented as a Julian date in string form. in_middle_result[:resolve_conflict][0].keys.must_include "2821702" in_middle_result[:resolve_conflict][1].must_be_kind_of Hash + # Note: This number is the date of the second start-end overlap, respresented as a Julian date in string form. in_middle_result[:resolve_conflict][1].keys.must_include "2822061" end @@ -240,7 +242,7 @@ describe "add_reservation(new_reservation)" do - it "must add itself to the room's collection of reservations" do + it "adds itself to the room's collection of reservations" do @room_300_nominal.reservations << @reservation_n1_nominal before_reservations = @room_300_nominal.reservations.dup @@ -310,7 +312,5 @@ end - - end end From 94d4064029d365d6729e172b24ea87cd5c1bf5dc Mon Sep 17 00:00:00 2001 From: Victoria Garcia Date: Sat, 10 Mar 2018 17:10:15 -0800 Subject: [PATCH 26/51] some changes to the initialize method for room, which I fought with after they broke things. --- lib/room.rb | 11 +++++++++-- specs/front_desk_spec.rb | 1 + 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/lib/room.rb b/lib/room.rb index 5c82c0ec8..2f8277487 100644 --- a/lib/room.rb +++ b/lib/room.rb @@ -6,11 +6,18 @@ module Hotel class Room - attr_reader :room_number - attr_accessor :reservations, :dates_unavailable + attr_reader :room_number, :base_resv_price, :min_res_sec, :rate_with_discount + attr_accessor :discount, :reservations, :dates_unavailable + + BASE_RESERV_PRICE = 200.00 + MIN_RESERV_SECONDS = 36000 def initialize(room_number) @room_number = room_number + @base_resv_price = BASE_RESERV_PRICE + @min_res_sec = MIN_RESERV_SECONDS + @discount = 0.00 + @rate_with_discount = BASE_RESERV_PRICE - (BASE_RESERV_PRICE * @discount) @reservations = [] @dates_unavailable = {} end diff --git a/specs/front_desk_spec.rb b/specs/front_desk_spec.rb index e9de260ee..9ea935622 100644 --- a/specs/front_desk_spec.rb +++ b/specs/front_desk_spec.rb @@ -7,6 +7,7 @@ end describe "generate_rooms" do + end describe "report_all_rooms" do From 5a6e28d8d08850e2fc3364090895e930a1007f68 Mon Sep 17 00:00:00 2001 From: Victoria Garcia Date: Sat, 10 Mar 2018 17:34:55 -0800 Subject: [PATCH 27/51] Lots of stuff stubbed, test-wise, in Front Desk --- lib/front_desk.rb | 12 +++---- specs/front_desk_spec.rb | 67 ++++++++++++++++++++++++++++++++-------- 2 files changed, 59 insertions(+), 20 deletions(-) diff --git a/lib/front_desk.rb b/lib/front_desk.rb index 326f5d832..9bee9b227 100644 --- a/lib/front_desk.rb +++ b/lib/front_desk.rb @@ -10,12 +10,10 @@ class FrontDesk attr_accessor TOTAL_ROOMS_IN_FACILITY = 20 - BASE_RATE = 200.00 - MINIMUM_RES_IN_SECONDS = 36000 def initialize @rooms_basic = generate_rooms - @rooms_block + @rooms_block = [] end def generate_rooms @@ -24,16 +22,16 @@ def generate_rooms def report_all_rooms end - def create_reservation_basic(start_date_juli, end_date_juli) + def find_available_room(start_julian, end_julian) end - def report_reservation_price(id) + def create_reservation_basic(start_date_juli, end_date_juli, room_id) end - def report_all_reservations_day(date_julian) + def report_reservation_price(id) end - def report_all_reservations_room(room) + def report_all_reservations_day(date_julian) end def report_all_availabile_rooms(start_dt_julian, end_dt_julian) diff --git a/specs/front_desk_spec.rb b/specs/front_desk_spec.rb index 9ea935622..edf1688ff 100644 --- a/specs/front_desk_spec.rb +++ b/specs/front_desk_spec.rb @@ -4,41 +4,82 @@ describe "FrontDesk class" do describe "initialize" do + + it "stores an array of instances of room in its @rooms_basic variable" do + end + + it "begins with an empty array as the value of its @rooms_block variable" do + end end describe "generate_rooms" do + it "creates a collection of instances of room, which it stores in an array." do + end + + it "gives each room a unique room number, in the form of a string, going from 1 through the total number of rooms in the facility" do + end + end describe "report_all_rooms" do + + it "reports a complete list of all the rooms in the facility" do + end + end - describe "create_reservation_basic(start_date_juli, end_date_juli)" do + describe "find_available_room(start_julian, end_julian)" do + + it "returns the ID of a room that is available between specified dates" do + end + + it "returns nil if no rooms are available between specified dates" do + end + end - describe "report_reservation_price(id)" do + describe "create_reservation_basic(start_date_juli, end_date_juli, room_id)" do + + it "generates a reservation for a given date range" do + end + + it "assigns the reservation to the hotel room specified" do + end + end + # I think this is fully covered in the reservation class? But maybe there's a better way? + + # describe "report_reservation_price(id)" do + # end + describe "report_all_reservations_day(date_julian)" do - end - describe "report_all_reservations_room(room)" do - end + it "reports a list of reservations for a specified date" do + end - describe "report_all_available_rooms(start_dt_julian, end_dt_julian)" do end - describe "check_availability_for_block" do - end + describe "report_all_available_rooms(start_dt_julian, end_dt_julian)" do - describe "create_room_block(block_size, block_discount)" do - end + it "reports a list of rooms that are available for a given date range" do + end - describe "report_available_block_rooms" do end - describe "create_reservation_block(start_date_jul, end_date_jul)" do - end + #NOT EVEN GOING TO THINK ABOUT THIS PART RIGHT NOW. + # describe "check_availability_for_block" do + # end + # + # describe "create_room_block(block_size, block_discount)" do + # end + # + # describe "report_available_block_rooms" do + # end + # + # describe "create_reservation_block(start_date_jul, end_date_jul)" do + # end end From 8fc9eed2ca95ef833dcfd76b0bf0ad798baf753f Mon Sep 17 00:00:00 2001 From: Victoria Garcia Date: Sat, 10 Mar 2018 17:44:32 -0800 Subject: [PATCH 28/51] first few tests passing for FrontDesk --- lib/front_desk.rb | 7 +++++++ specs/front_desk_spec.rb | 10 +++++----- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/lib/front_desk.rb b/lib/front_desk.rb index 9bee9b227..cc40181e4 100644 --- a/lib/front_desk.rb +++ b/lib/front_desk.rb @@ -17,6 +17,13 @@ def initialize end def generate_rooms + room_array = [] + for i in 1 .. TOTAL_ROOMS_IN_FACILITY + room_number = i.to_s + new_room = Hotel::Room.new(room_number) + room_array << new_room + end + return room_array end def report_all_rooms diff --git a/specs/front_desk_spec.rb b/specs/front_desk_spec.rb index edf1688ff..a15b2873b 100644 --- a/specs/front_desk_spec.rb +++ b/specs/front_desk_spec.rb @@ -22,14 +22,14 @@ end - describe "report_all_rooms" do + xdescribe "report_all_rooms" do it "reports a complete list of all the rooms in the facility" do end end - describe "find_available_room(start_julian, end_julian)" do + xdescribe "find_available_room(start_julian, end_julian)" do it "returns the ID of a room that is available between specified dates" do end @@ -39,7 +39,7 @@ end - describe "create_reservation_basic(start_date_juli, end_date_juli, room_id)" do + xdescribe "create_reservation_basic(start_date_juli, end_date_juli, room_id)" do it "generates a reservation for a given date range" do end @@ -54,14 +54,14 @@ # describe "report_reservation_price(id)" do # end - describe "report_all_reservations_day(date_julian)" do + xdescribe "report_all_reservations_day(date_julian)" do it "reports a list of reservations for a specified date" do end end - describe "report_all_available_rooms(start_dt_julian, end_dt_julian)" do + xdescribe "report_all_available_rooms(start_dt_julian, end_dt_julian)" do it "reports a list of rooms that are available for a given date range" do end From 47b59092772aaae492abada98532586636810cd7 Mon Sep 17 00:00:00 2001 From: Victoria Garcia Date: Sat, 10 Mar 2018 18:41:57 -0800 Subject: [PATCH 29/51] report_all_rooms is passing its tests. --- lib/front_desk.rb | 11 +++++--- specs/front_desk_spec.rb | 54 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 56 insertions(+), 9 deletions(-) diff --git a/lib/front_desk.rb b/lib/front_desk.rb index cc40181e4..db8a8c2a7 100644 --- a/lib/front_desk.rb +++ b/lib/front_desk.rb @@ -6,14 +6,15 @@ module Hotel class FrontDesk - attr_reader :rooms_basic, :rooms_block - attr_accessor + + attr_reader :rooms TOTAL_ROOMS_IN_FACILITY = 20 def initialize - @rooms_basic = generate_rooms - @rooms_block = [] + + @rooms = generate_rooms + end def generate_rooms @@ -27,6 +28,8 @@ def generate_rooms end def report_all_rooms + all_rooms = @rooms + return all_rooms end def find_available_room(start_julian, end_julian) diff --git a/specs/front_desk_spec.rb b/specs/front_desk_spec.rb index a15b2873b..90135600e 100644 --- a/specs/front_desk_spec.rb +++ b/specs/front_desk_spec.rb @@ -3,30 +3,74 @@ describe "FrontDesk class" do + before do + @front_desk_1 = Hotel::FrontDesk.new + end + describe "initialize" do - it "stores an array of instances of room in its @rooms_basic variable" do + before do + @front_desk_0 = Hotel::FrontDesk.new + end + + it "can be initialized" do + + @front_desk_0.must_be_instance_of Hotel::FrontDesk + end - it "begins with an empty array as the value of its @rooms_block variable" do + it "stores an array of instances of room in its @rooms_basic variable equal to the number of rooms in the hotel" do + + @front_desk_0.rooms.must_be_kind_of Array + @front_desk_0.rooms.each {|element| element.must_be_instance_of Hotel::Room} + @front_desk_0.rooms.count.must_equal 20 + end + end describe "generate_rooms" do - it "creates a collection of instances of room, which it stores in an array." do + before do + @test_rooms_1 = @front_desk_1.generate_rooms end + it "creates a collection of instances of Room, which it stores in an array." do + + @test_rooms_1.must_be_kind_of Array + @test_rooms_1.each {|element| element.must_be_instance_of Hotel::Room} + + end + + it "gives each room a unique room number, in the form of a string, going from 1 through the total number of rooms in the facility" do + + + rooms_in_order = @test_rooms_1.sort_by {|room| room.room_number.to_i} + + rooms_in_order.length.must_equal 20 + + rooms_in_order.each_with_index do |room, index| + room.room_number.must_equal (index + 1).to_s + end end end - xdescribe "report_all_rooms" do + describe "report_all_rooms" do it "reports a complete list of all the rooms in the facility" do - end + room_report = @front_desk_1.report_all_rooms.sort_by {|room| room.room_number.to_i} + + room_report.must_be_kind_of Array + room_report.length.must_equal 20 + + room_report.each_with_index do |room, index| + room.room_number.must_equal (index + 1).to_s + end + + end end xdescribe "find_available_room(start_julian, end_julian)" do From 46daa3b63f50b6e2947ecf847f62829819ccc53a Mon Sep 17 00:00:00 2001 From: Victoria Garcia Date: Sat, 10 Mar 2018 19:50:31 -0800 Subject: [PATCH 30/51] Tests written and failing in the desired way for the availability checking method in FrontDesk --- lib/front_desk.rb | 2 +- lib/reservation.rb | 4 +- specs/front_desk_spec.rb | 82 +++++++++++++++++++++++++++++++++------- 3 files changed, 71 insertions(+), 17 deletions(-) diff --git a/lib/front_desk.rb b/lib/front_desk.rb index db8a8c2a7..a947f30b1 100644 --- a/lib/front_desk.rb +++ b/lib/front_desk.rb @@ -7,7 +7,7 @@ module Hotel class FrontDesk - attr_reader :rooms + attr_accessor :rooms TOTAL_ROOMS_IN_FACILITY = 20 diff --git a/lib/reservation.rb b/lib/reservation.rb index 3b26eafba..81bc52bd4 100644 --- a/lib/reservation.rb +++ b/lib/reservation.rb @@ -7,7 +7,7 @@ module Hotel class Reservation - attr_accessor :start_date, :end_date, :days_booked_am_and_pm + attr_accessor :start_date, :end_date, :hotel_room_id, :days_booked_am_and_pm attr_reader :id, :total_nights, :total_reservation_cost @@last_id_base = 0 @@ -22,7 +22,7 @@ def initialize(start_date, end_date ) @id = assign_id @start_date = DateTime.parse(start_date) @end_date = DateTime.parse(end_date) - #@hotel_room_id = hotel_room_id + @hotel_room_id = nil @days_booked_am_and_pm = days_with_am_and_pm_occupation @total_nights = calculate_total_nights @total_reservation_cost = calculate_reservation_price diff --git a/specs/front_desk_spec.rb b/specs/front_desk_spec.rb index 90135600e..ecb83e0ab 100644 --- a/specs/front_desk_spec.rb +++ b/specs/front_desk_spec.rb @@ -4,7 +4,54 @@ describe "FrontDesk class" do before do + @front_desk_1 = Hotel::FrontDesk.new + @front_desk_2 = Hotel::FrontDesk.new + @front_desk_3 = Hotel::FrontDesk.new + + @room_1000_as = Hotel::Room.new("1000") + @room_2000_bs = Hotel::Room.new("2000") + @room_3000_cs = Hotel::Room.new("3000") + @room_4000 = Hotel::Room.new("4000") + @room_5000 = Hotel::Room.new("5000") + @room_6000 = Hotel::Room.new("6000") + + @reservation_n1_a = Hotel::Reservation.new('10th Jun 3013', '16th Jun 3013') + @reservation_n2_a = Hotel::Reservation.new('10th Jun 3014', '16th Jun 3014') + @reservation_n3_a = Hotel::Reservation.new('10th Oct 3015', '9th Dec 3015') + + @reservation_n1_b = Hotel::Reservation.new('10th Jun 3013', '16th Jun 3013') + @reservation_n2_b = Hotel::Reservation.new('10th Jun 3014', '16th Jun 3014') + @reservation_n3_b = Hotel::Reservation.new('10th Oct 3015', '9th Dec 3015') + + @reservation_n1_c = Hotel::Reservation.new('10th Jun 3013', '16th Jun 3013') + @reservation_n2_c = Hotel::Reservation.new('10th Jun 3014', '16th Jun 3014') + @reservation_n3_c = Hotel::Reservation.new('10th Oct 3015', '9th Dec 3015') + + @reservation_n1_d = Hotel::Reservation.new('10th Jun 3013', '16th Jun 3013') + @reservation_n2_d = Hotel::Reservation.new('10th Jun 3014', '16th Jun 3014') + @reservation_n3_d = Hotel::Reservation.new('10th Oct 3015', '9th Dec 3015') + + @res_0_precede_n1_direct = Hotel::Reservation.new('5th Jun 3013', '10th Jun 3013') + @res_1_fllws_n1_direct = Hotel::Reservation.new('16th Jun 3013', '2nd Jul 3013') + @res_2_overlps_n1_begin = Hotel::Reservation.new('8th Jun 3013', '11th Jun 3013') + @res_3_overlps_n1_end = Hotel::Reservation.new('15th Jun 3013', '5th Jul 3013') + @res_4_overlps_n1_precede_n2 = Hotel::Reservation.new('14th Jun 3013', '10th Jun 3014') + @res_5_fllws_n1_precedes_n2 = Hotel::Reservation.new('16th Jun 3013', '10th Jun 3014') + + @room_1000_as.add_reservation(@reservation_n1_a) + @room_1000_as.add_reservation(@reservation_n2_a) + @room_1000_as.add_reservation(@reservation_n3_a) + + @room_2000_bs.add_reservation(@reservation_n1_b) + @room_2000_bs.add_reservation(@reservation_n2_b) + @room_2000_bs.add_reservation(@reservation_n3_b) + + @rooms_w_nom_res = [@room_1000_as, @room_2000_bs] + + @front_desk_2.rooms = @rooms_w_nom_res + + end describe "initialize" do @@ -14,19 +61,14 @@ end it "can be initialized" do - @front_desk_0.must_be_instance_of Hotel::FrontDesk - end it "stores an array of instances of room in its @rooms_basic variable equal to the number of rooms in the hotel" do - @front_desk_0.rooms.must_be_kind_of Array @front_desk_0.rooms.each {|element| element.must_be_instance_of Hotel::Room} @front_desk_0.rooms.count.must_equal 20 - end - end describe "generate_rooms" do @@ -36,25 +78,19 @@ end it "creates a collection of instances of Room, which it stores in an array." do - @test_rooms_1.must_be_kind_of Array @test_rooms_1.each {|element| element.must_be_instance_of Hotel::Room} - end it "gives each room a unique room number, in the form of a string, going from 1 through the total number of rooms in the facility" do - rooms_in_order = @test_rooms_1.sort_by {|room| room.room_number.to_i} - rooms_in_order.length.must_equal 20 - rooms_in_order.each_with_index do |room, index| room.room_number.must_equal (index + 1).to_s end end - end describe "report_all_rooms" do @@ -65,20 +101,38 @@ room_report.must_be_kind_of Array room_report.length.must_equal 20 - room_report.each_with_index do |room, index| room.room_number.must_equal (index + 1).to_s end - end end - xdescribe "find_available_room(start_julian, end_julian)" do + describe "find_available_room(start_julian, end_julian)" do + + before do + + @room_4000.add_reservation(@reservation_n1_d) + @room_4000.add_reservation(@reservation_n2_d) + @room_4000.add_reservation(@res_5_fllws_n1_precedes_n2) + + @room_5000.add_reservation(@reservation_n1_c) + @room_5000.add_reservation(@res_1_fllws_n1_direct) + + @front_desk_3.rooms = [@room_1000_as, @room_4000, @room_5000] + + end it "returns the ID of a room that is available between specified dates" do + + # Julian dates translate to March 12, 3014, and March 21, 3014 + @front_desk_3.find_available_room("2821971", "2821980").must_equal "1000" + # Julian dates translate to November 12, 3015, and November 18, 3015 + @front_desk_3.find_available_room("2822581", "2822587").must_equal "4000" end it "returns nil if no rooms are available between specified dates" do + #The julian dates here translate to June 12, 3013, and June 14, 3013 + @front_desk_3.find_available_room("2821698", "2821700") end end From bab282a0a5814dbd384ddb3a74a7724d3c93f7ae Mon Sep 17 00:00:00 2001 From: Victoria Garcia Date: Sat, 10 Mar 2018 20:30:35 -0800 Subject: [PATCH 31/51] the room availability lookup procedure in FrontDesk is passing all its tests. --- lib/front_desk.rb | 37 ++++++++++++++++++++++++++++--------- specs/front_desk_spec.rb | 15 +++++++++------ 2 files changed, 37 insertions(+), 15 deletions(-) diff --git a/lib/front_desk.rb b/lib/front_desk.rb index a947f30b1..982f5cd39 100644 --- a/lib/front_desk.rb +++ b/lib/front_desk.rb @@ -32,33 +32,52 @@ def report_all_rooms return all_rooms end - def find_available_room(start_julian, end_julian) + def report_all_reservations_day(date) end - def create_reservation_basic(start_date_juli, end_date_juli, room_id) + def report_all_availabile_rooms(start_dt, end_dt) end - def report_reservation_price(id) + def find_available_room(start_d, end_d) + + proposed_reservation = Hotel::Reservation.new(start_d, end_d) + available_room = nil + @rooms.each do |room| + if available_room == nil + availability = room.can_accept_reservation?(proposed_reservation) + if availability[:accept] == true + available_room = room + end + end + end + unless available_room == nil + available_room = available_room.room_number + end + return available_room end - def report_all_reservations_day(date_julian) + def create_reservation_basic(start_date, end_date, room_id) end - def report_all_availabile_rooms(start_dt_julian, end_dt_julian) + def report_reservation_price(id) end - def check_availability_for_block(stt_dt_jln, end_dt_jln) + def report_all_reservations_day(date) end - def create_room_block(block_size, block_discount) + def report_all_availabile_rooms(start_dt, end_dt) end - def report_available_block_rooms(start_julian, end_julian) + def check_availability_for_block(st_dt, end_dt) end - def create_reservation_block(start_date_jul, end_date_jul) + def create_room_block(block_size, block_discount) end + def report_available_block_rooms(start_d, end_d) + end + def create_reservation_block(start_date, end_date) + end end end diff --git a/specs/front_desk_spec.rb b/specs/front_desk_spec.rb index ecb83e0ab..0cfea0122 100644 --- a/specs/front_desk_spec.rb +++ b/specs/front_desk_spec.rb @@ -109,6 +109,8 @@ describe "find_available_room(start_julian, end_julian)" do + # This method leverages availabiity-checking machinery that already exists in the Reservation class, and that machinery was already heavily tested by the Reservation spec, so it is just given a once-over here. + before do @room_4000.add_reservation(@reservation_n1_d) @@ -124,15 +126,16 @@ it "returns the ID of a room that is available between specified dates" do - # Julian dates translate to March 12, 3014, and March 21, 3014 - @front_desk_3.find_available_room("2821971", "2821980").must_equal "1000" - # Julian dates translate to November 12, 3015, and November 18, 3015 - @front_desk_3.find_available_room("2822581", "2822587").must_equal "4000" + @front_desk_3.find_available_room("12th Mar 3014", "21st Mar 3014").must_equal "1000" + + @front_desk_3.find_available_room("12th Nov 3015", "18th Nov 3015").must_equal "4000" + end it "returns nil if no rooms are available between specified dates" do - #The julian dates here translate to June 12, 3013, and June 14, 3013 - @front_desk_3.find_available_room("2821698", "2821700") + + @front_desk_3.find_available_room("12th Jun 3013", "14th Jun 3013") + end end From 7b1b62c20eb3a04d3fffbfc75fea8f8fd0d65b7c Mon Sep 17 00:00:00 2001 From: Victoria Garcia Date: Sat, 10 Mar 2018 21:01:46 -0800 Subject: [PATCH 32/51] tests written and failing in the desired way for the front desk's per-date reservation lookup method. --- specs/front_desk_spec.rb | 41 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/specs/front_desk_spec.rb b/specs/front_desk_spec.rb index 0cfea0122..61fd8ea61 100644 --- a/specs/front_desk_spec.rb +++ b/specs/front_desk_spec.rb @@ -15,6 +15,7 @@ @room_4000 = Hotel::Room.new("4000") @room_5000 = Hotel::Room.new("5000") @room_6000 = Hotel::Room.new("6000") + @room_7000 = Hotel::Room.new("7000") @reservation_n1_a = Hotel::Reservation.new('10th Jun 3013', '16th Jun 3013') @reservation_n2_a = Hotel::Reservation.new('10th Jun 3014', '16th Jun 3014') @@ -38,6 +39,7 @@ @res_3_overlps_n1_end = Hotel::Reservation.new('15th Jun 3013', '5th Jul 3013') @res_4_overlps_n1_precede_n2 = Hotel::Reservation.new('14th Jun 3013', '10th Jun 3014') @res_5_fllws_n1_precedes_n2 = Hotel::Reservation.new('16th Jun 3013', '10th Jun 3014') + @res_6_singleton = Hotel::Reservation.new('23rd Dec 3015', '3rd Jan 3016') @room_1000_as.add_reservation(@reservation_n1_a) @room_1000_as.add_reservation(@reservation_n2_a) @@ -107,7 +109,38 @@ end end - describe "find_available_room(start_julian, end_julian)" do + describe "report_all_reservations_day(date)" do + + before do + @room_4000.add_reservation(@res_2_overlps_n1_begin) + @room_5000.add_reservation(@res_5_fllws_n1_precedes_n2) + @room_6000.add_reservation(@res_6_singleton) + + @front_desk_3.rooms = [@room_1000_as, @room_4000, @room_5000, @room_6000] + end + + it "outputs a hash, where the keys are the numbers of reserved rooms, in string form, and the values are the id numbers of their reservations" do + + # Are we going to just report this as a string, or maybe a hash, yeah, that's it. A hash of rooms and reservation IDS + reservation_report_16_jun = @front_desk_3.report_all_reservations_day('16th Jun 3013') + + reservation_report_16_jun.must_be_kind_of Hash + reservation_report_16_jun.count.must_equal 2 + reservation_report_16_jun.keys.must_include "1000" + reservation_report_16_jun.keys.must_include "5000" + reservation_report_16_jun.keys.wont_include "4000" + reservation_report_16_jun.keys.wont_include "6000" + + reservation_report_16_jun["1000"].must_equal @reservation_n1_a.id + reservation_report_16_jun["5000"].must_equal @res_5_fllws_n1_precedes_n2.id + + end + + end + + + + describe "find_available_room(start_d, end_d)" do # This method leverages availabiity-checking machinery that already exists in the Reservation class, and that machinery was already heavily tested by the Reservation spec, so it is just given a once-over here. @@ -134,13 +167,13 @@ it "returns nil if no rooms are available between specified dates" do - @front_desk_3.find_available_room("12th Jun 3013", "14th Jun 3013") + @front_desk_3.find_available_room("12th Jun 3013", "14th Jun 3013").must_be_nil end end - xdescribe "create_reservation_basic(start_date_juli, end_date_juli, room_id)" do + xdescribe "create_reservation_basic(start_date, end_date, room_id)" do it "generates a reservation for a given date range" do end @@ -155,7 +188,7 @@ # describe "report_reservation_price(id)" do # end - xdescribe "report_all_reservations_day(date_julian)" do + xdescribe "report_all_reservations_day(date)" do it "reports a list of reservations for a specified date" do end From a79308deb0ed93f312cf7507bb540d9e53cdc5ee Mon Sep 17 00:00:00 2001 From: Victoria Garcia Date: Sat, 10 Mar 2018 21:50:46 -0800 Subject: [PATCH 33/51] initial tests for per-day reservation report in FrontDesk are passing. Do need one more, though. --- lib/front_desk.rb | 38 +++++++++++++++++++++++++------------- specs/front_desk_spec.rb | 16 +++++++++++----- 2 files changed, 36 insertions(+), 18 deletions(-) diff --git a/lib/front_desk.rb b/lib/front_desk.rb index 982f5cd39..3c9570aa6 100644 --- a/lib/front_desk.rb +++ b/lib/front_desk.rb @@ -32,14 +32,26 @@ def report_all_rooms return all_rooms end - def report_all_reservations_day(date) + def whatevs(date) + query_date = DateTime.parse(date).jd.to_s + overall_report = {} + @rooms.each do |room| + per_room_report = nil + per_room_report = room.report_reservations_for_day(query_date) + unless per_room_report == nil + resv_id_array = [] + per_room_report.each {|reservation| resv_id_array << reservation.id } + per_room_report = {room.room_number => resv_id_array} + overall_report.merge!(per_room_report) + end + end + return overall_report end def report_all_availabile_rooms(start_dt, end_dt) end def find_available_room(start_d, end_d) - proposed_reservation = Hotel::Reservation.new(start_d, end_d) available_room = nil @rooms.each do |room| @@ -68,16 +80,16 @@ def report_all_reservations_day(date) def report_all_availabile_rooms(start_dt, end_dt) end - def check_availability_for_block(st_dt, end_dt) - end - - def create_room_block(block_size, block_discount) - end - - def report_available_block_rooms(start_d, end_d) - end - - def create_reservation_block(start_date, end_date) - end + # def check_availability_for_block(st_dt, end_dt) + # end + # + # def create_room_block(block_size, block_discount) + # end + # + # def report_available_block_rooms(start_d, end_d) + # end + # + # def create_reservation_block(start_date, end_date) + # end end end diff --git a/specs/front_desk_spec.rb b/specs/front_desk_spec.rb index 61fd8ea61..c62533f74 100644 --- a/specs/front_desk_spec.rb +++ b/specs/front_desk_spec.rb @@ -112,6 +112,7 @@ describe "report_all_reservations_day(date)" do before do + @room_1000_as.add_reservation(@res_1_fllws_n1_direct) @room_4000.add_reservation(@res_2_overlps_n1_begin) @room_5000.add_reservation(@res_5_fllws_n1_precedes_n2) @room_6000.add_reservation(@res_6_singleton) @@ -119,20 +120,25 @@ @front_desk_3.rooms = [@room_1000_as, @room_4000, @room_5000, @room_6000] end - it "outputs a hash, where the keys are the numbers of reserved rooms, in string form, and the values are the id numbers of their reservations" do + it "outputs a hash, where the keys are the numbers of reserved rooms, in string form, and the value of each is an array containing the id numbers of their reservations" do - # Are we going to just report this as a string, or maybe a hash, yeah, that's it. A hash of rooms and reservation IDS - reservation_report_16_jun = @front_desk_3.report_all_reservations_day('16th Jun 3013') + reservation_report_16_jun = @front_desk_3.whatevs('16th Jun 3013') reservation_report_16_jun.must_be_kind_of Hash reservation_report_16_jun.count.must_equal 2 + reservation_report_16_jun.keys.must_include "1000" reservation_report_16_jun.keys.must_include "5000" + reservation_report_16_jun.keys.wont_include "4000" reservation_report_16_jun.keys.wont_include "6000" - reservation_report_16_jun["1000"].must_equal @reservation_n1_a.id - reservation_report_16_jun["5000"].must_equal @res_5_fllws_n1_precedes_n2.id + reservation_report_16_jun["1000"].must_be_kind_of Array + reservation_report_16_jun["1000"].must_include @reservation_n1_a.id + reservation_report_16_jun["1000"].must_include @res_1_fllws_n1_direct.id + + reservation_report_16_jun["5000"].must_be_kind_of Array + reservation_report_16_jun["5000"].must_include @res_5_fllws_n1_precedes_n2.id end From 93595f841473fd03b02e23d0d960f93361ccee97 Mon Sep 17 00:00:00 2001 From: Victoria Garcia Date: Sat, 10 Mar 2018 21:55:27 -0800 Subject: [PATCH 34/51] all tests for the FrontDesk's reservation lookup system are passing, including the new one. --- lib/front_desk.rb | 2 +- specs/front_desk_spec.rb | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/lib/front_desk.rb b/lib/front_desk.rb index 3c9570aa6..92ebebce4 100644 --- a/lib/front_desk.rb +++ b/lib/front_desk.rb @@ -32,7 +32,7 @@ def report_all_rooms return all_rooms end - def whatevs(date) + def find_all_reservations_for_date(date) query_date = DateTime.parse(date).jd.to_s overall_report = {} @rooms.each do |room| diff --git a/specs/front_desk_spec.rb b/specs/front_desk_spec.rb index c62533f74..2359a4410 100644 --- a/specs/front_desk_spec.rb +++ b/specs/front_desk_spec.rb @@ -122,7 +122,7 @@ it "outputs a hash, where the keys are the numbers of reserved rooms, in string form, and the value of each is an array containing the id numbers of their reservations" do - reservation_report_16_jun = @front_desk_3.whatevs('16th Jun 3013') + reservation_report_16_jun = @front_desk_3.find_all_reservations_for_date('16th Jun 3013') reservation_report_16_jun.must_be_kind_of Hash reservation_report_16_jun.count.must_equal 2 @@ -142,6 +142,15 @@ end + it "returns an empty hash when there are no rooms reserved for a given day" do + + reservation_report_1_jan = @front_desk_3.find_all_reservations_for_date('1st Jan 4047') + + reservation_report_1_jan.must_be_kind_of Hash + reservation_report_1_jan.must_be_empty + + end + end From 03913cbc7d6a2be25ad18c0970a21388a3ba50e5 Mon Sep 17 00:00:00 2001 From: Victoria Garcia Date: Sat, 10 Mar 2018 23:14:45 -0800 Subject: [PATCH 35/51] the method for generating a list of available rooms for a given date range is now passing all its tests. --- lib/front_desk.rb | 20 ++++++++++---- specs/front_desk_spec.rb | 59 +++++++++++++++++++++++++++++++--------- 2 files changed, 61 insertions(+), 18 deletions(-) diff --git a/lib/front_desk.rb b/lib/front_desk.rb index 92ebebce4..c22aa136c 100644 --- a/lib/front_desk.rb +++ b/lib/front_desk.rb @@ -48,7 +48,21 @@ def find_all_reservations_for_date(date) return overall_report end - def report_all_availabile_rooms(start_dt, end_dt) + def report_all_available_rooms(start_dt, end_dt) + imaginary_reservation = Hotel::Reservation.new(start_dt, end_dt) + all_available_rooms = [] + @rooms.each do |room| + available_room = nil + availability = room.can_accept_reservation?(imaginary_reservation) + if availability[:accept] == true + available_room = room + end + unless available_room == nil + available_room = available_room.room_number + all_available_rooms << available_room + end + end + return all_available_rooms end def find_available_room(start_d, end_d) @@ -74,11 +88,7 @@ def create_reservation_basic(start_date, end_date, room_id) def report_reservation_price(id) end - def report_all_reservations_day(date) - end - def report_all_availabile_rooms(start_dt, end_dt) - end # def check_availability_for_block(st_dt, end_dt) # end diff --git a/specs/front_desk_spec.rb b/specs/front_desk_spec.rb index 2359a4410..ac3c653ee 100644 --- a/specs/front_desk_spec.rb +++ b/specs/front_desk_spec.rb @@ -109,7 +109,7 @@ end end - describe "report_all_reservations_day(date)" do + describe "find_all_reservations_for_date(date)" do before do @room_1000_as.add_reservation(@res_1_fllws_n1_direct) @@ -150,10 +150,54 @@ reservation_report_1_jan.must_be_empty end - end + describe "report_all_available_rooms(start_dt, end_dt)" do + + before do + + @room_4000.add_reservation(@reservation_n1_d) + @room_4000.add_reservation(@reservation_n2_d) + @room_4000.add_reservation(@res_5_fllws_n1_precedes_n2) + + @room_5000.add_reservation(@reservation_n1_c) + @room_5000.add_reservation(@res_1_fllws_n1_direct) + + + @front_desk_3.rooms = [@room_1000_as, @room_2000_bs, @room_4000, @room_5000] + + end + + it "returns an array" do + + @front_desk_3.report_all_available_rooms("12 Jan 2099", "12 May 2099").must_be_kind_of Array + + end + + it "returns a collection of room numbers for the rooms available between specified dates" do + + aug_3013_rept = @front_desk_3.report_all_available_rooms("1 Aug 3013", "17 Aug 3013") + aug_3013_rept.count.must_equal 3 + + aug_3013_rept.must_include "1000" + aug_3013_rept.must_include "2000" + aug_3013_rept.must_include "5000" + + aug_3013_rept.wont_include "4000" + + end + + it "returns an empty array if no rooms are available between specified dates" do + + @front_desk_3.report_all_available_rooms("12th Jun 3013", "14th Jun 3013").must_be_empty + + end + + + + + end describe "find_available_room(start_d, end_d)" do @@ -203,19 +247,8 @@ # describe "report_reservation_price(id)" do # end - xdescribe "report_all_reservations_day(date)" do - - it "reports a list of reservations for a specified date" do - end - - end - xdescribe "report_all_available_rooms(start_dt_julian, end_dt_julian)" do - it "reports a list of rooms that are available for a given date range" do - end - - end #NOT EVEN GOING TO THINK ABOUT THIS PART RIGHT NOW. # describe "check_availability_for_block" do From 864dc7fa316d4adcef5327f69f5476d1e34380b1 Mon Sep 17 00:00:00 2001 From: Victoria Garcia Date: Sat, 10 Mar 2018 23:49:29 -0800 Subject: [PATCH 36/51] the available room-reporting and -choosing methods for FrontDesk are passing all tests. --- lib/front_desk.rb | 21 ++++++++------------- specs/front_desk_spec.rb | 18 +++++++++++++----- 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/lib/front_desk.rb b/lib/front_desk.rb index c22aa136c..04faab5f5 100644 --- a/lib/front_desk.rb +++ b/lib/front_desk.rb @@ -66,20 +66,15 @@ def report_all_available_rooms(start_dt, end_dt) end def find_available_room(start_d, end_d) - proposed_reservation = Hotel::Reservation.new(start_d, end_d) - available_room = nil - @rooms.each do |room| - if available_room == nil - availability = room.can_accept_reservation?(proposed_reservation) - if availability[:accept] == true - available_room = room - end - end - end - unless available_room == nil - available_room = available_room.room_number + + room_to_assign = nil + rooms_available = report_all_available_rooms(start_d, end_d) + unless rooms_available.empty? + rooms_by_int = rooms_available.map{ |rm_numb| rm_numb.to_i } + rooms_by_int.sort! + room_to_assign = rooms_by_int[0].to_s end - return available_room + return room_to_assign end def create_reservation_basic(start_date, end_date, room_id) diff --git a/specs/front_desk_spec.rb b/specs/front_desk_spec.rb index ac3c653ee..79e076634 100644 --- a/specs/front_desk_spec.rb +++ b/specs/front_desk_spec.rb @@ -154,6 +154,8 @@ describe "report_all_available_rooms(start_dt, end_dt)" do + # This method leverages availabiity-checking machinery that already exists in the Reservation class, and that machinery was already heavily tested by the Reservation spec, so it is just given a once-over here. + before do @room_4000.add_reservation(@reservation_n1_d) @@ -194,14 +196,11 @@ end - - - end describe "find_available_room(start_d, end_d)" do - # This method leverages availabiity-checking machinery that already exists in the Reservation class, and that machinery was already heavily tested by the Reservation spec, so it is just given a once-over here. + before do @@ -216,7 +215,16 @@ end - it "returns the ID of a room that is available between specified dates" do + it "returns the ID of a room that is available between specified dates in string form" do + + jun_19_jul_23_choice = @front_desk_3.find_available_room("19th Jun 2013", "23rd Jun 2013") + + jun_19_jul_23_choice.must_be_kind_of String + jun_19_jul_23_choice.must_equal "1000" + + end + + it "if more than one room is available during a given interval, returns the room with the lowest room number" do @front_desk_3.find_available_room("12th Mar 3014", "21st Mar 3014").must_equal "1000" From fb5fe9f73697e8312a58af9eb47b45bc23fee985 Mon Sep 17 00:00:00 2001 From: Victoria Garcia Date: Sun, 11 Mar 2018 00:32:53 -0800 Subject: [PATCH 37/51] tests written for FrontDesk's reservation creation method, and failing/erroring in the desired way. --- lib/front_desk.rb | 4 +++- lib/reservation.rb | 3 ++- lib/room.rb | 7 ++++++ specs/front_desk_spec.rb | 46 ++++++++++++++++++++++++++++++++++------ 4 files changed, 52 insertions(+), 8 deletions(-) diff --git a/lib/front_desk.rb b/lib/front_desk.rb index 04faab5f5..d8b3a6044 100644 --- a/lib/front_desk.rb +++ b/lib/front_desk.rb @@ -77,7 +77,9 @@ def find_available_room(start_d, end_d) return room_to_assign end - def create_reservation_basic(start_date, end_date, room_id) + def create_reservation_basic(start_date, end_date) + + end def report_reservation_price(id) diff --git a/lib/reservation.rb b/lib/reservation.rb index 81bc52bd4..f53aceed8 100644 --- a/lib/reservation.rb +++ b/lib/reservation.rb @@ -25,9 +25,10 @@ def initialize(start_date, end_date ) @hotel_room_id = nil @days_booked_am_and_pm = days_with_am_and_pm_occupation @total_nights = calculate_total_nights + @per_night_price = PER_NIGHT_PRICE @total_reservation_cost = calculate_reservation_price - #THIS IS GOOD, BUT IT EFFS UP YOUR ABILITY TO TEST CERTAIN SHIT. MAYBE PUT THE VALIDATION MEASURE FOR START-DATES IN THE PAST IN FrontDesk??? OR RESCUE?? + #THIS IS GOOD, BUT IT BORKS YOUR ABILITY TO TEST CERTAIN THINGS. MAYBE PUT THE VALIDATION MEASURE FOR START-DATES IN THE PAST IN FrontDesk??? OR RESCUE?? ## Commenting out the req about not starting reservations in the past--- for now. ## GOING TO HAVE THIS LOOK UP THE MIN_RES_IN_SEC on the room to which it is being assigned, using the room numer ID. YASS. diff --git a/lib/room.rb b/lib/room.rb index 2f8277487..3b1e85cf5 100644 --- a/lib/room.rb +++ b/lib/room.rb @@ -82,6 +82,13 @@ def can_accept_reservation?(reservation) def fix_conflicting_date(conflict_array) + # This method needs a better name, but it does something + # small but important. For dates that include the start of + # one reservation and the end of another, it creates a date hash + # with :am and :pm values of true, which another method then + # uses to replace the ones with false-s from the original + # reservations. This keeps the can_accept_reservation? method + # from going nuts in cases of abutting reservations. output_array = conflict_array.map {|d| {d.keys[0] => {:am => true, :pm => true}}} return output_array end diff --git a/specs/front_desk_spec.rb b/specs/front_desk_spec.rb index 79e076634..650920161 100644 --- a/specs/front_desk_spec.rb +++ b/specs/front_desk_spec.rb @@ -200,8 +200,6 @@ describe "find_available_room(start_d, end_d)" do - - before do @room_4000.add_reservation(@reservation_n1_d) @@ -240,20 +238,56 @@ end - xdescribe "create_reservation_basic(start_date, end_date, room_id)" do + describe "create_reservation_basic(start_date, end_date)" do + + before do + + @new_jan_3014_res = @front_desk_2.create_reservation_basic('2nd Jan 3014', '19th Jan 3014') + + end it "generates a reservation for a given date range" do + + @new_jan_3014_res.must_be_instance_of Hotel::Reservation + @new_jan_3014_res.start_date.must_equal DateTime.parse('2nd Jan 3014') + @new_jan_3014_res.end_date.must_equal DateTime.parse('19th Jan 3014') + end - it "assigns the reservation to the hotel room specified" do + it "assigns the reservation to a room that is available for that date range" do + + @new_jan_3014_res.hotel_room_id.must_equal "1000" + + end + + it "adds the reservation to the chosen room's collection" do + + @room_1000_as.reservations.must_include @new_jan_3014_res end + it "assingns the reservation the correct per-night price for the room" do + + @new_jan_3014_res.per_night_price.must_be_within_delta 200.00, 0.001 + + end + + it "raises an error if given an end-date that is earlier than its start date" do + + proc{ @front_desk_2.create_reservation_basic('19th Jan 3014','2nd Jan 3014')}.must_raise StandardError + + end + + it "raises an error if given start and and dates that are less than one night apart" do + + proc{ @front_desk_2.create_reservation_basic('19th Jan 3014','19th Jan 3014')}.must_raise StandardError + + end end # I think this is fully covered in the reservation class? But maybe there's a better way? - # describe "report_reservation_price(id)" do - # end + xdescribe "report_reservation_price(id)" do + end From a79376a1a69c6a3de46af90b9a1e83f29a66289f Mon Sep 17 00:00:00 2001 From: Victoria Garcia Date: Sun, 11 Mar 2018 01:18:52 -0800 Subject: [PATCH 38/51] helper method for the reservation addint now in place and passing tests. --- lib/front_desk.rb | 15 ++++++++++++++- specs/front_desk_spec.rb | 39 ++++++++++++++++++++++++--------------- 2 files changed, 38 insertions(+), 16 deletions(-) diff --git a/lib/front_desk.rb b/lib/front_desk.rb index d8b3a6044..353db42fb 100644 --- a/lib/front_desk.rb +++ b/lib/front_desk.rb @@ -77,11 +77,24 @@ def find_available_room(start_d, end_d) return room_to_assign end - def create_reservation_basic(start_date, end_date) + def look_up_per_night_price_for_room(query_room_numb) + target_room = @rooms.find {|room| room.room_number == query_room_numb} + target_price = target_room.rate_with_discount + end + def create_reservation_basic(start_date, end_date) + room_for_new_res = find_available_room(start_date, end_date) + if room_for_new_res.nil? + raise StandardError.new ("Alas, no rooms are available for this reservation.") + else + new_reservation = Hotel::Reservation.new(start_date, end_date) + end + new_reservation.hotel_room_id = room_for_new_res end + + def report_reservation_price(id) end diff --git a/specs/front_desk_spec.rb b/specs/front_desk_spec.rb index 650920161..df96cf8d7 100644 --- a/specs/front_desk_spec.rb +++ b/specs/front_desk_spec.rb @@ -238,48 +238,57 @@ end - describe "create_reservation_basic(start_date, end_date)" do + xdescribe "create_reservation_basic(start_date, end_date)" do before do - @new_jan_3014_res = @front_desk_2.create_reservation_basic('2nd Jan 3014', '19th Jan 3014') - end it "generates a reservation for a given date range" do - @new_jan_3014_res.must_be_instance_of Hotel::Reservation @new_jan_3014_res.start_date.must_equal DateTime.parse('2nd Jan 3014') @new_jan_3014_res.end_date.must_equal DateTime.parse('19th Jan 3014') - end it "assigns the reservation to a room that is available for that date range" do - @new_jan_3014_res.hotel_room_id.must_equal "1000" - end it "adds the reservation to the chosen room's collection" do - @room_1000_as.reservations.must_include @new_jan_3014_res end it "assingns the reservation the correct per-night price for the room" do - @new_jan_3014_res.per_night_price.must_be_within_delta 200.00, 0.001 - end it "raises an error if given an end-date that is earlier than its start date" do - proc{ @front_desk_2.create_reservation_basic('19th Jan 3014','2nd Jan 3014')}.must_raise StandardError - end it "raises an error if given start and and dates that are less than one night apart" do - proc{ @front_desk_2.create_reservation_basic('19th Jan 3014','19th Jan 3014')}.must_raise StandardError + end + + it "raises an error if no rooms are available in the desired date range." do + proc{ @front_desk_2.create_reservation_basic('11th Jun 3013','13th Jun 3013')}.must_raise StandardError + end + end + + + describe "look_up_per_night_price_for_room(query_room_numb)" do + + before do + @rm_1000_price = @front_desk_2.look_up_per_night_price_for_room("1000") + end + + it "returns a float" do + @rm_1000_price.must_be_kind_of Float + end + + it "correctly identifies the price per night for a given hotel room" do + + @rm_1000_price.must_be_within_delta 200.00, 0.003 end end @@ -288,7 +297,7 @@ xdescribe "report_reservation_price(id)" do end - +end @@ -304,7 +313,7 @@ # # describe "create_reservation_block(start_date_jul, end_date_jul)" do # end -end + From 520105220e9e1d9404d4030f198b72bcb9cd61f9 Mon Sep 17 00:00:00 2001 From: Victoria Garcia Date: Sun, 11 Mar 2018 01:35:27 -0800 Subject: [PATCH 39/51] another small helper method for the reservation creation mechanism in FrontDesk is written and passing its tests. --- lib/front_desk.rb | 8 ++++++++ specs/front_desk_spec.rb | 17 +++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/lib/front_desk.rb b/lib/front_desk.rb index 353db42fb..67d43717c 100644 --- a/lib/front_desk.rb +++ b/lib/front_desk.rb @@ -82,6 +82,10 @@ def look_up_per_night_price_for_room(query_room_numb) target_price = target_room.rate_with_discount end + def locate_room_by_id(query_rm_numb) + target_room = @rooms.find {|room| room.room_number == query_rm_numb} + return target_room + end def create_reservation_basic(start_date, end_date) room_for_new_res = find_available_room(start_date, end_date) @@ -91,6 +95,10 @@ def create_reservation_basic(start_date, end_date) new_reservation = Hotel::Reservation.new(start_date, end_date) end new_reservation.hotel_room_id = room_for_new_res + new_reservation.per_night_price = look_up_per_night_price_for_room(room_for_new_res) + room_object = @rooms.find {|room| room.room_number == room_for_new_res} + room_object.add_reservation(new_reservation) + return new_reservation end diff --git a/specs/front_desk_spec.rb b/specs/front_desk_spec.rb index df96cf8d7..0b518a43d 100644 --- a/specs/front_desk_spec.rb +++ b/specs/front_desk_spec.rb @@ -293,6 +293,23 @@ end end + describe "locate_room_by_id(query_rm_numb)" do + + before do + @rm_2000_object= @front_desk_2.locate_room_by_id("2000") + end + + it "returns an instance of Hotel::Room" do + @rm_2000_object.must_be_instance_of Hotel::Room + end + + it "identifies the correct instance of Room." do + + @rm_2000_object.must_be_same_as @room_2000_bs + + end + end + # I think this is fully covered in the reservation class? But maybe there's a better way? xdescribe "report_reservation_price(id)" do From f1cafbfa635232b332058e36bdecbde2000e66f4 Mon Sep 17 00:00:00 2001 From: Victoria Garcia Date: Sun, 11 Mar 2018 01:49:48 -0800 Subject: [PATCH 40/51] fixed up some stuff having to do with reservation price calculation. --- lib/front_desk.rb | 16 ++++++++++------ lib/reservation.rb | 15 +++------------ specs/front_desk_spec.rb | 2 +- specs/reservation_spec.rb | 6 +++--- 4 files changed, 17 insertions(+), 22 deletions(-) diff --git a/lib/front_desk.rb b/lib/front_desk.rb index 67d43717c..9ed942c65 100644 --- a/lib/front_desk.rb +++ b/lib/front_desk.rb @@ -88,16 +88,20 @@ def locate_room_by_id(query_rm_numb) end def create_reservation_basic(start_date, end_date) - room_for_new_res = find_available_room(start_date, end_date) - if room_for_new_res.nil? + room_numb_for_new_res = find_available_room(start_date, end_date) + if room_numb_for_new_res.nil? raise StandardError.new ("Alas, no rooms are available for this reservation.") else new_reservation = Hotel::Reservation.new(start_date, end_date) end - new_reservation.hotel_room_id = room_for_new_res - new_reservation.per_night_price = look_up_per_night_price_for_room(room_for_new_res) - room_object = @rooms.find {|room| room.room_number == room_for_new_res} - room_object.add_reservation(new_reservation) + new_reservation.hotel_room_id = room_numb_for_new_res + + new_reservation.per_night_price = look_up_per_night_price_for_room(room_numb_for_new_res) + + room_instance_for_res = locate_room_by_id(room_numb_for_new_res) + + room_instance_for_res.add_reservation(new_reservation) + return new_reservation end diff --git a/lib/reservation.rb b/lib/reservation.rb index f53aceed8..ca7f5120e 100644 --- a/lib/reservation.rb +++ b/lib/reservation.rb @@ -7,7 +7,7 @@ module Hotel class Reservation - attr_accessor :start_date, :end_date, :hotel_room_id, :days_booked_am_and_pm + attr_accessor :start_date, :end_date, :hotel_room_id, :days_booked_am_and_pm, :per_night_price attr_reader :id, :total_nights, :total_reservation_cost @@last_id_base = 0 @@ -15,9 +15,6 @@ class Reservation # The constant below, MIN_RES_IN_SEC, is the length of the minimum reservation, in seconds. This figure was arrived at by calculating the number of seconds between an early-but-common check-out time (10:00 am) and the change of date at midnight. The putative customer could, of course, change this to whatever they wanted. MIN_RES_IN_SEC = 36000 - #Since all rooms are identical, and we haven't been given any parameters for price variation, it makes sense to assign a default price for the moment. If the customer needs more options or granularity here, that cna be implemented later - PER_NIGHT_PRICE = 100.00 - def initialize(start_date, end_date ) @id = assign_id @start_date = DateTime.parse(start_date) @@ -25,7 +22,7 @@ def initialize(start_date, end_date ) @hotel_room_id = nil @days_booked_am_and_pm = days_with_am_and_pm_occupation @total_nights = calculate_total_nights - @per_night_price = PER_NIGHT_PRICE + @per_night_price = 200.00 # Assigning this as a default, but there is a mechanism for overwriting during reservation creation in FrontDesk. @total_reservation_cost = calculate_reservation_price #THIS IS GOOD, BUT IT BORKS YOUR ABILITY TO TEST CERTAIN THINGS. MAYBE PUT THE VALIDATION MEASURE FOR START-DATES IN THE PAST IN FrontDesk??? OR RESCUE?? @@ -88,13 +85,7 @@ def days_with_am_and_pm_occupation end def calculate_reservation_price - #I know this isn't exactly best practice for dealing with real-world currency. But since we haven't covered that yet and this isn't the real world, this is what I'm going with. - - #OK, SO WHAT THIS IS ACTUALLY GOING TO DO IS: - # LOOK UP THE ROOM TO WHICH IT AS ASSIGNED USING HOTEL_ROOM_ID - # FIND THE PRICE AND DISCOUNT OF THAT ROOM - # APPLY THEM HERE. - (@total_nights * PER_NIGHT_PRICE).round(2) + (@total_nights * @per_night_price).round(2) end end end diff --git a/specs/front_desk_spec.rb b/specs/front_desk_spec.rb index 0b518a43d..1d661e999 100644 --- a/specs/front_desk_spec.rb +++ b/specs/front_desk_spec.rb @@ -238,7 +238,7 @@ end - xdescribe "create_reservation_basic(start_date, end_date)" do + describe "create_reservation_basic(start_date, end_date)" do before do @new_jan_3014_res = @front_desk_2.create_reservation_basic('2nd Jan 3014', '19th Jan 3014') diff --git a/specs/reservation_spec.rb b/specs/reservation_spec.rb index 195617ffb..db534f0b8 100644 --- a/specs/reservation_spec.rb +++ b/specs/reservation_spec.rb @@ -138,9 +138,9 @@ end it "accurately returns the product of the room's per-day price and the length (in days) of the reservation" do - @reservation_0_nominal_6n.calculate_reservation_price.must_be_within_delta 600.00, 0.003 - @reservation_1_1n.calculate_reservation_price.must_be_within_delta 100.00, 0.003 - @reservation_3_35n.calculate_reservation_price.must_be_within_delta 3500.00, 0.003 + @reservation_0_nominal_6n.calculate_reservation_price.must_be_within_delta 1200.00, 0.003 + @reservation_1_1n.calculate_reservation_price.must_be_within_delta 200.00, 0.003 + @reservation_3_35n.calculate_reservation_price.must_be_within_delta 7000.00, 0.003 end end end From 6c23ed17687387203ee0cfead03b8b9148c672b3 Mon Sep 17 00:00:00 2001 From: Victoria Garcia Date: Sun, 11 Mar 2018 03:09:24 -0700 Subject: [PATCH 41/51] tests written for FrontDesk's reservation price calculation method, and failing/erroring the right way. --- lib/front_desk.rb | 1 + specs/front_desk_spec.rb | 22 ++++++++++++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/lib/front_desk.rb b/lib/front_desk.rb index 9ed942c65..a7744a88f 100644 --- a/lib/front_desk.rb +++ b/lib/front_desk.rb @@ -108,6 +108,7 @@ def create_reservation_basic(start_date, end_date) def report_reservation_price(id) + end diff --git a/specs/front_desk_spec.rb b/specs/front_desk_spec.rb index 1d661e999..c5cff4667 100644 --- a/specs/front_desk_spec.rb +++ b/specs/front_desk_spec.rb @@ -16,6 +16,7 @@ @room_5000 = Hotel::Room.new("5000") @room_6000 = Hotel::Room.new("6000") @room_7000 = Hotel::Room.new("7000") + @room_8000 = Hotel::Room.new("8000") @reservation_n1_a = Hotel::Reservation.new('10th Jun 3013', '16th Jun 3013') @reservation_n2_a = Hotel::Reservation.new('10th Jun 3014', '16th Jun 3014') @@ -310,9 +311,26 @@ end end - # I think this is fully covered in the reservation class? But maybe there's a better way? + describe "report_reservation_price(id)" do - xdescribe "report_reservation_price(id)" do + before do + @room_6000.add_reservation(@reservation_n1_c) + @room_6000.add_reservation(@res_6_singleton) + + @front_desk_3.rooms = [@room_1000_as, @room_6000, @room_2000_bs] + + @qres_price_query_id = @res_6_singleton.id + + @reported_price = @front_desk_3.report_reservation_price(@res_price_query_id) + end + + it "identifies returns a float" do + @reported_price.must_be_kind_of Float + end + + it "correctly reports the price of a reservation" do + @reported_price.must_be_within_delta 2200.00, 0.003 + end end end From 306b34552a387a8e0e95ec5fc5ad64333a4f6726 Mon Sep 17 00:00:00 2001 From: Victoria Garcia Date: Sun, 11 Mar 2018 03:44:01 -0700 Subject: [PATCH 42/51] last of the pre-Wave 3 FrontDesk methods are now passing all tests. that's all for tonight. --- lib/front_desk.rb | 16 ++++++++++++++-- specs/front_desk_spec.rb | 8 ++++++-- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/lib/front_desk.rb b/lib/front_desk.rb index a7744a88f..e0a206fee 100644 --- a/lib/front_desk.rb +++ b/lib/front_desk.rb @@ -107,12 +107,24 @@ def create_reservation_basic(start_date, end_date) - def report_reservation_price(id) + def find_reservation_price(query_id) + target_reservation = nil + price_of_target = nil + @rooms.each do |room| + unless target_reservation != nil + room.reservations.each do |reservation| + if reservation.id == query_id + target_reservation = reservation + price_of_target = target_reservation.total_reservation_cost + end + end + end + end + return price_of_target end - # def check_availability_for_block(st_dt, end_dt) # end # diff --git a/specs/front_desk_spec.rb b/specs/front_desk_spec.rb index c5cff4667..76ead8fb1 100644 --- a/specs/front_desk_spec.rb +++ b/specs/front_desk_spec.rb @@ -319,9 +319,9 @@ @front_desk_3.rooms = [@room_1000_as, @room_6000, @room_2000_bs] - @qres_price_query_id = @res_6_singleton.id + @res_price_query_id = @res_6_singleton.id - @reported_price = @front_desk_3.report_reservation_price(@res_price_query_id) + @reported_price = @front_desk_3.find_reservation_price(@res_price_query_id) end it "identifies returns a float" do @@ -331,6 +331,10 @@ it "correctly reports the price of a reservation" do @reported_price.must_be_within_delta 2200.00, 0.003 end + + it "returns nil if the reservation id does not exist" do + @front_desk_3.find_reservation_price("1111111111111").must_be_nil + end end end From 8ba248597f9d5265be9ef61a6e612fd6f34bf134 Mon Sep 17 00:00:00 2001 From: Victoria Garcia Date: Sun, 11 Mar 2018 23:10:27 -0700 Subject: [PATCH 43/51] room identificaiton method for the block stuff is now passing all tests. --- lib/front_desk.rb | 27 +++++++------ specs/front_desk_spec.rb | 85 ++++++++++++++++++++++++++++++++++------ 2 files changed, 88 insertions(+), 24 deletions(-) diff --git a/lib/front_desk.rb b/lib/front_desk.rb index e0a206fee..4925e26f3 100644 --- a/lib/front_desk.rb +++ b/lib/front_desk.rb @@ -125,16 +125,21 @@ def find_reservation_price(query_id) end - # def check_availability_for_block(st_dt, end_dt) - # end - # - # def create_room_block(block_size, block_discount) - # end - # - # def report_available_block_rooms(start_d, end_d) - # end - # - # def create_reservation_block(start_date, end_date) - # end + def check_block_feasibility(st_dt, end_dt, block_size) + block_y_or_n = nil + elig_for_block = report_all_available_rooms(st_dt, end_dt) + if elig_for_block.length >= block_size + block_y_or_n = {:yes => elig_for_block} + else + block_y_or_n = {:no => []} + end + return block_y_or_n + end + + def create_room_block(st_date, end_date, block_discount) + end + + def create_reservation_block(start_date, end_date) + end end end diff --git a/specs/front_desk_spec.rb b/specs/front_desk_spec.rb index 76ead8fb1..57ad07d50 100644 --- a/specs/front_desk_spec.rb +++ b/specs/front_desk_spec.rb @@ -336,24 +336,83 @@ @front_desk_3.find_reservation_price("1111111111111").must_be_nil end end -end + describe "check_block_feasibility(st_dt, end_dt, block_size)" do + + before do + + @room_3000_cs.add_reservation(@reservation_n1_c) + @room_3000_cs.add_reservation(@reservation_n2_c) + @room_3000_cs.add_reservation(@reservation_n3_c) + + @three_rooms_identical_avail = [@room_1000_as, @room_2000_bs, @room_3000_cs] + + @front_desk_3.rooms = @three_rooms_identical_avail + + @three_ident_feasible = @front_desk_3.check_block_feasibility('1st Mar 3015', '10th Mar 3015', 3) + + + @three_ident_infeas = @front_desk_3.check_block_feasibility('1st Nov 3015', '10th Nov 3015', 3) + + end - #NOT EVEN GOING TO THINK ABOUT THIS PART RIGHT NOW. - # describe "check_availability_for_block" do - # end - # - # describe "create_room_block(block_size, block_discount)" do - # end - # - # describe "report_available_block_rooms" do - # end - # - # describe "create_reservation_block(start_date_jul, end_date_jul)" do - # end + it "returns a hash containing a single key-value pair, whether a block of rooms is available or not." do + @three_ident_feasible.must_be_kind_of Hash + @three_ident_infeas.must_be_kind_of Hash + @three_ident_feasible.count.must_equal 1 + @three_ident_infeas.count.must_equal 1 + + end + + it "has a key with the value :yes when rooms are available for the block" do + + @three_ident_feasible.keys.must_include :yes + + end + + it "has a key with the value :no when not enough rooms are available for the block" do + + @three_ident_infeas.keys.must_include :no + + end + + it "when rooms are available for the block, returns a key-value where the value is an array of the room numbers of available rooms" do + + @three_ident_feasible[:yes].must_be_kind_of Array + @three_ident_feasible[:yes].each {|element| element.must_be_kind_of String} + @three_ident_feasible[:yes].each {|element| element.must_match /^\d+$/ } + + end + + it "accurately reports the room numbers of rooms available for the block" do + + @three_ident_feasible[:yes].length.must_equal 3 + @three_ident_feasible[:yes].must_include "1000" + @three_ident_feasible[:yes].must_include "2000" + @three_ident_feasible[:yes].must_include "3000" + end + + it "returns a key-value pair with an empty array as the value if not enough rooms are available for the block" do + + @three_ident_infeas[:no].must_be_kind_of Array + @three_ident_infeas[:no].must_be_empty + + end + end + + describe "create_room_block(block_size, block_discount)" do + end + + describe "report_available_rooms_within_block" do + end + + describe "create_reservation_block(start_date_jul, end_date_jul)" do + end + +end From 7e63aa696a84ca0339b30c41fa786506142edd8e Mon Sep 17 00:00:00 2001 From: Victoria Garcia Date: Mon, 12 Mar 2018 02:52:42 -0700 Subject: [PATCH 44/51] a whole bunch of machinery for hte Block Resrvation stuff is now functioning and passing tests, including the new class BlockRoo. --- lib/BlockRoom.rb | 19 ++++++++++++++++ lib/front_desk.rb | 41 ++++++++++++++++++++++++++++++--- lib/reservation.rb | 13 +++++++---- lib/room.rb | 3 ++- specs/BlockRoom_spec.rb | 41 +++++++++++++++++++++++++++++++++ specs/front_desk_spec.rb | 48 ++++++++++++++++++++++++++++----------- specs/reservation_spec.rb | 6 +++++ specs/room_spec.rb | 4 ++++ specs/spec_helper.rb | 1 + 9 files changed, 154 insertions(+), 22 deletions(-) create mode 100644 lib/BlockRoom.rb create mode 100644 specs/BlockRoom_spec.rb diff --git a/lib/BlockRoom.rb b/lib/BlockRoom.rb new file mode 100644 index 000000000..a95e169ca --- /dev/null +++ b/lib/BlockRoom.rb @@ -0,0 +1,19 @@ + + +module Hotel + class BlockRoom < Hotel::Room + + attr_reader :room_number, :base_resv_price, :min_res_sec, :rate_with_discount, :block_id, :block_start, :block_end + + attr_accessor :discount, :reservations, :dates_unavailable + + def initialize(room_number, block_id, discount, block_start, block_end) + + @room_number = room_number.concat("-B") + @block_id = block_id + @block_start = DateTime.parse(block_start) + @block_end = DateTime.parse(block_end) + end + + end +end diff --git a/lib/front_desk.rb b/lib/front_desk.rb index 4925e26f3..7a6260ed6 100644 --- a/lib/front_desk.rb +++ b/lib/front_desk.rb @@ -7,13 +7,14 @@ module Hotel class FrontDesk - attr_accessor :rooms + attr_accessor :rooms, :blocks TOTAL_ROOMS_IN_FACILITY = 20 def initialize @rooms = generate_rooms + @blocks = [] end @@ -107,6 +108,7 @@ def create_reservation_basic(start_date, end_date) + def find_reservation_price(query_id) target_reservation = nil @@ -136,10 +138,43 @@ def check_block_feasibility(st_dt, end_dt, block_size) return block_y_or_n end - def create_room_block(st_date, end_date, block_discount) + def create_placeholder_res(start_date, end_date, room_id, block_id) + + reservation_for_block = Hotel::Reservation.new(start_date, end_date) + + reservation_for_block.hotel_room_id = room_id + reservation_for_block.block_set_aside = true + reservation_for_block.block_id = block_id + + return reservation_for_block end - def create_reservation_block(start_date, end_date) + # def create_room_block(st_date, end_date, block_size, block_discount) + # feasability_result = check_block_feasibility(st_date, end_date, block_size) + # if feasability_result.keys.include?(:no) + # raise StandardError.new("There are not enough available rooms to create this block") + # else + # block_id = Hotel::Reservation.assign_id(Hotel::Reservation.last_block_base) + # Hotel::Reservation.last_block_base += 1 + # rooms_available_for_block = feasability_result[:yes] + # rooms_reserved_in_block = [] + # rooms_available_for_block block_size.times do |room_id| + # room_for_block = locate_room_by_id(room_id) + # placeholder_res = create_block_placeholder_reservation(st_date, end_date, room_id, block_id) + # room_for_block.add_reservation(placeholder_res) + # block_availability_object = Hotel::BlockRoom.new(room_id, block_id, block_discount, block_start, block_end) + # rooms_reserved_in_block << block_availability_object + # end + # block = {block_id.to_sym => rooms_reserved_in_block} + # end + # return block + # end + + def check_availability_within_block(start_date, end_date, block_id) + end + + + def create_reservation_within_block(start_date, end_date, block_id) end end end diff --git a/lib/reservation.rb b/lib/reservation.rb index ca7f5120e..488f961bb 100644 --- a/lib/reservation.rb +++ b/lib/reservation.rb @@ -7,16 +7,17 @@ module Hotel class Reservation - attr_accessor :start_date, :end_date, :hotel_room_id, :days_booked_am_and_pm, :per_night_price + attr_accessor :start_date, :end_date, :hotel_room_id, :days_booked_am_and_pm, :per_night_price, :block_set_aside, :block_id attr_reader :id, :total_nights, :total_reservation_cost @@last_id_base = 0 + @@last_block_base = 0 # The constant below, MIN_RES_IN_SEC, is the length of the minimum reservation, in seconds. This figure was arrived at by calculating the number of seconds between an early-but-common check-out time (10:00 am) and the change of date at midnight. The putative customer could, of course, change this to whatever they wanted. MIN_RES_IN_SEC = 36000 def initialize(start_date, end_date ) - @id = assign_id + @id = assign_id(@@last_id_base) @start_date = DateTime.parse(start_date) @end_date = DateTime.parse(end_date) @hotel_room_id = nil @@ -24,6 +25,8 @@ def initialize(start_date, end_date ) @total_nights = calculate_total_nights @per_night_price = 200.00 # Assigning this as a default, but there is a mechanism for overwriting during reservation creation in FrontDesk. @total_reservation_cost = calculate_reservation_price + @block_set_aside = false + @block_id = nil #THIS IS GOOD, BUT IT BORKS YOUR ABILITY TO TEST CERTAIN THINGS. MAYBE PUT THE VALIDATION MEASURE FOR START-DATES IN THE PAST IN FrontDesk??? OR RESCUE?? ## Commenting out the req about not starting reservations in the past--- for now. @@ -32,11 +35,11 @@ def initialize(start_date, end_date ) if (@end_date.to_time.to_i - @start_date.to_time.to_i) < MIN_RES_IN_SEC #|| @start_date.to_time.to_i < Time.now.to_i raise StandardError.new("A reservation's end date must come after its start date, and it must be at least one night long.") end + @@last_id_base += 1 end - def assign_id - new_id_base = (@@last_id_base + 1).to_s - @@last_id_base += 1 + def assign_id(base_id) + new_id_base = (base_id + 1).to_s zeroes_needed = 8 - new_id_base.length leading_zero_array = (1..zeroes_needed).collect {"0"} new_id = leading_zero_array.join.concat(new_id_base) diff --git a/lib/room.rb b/lib/room.rb index 3b1e85cf5..8cd1c5b0e 100644 --- a/lib/room.rb +++ b/lib/room.rb @@ -7,7 +7,7 @@ module Hotel class Room attr_reader :room_number, :base_resv_price, :min_res_sec, :rate_with_discount - attr_accessor :discount, :reservations, :dates_unavailable + attr_accessor :discount, :reservations, :dates_unavailable, :block_set_asides BASE_RESERV_PRICE = 200.00 MIN_RESERV_SECONDS = 36000 @@ -20,6 +20,7 @@ def initialize(room_number) @rate_with_discount = BASE_RESERV_PRICE - (BASE_RESERV_PRICE * @discount) @reservations = [] @dates_unavailable = {} + @block_set_asides = [] end def report_all_reservations diff --git a/specs/BlockRoom_spec.rb b/specs/BlockRoom_spec.rb new file mode 100644 index 000000000..39ab1b758 --- /dev/null +++ b/specs/BlockRoom_spec.rb @@ -0,0 +1,41 @@ +require 'date' +require 'pry' +require_relative 'spec_helper' + +describe "BlockRoom class" do + + before do + + @basic_blockrm_1 = Hotel::BlockRoom.new("21", "3", 0.75, '12th March 4014', '20th March 4014') + + end + + describe "initialize(room_number, block_id, discount, block_start, block_end)" do + + it "can be initialized" do + @basic_blockrm_1.must_be_instance_of Hotel::BlockRoom + end + + + it "has a @block_id variable that contains a number in string form" do + + @basic_blockrm_1.block_id.must_be_kind_of String + @basic_blockrm_1.block_id.must_match /^\d+$/ + end + it "has a @block_start variable that contains an instance of Ruby's date class " do + + @basic_blockrm_1.block_start.must_be_instance_of DateTime + end + + it "has a @block_end variable that contains an instance of Ruby's date class " do + + @basic_blockrm_1.block_end.must_be_instance_of DateTime + + end + + + end + + + +end diff --git a/specs/front_desk_spec.rb b/specs/front_desk_spec.rb index 57ad07d50..9e6712ab4 100644 --- a/specs/front_desk_spec.rb +++ b/specs/front_desk_spec.rb @@ -1,4 +1,5 @@ require 'date' +require 'pry' require_relative 'spec_helper' describe "FrontDesk class" do @@ -8,6 +9,7 @@ @front_desk_1 = Hotel::FrontDesk.new @front_desk_2 = Hotel::FrontDesk.new @front_desk_3 = Hotel::FrontDesk.new + @front_desk_4 = Hotel::FrontDesk.new @room_1000_as = Hotel::Room.new("1000") @room_2000_bs = Hotel::Room.new("2000") @@ -72,6 +74,15 @@ @front_desk_0.rooms.each {|element| element.must_be_instance_of Hotel::Room} @front_desk_0.rooms.count.must_equal 20 end + + it "has an instance variable, @blocks, which begins as an empty array" do + + + @front_desk_0.blocks.must_be_kind_of Array + + @front_desk_0.blocks.must_be_empty + + end end describe "generate_rooms" do @@ -403,30 +414,41 @@ end end - describe "create_room_block(block_size, block_discount)" do - end + describe "create_block_placeholder_res(start_date, end_date, room_id, block_id)" do - describe "report_available_rooms_within_block" do - end - describe "create_reservation_block(start_date_jul, end_date_jul)" do - end + before do -end + @placeholder_reservation = @front_desk_4.create_placeholder_res('12th Jan 2099', '19th Jan 2099', '7000', '8') + end + + it "is an instance of Reservation" do + + @placeholder_reservation.must_be_instance_of Hotel::Reservation + end + it "has a start date and an end date that are instances of Ruby's DateTime class" do + @placeholder_reservation.start_date.must_be_instance_of DateTime + @placeholder_reservation.end_date.must_be_instance_of DateTime + end + it "has a value of true for its @block_set_aside instance variable" do + @placeholder_reservation.block_set_aside.must_equal true + end -# Note: COMMENTING THIS OUT FOR NOW. WILL PROBABLY move this functionality to FrontDesk. -# it "Raises an error if the start date comes before the date of instantiation" do -# too_early_start = '1st Feb 1975' -# acceptible_end = '2nd Feb 3080' -# proc{ Hotel::Reservation.new(too_early_start, acceptible_end) }.must_raise StandardError -# end + it "has a @block_id variable that takes a number in string form as its value" do + + @placeholder_reservation.block_id.must_be_kind_of String + @placeholder_reservation.block_id.must_match /^\d+$/ + + end + end +end diff --git a/specs/reservation_spec.rb b/specs/reservation_spec.rb index db534f0b8..bd4c65e63 100644 --- a/specs/reservation_spec.rb +++ b/specs/reservation_spec.rb @@ -25,7 +25,13 @@ @reservation_0_nominal_6n.end_date.must_be_instance_of DateTime end + it "has a default value of false for @block_set_aside" do + @reservation_0_nominal_6n.block_set_aside.must_equal false + end + it "has a default value of nil for @block_id" do + @reservation_0_nominal_6n.block_id.must_be_nil + end it "raises an error if the end date is not at least one day after the end date" do late_start = '3rd May 3075' diff --git a/specs/room_spec.rb b/specs/room_spec.rb index 912e92bb6..835ff1aeb 100644 --- a/specs/room_spec.rb +++ b/specs/room_spec.rb @@ -39,6 +39,10 @@ it "must store its reservations in an array" do @room_300_nominal.reservations.must_be_kind_of Array end + it "must have a @block_set_asides variable that begins as an empty array " do + @room_300_nominal.block_set_asides.must_be_kind_of Array + @room_300_nominal.block_set_asides.must_be_empty + end end describe "report_all_reservations" do diff --git a/specs/spec_helper.rb b/specs/spec_helper.rb index ed1ccc2a3..15ca2c96a 100644 --- a/specs/spec_helper.rb +++ b/specs/spec_helper.rb @@ -12,3 +12,4 @@ require_relative '../lib/front_desk' require_relative '../lib/reservation' require_relative '../lib/room' +require_relative '../lib/BlockRoom' From cf17877d8d5537df1259d790b4b8ae3aacc938e1 Mon Sep 17 00:00:00 2001 From: Victoria Garcia Date: Mon, 12 Mar 2018 03:51:29 -0700 Subject: [PATCH 45/51] the block set-aside mechanism in FrontDesk is passing initial tests. --- lib/front_desk.rb | 44 ++++++++++++++++++++---------------- lib/reservation.rb | 10 ++++---- specs/front_desk_spec.rb | 49 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+), 26 deletions(-) diff --git a/lib/front_desk.rb b/lib/front_desk.rb index 7a6260ed6..35ab4fe54 100644 --- a/lib/front_desk.rb +++ b/lib/front_desk.rb @@ -10,6 +10,7 @@ class FrontDesk attr_accessor :rooms, :blocks TOTAL_ROOMS_IN_FACILITY = 20 + @@last_block_base = 100 def initialize @@ -149,26 +150,29 @@ def create_placeholder_res(start_date, end_date, room_id, block_id) return reservation_for_block end - # def create_room_block(st_date, end_date, block_size, block_discount) - # feasability_result = check_block_feasibility(st_date, end_date, block_size) - # if feasability_result.keys.include?(:no) - # raise StandardError.new("There are not enough available rooms to create this block") - # else - # block_id = Hotel::Reservation.assign_id(Hotel::Reservation.last_block_base) - # Hotel::Reservation.last_block_base += 1 - # rooms_available_for_block = feasability_result[:yes] - # rooms_reserved_in_block = [] - # rooms_available_for_block block_size.times do |room_id| - # room_for_block = locate_room_by_id(room_id) - # placeholder_res = create_block_placeholder_reservation(st_date, end_date, room_id, block_id) - # room_for_block.add_reservation(placeholder_res) - # block_availability_object = Hotel::BlockRoom.new(room_id, block_id, block_discount, block_start, block_end) - # rooms_reserved_in_block << block_availability_object - # end - # block = {block_id.to_sym => rooms_reserved_in_block} - # end - # return block - # end + def create_room_block(st_date, end_date, block_size, block_discount) + feasability_result = check_block_feasibility(st_date, end_date, block_size) + if feasability_result.keys.include?(:no) + raise StandardError.new("There are not enough available rooms to create this block") + else + block_id = @@last_block_base.to_s + @@last_block_base += 1 + rooms_available_for_block = feasability_result[:yes] + room_surplus = rooms_available_for_block.length - block_size + as_many_rooms_as_needed = rooms_available_for_block.drop(room_surplus) + rooms_reserved_in_block = [] + as_many_rooms_as_needed.each do |room_id| + room_for_block = locate_room_by_id(room_id) + placeholder_res = create_placeholder_res(st_date, end_date, room_id, block_id) + room_for_block.add_reservation(placeholder_res) + block_availability_object = Hotel::BlockRoom.new(room_id, block_id, block_discount, st_date, end_date) + rooms_reserved_in_block << block_availability_object + end + block = {block_id.to_sym => rooms_reserved_in_block} + @blocks << block + end + return block + end def check_availability_within_block(start_date, end_date, block_id) end diff --git a/lib/reservation.rb b/lib/reservation.rb index 488f961bb..71192a5d2 100644 --- a/lib/reservation.rb +++ b/lib/reservation.rb @@ -11,13 +11,12 @@ class Reservation attr_reader :id, :total_nights, :total_reservation_cost @@last_id_base = 0 - @@last_block_base = 0 # The constant below, MIN_RES_IN_SEC, is the length of the minimum reservation, in seconds. This figure was arrived at by calculating the number of seconds between an early-but-common check-out time (10:00 am) and the change of date at midnight. The putative customer could, of course, change this to whatever they wanted. MIN_RES_IN_SEC = 36000 - def initialize(start_date, end_date ) - @id = assign_id(@@last_id_base) + def initialize(start_date, end_date) + @id = assign_id @start_date = DateTime.parse(start_date) @end_date = DateTime.parse(end_date) @hotel_room_id = nil @@ -35,11 +34,10 @@ def initialize(start_date, end_date ) if (@end_date.to_time.to_i - @start_date.to_time.to_i) < MIN_RES_IN_SEC #|| @start_date.to_time.to_i < Time.now.to_i raise StandardError.new("A reservation's end date must come after its start date, and it must be at least one night long.") end - @@last_id_base += 1 end - def assign_id(base_id) - new_id_base = (base_id + 1).to_s + def assign_id + new_id_base = (@@last_id_base += 1).to_s zeroes_needed = 8 - new_id_base.length leading_zero_array = (1..zeroes_needed).collect {"0"} new_id = leading_zero_array.join.concat(new_id_base) diff --git a/specs/front_desk_spec.rb b/specs/front_desk_spec.rb index 9e6712ab4..9bbe5adab 100644 --- a/specs/front_desk_spec.rb +++ b/specs/front_desk_spec.rb @@ -451,4 +451,53 @@ end end + describe "create_room_block(st_date, end_date, block_size, block_discount)" do + + before do + @room_3000_cs.add_reservation(@reservation_n1_c) + @room_3000_cs.add_reservation(@reservation_n2_c) + @room_3000_cs.add_reservation(@reservation_n3_c) + + @three_rooms_identical_avail = [@room_1000_as, @room_2000_bs, @room_3000_cs] + + @front_desk_3.rooms = @three_rooms_identical_avail + + @valid_block = @front_desk_3.create_room_block('1st Mar 3015', '10th Mar 3015', 3, 0.2) + + + # @three_ident_infeas = @front_desk_3.check_block_feasibility('1st Nov 3015', '10th Nov 3015', 3) + end + + it "returns a hash exactly one key-value pair long, when enough rooms are available for the reservation" do + + @valid_block.must_be_kind_of Hash + @valid_block.count.must_equal 1 + + end + + it "Raises a StandardError when there are not enough rooms available for the block" do + + proc{ @front_desk_3.create_room_block('1st Nov 3015', '10th Nov 3015', 3)}.must_raise StandardError + + end + + it "has a key that is a procedurally generated block id number in symbol look_up_per_night_price_for_room" do + + @valid_block.keys.length.must_equal 1 + @valid_block.keys[0].must_be_kind_of Symbol + @valid_block.keys[0].to_s.must_match /^\d+$/ + + end + + it "has as its value an array of instances of BlockRoom" do + + @valid_block.values.length.must_equal 1 + @valid_block.values[0].must_be_kind_of Array + @valid_block.values[0].each {|element| element.must_be_instance_of Hotel::BlockRoom} + + end + + # check + + end end From 620f3177ad5318ced54ea5d11734fcee8f8019fb Mon Sep 17 00:00:00 2001 From: Victoria Garcia Date: Mon, 12 Mar 2018 05:36:35 -0700 Subject: [PATCH 46/51] The availability-checking mechanisms for within the blocks is now working --- lib/BlockRoom.rb | 3 ++ lib/front_desk.rb | 25 +++++++----- specs/front_desk_spec.rb | 82 ++++++++++++++++++++++++++++++---------- 3 files changed, 81 insertions(+), 29 deletions(-) diff --git a/lib/BlockRoom.rb b/lib/BlockRoom.rb index a95e169ca..95d6ecf16 100644 --- a/lib/BlockRoom.rb +++ b/lib/BlockRoom.rb @@ -7,8 +7,11 @@ class BlockRoom < Hotel::Room attr_accessor :discount, :reservations, :dates_unavailable + def initialize(room_number, block_id, discount, block_start, block_end) + super(room_number) + @room_number = room_number.concat("-B") @block_id = block_id @block_start = DateTime.parse(block_start) diff --git a/lib/front_desk.rb b/lib/front_desk.rb index 35ab4fe54..b3c21e65a 100644 --- a/lib/front_desk.rb +++ b/lib/front_desk.rb @@ -50,10 +50,10 @@ def find_all_reservations_for_date(date) return overall_report end - def report_all_available_rooms(start_dt, end_dt) + def report_all_available_rooms(start_dt, end_dt, room_set) imaginary_reservation = Hotel::Reservation.new(start_dt, end_dt) all_available_rooms = [] - @rooms.each do |room| + room_set.each do |room| available_room = nil availability = room.can_accept_reservation?(imaginary_reservation) if availability[:accept] == true @@ -67,10 +67,10 @@ def report_all_available_rooms(start_dt, end_dt) return all_available_rooms end - def find_available_room(start_d, end_d) + def find_available_room(start_d, end_d, room_set) room_to_assign = nil - rooms_available = report_all_available_rooms(start_d, end_d) + rooms_available = report_all_available_rooms(start_d, end_d, room_set) unless rooms_available.empty? rooms_by_int = rooms_available.map{ |rm_numb| rm_numb.to_i } rooms_by_int.sort! @@ -89,8 +89,8 @@ def locate_room_by_id(query_rm_numb) return target_room end - def create_reservation_basic(start_date, end_date) - room_numb_for_new_res = find_available_room(start_date, end_date) + def create_reservation_basic(start_date, end_date, room_set) + room_numb_for_new_res = find_available_room(start_date, end_date, room_set) if room_numb_for_new_res.nil? raise StandardError.new ("Alas, no rooms are available for this reservation.") else @@ -128,9 +128,9 @@ def find_reservation_price(query_id) end - def check_block_feasibility(st_dt, end_dt, block_size) + def check_block_feasibility(st_dt, end_dt,room_set, block_size) block_y_or_n = nil - elig_for_block = report_all_available_rooms(st_dt, end_dt) + elig_for_block = report_all_available_rooms(st_dt, end_dt, room_set) if elig_for_block.length >= block_size block_y_or_n = {:yes => elig_for_block} else @@ -150,8 +150,8 @@ def create_placeholder_res(start_date, end_date, room_id, block_id) return reservation_for_block end - def create_room_block(st_date, end_date, block_size, block_discount) - feasability_result = check_block_feasibility(st_date, end_date, block_size) + def create_room_block(st_date, end_date, block_size, room_set, block_discount) + feasability_result = check_block_feasibility(st_date, end_date, room_set, block_size) if feasability_result.keys.include?(:no) raise StandardError.new("There are not enough available rooms to create this block") else @@ -166,6 +166,7 @@ def create_room_block(st_date, end_date, block_size, block_discount) placeholder_res = create_placeholder_res(st_date, end_date, room_id, block_id) room_for_block.add_reservation(placeholder_res) block_availability_object = Hotel::BlockRoom.new(room_id, block_id, block_discount, st_date, end_date) + block_availability_object.discount = block_discount rooms_reserved_in_block << block_availability_object end block = {block_id.to_sym => rooms_reserved_in_block} @@ -175,6 +176,10 @@ def create_room_block(st_date, end_date, block_size, block_discount) end def check_availability_within_block(start_date, end_date, block_id) + block_key = block_id.to_sym + target_block = @blocks.find {|element| element.has_key?(block_key)} + available_block_rooms = report_all_available_rooms(start_date, end_date, target_block.values[0]) + return available_block_rooms end diff --git a/specs/front_desk_spec.rb b/specs/front_desk_spec.rb index 9bbe5adab..69f92c711 100644 --- a/specs/front_desk_spec.rb +++ b/specs/front_desk_spec.rb @@ -164,7 +164,7 @@ end end - describe "report_all_available_rooms(start_dt, end_dt)" do + describe "report_all_available_rooms(start_dt, end_dt, room_set)" do # This method leverages availabiity-checking machinery that already exists in the Reservation class, and that machinery was already heavily tested by the Reservation spec, so it is just given a once-over here. @@ -184,13 +184,13 @@ it "returns an array" do - @front_desk_3.report_all_available_rooms("12 Jan 2099", "12 May 2099").must_be_kind_of Array + @front_desk_3.report_all_available_rooms("12 Jan 2099", "12 May 2099", @front_desk_3.rooms).must_be_kind_of Array end it "returns a collection of room numbers for the rooms available between specified dates" do - aug_3013_rept = @front_desk_3.report_all_available_rooms("1 Aug 3013", "17 Aug 3013") + aug_3013_rept = @front_desk_3.report_all_available_rooms("1 Aug 3013", "17 Aug 3013", @front_desk_3.rooms) aug_3013_rept.count.must_equal 3 @@ -204,13 +204,13 @@ it "returns an empty array if no rooms are available between specified dates" do - @front_desk_3.report_all_available_rooms("12th Jun 3013", "14th Jun 3013").must_be_empty + @front_desk_3.report_all_available_rooms("12th Jun 3013", "14th Jun 3013", @front_desk_3.rooms).must_be_empty end end - describe "find_available_room(start_d, end_d)" do + describe "find_available_room(start_d, end_d, room_set)" do before do @@ -227,7 +227,7 @@ it "returns the ID of a room that is available between specified dates in string form" do - jun_19_jul_23_choice = @front_desk_3.find_available_room("19th Jun 2013", "23rd Jun 2013") + jun_19_jul_23_choice = @front_desk_3.find_available_room("19th Jun 2013", "23rd Jun 2013", @front_desk_3.rooms) jun_19_jul_23_choice.must_be_kind_of String jun_19_jul_23_choice.must_equal "1000" @@ -236,24 +236,24 @@ it "if more than one room is available during a given interval, returns the room with the lowest room number" do - @front_desk_3.find_available_room("12th Mar 3014", "21st Mar 3014").must_equal "1000" + @front_desk_3.find_available_room("12th Mar 3014", "21st Mar 3014", @front_desk_3.rooms).must_equal "1000" - @front_desk_3.find_available_room("12th Nov 3015", "18th Nov 3015").must_equal "4000" + @front_desk_3.find_available_room("12th Nov 3015", "18th Nov 3015", @front_desk_3.rooms).must_equal "4000" end it "returns nil if no rooms are available between specified dates" do - @front_desk_3.find_available_room("12th Jun 3013", "14th Jun 3013").must_be_nil + @front_desk_3.find_available_room("12th Jun 3013", "14th Jun 3013", @front_desk_3.rooms).must_be_nil end end - describe "create_reservation_basic(start_date, end_date)" do + describe "create_reservation_basic(start_date, end_date, room_set)" do before do - @new_jan_3014_res = @front_desk_2.create_reservation_basic('2nd Jan 3014', '19th Jan 3014') + @new_jan_3014_res = @front_desk_2.create_reservation_basic('2nd Jan 3014', '19th Jan 3014', @front_desk_2.rooms) end it "generates a reservation for a given date range" do @@ -283,7 +283,7 @@ end it "raises an error if no rooms are available in the desired date range." do - proc{ @front_desk_2.create_reservation_basic('11th Jun 3013','13th Jun 3013')}.must_raise StandardError + proc{ @front_desk_2.create_reservation_basic('11th Jun 3013','13th Jun 3013', @front_desk_2.rooms)}.must_raise StandardError end end @@ -349,7 +349,7 @@ end - describe "check_block_feasibility(st_dt, end_dt, block_size)" do + describe "check_block_feasibility(st_dt, end_dt, room_set, block_size)" do before do @@ -361,10 +361,10 @@ @front_desk_3.rooms = @three_rooms_identical_avail - @three_ident_feasible = @front_desk_3.check_block_feasibility('1st Mar 3015', '10th Mar 3015', 3) + @three_ident_feasible = @front_desk_3.check_block_feasibility('1st Mar 3015', '10th Mar 3015',@front_desk_3.rooms, 3) - @three_ident_infeas = @front_desk_3.check_block_feasibility('1st Nov 3015', '10th Nov 3015', 3) + @three_ident_infeas = @front_desk_3.check_block_feasibility('1st Nov 3015', '10th Nov 3015', @front_desk_3.rooms, 3) end @@ -451,7 +451,7 @@ end end - describe "create_room_block(st_date, end_date, block_size, block_discount)" do + describe "create_room_block(st_date, end_date, block_size, room_set, block_discount)" do before do @room_3000_cs.add_reservation(@reservation_n1_c) @@ -462,10 +462,9 @@ @front_desk_3.rooms = @three_rooms_identical_avail - @valid_block = @front_desk_3.create_room_block('1st Mar 3015', '10th Mar 3015', 3, 0.2) + @valid_block = @front_desk_3.create_room_block('1st Mar 3015', '10th Mar 3015', 3, @front_desk_3.rooms, 0.2) - # @three_ident_infeas = @front_desk_3.check_block_feasibility('1st Nov 3015', '10th Nov 3015', 3) end it "returns a hash exactly one key-value pair long, when enough rooms are available for the reservation" do @@ -497,7 +496,52 @@ end - # check + it "has one instance of BlockRoom for every room in the block" do + @valid_block.values[0].length.must_equal 3 + end + + it "stores the blocks in FrontDesk's @blocks array" do + @front_desk_3.blocks.must_include @valid_block + end + + it "marks the dates of the block as unavailable in the room's dates_unavailable hash" do + + @room_3000_cs.dates_unavailable.keys.must_include "2822333" + @room_2000_bs.dates_unavailable.keys.must_include "2822332" + @room_1000_as.dates_unavailable.keys.must_include "2822329" + end + end + describe "check_availability_within_block(start_date, end_date, block_id)" do + before do + @room_3000_cs.add_reservation(@reservation_n1_c) + @room_3000_cs.add_reservation(@reservation_n2_c) + @room_3000_cs.add_reservation(@reservation_n3_c) + @three_rooms_identical_avail = [@room_1000_as, @room_2000_bs, @room_3000_cs] + + @front_desk_3.rooms = @three_rooms_identical_avail + + @valid_block = @front_desk_3.create_room_block('1st Mar 3015', '10th Mar 3015', 3, @front_desk_3.rooms, 0.2) + @valid_blocK_id = @valid_block.keys[0] + + @block_search_result = @front_desk_3.check_availability_within_block('3rd Mar 3015', '7th Mar 3015', @valid_blocK_id) + end + + it "returns an array" do + @block_search_result.must_be_kind_of Array + end + + it 'returns a collection of room numbers for the rooms available between the specified dates' do + + @block_search_result.must_include "1000-B" + @block_search_result.must_include "2000-B" + @block_search_result.must_include "3000-B" + + end + + it 'returns an empty array if no rooms are available between the specified dates' do + + # COME BACK TO THIS AFTER YOU HAVE RESERVATION ADD WORKING + end end end From 4c1f2defe015cac2196eddb8e57fe83cac99805c Mon Sep 17 00:00:00 2001 From: Victoria Garcia Date: Mon, 12 Mar 2018 06:08:27 -0700 Subject: [PATCH 47/51] This is as far as I'm going. One method shy of finishing Wave 3. --- lib/front_desk.rb | 14 ++++++++++++-- specs/front_desk_spec.rb | 29 +++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/lib/front_desk.rb b/lib/front_desk.rb index b3c21e65a..acc633574 100644 --- a/lib/front_desk.rb +++ b/lib/front_desk.rb @@ -182,8 +182,18 @@ def check_availability_within_block(start_date, end_date, block_id) return available_block_rooms end + # RIGHT HERE IS WHERE I RAN OUT OF GAS. - def create_reservation_within_block(start_date, end_date, block_id) - end + #I ALMOST GOT THROGUH WAVE 3, but at 6:00 am, I just had nothing left. + + + # def create_reservation_within_block(start_date, end_date, block_id) + # rooms_available = check_availability_within_block(start_date, end_date, block_id) + # room_instances_for_reservation = rooms_available.map {|id| @blocks.find } + # + # + # new_block_reservation = create_reservation_basic(start_date, end_date, rooms_available) + # return new_block_reservation + # end end end diff --git a/specs/front_desk_spec.rb b/specs/front_desk_spec.rb index 69f92c711..487b10de7 100644 --- a/specs/front_desk_spec.rb +++ b/specs/front_desk_spec.rb @@ -544,4 +544,33 @@ # COME BACK TO THIS AFTER YOU HAVE RESERVATION ADD WORKING end end + + xdescribe "create_reservation_within_block(start_date, end_date, block_id)" do + + #NOTES: THIS IS WHERE THE WHEELS FELL OFF FOR ME. I GOT ALMOST ALL THE WAY THROUGH, BUT EXHAUSTION FINALLY WON. + + + before do + @room_3000_cs.add_reservation(@reservation_n1_c) + @room_3000_cs.add_reservation(@reservation_n2_c) + @room_3000_cs.add_reservation(@reservation_n3_c) + + @three_rooms_identical_avail = [@room_1000_as, @room_2000_bs, @room_3000_cs] + + @front_desk_3.rooms = @three_rooms_identical_avail + + @valid_block = @front_desk_3.create_room_block('1st Mar 3015', '10th Mar 3015', 3, @front_desk_3.rooms, 0.2) + + @valid_block_id = @valid_block.keys[0] + + @block_reservation_req_result = @front_desk_3.create_reservation_within_block('4th Mar 3015', '7th Mar 3015', @valid_block_id) + end + + it "returns an instance of Hotel::Reservation" do + + + @block_reservation_req_result.must_be_instance_of Hotel::Reservation + + end + end end From 554ac8b5466efa0d5598e0f4db0b5a7ebfea5ee7 Mon Sep 17 00:00:00 2001 From: Victoria Garcia Date: Sat, 31 Mar 2018 19:10:24 -0700 Subject: [PATCH 48/51] All prompts answered. --- design-activity.md | 80 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 design-activity.md diff --git a/design-activity.md b/design-activity.md new file mode 100644 index 000000000..71a5bb34d --- /dev/null +++ b/design-activity.md @@ -0,0 +1,80 @@ +1. Which classes does each implementation include? Are the lists the same? + + CartEntry -- Impl. A & Impl. B + ShoppingCart -- Impl. A & Impl. B + Order -- Impl. A & Impl. B + + (So yes, the lists are the same.) + +2. Write down a sentence to describe each class. + + CartEntry keeps track of unit price and quantity, and in Implementation B, has a method for multiplying those values to obtain a price. (It does not, however, have any way of retaining the value calculated.) + + ShoppingCart holds an array, called @entries, and in Implementation B, it has a method for calculating an overall sum based on the contents of @entries that makes use of CartEntry's price calculation method. + + Order contains an instance of ShoppingCart, stores SALES_TAX as a variable, and includes a method for calculating the total price of the ShoppingCart instance's contents, with the B version leveraging ShoppingCart's inborn price-calculation method, while the A version has its own, entirely _de novo_ price calculation method. + +3. How do the classes relate to each other? + + A CartEntry appears to correspond to the type of item that a person might buy-- so a blue, spade-tip Sharpie, or a paperback copy of POODR, or a banana. (We don't get the name of the itme here, just its per-item price and the quantity the customer is buying. ShoppingCart appears to be meant to hold instances of CartEntry. And Order holds an instance of ShoppingCart (which contains CartEntry instances) so that the price of its contents can be tallied, and have an appropriate sales tax rate can be applied. + + Basically, they're like Matryoshka dolls, with the smallest doll being CartEntry, and the largest being Order. + +4. What DATA does each class store? How (if at all) does this differ between the two implementations? + + CartEntry stores a unit price and a quantity in both implementations, and nothing else. (While Implementation B has a means of calculating a price based on those two values, it does not have a way of storing it.) + + ShoppingCart stores instances of CartEntry (each, presumably, with a quantity and a unit price), and nothing else. (Much like CartEntry, Implementation B has a means of generating an overall price for the contents of its array of CartEntry instances, but no way of storing that price.) + + Order stores the sales tax rate, and an instance of ShoppingCart, which (presumably) contains one or more instances of CartEntry. Both implementations A and B have a method for calculating the overall price of the contents, with sales tax, but no way of storing that value. + +5. What METHODS does each class have? How (if at all) does this differ between the two implementations? + + CartEntry: + initialize: unit_price, quantity -- Imp. A & Imp. B + attr_accessor: unit_price, quantity -- Imp. A only + price: -- Imp. B only + + ShoppingCart: + intiialize: entries -- Imp. A & Imp. B + attr_accessor: entries -- Imp. A only + price: -- Imp. B only + + Order: + initialize: CartEntry -- Imp. A & Imp. B + total_price: -- Imp. A & Imp. B + + KEY DIFFERENCES: + + Accessors: Implementation A has attr_accessor methods that Implementation B does not have. This, I think, is because B provides access to the values of those variables as the return value of its .price methods, instead of having the Order method's total_price method access them directly. + + Price methods: As mentioned above, in Implementation B, the CartEntry and ShoppingCart methods have their own price methods. ShppingCart's price method uses values returned by CartEntry's price method, and Order does something similar with ShoppingCart's price method. In contrast, Implementation A has a single price method that obtains a result by accessing variables within the other classes directly. + + 6. 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 B, it is delegated to lower classes. In Implementation A, it is retained by Order. + + * Does total_price directly manipulate the instance variables of other classes? + + Depends on your definition of 'manipulate'. It does not change the values of those variables in either case. However, in Implementation A, it does directly access the values of variables in other classes, and it performs calculations based on those values. + + 7. If decide items are cheaper if bought in bulk, how would this change the code? Which implementation is easier to modify? + + I'm guessing that you'd want to have some sort of discount get triggered, probably as a multiplier, if the value of quantity for a given CartEntry instance is above a certain threshhold. + + In Implementation B, you could do this easily, by adding a conditional to CartEntry's price method (and either putting the discount logic there, or triggering a helper method.) Downstream of that, ShoppingCart#price and Order#total_price wouldn't have to change. + + In Implementation A, you'd have to put the discounting logic in Order#total_price, and you'd have a conditional (and possibly the trigger for a helper method) inside of a .each loop, which would be inefficient and fiddly. + + The code for this would be easier to write and read in Implementation B. + + 8. Which implementation adheres better to the single responsibility principle? + + Initially, I thought it was Implementation A, because there, Order has sole responsibility for calculating prices. However, after working through these prompts, I can see that it's actually Implementation B, because: (1) No class accesses the instances variables of instances of another class; and (2) Since instances of each class can generate their own prices (and the price method has a consistent name across classes) they're actually more fungible and easier to modify and use. + + + 9. Which implementation is more loosely coupled? + + Implementation B. In Implementation B, the Order class doesn't need to know the names of variables within another class, and the lower classes themselves are more fungible. From b6dd3c58bf68da2b273734553e1c4b4d5be1f864 Mon Sep 17 00:00:00 2001 From: Victoria Garcia Date: Sun, 1 Apr 2018 17:48:53 -0700 Subject: [PATCH 49/51] Added to the design-activity document, and while doing so, made a few changes recommended by Kari on the feedback. --- design-activity.md | 57 ++++++++++++++++++++++++++++++++++++++++ lib/front_desk.rb | 16 ++++------- lib/reservation.rb | 4 +++ lib/room.rb | 6 +---- specs/front_desk_spec.rb | 18 +++---------- 5 files changed, 71 insertions(+), 30 deletions(-) diff --git a/design-activity.md b/design-activity.md index 71a5bb34d..d14a3fe2b 100644 --- a/design-activity.md +++ b/design-activity.md @@ -1,3 +1,6 @@ + +PART I: SHOPPING CART, ETC: + 1. Which classes does each implementation include? Are the lists the same? CartEntry -- Impl. A & Impl. B @@ -78,3 +81,57 @@ 9. Which implementation is more loosely coupled? Implementation B. In Implementation B, the Order class doesn't need to know the names of variables within another class, and the lower classes themselves are more fungible. + + +PART II: REVISITING HOTEL: + +A. Preface: + +While I did lots and lots of things wrong in Hotel, the class interdependence and coupling were among the least-wrong aspects of the project. I actually tried really hard to design my Reservation class so that it could be expanded to reserve things other than rooms, just as an exercise for myself-- and the comments I got back from Kari seem to support my perception of the project: Overcomplicated and messy, yes: Tightly coupled classes, no: Single responsibility problems: Mostly no on the class level, though (in my opinion) OMFG yes, in some places, on the method level. + +A large part of the excessive tangliness and all or nearly all of the moments of bad class interdependence are, IMO, largely fallout largely fallout from my having made a bad choice of data structures, w/re storing information about rooms' bookings and date availability, and then cleaving unto those poorly-chosen data structures until the very bitter end-- and fixing the bad data structure at this point, even in the limited way this assignment suggests, would amount to very major surgery, both in terms of rewriting production code and in terms of reconceptualizing and redeveloping tests. + +Given that, I decided that the best way to complete this assignment without letting its scope expand out of control was to finish the last class (BlockRoom), and to make sure that it stands alone and is loosely coupled to the other classes, in keeping with good OO programming principles. + +B. Hotel Revision Prompts: + + 1. Reservation: + + What is this class's responsibility? + + An instance of Reservation is, in essence, a collection of dates for which something (in this case, a hotel room) is reserved. + + It can calculate its own length and its own cost. + + Is this class responsible for exactly one thing? + + Yes. It just knows its own dates, and based on them, it can calculate its own length and its own price. + + + Does this class take on any responsibility that should be delegated to lower-level classes? + + It is the lowest level class in this project, so no. + + Is there code in other classes that directly manipulates this class's instance variables? + + + 2. Room: + + What is this class's responsibility? + + Room holds its own reservations as an array, and it knows the dates for which it is booked, and using these, it can decide whether to accept or reject a new reservation. + + Is this class responsible for exactly one thing? + + Yes. It just holds its own bookings, and uses that information to accept or reject new bookings. + + + Does this class take on any responsiblity that should be delegated to lower-level classes? + + It does, currently, have some (as-yet unused) + + 3. Front_desk: + + What is this class's responsibility? + + Front desk is the equivanent of RideShare's Dispatcher class-- it holds all the instances of Room, and it diff --git a/lib/front_desk.rb b/lib/front_desk.rb index acc633574..46aa7af75 100644 --- a/lib/front_desk.rb +++ b/lib/front_desk.rb @@ -29,11 +29,6 @@ def generate_rooms return room_array end - def report_all_rooms - all_rooms = @rooms - return all_rooms - end - def find_all_reservations_for_date(date) query_date = DateTime.parse(date).jd.to_s overall_report = {} @@ -68,7 +63,6 @@ def report_all_available_rooms(start_dt, end_dt, room_set) end def find_available_room(start_d, end_d, room_set) - room_to_assign = nil rooms_available = report_all_available_rooms(start_d, end_d, room_set) unless rooms_available.empty? @@ -79,16 +73,16 @@ def find_available_room(start_d, end_d, room_set) return room_to_assign end - def look_up_per_night_price_for_room(query_room_numb) - target_room = @rooms.find {|room| room.room_number == query_room_numb} - target_price = target_room.rate_with_discount - end - def locate_room_by_id(query_rm_numb) target_room = @rooms.find {|room| room.room_number == query_rm_numb} return target_room end + def look_up_per_night_price_for_room(query_room_numb) + target_room = locate_room_by_id(query_room_numb) + target_price = target_room.rate_with_discount + end + def create_reservation_basic(start_date, end_date, room_set) room_numb_for_new_res = find_available_room(start_date, end_date, room_set) if room_numb_for_new_res.nil? diff --git a/lib/reservation.rb b/lib/reservation.rb index 71192a5d2..f475e6d76 100644 --- a/lib/reservation.rb +++ b/lib/reservation.rb @@ -85,6 +85,10 @@ def days_with_am_and_pm_occupation all_days_in_use = start_and_end_days.merge(full_days_in_use.to_h) end + def calculate_total_nights + (@end_date.to_date - @start_date.to_date).to_i + end + def calculate_reservation_price (@total_nights * @per_night_price).round(2) end diff --git a/lib/room.rb b/lib/room.rb index 8cd1c5b0e..3a3ddc4a7 100644 --- a/lib/room.rb +++ b/lib/room.rb @@ -46,7 +46,7 @@ def can_accept_reservation?(reservation) unless @dates_unavailable.empty? unless reservation_acceptable[:accept] == false @dates_unavailable.each do |booked_date| - # Note: I originally had the am/pm conflict checking written as a single, long, one-line thing, but that made minitest loose its mind, so now it's in all these little chunks. + # Note: I originally had the am/pm conflict checking written as a single, long, one-line thing, but that made minitest lose its mind, so now it's in all these little chunks. date = booked_date if reservation.days_booked_am_and_pm.keys.include?(date[0]) am_conflict = nil @@ -91,11 +91,9 @@ def fix_conflicting_date(conflict_array) # reservations. This keeps the can_accept_reservation? method # from going nuts in cases of abutting reservations. output_array = conflict_array.map {|d| {d.keys[0] => {:am => true, :pm => true}}} - return output_array end def add_reservation(new_reservation) - adding_instructions = can_accept_reservation?(new_reservation) if adding_instructions[:accept] == false raise StandardError.new ("You are trying to add a reservation that conflicts with a pre-existing reservation") @@ -106,9 +104,7 @@ def add_reservation(new_reservation) dates_with_conflicts_fixed = nil if adding_instructions[:resolve_conflict].kind_of? Array dates_with_conflicts_fixed = fix_conflicting_date(adding_instructions[:resolve_conflict]) - # binding.pry dates_with_conflicts_fixed.each {|date| @dates_unavailable.merge!(date)} - # binding.pry end end end diff --git a/specs/front_desk_spec.rb b/specs/front_desk_spec.rb index 487b10de7..2f1583d5a 100644 --- a/specs/front_desk_spec.rb +++ b/specs/front_desk_spec.rb @@ -73,6 +73,10 @@ @front_desk_0.rooms.must_be_kind_of Array @front_desk_0.rooms.each {|element| element.must_be_instance_of Hotel::Room} @front_desk_0.rooms.count.must_equal 20 + + @front_desk_0.rooms.each_with_index do |room, index| + room.room_number.must_equal (index + 1).to_s + end end it "has an instance variable, @blocks, which begins as an empty array" do @@ -107,20 +111,6 @@ end end - describe "report_all_rooms" do - - it "reports a complete list of all the rooms in the facility" do - - room_report = @front_desk_1.report_all_rooms.sort_by {|room| room.room_number.to_i} - - room_report.must_be_kind_of Array - room_report.length.must_equal 20 - room_report.each_with_index do |room, index| - room.room_number.must_equal (index + 1).to_s - end - end - end - describe "find_all_reservations_for_date(date)" do before do From 59dc1451d5120d2975a57ce9a11c0d1b0c680da3 Mon Sep 17 00:00:00 2001 From: Victoria Garcia Date: Sun, 1 Apr 2018 20:32:22 -0700 Subject: [PATCH 50/51] made changes to room availability report-generating mechanisms in Room and Front Desk to reduce class interdependene. Changes to Room are successful and passing all tests. Tests written for FrontDesk, but production code has not yet been adjusted. --- lib/front_desk.rb | 62 ++++++++++++++++++++----- lib/room.rb | 5 +++ specs/front_desk_spec.rb | 97 +++++++++++++++++++++++++++++++++------- specs/room_spec.rb | 96 +++++++++++++++++++++++++++++++++------ 4 files changed, 220 insertions(+), 40 deletions(-) diff --git a/lib/front_desk.rb b/lib/front_desk.rb index 46aa7af75..92fa6313f 100644 --- a/lib/front_desk.rb +++ b/lib/front_desk.rb @@ -29,12 +29,50 @@ def generate_rooms return room_array end - def find_all_reservations_for_date(date) + + # def find_all_reservations_for_date(date) + # query_date = DateTime.parse(date).jd.to_s + # overall_report = {} + # @rooms.each do |room| + # per_room_report = nil + # per_room_report = room.report_reservations_for_day(query_date) + # unless per_room_report == nil + # resv_id_array = [] + # per_room_report.each {|reservation| resv_id_array << reservation.id } + # per_room_report = {room.room_number => resv_id_array} + # overall_report.merge!(per_room_report) + # end + # end + # return overall_report + # end + + # def report_reservation_status_for_date(date) + # query_date = DateTime.parse(date).jd.to_s + # overall_report = {} + # @rooms.each do |room| + # per_room_report = {} + # room.report_reservation_status_for_day(query_date) + # + # + # unless per_room_report == nil + # resv_id_array = [] + # per_room_report.each {|reservation| resv_id_array << reservation.id } + # per_room_report = {room.room_number => resv_id_array} + # overall_report.merge!(per_room_report) + # end + # end + # return overall_report + # end + + + def report_reservation_status_for_date(date) query_date = DateTime.parse(date).jd.to_s overall_report = {} @rooms.each do |room| - per_room_report = nil - per_room_report = room.report_reservations_for_day(query_date) + per_room_report = {} + room.report_reservation_status_for_day(query_date) + + unless per_room_report == nil resv_id_array = [] per_room_report.each {|reservation| resv_id_array << reservation.id } @@ -75,7 +113,6 @@ def find_available_room(start_d, end_d, room_set) def locate_room_by_id(query_rm_numb) target_room = @rooms.find {|room| room.room_number == query_rm_numb} - return target_room end def look_up_per_night_price_for_room(query_room_numb) @@ -90,6 +127,7 @@ def create_reservation_basic(start_date, end_date, room_set) else new_reservation = Hotel::Reservation.new(start_date, end_date) end + new_reservation.hotel_room_id = room_numb_for_new_res new_reservation.per_night_price = look_up_per_night_price_for_room(room_numb_for_new_res) @@ -181,13 +219,13 @@ def check_availability_within_block(start_date, end_date, block_id) #I ALMOST GOT THROGUH WAVE 3, but at 6:00 am, I just had nothing left. - # def create_reservation_within_block(start_date, end_date, block_id) - # rooms_available = check_availability_within_block(start_date, end_date, block_id) - # room_instances_for_reservation = rooms_available.map {|id| @blocks.find } - # - # - # new_block_reservation = create_reservation_basic(start_date, end_date, rooms_available) - # return new_block_reservation - # end + def create_reservation_within_block(start_date, end_date, block_id) + rooms_available = check_availability_within_block(start_date, end_date, block_id) + room_instances_for_reservation = rooms_available.map {|id| @blocks.find } + + + new_block_reservation = create_reservation_basic(start_date, end_date, rooms_available) + return new_block_reservation + end end end diff --git a/lib/room.rb b/lib/room.rb index 3a3ddc4a7..79fc8e570 100644 --- a/lib/room.rb +++ b/lib/room.rb @@ -40,6 +40,11 @@ def report_reservations_for_day(date_julian) return report end + def report_reservation_status_for_day(date_julian) + resvs_for_day = {@room_number => @dates_unavailable.fetch(date_julian, "no bookings")} + end + + def can_accept_reservation?(reservation) reservation_acceptable = {:accept => true, :resolve_conflict => false} resolve_date_conflict = [] diff --git a/specs/front_desk_spec.rb b/specs/front_desk_spec.rb index 2f1583d5a..4ebc87fae 100644 --- a/specs/front_desk_spec.rb +++ b/specs/front_desk_spec.rb @@ -111,7 +111,51 @@ end end - describe "find_all_reservations_for_date(date)" do + + # describe "find_all_reservations_for_date(date)" do + # + # before do + # @room_1000_as.add_reservation(@res_1_fllws_n1_direct) + # @room_4000.add_reservation(@res_2_overlps_n1_begin) + # @room_5000.add_reservation(@res_5_fllws_n1_precedes_n2) + # @room_6000.add_reservation(@res_6_singleton) + # + # @front_desk_3.rooms = [@room_1000_as, @room_4000, @room_5000, @room_6000] + # end + # + # it "outputs a hash, where the keys are the numbers of reserved rooms, in string form, and the value of each is an array containing the id numbers of their reservations" do + # + # reservation_report_16_jun = @front_desk_3.find_all_reservations_for_date('16th Jun 3013') + # + # reservation_report_16_jun.must_be_kind_of Hash + # reservation_report_16_jun.count.must_equal 2 + # + # reservation_report_16_jun.keys.must_include "1000" + # reservation_report_16_jun.keys.must_include "5000" + # + # reservation_report_16_jun.keys.wont_include "4000" + # reservation_report_16_jun.keys.wont_include "6000" + # + # reservation_report_16_jun["1000"].must_be_kind_of Array + # reservation_report_16_jun["1000"].must_include @reservation_n1_a.id + # reservation_report_16_jun["1000"].must_include @res_1_fllws_n1_direct.id + # + # reservation_report_16_jun["5000"].must_be_kind_of Array + # reservation_report_16_jun["5000"].must_include @res_5_fllws_n1_precedes_n2.id + # + # end + # + # it "returns an empty hash when there are no rooms reserved for a given day" do + # + # reservation_report_1_jan = @front_desk_3.find_all_reservations_for_date('1st Jan 4047') + # + # reservation_report_1_jan.must_be_kind_of Hash + # reservation_report_1_jan.must_be_empty + # + # end + # end + + describe "report_overall_booking_status_for_date(date)" do before do @room_1000_as.add_reservation(@res_1_fllws_n1_direct) @@ -120,40 +164,63 @@ @room_6000.add_reservation(@res_6_singleton) @front_desk_3.rooms = [@room_1000_as, @room_4000, @room_5000, @room_6000] + + reservation_report_16_jun = @front_desk_3.report_overall_booking_status_for_date('16th Jun 3013') + end - it "outputs a hash, where the keys are the numbers of reserved rooms, in string form, and the value of each is an array containing the id numbers of their reservations" do + it "outputs a hash, where the keys are the numbers of all the hotel's rooms, in string form" do reservation_report_16_jun = @front_desk_3.find_all_reservations_for_date('16th Jun 3013') reservation_report_16_jun.must_be_kind_of Hash - reservation_report_16_jun.count.must_equal 2 + reservation_report_16_jun.length.must_equal 4 reservation_report_16_jun.keys.must_include "1000" reservation_report_16_jun.keys.must_include "5000" + reservation_report_16_jun.keys.must_include "4000" + reservation_report_16_jun.keys.must_include "6000" - reservation_report_16_jun.keys.wont_include "4000" - reservation_report_16_jun.keys.wont_include "6000" + reservation_report_16_jun.keys.wont_include "2" + reservation_report_16_jun.keys.wont_include "2000" - reservation_report_16_jun["1000"].must_be_kind_of Array - reservation_report_16_jun["1000"].must_include @reservation_n1_a.id - reservation_report_16_jun["1000"].must_include @res_1_fllws_n1_direct.id + end - reservation_report_16_jun["5000"].must_be_kind_of Array - reservation_report_16_jun["5000"].must_include @res_5_fllws_n1_precedes_n2.id + it "outputs a hash where the value of each key is a hash containing two key-value pairs, one with a key of :am, and one with a key of :pm, which have values of either true or false depending on the room's reservation status" do - end + reservation_report_16_jun["1000"].must_be_kind_of Hash + reservation_report_16_jun["1000"].length.must_equal 2 + reservation_report_16_jun["1000"].keys.must_include :am + reservation_report_16_jun["1000"].keys.must_include :pm + + reservation_report_16_jun.dig("1000", :am).must_equal true + reservation_report_16_jun.dig("1000", :pm).must_equal true - it "returns an empty hash when there are no rooms reserved for a given day" do + reservation_report_16_jun["5000"].must_be_kind_of Hash + reservation_report_16_jun["5000"].length.must_equal 2 + reservation_report_16_jun["5000"].keys.must_include :am + reservation_report_16_jun["5000"].keys.must_include :pm + reservation_report_16_jun.dig("5000", :am).must_equal false + reservation_report_16_jun.dig("5000", :pm).must_equal true - reservation_report_1_jan = @front_desk_3.find_all_reservations_for_date('1st Jan 4047') + end - reservation_report_1_jan.must_be_kind_of Hash - reservation_report_1_jan.must_be_empty + it "For a room with no bookings on a given date, it returns a hash with the room's number as the key, and the string 'no bookings' as the value." do + + reservation_report_16_jun["4000"].must_be_kind_of Hash + reservation_report_16_jun["4000"].length.must_equal 1 + reservation_report_16_jun["4000"].must_equal "no bookings" + reservation_report_16_jun["4000"].keys.wont_include :am + reservation_report_16_jun["4000"].keys.wont_include :pm end + end + + + + describe "report_all_available_rooms(start_dt, end_dt, room_set)" do # This method leverages availabiity-checking machinery that already exists in the Reservation class, and that machinery was already heavily tested by the Reservation spec, so it is just given a once-over here. diff --git a/specs/room_spec.rb b/specs/room_spec.rb index 835ff1aeb..1c360dfd9 100644 --- a/specs/room_spec.rb +++ b/specs/room_spec.rb @@ -59,7 +59,49 @@ end - describe "report_reservations_for_day(date_julian)" do + # THIS VERSION OF THIS METHOD WAS REMOVED FOR PURPOSES OF THE + # 'HOTEL REVISITED' ASSIGNMENT. ITS REPLACEMENT IS IMMEDIATELY BELOW. + + + # describe "report_reservations_for_day(date_julian)" do + # before do + # + # @room_300_nominal.add_reservation(@reservation_n1_nominal) + # @room_300_nominal.add_reservation(@reservation_1_follows_n1_directly) + # @room_300_nominal.add_reservation(@reservation_n3_nominal) + # + # end + # + # it "accurately reports reservations for a day on which there is a single reservation" do + # + # jun_12_reservations = @room_300_nominal.report_reservations_for_day("2821698") + # jun_12_reservations.must_be_kind_of Array + # jun_12_reservations.length.must_equal 1 + # jun_12_reservations.must_include @reservation_n1_nominal + # + # end + # + # it "accurately reports reservations when run for a day on which one reservation begins and another ends" do + # + # jun_16_reservations = @room_300_nominal.report_reservations_for_day("2821702") + # jun_16_reservations.length.must_equal 2 + # jun_16_reservations.must_be_kind_of Array + # jun_16_reservations.must_include @reservation_n1_nominal + # jun_16_reservations.must_include @reservation_1_follows_n1_directly + # + # end + # + # it "returns nil if a room has no reservations for a given day." do + # + # xmas_3075_reservations = @room_300_nominal.report_reservations_for_day("2844539") + # + # xmas_3075_reservations.must_be_nil + # + # end + # end + + + describe "report_reservation_status_for_day(date_julian)" do before do @room_300_nominal.add_reservation(@reservation_n1_nominal) @@ -68,34 +110,62 @@ end - it "accurately reports reservations for a day on which there is a single reservation" do + it "accurately reports reservations for a day that is reserved for both morning and evening" do - jun_12_reservations = @room_300_nominal.report_reservations_for_day("2821698") - jun_12_reservations.must_be_kind_of Array + jun_12_reservations = @room_300_nominal.report_reservation_status_for_day("2821698") + jun_12_reservations.must_be_kind_of Hash jun_12_reservations.length.must_equal 1 - jun_12_reservations.must_include @reservation_n1_nominal + jun_12_reservations.keys.must_include "300" + jun_12_reservations.dig("300", :am).must_equal true + jun_12_reservations.dig("300", :pm).must_equal true end it "accurately reports reservations when run for a day on which one reservation begins and another ends" do - jun_16_reservations = @room_300_nominal.report_reservations_for_day("2821702") - jun_16_reservations.length.must_equal 2 - jun_16_reservations.must_be_kind_of Array - jun_16_reservations.must_include @reservation_n1_nominal - jun_16_reservations.must_include @reservation_1_follows_n1_directly + jun_16_reservations = @room_300_nominal.report_reservation_status_for_day("2821702") + jun_16_reservations.must_be_kind_of Hash + jun_16_reservations.length.must_equal 1 + jun_16_reservations.keys.must_include "300" + jun_16_reservations.dig("300", :am).must_equal true + jun_16_reservations.dig("300", :pm).must_equal true end - it "returns nil if a room has no reservations for a given day." do + it "accurately reports reservation status for a room that was not reserved for the night before a new reservation begins" do - xmas_3075_reservations = @room_300_nominal.report_reservations_for_day("2844539") + jun_10_reservations = @room_300_nominal.report_reservation_status_for_day("2821696") + jun_10_reservations.must_be_kind_of Hash + jun_10_reservations.length.must_equal 1 + jun_10_reservations.keys.must_include "300" + jun_10_reservations.dig("300", :am).must_equal false + jun_10_reservations.dig("300", :pm).must_equal true - xmas_3075_reservations.must_be_nil + end + + it "accurately reports reservation status for a room that is not reserved for the night after a reservation ends" do + + jul_3_reservations = @room_300_nominal.report_reservation_status_for_day("2821718") + jul_3_reservations.must_be_kind_of Hash + jul_3_reservations.length.must_equal 1 + jul_3_reservations.keys.must_include "300" + jul_3_reservations.dig("300", :am).must_equal true + jul_3_reservations.dig("300", :pm).must_equal false + + end + + it "returns 'no bookings' if a room has no reservations for a given day." do + + xmas_3075_reservations = @room_300_nominal.report_reservation_status_for_day("2844539") + xmas_3075_reservations.must_be_kind_of Hash + xmas_3075_reservations.length.must_equal 1 + xmas_3075_reservations.keys.must_include "300" + xmas_3075_reservations["300"].must_equal "no bookings" end end + describe "can_accept_reservation?(reservation)" do before do From fa4d9e3a4b0ed4c43a3f75291a4d83d146b7b555 Mon Sep 17 00:00:00 2001 From: Victoria Garcia Date: Sun, 1 Apr 2018 22:50:20 -0700 Subject: [PATCH 51/51] Modifications to the room availability report generation mechanism in FrontDesk are now written and passing all tests. Also, the design-activity.md document has been updated. It's now time for a pull request. --- design-activity.md | 51 +++---------------------------------- lib/front_desk.rb | 32 ++---------------------- specs/front_desk_spec.rb | 54 +++++++++++++++++++--------------------- 3 files changed, 31 insertions(+), 106 deletions(-) diff --git a/design-activity.md b/design-activity.md index d14a3fe2b..c76d14891 100644 --- a/design-activity.md +++ b/design-activity.md @@ -85,53 +85,10 @@ PART I: SHOPPING CART, ETC: PART II: REVISITING HOTEL: -A. Preface: + For this project, I chose to work on the program's room availability reporting mechanics. (Note that this is far from the worst problem that my implementation of Hotel has-- I chose this because it felt like a finite task with an achievable goal, not because it was the code's most important issue.) -While I did lots and lots of things wrong in Hotel, the class interdependence and coupling were among the least-wrong aspects of the project. I actually tried really hard to design my Reservation class so that it could be expanded to reserve things other than rooms, just as an exercise for myself-- and the comments I got back from Kari seem to support my perception of the project: Overcomplicated and messy, yes: Tightly coupled classes, no: Single responsibility problems: Mostly no on the class level, though (in my opinion) OMFG yes, in some places, on the method level. + In the previous implementation, FrontDesk generated a report of bookings for a given date by going through all the instances of Room, and using one of Room's class methods (report_reservations_for_day) to look at all the instances of Reservation held by a given room, checking each Reservation instance's @days_booked_am_and_pm variable for matching dates. In other words, there was a multi-layered class entanglement here, and it had a really rotten time complexity to boot. -A large part of the excessive tangliness and all or nearly all of the moments of bad class interdependence are, IMO, largely fallout largely fallout from my having made a bad choice of data structures, w/re storing information about rooms' bookings and date availability, and then cleaving unto those poorly-chosen data structures until the very bitter end-- and fixing the bad data structure at this point, even in the limited way this assignment suggests, would amount to very major surgery, both in terms of rewriting production code and in terms of reconceptualizing and redeveloping tests. + To improve this, I created a different method (report_reservation_status_for_day) within Room that looks, not at any of Reservation's class variables, but at Room's own @dates_unavailable variable. (The new method then produces a hash where the key is the room's number, and the value is its booking status for the query date.) -Given that, I decided that the best way to complete this assignment without letting its scope expand out of control was to finish the last class (BlockRoom), and to make sure that it stands alone and is loosely coupled to the other classes, in keeping with good OO programming principles. - -B. Hotel Revision Prompts: - - 1. Reservation: - - What is this class's responsibility? - - An instance of Reservation is, in essence, a collection of dates for which something (in this case, a hotel room) is reserved. - - It can calculate its own length and its own cost. - - Is this class responsible for exactly one thing? - - Yes. It just knows its own dates, and based on them, it can calculate its own length and its own price. - - - Does this class take on any responsibility that should be delegated to lower-level classes? - - It is the lowest level class in this project, so no. - - Is there code in other classes that directly manipulates this class's instance variables? - - - 2. Room: - - What is this class's responsibility? - - Room holds its own reservations as an array, and it knows the dates for which it is booked, and using these, it can decide whether to accept or reject a new reservation. - - Is this class responsible for exactly one thing? - - Yes. It just holds its own bookings, and uses that information to accept or reject new bookings. - - - Does this class take on any responsiblity that should be delegated to lower-level classes? - - It does, currently, have some (as-yet unused) - - 3. Front_desk: - - What is this class's responsibility? - - Front desk is the equivanent of RideShare's Dispatcher class-- it holds all the instances of Room, and it + I also created a new reporting method in FrontDesk (report_overall_booking_status_for_date(date)) that uses Room's new method, report_reservation_status_for_day, to generate its contents, instead of having Room's older report_reservations_for_day(date_julian) read from Reservation's @days_booked_am_and_pm variable. diff --git a/lib/front_desk.rb b/lib/front_desk.rb index 92fa6313f..4142996c7 100644 --- a/lib/front_desk.rb +++ b/lib/front_desk.rb @@ -46,39 +46,11 @@ def generate_rooms # return overall_report # end - # def report_reservation_status_for_date(date) - # query_date = DateTime.parse(date).jd.to_s - # overall_report = {} - # @rooms.each do |room| - # per_room_report = {} - # room.report_reservation_status_for_day(query_date) - # - # - # unless per_room_report == nil - # resv_id_array = [] - # per_room_report.each {|reservation| resv_id_array << reservation.id } - # per_room_report = {room.room_number => resv_id_array} - # overall_report.merge!(per_room_report) - # end - # end - # return overall_report - # end - - - def report_reservation_status_for_date(date) + def report_overall_booking_status_for_date(date) query_date = DateTime.parse(date).jd.to_s overall_report = {} @rooms.each do |room| - per_room_report = {} - room.report_reservation_status_for_day(query_date) - - - unless per_room_report == nil - resv_id_array = [] - per_room_report.each {|reservation| resv_id_array << reservation.id } - per_room_report = {room.room_number => resv_id_array} - overall_report.merge!(per_room_report) - end + overall_report.merge!(room.report_reservation_status_for_day(query_date)) end return overall_report end diff --git a/specs/front_desk_spec.rb b/specs/front_desk_spec.rb index 4ebc87fae..022453f2d 100644 --- a/specs/front_desk_spec.rb +++ b/specs/front_desk_spec.rb @@ -111,8 +111,9 @@ end end + # Note: THE METHOD THAT CORRESPONDS TO THIS WAS REPLACED, PER THE 'HOTEL REVISITED' ASSIGNMENT, BY THE ONE TESTED IMMEDIATELY BELOW IT. - # describe "find_all_reservations_for_date(date)" do + #describe "find_all_reservations_for_date(date)" do # # before do # @room_1000_as.add_reservation(@res_1_fllws_n1_direct) @@ -165,53 +166,48 @@ @front_desk_3.rooms = [@room_1000_as, @room_4000, @room_5000, @room_6000] - reservation_report_16_jun = @front_desk_3.report_overall_booking_status_for_date('16th Jun 3013') + @reservation_report_16_jun = @front_desk_3.report_overall_booking_status_for_date('16th Jun 3013') end it "outputs a hash, where the keys are the numbers of all the hotel's rooms, in string form" do - reservation_report_16_jun = @front_desk_3.find_all_reservations_for_date('16th Jun 3013') + @reservation_report_16_jun.must_be_kind_of Hash + @reservation_report_16_jun.length.must_equal 4 - reservation_report_16_jun.must_be_kind_of Hash - reservation_report_16_jun.length.must_equal 4 + @reservation_report_16_jun.keys.must_include "1000" + @reservation_report_16_jun.keys.must_include "5000" + @reservation_report_16_jun.keys.must_include "4000" + @reservation_report_16_jun.keys.must_include "6000" - reservation_report_16_jun.keys.must_include "1000" - reservation_report_16_jun.keys.must_include "5000" - reservation_report_16_jun.keys.must_include "4000" - reservation_report_16_jun.keys.must_include "6000" - - reservation_report_16_jun.keys.wont_include "2" - reservation_report_16_jun.keys.wont_include "2000" + @reservation_report_16_jun.keys.wont_include "2" + @reservation_report_16_jun.keys.wont_include "2000" end it "outputs a hash where the value of each key is a hash containing two key-value pairs, one with a key of :am, and one with a key of :pm, which have values of either true or false depending on the room's reservation status" do - reservation_report_16_jun["1000"].must_be_kind_of Hash - reservation_report_16_jun["1000"].length.must_equal 2 - reservation_report_16_jun["1000"].keys.must_include :am - reservation_report_16_jun["1000"].keys.must_include :pm + @reservation_report_16_jun["1000"].must_be_kind_of Hash + @reservation_report_16_jun["1000"].length.must_equal 2 + @reservation_report_16_jun["1000"].keys.must_include :am + @reservation_report_16_jun["1000"].keys.must_include :pm - reservation_report_16_jun.dig("1000", :am).must_equal true - reservation_report_16_jun.dig("1000", :pm).must_equal true + @reservation_report_16_jun.dig("1000", :am).must_equal true + @reservation_report_16_jun.dig("1000", :pm).must_equal true - reservation_report_16_jun["5000"].must_be_kind_of Hash - reservation_report_16_jun["5000"].length.must_equal 2 - reservation_report_16_jun["5000"].keys.must_include :am - reservation_report_16_jun["5000"].keys.must_include :pm - reservation_report_16_jun.dig("5000", :am).must_equal false - reservation_report_16_jun.dig("5000", :pm).must_equal true + @reservation_report_16_jun["5000"].must_be_kind_of Hash + @reservation_report_16_jun["5000"].length.must_equal 2 + @reservation_report_16_jun["5000"].keys.must_include :am + @reservation_report_16_jun["5000"].keys.must_include :pm + @reservation_report_16_jun.dig("5000", :am).must_equal false + @reservation_report_16_jun.dig("5000", :pm).must_equal true end it "For a room with no bookings on a given date, it returns a hash with the room's number as the key, and the string 'no bookings' as the value." do - reservation_report_16_jun["4000"].must_be_kind_of Hash - reservation_report_16_jun["4000"].length.must_equal 1 - reservation_report_16_jun["4000"].must_equal "no bookings" - reservation_report_16_jun["4000"].keys.wont_include :am - reservation_report_16_jun["4000"].keys.wont_include :pm + @reservation_report_16_jun["4000"].must_be_kind_of String + @reservation_report_16_jun["4000"].must_equal "no bookings" end