From 983cc93ff1acb1056a6a153356e9687adcbbdc23 Mon Sep 17 00:00:00 2001 From: Kat Date: Thu, 1 Mar 2018 09:34:01 -0800 Subject: [PATCH 01/33] created Rakefile, lib files and spec files. --- Rakefile | 9 +++++++++ lib/block.rb | 0 lib/booking.rb | 0 lib/booking_manager.rb | 0 lib/customer.rb | 0 lib/room.rb | 0 lib/staff.rb | 0 specs/block_spec.rb | 5 +++++ specs/booking_manager_spec.rb | 5 +++++ specs/booking_spec.rb | 5 +++++ specs/customer_spec.rb | 5 +++++ specs/room_spec.rb | 5 +++++ specs/spec_helper.rb | 16 ++++++++++++++++ specs/staff_spec.rb | 5 +++++ 14 files changed, 55 insertions(+) create mode 100644 Rakefile create mode 100644 lib/block.rb create mode 100644 lib/booking.rb create mode 100644 lib/booking_manager.rb create mode 100644 lib/customer.rb create mode 100644 lib/room.rb create mode 100644 lib/staff.rb create mode 100644 specs/block_spec.rb create mode 100644 specs/booking_manager_spec.rb create mode 100644 specs/booking_spec.rb create mode 100644 specs/customer_spec.rb create mode 100644 specs/room_spec.rb create mode 100644 specs/spec_helper.rb create mode 100644 specs/staff_spec.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/block.rb b/lib/block.rb new file mode 100644 index 000000000..e69de29bb diff --git a/lib/booking.rb b/lib/booking.rb new file mode 100644 index 000000000..e69de29bb diff --git a/lib/booking_manager.rb b/lib/booking_manager.rb new file mode 100644 index 000000000..e69de29bb diff --git a/lib/customer.rb b/lib/customer.rb new file mode 100644 index 000000000..e69de29bb diff --git a/lib/room.rb b/lib/room.rb new file mode 100644 index 000000000..e69de29bb diff --git a/lib/staff.rb b/lib/staff.rb new file mode 100644 index 000000000..e69de29bb diff --git a/specs/block_spec.rb b/specs/block_spec.rb new file mode 100644 index 000000000..3b4cb1d93 --- /dev/null +++ b/specs/block_spec.rb @@ -0,0 +1,5 @@ +require_relative 'spec_helper' + +describe "Block" do + +end diff --git a/specs/booking_manager_spec.rb b/specs/booking_manager_spec.rb new file mode 100644 index 000000000..4d741a246 --- /dev/null +++ b/specs/booking_manager_spec.rb @@ -0,0 +1,5 @@ +require_relative 'spec_helper' + +describe "BookingManager" do + +end diff --git a/specs/booking_spec.rb b/specs/booking_spec.rb new file mode 100644 index 000000000..ea49387ac --- /dev/null +++ b/specs/booking_spec.rb @@ -0,0 +1,5 @@ +require_relative 'spec_helper' + +describe "Booking" do + +end diff --git a/specs/customer_spec.rb b/specs/customer_spec.rb new file mode 100644 index 000000000..e803d8daa --- /dev/null +++ b/specs/customer_spec.rb @@ -0,0 +1,5 @@ +require_relative 'spec_helper' + +describe "Customer" do + +end diff --git a/specs/room_spec.rb b/specs/room_spec.rb new file mode 100644 index 000000000..37ee74e5f --- /dev/null +++ b/specs/room_spec.rb @@ -0,0 +1,5 @@ +require_relative 'spec_helper' + +describe "Room" do + +end diff --git a/specs/spec_helper.rb b/specs/spec_helper.rb new file mode 100644 index 000000000..17eff505c --- /dev/null +++ b/specs/spec_helper.rb @@ -0,0 +1,16 @@ +require 'time' +require 'minitest' +require 'minitest/autorun' +require 'minitest/reporters' +require 'minitest/skip_dsl' +# Add simplecov + +Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new + +# Require_relative your lib files here! +require_relative '../lib/booking' +require_relative '../lib/booking_manager' +require_relative '../lib/room' +require_relative '../lib/block' +require_relative '../lib/staff' +require_relative '../lib/customer' diff --git a/specs/staff_spec.rb b/specs/staff_spec.rb new file mode 100644 index 000000000..48b9e9a11 --- /dev/null +++ b/specs/staff_spec.rb @@ -0,0 +1,5 @@ +require_relative 'spec_helper' + +describe "Staff" do + +end From 6fbb6a4dd38b5de7db25a4b835a754a65e18ea26 Mon Sep 17 00:00:00 2001 From: Kat Date: Sun, 4 Mar 2018 18:07:43 -0800 Subject: [PATCH 02/33] Finished Wave1 pseudocode for the propotential program. --- lib/block.rb | 0 lib/booking.rb | 24 ++++++++++++++++++++++++ lib/booking_manager.rb | 17 +++++++++++++++++ lib/customer.rb | 0 lib/room.rb | 16 ++++++++++++++++ lib/staff.rb | 0 lib/user.rb | 16 ++++++++++++++++ specs/block_spec.rb | 5 ----- specs/customer_spec.rb | 5 ----- specs/spec_helper.rb | 7 +++---- specs/{staff_spec.rb => user_spec.rb} | 0 11 files changed, 76 insertions(+), 14 deletions(-) delete mode 100644 lib/block.rb delete mode 100644 lib/customer.rb delete mode 100644 lib/staff.rb create mode 100644 lib/user.rb delete mode 100644 specs/block_spec.rb delete mode 100644 specs/customer_spec.rb rename specs/{staff_spec.rb => user_spec.rb} (100%) diff --git a/lib/block.rb b/lib/block.rb deleted file mode 100644 index e69de29bb..000000000 diff --git a/lib/booking.rb b/lib/booking.rb index e69de29bb..0acac79b0 100644 --- a/lib/booking.rb +++ b/lib/booking.rb @@ -0,0 +1,24 @@ +require 'awesome_print' +require 'pry' +require 'date' +require 'simplecov' + +module Hotel + class Booking + def initialize(date_range) + @reservation = reserve_room(date_range) # probably references a method to find an available room + @cost_estimate = cost_estimate # this may belong in BookingManager, we'll see + end + + def reserve_room(date_range) + # method to find available room and push it to @reservation + # must raise StandardError if an invalid date range is used + end + + def cost_estimate + # calculates the estimated total for a reservation + # does not include the last day of reservation in + # the calculation + end + end +end diff --git a/lib/booking_manager.rb b/lib/booking_manager.rb index e69de29bb..35c2f34d4 100644 --- a/lib/booking_manager.rb +++ b/lib/booking_manager.rb @@ -0,0 +1,17 @@ +require 'awesome_print' +require 'pry' +require 'date' +require 'simplecov' + +module Hotel + class BookingManager + # should handle the business logic for bookings + # e.g. all methods related to tracking room availability + # and blocks and costs + def initialize + @rooms = # method which populates all rooms on creation of the manager + @reservations = [] # user story, list all reservations + end + + end +end diff --git a/lib/customer.rb b/lib/customer.rb deleted file mode 100644 index e69de29bb..000000000 diff --git a/lib/room.rb b/lib/room.rb index e69de29bb..f13ac4bd7 100644 --- a/lib/room.rb +++ b/lib/room.rb @@ -0,0 +1,16 @@ +require 'awesome_print' +require 'pry' +require 'date' +require 'simplecov' + +module Hotel + class Room + def initialize(number) + # rooms that know their room number and cost + # make more sense as objects than a hash, for future + # proofing reasons, maybe overcomplicating things + @number = number + @cost_per_night = 200 + end + end +end diff --git a/lib/staff.rb b/lib/staff.rb deleted file mode 100644 index e69de29bb..000000000 diff --git a/lib/user.rb b/lib/user.rb new file mode 100644 index 000000000..d09e87d17 --- /dev/null +++ b/lib/user.rb @@ -0,0 +1,16 @@ +require 'awesome_print' +require 'pry' +require 'date' +require 'simplecov' + +module Hotel + class User + # Needs user types to limit functionality, + # between a customer, a staff person and + # an administrator, possibly store username + # and password + @user = admin + end +end + +binding.pry diff --git a/specs/block_spec.rb b/specs/block_spec.rb deleted file mode 100644 index 3b4cb1d93..000000000 --- a/specs/block_spec.rb +++ /dev/null @@ -1,5 +0,0 @@ -require_relative 'spec_helper' - -describe "Block" do - -end diff --git a/specs/customer_spec.rb b/specs/customer_spec.rb deleted file mode 100644 index e803d8daa..000000000 --- a/specs/customer_spec.rb +++ /dev/null @@ -1,5 +0,0 @@ -require_relative 'spec_helper' - -describe "Customer" do - -end diff --git a/specs/spec_helper.rb b/specs/spec_helper.rb index 17eff505c..16ce1a091 100644 --- a/specs/spec_helper.rb +++ b/specs/spec_helper.rb @@ -3,7 +3,8 @@ require 'minitest/autorun' require 'minitest/reporters' require 'minitest/skip_dsl' -# Add simplecov +require 'simplecov' +SimpleCov.start Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new @@ -11,6 +12,4 @@ require_relative '../lib/booking' require_relative '../lib/booking_manager' require_relative '../lib/room' -require_relative '../lib/block' -require_relative '../lib/staff' -require_relative '../lib/customer' +require_relative '../lib/user' diff --git a/specs/staff_spec.rb b/specs/user_spec.rb similarity index 100% rename from specs/staff_spec.rb rename to specs/user_spec.rb From d6a100a6243df47685db12f6b11e3bb6ff2d1cc7 Mon Sep 17 00:00:00 2001 From: Kat Date: Sun, 4 Mar 2018 18:18:52 -0800 Subject: [PATCH 03/33] Finished Wave1 pseudocode for the spec files, some of it has ts tests already because they made sense, the others will be made shortly. --- specs/booking_manager_spec.rb | 11 +++++++++++ specs/booking_spec.rb | 12 ++++++++++++ specs/room_spec.rb | 16 ++++++++++++++++ specs/user_spec.rb | 11 ++++++++++- 4 files changed, 49 insertions(+), 1 deletion(-) diff --git a/specs/booking_manager_spec.rb b/specs/booking_manager_spec.rb index 4d741a246..dafcd7c65 100644 --- a/specs/booking_manager_spec.rb +++ b/specs/booking_manager_spec.rb @@ -1,5 +1,16 @@ require_relative 'spec_helper' describe "BookingManager" do + it "has a list of rooms" do + # check that it has a list of rooms + end + it "has a list of reservations" do + # check that it has a list of reservations + end + + it "has business logic" do + # add as many tests as you need to test the business logic + + end end diff --git a/specs/booking_spec.rb b/specs/booking_spec.rb index ea49387ac..d470ae65b 100644 --- a/specs/booking_spec.rb +++ b/specs/booking_spec.rb @@ -2,4 +2,16 @@ describe "Booking" do + describe "Booking#reserve_room" do + # takes a date_range as an argument + # creates a booking + + end + + describe "Booking#cost_estimate" do + # creates a cost estimate total for all nights stayed + # does not include last night in reservation + + end + end diff --git a/specs/room_spec.rb b/specs/room_spec.rb index 37ee74e5f..2d2ac16bd 100644 --- a/specs/room_spec.rb +++ b/specs/room_spec.rb @@ -1,5 +1,21 @@ require_relative 'spec_helper' describe "Room" do + it "can be created" do + result = Hotel::Room.new(1) + result.must_be_instance_of Hotel::Room + end + it "knows its number" do + numbers = (1..20).to_a + numbers.each do |num| + result = Hotel::Room.new(num) + result.number.must_equal num + end + end + + it "knows its cost per night" do + result = Hotel::Room.new(1) + result.cost_per_night.must_equal 200 + end end diff --git a/specs/user_spec.rb b/specs/user_spec.rb index 48b9e9a11..0518b84e8 100644 --- a/specs/user_spec.rb +++ b/specs/user_spec.rb @@ -1,5 +1,14 @@ require_relative 'spec_helper' -describe "Staff" do +describe "User" do +it "creates a user" do + # test that it creates a user + result = Hotel::User.new + result.must_be_instance_of Hotel::User +end +it "can do things" do + # create as many tests as are needed to make sure + # that the user can actually navigate the program +end end From 3978b7fcda8ab58d0dfc7f9521a55e304673f93f Mon Sep 17 00:00:00 2001 From: Kat Date: Mon, 5 Mar 2018 02:34:28 -0800 Subject: [PATCH 04/33] fleshing out tests, adding attr_readers and checking for existence of stated methods. --- lib/booking_manager.rb | 4 +++- lib/room.rb | 1 + lib/user.rb | 4 +--- specs/booking_manager_spec.rb | 19 +++++++++++++++++-- 4 files changed, 22 insertions(+), 6 deletions(-) diff --git a/lib/booking_manager.rb b/lib/booking_manager.rb index 35c2f34d4..148f42449 100644 --- a/lib/booking_manager.rb +++ b/lib/booking_manager.rb @@ -4,12 +4,14 @@ require 'simplecov' module Hotel + class BookingManager # should handle the business logic for bookings # e.g. all methods related to tracking room availability # and blocks and costs + attr_reader :rooms, :reservations def initialize - @rooms = # method which populates all rooms on creation of the manager + @rooms = [] # method which populates all rooms on creation of the manager @reservations = [] # user story, list all reservations end diff --git a/lib/room.rb b/lib/room.rb index f13ac4bd7..9acabf51c 100644 --- a/lib/room.rb +++ b/lib/room.rb @@ -5,6 +5,7 @@ module Hotel class Room + attr_reader :number, :cost_per_night def initialize(number) # rooms that know their room number and cost # make more sense as objects than a hash, for future diff --git a/lib/user.rb b/lib/user.rb index d09e87d17..f37e26550 100644 --- a/lib/user.rb +++ b/lib/user.rb @@ -9,8 +9,6 @@ class User # between a customer, a staff person and # an administrator, possibly store username # and password - @user = admin + @user = "admin" end end - -binding.pry diff --git a/specs/booking_manager_spec.rb b/specs/booking_manager_spec.rb index dafcd7c65..a155bfc28 100644 --- a/specs/booking_manager_spec.rb +++ b/specs/booking_manager_spec.rb @@ -1,12 +1,27 @@ require_relative 'spec_helper' describe "BookingManager" do + before do + @result = Hotel::BookingManager.new + end + it "can be created" do + @result.must_be_instance_of Hotel::BookingManager + end + it "has a list of rooms" do - # check that it has a list of rooms + result = @result.rooms + + result.must_be_kind_of Array + result.length.must_equal 20 + end it "has a list of reservations" do - # check that it has a list of reservations + + result = @result.reservations + + result.must_be_kind_of Array + end it "has business logic" do From b9f45dac46b687abc4f0ad89969bf384a1ba24ab Mon Sep 17 00:00:00 2001 From: Kat Date: Mon, 5 Mar 2018 02:51:04 -0800 Subject: [PATCH 05/33] added BookingManager#load_rooms to populate @rooms list with room instances. --- lib/booking_manager.rb | 11 ++++++++++- lib/room.rb | 4 ++-- specs/booking_manager_spec.rb | 1 + specs/room_spec.rb | 5 ++++- 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/lib/booking_manager.rb b/lib/booking_manager.rb index 148f42449..cfd817d63 100644 --- a/lib/booking_manager.rb +++ b/lib/booking_manager.rb @@ -11,9 +11,18 @@ class BookingManager # and blocks and costs attr_reader :rooms, :reservations def initialize - @rooms = [] # method which populates all rooms on creation of the manager + @rooms = load_rooms # method which populates all rooms on creation of the manager @reservations = [] # user story, list all reservations end + def load_rooms + rooms = [] + numbers = (1..20).to_a + numbers.each do |num| + rooms << Room.new(num) + end + return rooms + end + end end diff --git a/lib/room.rb b/lib/room.rb index 9acabf51c..0c421614a 100644 --- a/lib/room.rb +++ b/lib/room.rb @@ -5,12 +5,12 @@ module Hotel class Room - attr_reader :number, :cost_per_night + attr_reader :room_number, :cost_per_night def initialize(number) # rooms that know their room number and cost # make more sense as objects than a hash, for future # proofing reasons, maybe overcomplicating things - @number = number + @room_number = number @cost_per_night = 200 end end diff --git a/specs/booking_manager_spec.rb b/specs/booking_manager_spec.rb index a155bfc28..6b03897e7 100644 --- a/specs/booking_manager_spec.rb +++ b/specs/booking_manager_spec.rb @@ -13,6 +13,7 @@ result.must_be_kind_of Array result.length.must_equal 20 + result.last.room_number.must_equal 20 end diff --git a/specs/room_spec.rb b/specs/room_spec.rb index 2d2ac16bd..c7deb3bca 100644 --- a/specs/room_spec.rb +++ b/specs/room_spec.rb @@ -10,7 +10,10 @@ numbers = (1..20).to_a numbers.each do |num| result = Hotel::Room.new(num) - result.number.must_equal num + + + result.room_number.must_equal num + end end From 2398bed5af7663c0f23d1a52c1f5b88e89e10f01 Mon Sep 17 00:00:00 2001 From: Kat Date: Mon, 5 Mar 2018 10:06:56 -0800 Subject: [PATCH 06/33] Added coverage folder to .gitignore file --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 5e1422c9c..8a3238615 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ /test/tmp/ /test/version_tmp/ /tmp/ +.DS_Store # Used by dotenv library to load environment variables. # .env From eb97e819437b36b0143dbbc6b8d1e58275a214aa Mon Sep 17 00:00:00 2001 From: Kat Date: Mon, 5 Mar 2018 15:41:52 -0800 Subject: [PATCH 07/33] shuShuffled methods around to hopefully have them make more se sense. Functionality for Wave 1 is complete. --- lib/booking.rb | 24 ++++++++++++++++++------ lib/booking_manager.rb | 32 +++++++++++++++++++++++++++++--- lib/room.rb | 4 ++++ specs/booking_manager_spec.rb | 15 ++++++++++++++- 4 files changed, 65 insertions(+), 10 deletions(-) diff --git a/lib/booking.rb b/lib/booking.rb index 0acac79b0..2499b9c92 100644 --- a/lib/booking.rb +++ b/lib/booking.rb @@ -4,21 +4,33 @@ require 'simplecov' module Hotel + + class Booking - def initialize(date_range) - @reservation = reserve_room(date_range) # probably references a method to find an available room - @cost_estimate = cost_estimate # this may belong in BookingManager, we'll see + attr_reader :cost_estimate, :room, :period + def initialize(open_room, date_range) + @room = open_room + @period = reserve_room(date_range) + @cost_estimate = get_cost_estimate(period) # this may belong in BookingManager, we'll see end def reserve_room(date_range) - # method to find available room and push it to @reservation - # must raise StandardError if an invalid date range is used + room.status = :RESERVED + dates = [] + date1 = date_range.first + date_range.each_with_object(date1) {|date| dates << date } + return dates end - def cost_estimate + + def get_cost_estimate(period) # calculates the estimated total for a reservation # does not include the last day of reservation in # the calculation + length = period.length - 1 + subtotal = room.cost_per_night * length + return subtotal end + end end diff --git a/lib/booking_manager.rb b/lib/booking_manager.rb index cfd817d63..5e5010f97 100644 --- a/lib/booking_manager.rb +++ b/lib/booking_manager.rb @@ -1,10 +1,11 @@ require 'awesome_print' require 'pry' -require 'date' -require 'simplecov' +require 'time' -module Hotel +require_relative 'booking' +require_relative 'room' +module Hotel class BookingManager # should handle the business logic for bookings # e.g. all methods related to tracking room availability @@ -24,5 +25,30 @@ def load_rooms return rooms end + + def get_booking(start_date, end_date) + check_date(start_date) + check_date(end_date) + + date_range = (Date.parse(start_date)..Date.parse(end_date)) + + open_room = rooms.find { |room| room.status == :AVAILABLE } + @reservations << Booking.new(open_room, date_range) + end + + # unless Date.valid_commercial?(start_date.year, start_date.mon, start_date.mday) && Date.valid_commercial?(end_date.year, end_date.mon, end_date.mday) + + + + private + def check_date(date) + parsed_date = Date.parse(date.to_s) + raise StandardError.new("Invalid reservation date entry: #{date}") if parsed_date.class != Date + compare = parsed_date <=> Date.today.prev_day + raise StandardError.new("Invalid reservation date entry: #{date} has already passed.") if compare == -1 + return parsed_date + end + end end +binding.pry diff --git a/lib/room.rb b/lib/room.rb index 0c421614a..0d89e9baa 100644 --- a/lib/room.rb +++ b/lib/room.rb @@ -5,13 +5,17 @@ module Hotel class Room + attr_accessor :status attr_reader :room_number, :cost_per_night + def initialize(number) # rooms that know their room number and cost # make more sense as objects than a hash, for future # proofing reasons, maybe overcomplicating things @room_number = number @cost_per_night = 200 + @status = :AVAILABLE + @dates = nil end end end diff --git a/specs/booking_manager_spec.rb b/specs/booking_manager_spec.rb index 6b03897e7..dc1ccea3c 100644 --- a/specs/booking_manager_spec.rb +++ b/specs/booking_manager_spec.rb @@ -20,11 +20,24 @@ it "has a list of reservations" do result = @result.reservations - result.must_be_kind_of Array end + it "raises an error if an invalid date is used" do + #this test doesn't seem to pass for the right reasons, investigate further + today = Date.today + start_date = "frog" + proc{ @result.reserve_room(start_date, today)}.must_raise StandardError + end + + it "raises an error if the first day of the reservation is before the current day" do + #this test doesn't seem to pass for the right reasons, investigate further + today = Date.today + start_date = today << 1 + proc{ @result.reserve_room(start_date, today)}.must_raise StandardError + end + it "has business logic" do # add as many tests as you need to test the business logic From c9988f7d7e05ac400c09fef7b0ee51a13b06130d Mon Sep 17 00:00:00 2001 From: Kat Date: Tue, 6 Mar 2018 11:45:16 -0800 Subject: [PATCH 08/33] changed BookingManger#get_booking to #set_booking, added a booking id for tracking purposes. --- .gitignore | 1 + lib/booking.rb | 4 +++- lib/booking_manager.rb | 2 +- lib/room.rb | 2 +- 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 8a3238615..703a023e5 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ /test/version_tmp/ /tmp/ .DS_Store +/lib/junk_files/ # Used by dotenv library to load environment variables. # .env diff --git a/lib/booking.rb b/lib/booking.rb index 2499b9c92..eadf108d5 100644 --- a/lib/booking.rb +++ b/lib/booking.rb @@ -7,8 +7,10 @@ module Hotel class Booking - attr_reader :cost_estimate, :room, :period + @@id_count = 0 + attr_reader :cost_estimate, :room, :period, :id def initialize(open_room, date_range) + @id = @@id_count += 1 @room = open_room @period = reserve_room(date_range) @cost_estimate = get_cost_estimate(period) # this may belong in BookingManager, we'll see diff --git a/lib/booking_manager.rb b/lib/booking_manager.rb index 5e5010f97..af0dab3b3 100644 --- a/lib/booking_manager.rb +++ b/lib/booking_manager.rb @@ -26,7 +26,7 @@ def load_rooms end - def get_booking(start_date, end_date) + def set_booking(start_date, end_date) check_date(start_date) check_date(end_date) diff --git a/lib/room.rb b/lib/room.rb index 0d89e9baa..684e87ede 100644 --- a/lib/room.rb +++ b/lib/room.rb @@ -7,8 +7,8 @@ module Hotel class Room attr_accessor :status attr_reader :room_number, :cost_per_night - def initialize(number) + # rooms that know their room number and cost # make more sense as objects than a hash, for future # proofing reasons, maybe overcomplicating things From 9a3d9ec8323223eabf395dc7e930488695f28a66 Mon Sep 17 00:00:00 2001 From: Kat Date: Tue, 6 Mar 2018 12:09:55 -0800 Subject: [PATCH 09/33] My lie, missed functionality from Wave 1 to return all bookings for a specific date. Added now. --- lib/booking_manager.rb | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/booking_manager.rb b/lib/booking_manager.rb index af0dab3b3..99755eb34 100644 --- a/lib/booking_manager.rb +++ b/lib/booking_manager.rb @@ -25,7 +25,6 @@ def load_rooms return rooms end - def set_booking(start_date, end_date) check_date(start_date) check_date(end_date) @@ -36,6 +35,16 @@ def set_booking(start_date, end_date) @reservations << Booking.new(open_room, date_range) end + def get_bookings_by_date(date) + parsed_date = check_date(date) + bookings = @reservations.find_all { |booking| booking.period.include? parsed_date} + + return bookings + end + + def get_booking_by_id(id) + end + # unless Date.valid_commercial?(start_date.year, start_date.mon, start_date.mday) && Date.valid_commercial?(end_date.year, end_date.mon, end_date.mday) From 0fbc7181d26a88a86fb23c2f8f9eb45fde77037d Mon Sep 17 00:00:00 2001 From: Kat Date: Tue, 6 Mar 2018 12:33:33 -0800 Subject: [PATCH 10/33] spec_helper fixed by moving simplecov up. --- lib/booking_manager.rb | 8 +++++--- specs/booking_manager_spec.rb | 37 +++++++++++++++++++++++++++-------- specs/spec_helper.rb | 5 +++-- 3 files changed, 37 insertions(+), 13 deletions(-) diff --git a/lib/booking_manager.rb b/lib/booking_manager.rb index 99755eb34..7c3e5107c 100644 --- a/lib/booking_manager.rb +++ b/lib/booking_manager.rb @@ -36,8 +36,11 @@ def set_booking(start_date, end_date) end def get_bookings_by_date(date) - parsed_date = check_date(date) - bookings = @reservations.find_all { |booking| booking.period.include? parsed_date} + unless date.class == Date + parsed_date = check_date(date) + date = parsed_date + end + bookings = @reservations.find_all { |booking| booking.period.include? date} return bookings end @@ -60,4 +63,3 @@ def check_date(date) end end -binding.pry diff --git a/specs/booking_manager_spec.rb b/specs/booking_manager_spec.rb index dc1ccea3c..7a6843f6e 100644 --- a/specs/booking_manager_spec.rb +++ b/specs/booking_manager_spec.rb @@ -2,25 +2,46 @@ describe "BookingManager" do before do + date1 = Date.today + date2 = date1 + 3 + @result = Hotel::BookingManager.new + @booking1 = @result.set_booking(date1.to_s, date2.to_s) + @booking2 = @result.set_booking((date1 + 1).to_s, date2.to_s) end - it "can be created" do - @result.must_be_instance_of Hotel::BookingManager - end + describe "Initialize" do + it "can be created" do + @result.must_be_instance_of Hotel::BookingManager + end - it "has a list of rooms" do - result = @result.rooms + it "creates a list of rooms" do + result = @result.rooms - result.must_be_kind_of Array - result.length.must_equal 20 - result.last.room_number.must_equal 20 + result.must_be_kind_of Array + result.length.must_equal 20 + result.last.room_number.must_equal 20 + end end + + + it "has a list of reservations" do result = @result.reservations result.must_be_kind_of Array + result.length.must_equal 2 + + end + + it "can find a list of reservations by date" do + date = Date.today + 2 + result = @result.get_bookings_by_date(date) + + result.must_be_kind_of Array + result[0].must_be_instance_of Hotel::Booking + result[0].period.must_include date end diff --git a/specs/spec_helper.rb b/specs/spec_helper.rb index 16ce1a091..21c6f4c8a 100644 --- a/specs/spec_helper.rb +++ b/specs/spec_helper.rb @@ -1,10 +1,11 @@ +require 'simplecov' +SimpleCov.start + require 'time' require 'minitest' require 'minitest/autorun' require 'minitest/reporters' require 'minitest/skip_dsl' -require 'simplecov' -SimpleCov.start Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new From b55f686c143233cd0859bf0852d7c5d0e53c1e11 Mon Sep 17 00:00:00 2001 From: Kat Date: Tue, 6 Mar 2018 13:06:27 -0800 Subject: [PATCH 11/33] added get_booking_by_id method and test. --- lib/booking_manager.rb | 13 +++++++++---- specs/booking_manager_spec.rb | 27 +++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/lib/booking_manager.rb b/lib/booking_manager.rb index 7c3e5107c..cbf08b962 100644 --- a/lib/booking_manager.rb +++ b/lib/booking_manager.rb @@ -10,10 +10,11 @@ class BookingManager # should handle the business logic for bookings # e.g. all methods related to tracking room availability # and blocks and costs - attr_reader :rooms, :reservations + attr_reader :rooms, :reservations, :occupied_rooms def initialize @rooms = load_rooms # method which populates all rooms on creation of the manager @reservations = [] # user story, list all reservations + @occupied_rooms = [] end def load_rooms @@ -32,7 +33,11 @@ def set_booking(start_date, end_date) date_range = (Date.parse(start_date)..Date.parse(end_date)) open_room = rooms.find { |room| room.status == :AVAILABLE } - @reservations << Booking.new(open_room, date_range) + if open_room == nil + raise StandardError.new("There are no available rooms") + else + @reservations << Booking.new(open_room, date_range) + end end def get_bookings_by_date(date) @@ -41,11 +46,12 @@ def get_bookings_by_date(date) date = parsed_date end bookings = @reservations.find_all { |booking| booking.period.include? date} - + @occupied_rooms << Hash[bookings.map { |booking| [booking.room.room_number, booking.room]}] return bookings end def get_booking_by_id(id) + return @reservations.find { |booking| booking.id == id} end # unless Date.valid_commercial?(start_date.year, start_date.mon, start_date.mday) && Date.valid_commercial?(end_date.year, end_date.mon, end_date.mday) @@ -60,6 +66,5 @@ def check_date(date) raise StandardError.new("Invalid reservation date entry: #{date} has already passed.") if compare == -1 return parsed_date end - end end diff --git a/specs/booking_manager_spec.rb b/specs/booking_manager_spec.rb index 7a6843f6e..d3970b886 100644 --- a/specs/booking_manager_spec.rb +++ b/specs/booking_manager_spec.rb @@ -45,6 +45,26 @@ end + it "can find a reservation by id" do + id = 1 + result = @result.get_booking_by_id(id) + + result.must_be_instance_of Hotel::Booking + result.id.must_equal id + + end + + it "can handle string dates" do #edge_case + date = "#{Date.today + 2}" + expected_result = Date.today + 2 + result = @result.get_bookings_by_date(date) + + result.must_be_kind_of Array + result[0].must_be_instance_of Hotel::Booking + result[0].period.must_include expected_result + + end + it "raises an error if an invalid date is used" do #this test doesn't seem to pass for the right reasons, investigate further today = Date.today @@ -59,6 +79,13 @@ proc{ @result.reserve_room(start_date, today)}.must_raise StandardError end + it "can handle :AVAILABLE/:UNAVAILABLE reservation logic" do + proc{ 20.times do + @result.set_booking(date1.to_s, date2.to_s) + end}.must_raise StandardError + + end + it "has business logic" do # add as many tests as you need to test the business logic From 0283f4ddabe8170f57bba168ea3cef0b1f16480b Mon Sep 17 00:00:00 2001 From: Kat Date: Tue, 6 Mar 2018 15:57:09 -0800 Subject: [PATCH 12/33] added method to set the availability each day, based ed on the bookings for that day, tested to confirm functionality. --- lib/booking.rb | 5 +- lib/booking_manager.rb | 38 ++++++++++--- lib/room.rb | 12 ++++ specs/booking_manager_spec.rb | 102 +++++++++++++++++++--------------- specs/booking_spec.rb | 31 ++++++++++- specs/room_spec.rb | 58 +++++++++++++++---- 6 files changed, 173 insertions(+), 73 deletions(-) diff --git a/lib/booking.rb b/lib/booking.rb index eadf108d5..deb9f8cef 100644 --- a/lib/booking.rb +++ b/lib/booking.rb @@ -8,7 +8,7 @@ module Hotel class Booking @@id_count = 0 - attr_reader :cost_estimate, :room, :period, :id + attr_reader :cost_estimate, :room, :period, :id, :id_count def initialize(open_room, date_range) @id = @@id_count += 1 @room = open_room @@ -17,14 +17,12 @@ def initialize(open_room, date_range) end def reserve_room(date_range) - room.status = :RESERVED dates = [] date1 = date_range.first date_range.each_with_object(date1) {|date| dates << date } return dates end - def get_cost_estimate(period) # calculates the estimated total for a reservation # does not include the last day of reservation in @@ -33,6 +31,5 @@ def get_cost_estimate(period) subtotal = room.cost_per_night * length return subtotal end - end end diff --git a/lib/booking_manager.rb b/lib/booking_manager.rb index cbf08b962..3a9dffa3d 100644 --- a/lib/booking_manager.rb +++ b/lib/booking_manager.rb @@ -46,25 +46,47 @@ def get_bookings_by_date(date) date = parsed_date end bookings = @reservations.find_all { |booking| booking.period.include? date} - @occupied_rooms << Hash[bookings.map { |booking| [booking.room.room_number, booking.room]}] + occupied_rooms = Hash[bookings.map { |booking| [booking.room.room_number, booking.room]}] + @occupied_rooms << occupied_rooms return bookings end - def get_booking_by_id(id) - return @reservations.find { |booking| booking.id == id} + def get_booking_by_id(id_to_find) + find_booking = @reservations.find { |booking| booking.id == id_to_find} + return find_booking end - # unless Date.valid_commercial?(start_date.year, start_date.mon, start_date.mday) && Date.valid_commercial?(end_date.year, end_date.mon, end_date.mday) + def get_availability_by_date(date) + check_date(date) + find_bookings = @reservations.find_all { |booking| booking.period.include? date} + return find_bookings + end + + def set_availability + today = Date.today + get_bookings_by_date(today) + occupied_rooms[0].each_value do |room| + room.change_status + end + end + def check_out(room_number) + find_room = @rooms.find { |room| room.room_number == room_number} + find_room.change_status(:AVAILABLE) + end + # unless Date.valid_commercial?(start_date.year, start_date.mon, start_date.mday) && Date.valid_commercial?(end_date.year, end_date.mon, end_date.mday) private def check_date(date) - parsed_date = Date.parse(date.to_s) - raise StandardError.new("Invalid reservation date entry: #{date}") if parsed_date.class != Date - compare = parsed_date <=> Date.today.prev_day + unless date.class == Date + parsed_date = Date.parse(date.to_s) + date = parsed_date + end + raise StandardError.new("Invalid reservation date entry: #{date}") if date.class != Date + compare = date <=> Date.today.prev_day raise StandardError.new("Invalid reservation date entry: #{date} has already passed.") if compare == -1 - return parsed_date + return date end end end diff --git a/lib/room.rb b/lib/room.rb index 684e87ede..e061d957b 100644 --- a/lib/room.rb +++ b/lib/room.rb @@ -17,5 +17,17 @@ def initialize(number) @status = :AVAILABLE @dates = nil end + + def change_status(new_status: :RESERVED) + case new_status + when :RESERVED + @status = :RESERVED + when :AVAILABLE + @status = :AVAILABLE + else + raise ArgumentError.new("Cannot set status to: #{new_status}") + end + end + end end diff --git a/specs/booking_manager_spec.rb b/specs/booking_manager_spec.rb index d3970b886..d7f193239 100644 --- a/specs/booking_manager_spec.rb +++ b/specs/booking_manager_spec.rb @@ -24,70 +24,80 @@ end end + describe "BookingManager - Business Logic" do + describe "Reservation Handling" do + it "has a list of reservations" do + result = @result.reservations + result.must_be_kind_of Array + result.length.must_equal 2 + end - it "has a list of reservations" do + it "can find a list of reservations by date" do + date = Date.today + 2 + result = @result.get_bookings_by_date(date) - result = @result.reservations - result.must_be_kind_of Array - result.length.must_equal 2 + result.must_be_kind_of Array + result[0].must_be_instance_of Hotel::Booking + result[0].period.must_include date - end - - it "can find a list of reservations by date" do - date = Date.today + 2 - result = @result.get_bookings_by_date(date) + end - result.must_be_kind_of Array - result[0].must_be_instance_of Hotel::Booking - result[0].period.must_include date + it "can find a reservation by id" do + id_to_find = @result.reservations[0].id + result = @result.get_booking_by_id(id_to_find) - end + result.must_be_instance_of Hotel::Booking + result.id.must_equal id_to_find + end - it "can find a reservation by id" do - id = 1 - result = @result.get_booking_by_id(id) + it "can handle :AVAILABLE/:UNAVAILABLE reservation logic" do + proc{ 20.times do + @result.set_booking(date1.to_s, date2.to_s) + end}.must_raise StandardError + end - result.must_be_instance_of Hotel::Booking - result.id.must_equal id + it "can set the availability of rooms each day" do + @result.set_availability + result = @result.occupied_rooms.first.first.last - end + result.status.must_equal :RESERVED + end + end - it "can handle string dates" do #edge_case - date = "#{Date.today + 2}" - expected_result = Date.today + 2 - result = @result.get_bookings_by_date(date) + describe "Date Handling" do - result.must_be_kind_of Array - result[0].must_be_instance_of Hotel::Booking - result[0].period.must_include expected_result + it "can handle string dates" do #edge_case + date = "#{Date.today + 2}" + expected_result = Date.today + 2 + result = @result.get_bookings_by_date(date) - end + result.must_be_kind_of Array + result[0].must_be_instance_of Hotel::Booking + result[0].period.must_include expected_result - it "raises an error if an invalid date is used" do - #this test doesn't seem to pass for the right reasons, investigate further - today = Date.today - start_date = "frog" - proc{ @result.reserve_room(start_date, today)}.must_raise StandardError - end + end - it "raises an error if the first day of the reservation is before the current day" do - #this test doesn't seem to pass for the right reasons, investigate further - today = Date.today - start_date = today << 1 - proc{ @result.reserve_room(start_date, today)}.must_raise StandardError - end + it "raises an error if an invalid date is used" do + #this test doesn't seem to pass for the right reasons, investigate further + today = Date.today + start_date = "frog" + proc{ @result.reserve_room(start_date, today)}.must_raise StandardError + end - it "can handle :AVAILABLE/:UNAVAILABLE reservation logic" do - proc{ 20.times do - @result.set_booking(date1.to_s, date2.to_s) - end}.must_raise StandardError + it "raises an error if the first day of the reservation is before the current day" do + #this test doesn't seem to pass for the right reasons, investigate further + today = Date.today + start_date = today << 1 + proc{ @result.reserve_room(start_date, today)}.must_raise StandardError + end - end - it "has business logic" do - # add as many tests as you need to test the business logic + it "has business logic" do + # add as many tests as you need to test the business logic + end + end end end diff --git a/specs/booking_spec.rb b/specs/booking_spec.rb index d470ae65b..f2dea41da 100644 --- a/specs/booking_spec.rb +++ b/specs/booking_spec.rb @@ -1,17 +1,42 @@ require_relative 'spec_helper' describe "Booking" do + before do + date1 = Date.today + date2 = date1 + 4 - describe "Booking#reserve_room" do - # takes a date_range as an argument - # creates a booking + @manager = Hotel::BookingManager.new + @booking = @manager.set_booking(date1.to_s, date2.to_s).first + end + describe "Booking#initialize" do + it "can be created" do + result = @booking + result.must_be_kind_of Hotel::Booking + end + end + describe "Booking#reserve_room" do + # deprecated by later features + # it "changes the status to :RESERVED" do + # result = @booking.room.status + # result.must_equal :RESERVED + # end end describe "Booking#cost_estimate" do # creates a cost estimate total for all nights stayed # does not include last night in reservation + it "creates a cost estimate" do + result = @booking.cost_estimate + days = @booking.period.length + nights = days - 1 + + result.must_equal nights * 200 + result.wont_equal days * 200 + end end + + end diff --git a/specs/room_spec.rb b/specs/room_spec.rb index c7deb3bca..69e3caa91 100644 --- a/specs/room_spec.rb +++ b/specs/room_spec.rb @@ -1,24 +1,58 @@ require_relative 'spec_helper' describe "Room" do - it "can be created" do - result = Hotel::Room.new(1) - result.must_be_instance_of Hotel::Room - end + describe "Room#Initialize" do + it "can be created" do + result = Hotel::Room.new(1) + result.must_be_instance_of Hotel::Room + end + + it "knows its number" do + numbers = (1..20).to_a + numbers.each do |num| + result = Hotel::Room.new(num) - it "knows its number" do - numbers = (1..20).to_a - numbers.each do |num| - result = Hotel::Room.new(num) + result.room_number.must_equal num - result.room_number.must_equal num + end + end + it "knows its cost per night" do + result = Hotel::Room.new(1) + result.cost_per_night.must_equal 200 end end - it "knows its cost per night" do - result = Hotel::Room.new(1) - result.cost_per_night.must_equal 200 + describe "Room#change_status" do + before do + @rooms = [] + numbers = (1..20).to_a + numbers.each do |num| + rooms << Room.new(num) + end + + it "does not accept an invalid status" do + room = @rooms[0] + proc{ room.change_status(new_status: :UNAVAILABLE)}.must_raise StandardError + end + + it "defaults to a status of :RESERVED with no argument" do + room = @rooms[0] + result = room.change_status + + result.must_equal :RESERVED + end + + it "Can change a :RESERVED status to :AVAILABLE" do + room = @rooms[0] + room.change_status + result = room.change_status(new_status: :AVAILABLE) + + result.must_equal :AVAILABLE + end + + + end end end From 2fe99ce86796d139ed31d75c78b31206e6af21fa Mon Sep 17 00:00:00 2001 From: Kat Date: Tue, 6 Mar 2018 16:19:46 -0800 Subject: [PATCH 13/33] streamlined syntax for test, and methods to set_availability. --- lib/booking.rb | 3 +-- lib/booking_manager.rb | 8 +++----- specs/booking_manager_spec.rb | 2 +- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/lib/booking.rb b/lib/booking.rb index deb9f8cef..dfe95e0ec 100644 --- a/lib/booking.rb +++ b/lib/booking.rb @@ -18,8 +18,7 @@ def initialize(open_room, date_range) def reserve_room(date_range) dates = [] - date1 = date_range.first - date_range.each_with_object(date1) {|date| dates << date } + date_range.each {|date| dates << date } return dates end diff --git a/lib/booking_manager.rb b/lib/booking_manager.rb index 3a9dffa3d..1e068c63f 100644 --- a/lib/booking_manager.rb +++ b/lib/booking_manager.rb @@ -46,8 +46,6 @@ def get_bookings_by_date(date) date = parsed_date end bookings = @reservations.find_all { |booking| booking.period.include? date} - occupied_rooms = Hash[bookings.map { |booking| [booking.room.room_number, booking.room]}] - @occupied_rooms << occupied_rooms return bookings end @@ -64,9 +62,9 @@ def get_availability_by_date(date) def set_availability today = Date.today - get_bookings_by_date(today) - occupied_rooms[0].each_value do |room| - room.change_status + @occupied_rooms = get_bookings_by_date(today) + @occupied_rooms.each do |booking| + booking.room.change_status end end diff --git a/specs/booking_manager_spec.rb b/specs/booking_manager_spec.rb index d7f193239..71f05c1fd 100644 --- a/specs/booking_manager_spec.rb +++ b/specs/booking_manager_spec.rb @@ -60,7 +60,7 @@ it "can set the availability of rooms each day" do @result.set_availability - result = @result.occupied_rooms.first.first.last + result = @result.occupied_rooms[0].room result.status.must_equal :RESERVED end From 37931dfe2352dbef8a39acbb81cd3ada2a4aad80 Mon Sep 17 00:00:00 2001 From: Kat Date: Wed, 7 Mar 2018 14:33:58 -0800 Subject: [PATCH 14/33] modified date range and tests. --- lib/booking.rb | 2 +- lib/booking_manager.rb | 21 ++++++++++++++++----- specs/booking_manager_spec.rb | 12 ++++++++++++ specs/booking_spec.rb | 4 ++-- 4 files changed, 31 insertions(+), 8 deletions(-) diff --git a/lib/booking.rb b/lib/booking.rb index dfe95e0ec..21a6c2053 100644 --- a/lib/booking.rb +++ b/lib/booking.rb @@ -26,7 +26,7 @@ def get_cost_estimate(period) # calculates the estimated total for a reservation # does not include the last day of reservation in # the calculation - length = period.length - 1 + length = period.length subtotal = room.cost_per_night * length return subtotal end diff --git a/lib/booking_manager.rb b/lib/booking_manager.rb index 1e068c63f..540f0c0e3 100644 --- a/lib/booking_manager.rb +++ b/lib/booking_manager.rb @@ -30,7 +30,7 @@ def set_booking(start_date, end_date) check_date(start_date) check_date(end_date) - date_range = (Date.parse(start_date)..Date.parse(end_date)) + date_range = (Date.parse(start_date)...Date.parse(end_date)) open_room = rooms.find { |room| room.status == :AVAILABLE } if open_room == nil @@ -38,6 +38,12 @@ def set_booking(start_date, end_date) else @reservations << Booking.new(open_room, date_range) end + + # Here for testing purposes, will find a better place or delete if unnecessary + # date_range.each do |date| + # get_availability_by_date(date) + # end + end def get_bookings_by_date(date) @@ -55,9 +61,14 @@ def get_booking_by_id(id_to_find) end def get_availability_by_date(date) - check_date(date) - find_bookings = @reservations.find_all { |booking| booking.period.include? date} - return find_bookings + unavailable_rooms = [] + find_bookings = get_bookings_by_date(date) + find_bookings.each do |booking| + unavailable_rooms << booking.room + end + + available_rooms = @rooms - unavailable_rooms + return available_rooms end def set_availability @@ -78,7 +89,7 @@ def check_out(room_number) private def check_date(date) unless date.class == Date - parsed_date = Date.parse(date.to_s) + parsed_date = Date.parse(date) date = parsed_date end raise StandardError.new("Invalid reservation date entry: #{date}") if date.class != Date diff --git a/specs/booking_manager_spec.rb b/specs/booking_manager_spec.rb index 71f05c1fd..8939e24fd 100644 --- a/specs/booking_manager_spec.rb +++ b/specs/booking_manager_spec.rb @@ -5,6 +5,7 @@ date1 = Date.today date2 = date1 + 3 + @date = date2 @result = Hotel::BookingManager.new @booking1 = @result.set_booking(date1.to_s, date2.to_s) @booking2 = @result.set_booking((date1 + 1).to_s, date2.to_s) @@ -64,6 +65,17 @@ result.status.must_equal :RESERVED end + + it "can get a list of available rooms by date" do + result = @result.get_availability_by_date(@date) + result.must_be_kind_of Array + #--- + + result = @result.get_availability_by_date(@date).first + + result.must_be_instance_of Hotel::Room + result.status.must_equal :AVAILABLE + end end describe "Date Handling" do diff --git a/specs/booking_spec.rb b/specs/booking_spec.rb index f2dea41da..80ff8ab40 100644 --- a/specs/booking_spec.rb +++ b/specs/booking_spec.rb @@ -28,8 +28,8 @@ # does not include last night in reservation it "creates a cost estimate" do result = @booking.cost_estimate - days = @booking.period.length - nights = days - 1 + days = @booking.period.length + 1 + nights = @booking.period.length result.must_equal nights * 200 result.wont_equal days * 200 From fea1edef34fc9cc897aa694e1ef90b82b7863433 Mon Sep 17 00:00:00 2001 From: Kat Date: Wed, 7 Mar 2018 15:05:44 -0800 Subject: [PATCH 15/33] Removed spec files from simple coverage reports, added a new block class and spec file. --- lib/block.rb | 11 +++++++++++ specs/spec_helper.rb | 5 ++++- specs/user_spec.rb | 8 ++++---- 3 files changed, 19 insertions(+), 5 deletions(-) create mode 100644 lib/block.rb diff --git a/lib/block.rb b/lib/block.rb new file mode 100644 index 000000000..5fc70ea94 --- /dev/null +++ b/lib/block.rb @@ -0,0 +1,11 @@ +require 'awesome_print' +require 'pry' +require 'date' +require 'simplecov' + +module Hotel + class Block + def initialize + end + end +end diff --git a/specs/spec_helper.rb b/specs/spec_helper.rb index 21c6f4c8a..7344c2de0 100644 --- a/specs/spec_helper.rb +++ b/specs/spec_helper.rb @@ -1,5 +1,7 @@ require 'simplecov' -SimpleCov.start +SimpleCov.start do + add_filter "/specs/" +end require 'time' require 'minitest' @@ -14,3 +16,4 @@ require_relative '../lib/booking_manager' require_relative '../lib/room' require_relative '../lib/user' +require_relative '../lib/block' diff --git a/specs/user_spec.rb b/specs/user_spec.rb index 0518b84e8..f47c231cb 100644 --- a/specs/user_spec.rb +++ b/specs/user_spec.rb @@ -1,10 +1,10 @@ require_relative 'spec_helper' -describe "User" do -it "creates a user" do +describe "Block" do +it "creates a block" do # test that it creates a user - result = Hotel::User.new - result.must_be_instance_of Hotel::User + result = Hotel::Block.new + result.must_be_instance_of Hotel::Block end it "can do things" do From 700815c838993e484362dd1ccd509784afa13a1f Mon Sep 17 00:00:00 2001 From: Kat Date: Wed, 7 Mar 2018 15:17:02 -0800 Subject: [PATCH 16/33] Streamlined the date parsing in #set_booking. --- lib/booking_manager.rb | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/booking_manager.rb b/lib/booking_manager.rb index 540f0c0e3..12640ed2f 100644 --- a/lib/booking_manager.rb +++ b/lib/booking_manager.rb @@ -27,10 +27,10 @@ def load_rooms end def set_booking(start_date, end_date) - check_date(start_date) - check_date(end_date) - date_range = (Date.parse(start_date)...Date.parse(end_date)) + + + date_range = (check_date(start_date)...check_date(end_date)) open_room = rooms.find { |room| room.status == :AVAILABLE } if open_room == nil @@ -79,6 +79,10 @@ def set_availability end end + def reserve_block + + end + def check_out(room_number) find_room = @rooms.find { |room| room.room_number == room_number} find_room.change_status(:AVAILABLE) From e047d352dbf54351018d18987da7ebcdcec5c580 Mon Sep 17 00:00:00 2001 From: Kat Date: Wed, 7 Mar 2018 15:18:08 -0800 Subject: [PATCH 17/33] Streamlined the status parsing in Room#change_status to include the block status options. --- lib/room.rb | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/lib/room.rb b/lib/room.rb index e061d957b..f85f1be54 100644 --- a/lib/room.rb +++ b/lib/room.rb @@ -15,15 +15,14 @@ def initialize(number) @room_number = number @cost_per_night = 200 @status = :AVAILABLE - @dates = nil + @block_dates = nil + end def change_status(new_status: :RESERVED) case new_status - when :RESERVED - @status = :RESERVED - when :AVAILABLE - @status = :AVAILABLE + when :RESERVED, :AVAILABLE, :BLOCK, :BLOCK_RESERVED + @status = new_status else raise ArgumentError.new("Cannot set status to: #{new_status}") end From 88827f7319325ad4d040fd365a9fd89c8d48a4d4 Mon Sep 17 00:00:00 2001 From: Kat Date: Wed, 7 Mar 2018 15:27:23 -0800 Subject: [PATCH 18/33] stubbed out neccessary elements of reserve block --- lib/booking_manager.rb | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/lib/booking_manager.rb b/lib/booking_manager.rb index 12640ed2f..61c3adf10 100644 --- a/lib/booking_manager.rb +++ b/lib/booking_manager.rb @@ -28,8 +28,6 @@ def load_rooms def set_booking(start_date, end_date) - - date_range = (check_date(start_date)...check_date(end_date)) open_room = rooms.find { |room| room.status == :AVAILABLE } @@ -80,7 +78,16 @@ def set_availability end def reserve_block - + # find {n} rooms that are near eachother and available for those dates + # requirements: + #=> date range, no more than 5 rooms at a discounted rate + #=> only include rooms available for the given date range + #=> a room in a block is not available or included in another block + + #needs: + #=> date_range + #=> availablity_checking + #=> uniqueness end def check_out(room_number) @@ -88,8 +95,6 @@ def check_out(room_number) find_room.change_status(:AVAILABLE) end - # unless Date.valid_commercial?(start_date.year, start_date.mon, start_date.mday) && Date.valid_commercial?(end_date.year, end_date.mon, end_date.mday) - private def check_date(date) unless date.class == Date From eda245820c393e39f5af0e6abbe8e1bd87c444ee Mon Sep 17 00:00:00 2001 From: Kat Date: Wed, 7 Mar 2018 16:54:42 -0800 Subject: [PATCH 19/33] Cleaning up logic and tests, adding additional classes to handle date logic. --- lib/block.rb | 6 ++++++ lib/booking.rb | 3 +++ lib/booking_manager.rb | 25 +++++++++---------------- specs/booking_manager_spec.rb | 33 ++++++++++++++++++--------------- specs/spec_helper.rb | 1 + 5 files changed, 37 insertions(+), 31 deletions(-) diff --git a/lib/block.rb b/lib/block.rb index 5fc70ea94..855bb225f 100644 --- a/lib/block.rb +++ b/lib/block.rb @@ -4,8 +4,14 @@ require 'simplecov' module Hotel + class Block + @@block_count = 0 def initialize + @id = @@block_count += 1 + @rooms = [] #check availability? + @period = [] end + end end diff --git a/lib/booking.rb b/lib/booking.rb index 21a6c2053..0641ee474 100644 --- a/lib/booking.rb +++ b/lib/booking.rb @@ -17,8 +17,11 @@ def initialize(open_room, date_range) end def reserve_room(date_range) + + #need to clean this up, took the logic and put it elsewhere, this may be a repeat dates = [] date_range.each {|date| dates << date } + #add in call to check availability of the room. return dates end diff --git a/lib/booking_manager.rb b/lib/booking_manager.rb index 61c3adf10..984c3410a 100644 --- a/lib/booking_manager.rb +++ b/lib/booking_manager.rb @@ -4,6 +4,8 @@ require_relative 'booking' require_relative 'room' +require_relative 'block' +require_relative 'stay' module Hotel class BookingManager @@ -27,9 +29,11 @@ def load_rooms end def set_booking(start_date, end_date) + dates = Stay.new(start_date, end_date) + date_range = dates.period - date_range = (check_date(start_date)...check_date(end_date)) + #(does this logic belong to room?) open_room = rooms.find { |room| room.status == :AVAILABLE } if open_room == nil raise StandardError.new("There are no available rooms") @@ -45,11 +49,9 @@ def set_booking(start_date, end_date) end def get_bookings_by_date(date) - unless date.class == Date - parsed_date = check_date(date) - date = parsed_date + bookings = @reservations.find_all do |booking| + booking.period.include? date end - bookings = @reservations.find_all { |booking| booking.period.include? date} return bookings end @@ -70,6 +72,7 @@ def get_availability_by_date(date) end def set_availability + #unneccesary function today = Date.today @occupied_rooms = get_bookings_by_date(today) @occupied_rooms.each do |booking| @@ -95,16 +98,6 @@ def check_out(room_number) find_room.change_status(:AVAILABLE) end - private - def check_date(date) - unless date.class == Date - parsed_date = Date.parse(date) - date = parsed_date - end - raise StandardError.new("Invalid reservation date entry: #{date}") if date.class != Date - compare = date <=> Date.today.prev_day - raise StandardError.new("Invalid reservation date entry: #{date} has already passed.") if compare == -1 - return date - end + end end diff --git a/specs/booking_manager_spec.rb b/specs/booking_manager_spec.rb index 8939e24fd..2fc75a61d 100644 --- a/specs/booking_manager_spec.rb +++ b/specs/booking_manager_spec.rb @@ -59,12 +59,15 @@ end}.must_raise StandardError end - it "can set the availability of rooms each day" do - @result.set_availability - result = @result.occupied_rooms[0].room + #Will likely be removed from final code - result.status.must_equal :RESERVED - end + #--- + # it "can set the availability of rooms each day" do + # @result.set_availability + # result = @result.occupied_rooms[0].room + # + # result.status.must_equal :RESERVED + # end it "can get a list of available rooms by date" do result = @result.get_availability_by_date(@date) @@ -80,16 +83,16 @@ describe "Date Handling" do - it "can handle string dates" do #edge_case - date = "#{Date.today + 2}" - expected_result = Date.today + 2 - result = @result.get_bookings_by_date(date) - - result.must_be_kind_of Array - result[0].must_be_instance_of Hotel::Booking - result[0].period.must_include expected_result - - end + # it "can handle string dates" do #edge_case, too closely coupled + # date = "#{Date.today + 2}" + # expected_result = Date.today + 2 + # result = @result.get_bookings_by_date(date) + # + # result.must_be_kind_of Array + # result[0].must_be_instance_of Hotel::Booking + # result[0].period.must_include expected_result + # + # end it "raises an error if an invalid date is used" do #this test doesn't seem to pass for the right reasons, investigate further diff --git a/specs/spec_helper.rb b/specs/spec_helper.rb index 7344c2de0..adcb090d8 100644 --- a/specs/spec_helper.rb +++ b/specs/spec_helper.rb @@ -17,3 +17,4 @@ require_relative '../lib/room' require_relative '../lib/user' require_relative '../lib/block' +require_relative '../lib/stay' From c8f1beb25af1543db081f998bfa97e9c2bbfb216 Mon Sep 17 00:00:00 2001 From: Kat Date: Wed, 7 Mar 2018 16:55:23 -0800 Subject: [PATCH 20/33] added class stay, and specs for block and stay. --- lib/stay.rb | 37 +++++++++++++++++++++++++++++++++++++ specs/block_spec.rb | 14 ++++++++++++++ specs/stay_spec.rb | 14 ++++++++++++++ 3 files changed, 65 insertions(+) create mode 100644 lib/stay.rb create mode 100644 specs/block_spec.rb create mode 100644 specs/stay_spec.rb diff --git a/lib/stay.rb b/lib/stay.rb new file mode 100644 index 000000000..1a1493032 --- /dev/null +++ b/lib/stay.rb @@ -0,0 +1,37 @@ +require 'awesome_print' +require 'pry' +require 'date' +require 'simplecov' + +module Hotel + class Stay + attr_reader :period + def initialize(start_date, end_date) + @period = date_range(start_date, end_date) + end + + def date_range(start_date, end_date) + new_range = (check_date(start_date)...check_date(end_date)) + return new_range + end + + def list(date_range) + + end + private + def check_date(date) + unless date.class == Date + parsed_date = Date.parse(date) + date = parsed_date + end + if date.class != Date + raise StandardError.new("Invalid reservation date entry: #{date}") + end + compare = date <=> Date.today.prev_day + if compare == -1 + raise StandardError.new("Invalid reservation date entry: #{date} has already passed.") + end + return date + end + end +end diff --git a/specs/block_spec.rb b/specs/block_spec.rb new file mode 100644 index 000000000..f47c231cb --- /dev/null +++ b/specs/block_spec.rb @@ -0,0 +1,14 @@ +require_relative 'spec_helper' + +describe "Block" do +it "creates a block" do + # test that it creates a user + result = Hotel::Block.new + result.must_be_instance_of Hotel::Block +end + +it "can do things" do + # create as many tests as are needed to make sure + # that the user can actually navigate the program +end +end diff --git a/specs/stay_spec.rb b/specs/stay_spec.rb new file mode 100644 index 000000000..d061ac386 --- /dev/null +++ b/specs/stay_spec.rb @@ -0,0 +1,14 @@ +require_relative 'spec_helper' + +describe "Stay" do +it "can be created" do + # test that it creates a user + result = Hotel::Stay.new("apr4, 2018", "apr7, 2018") + result.must_be_instance_of Hotel::Stay +end + +it "can do things" do + # create as many tests as are needed to make sure + # that the user can actually navigate the program +end +end From 13868ca10514b1b75c36261b69a4ff5f97455c28 Mon Sep 17 00:00:00 2001 From: Kat Date: Wed, 7 Mar 2018 17:17:07 -0800 Subject: [PATCH 21/33] will amend this later, for now, added things and they were glorious. --- lib/block.rb | 18 ++++++++++++++++-- lib/booking_manager.rb | 34 ++++++++++++++-------------------- lib/room.rb | 3 +++ lib/stay.rb | 12 +++++++++--- specs/block_spec.rb | 6 +++++- specs/user_spec.rb | 6 +++--- 6 files changed, 50 insertions(+), 29 deletions(-) diff --git a/lib/block.rb b/lib/block.rb index 855bb225f..05c68119d 100644 --- a/lib/block.rb +++ b/lib/block.rb @@ -7,11 +7,25 @@ module Hotel class Block @@block_count = 0 - def initialize + def initialize(date_range) @id = @@block_count += 1 @rooms = [] #check availability? - @period = [] + @period = date_range end + + + + # find {n} rooms that are near eachother and available for those dates + # requirements: + #=> date range, no more than 5 rooms at a discounted rate + #=> only include rooms available for the given date range + #=> a room in a block is not available or included in another block + + #needs: + #=> date_range + #=> availablity_checking + #=> uniqueness + end end diff --git a/lib/booking_manager.rb b/lib/booking_manager.rb index 984c3410a..9ae7aa7ec 100644 --- a/lib/booking_manager.rb +++ b/lib/booking_manager.rb @@ -17,6 +17,7 @@ def initialize @rooms = load_rooms # method which populates all rooms on creation of the manager @reservations = [] # user story, list all reservations @occupied_rooms = [] + @block_reservations = [] end def load_rooms @@ -32,7 +33,6 @@ def set_booking(start_date, end_date) dates = Stay.new(start_date, end_date) date_range = dates.period - #(does this logic belong to room?) open_room = rooms.find { |room| room.status == :AVAILABLE } if open_room == nil @@ -71,26 +71,20 @@ def get_availability_by_date(date) return available_rooms end - def set_availability - #unneccesary function - today = Date.today - @occupied_rooms = get_bookings_by_date(today) - @occupied_rooms.each do |booking| - booking.room.change_status - end - end + # def set_availability + # #unneccesary function + # today = Date.today + # @occupied_rooms = get_bookings_by_date(today) + # @occupied_rooms.each do |booking| + # booking.room.change_status + # end + # end + + def reserve_block(start_date, end_date) + block_dates = Stay.new(start_date, end_date) + block = Block.new(block_dates) - def reserve_block - # find {n} rooms that are near eachother and available for those dates - # requirements: - #=> date range, no more than 5 rooms at a discounted rate - #=> only include rooms available for the given date range - #=> a room in a block is not available or included in another block - - #needs: - #=> date_range - #=> availablity_checking - #=> uniqueness + @block_reservations << block end def check_out(room_number) diff --git a/lib/room.rb b/lib/room.rb index f85f1be54..c0e41e1f7 100644 --- a/lib/room.rb +++ b/lib/room.rb @@ -28,5 +28,8 @@ def change_status(new_status: :RESERVED) end end + def self.open_room + end + end end diff --git a/lib/stay.rb b/lib/stay.rb index 1a1493032..2ea8db9ab 100644 --- a/lib/stay.rb +++ b/lib/stay.rb @@ -7,7 +7,8 @@ module Hotel class Stay attr_reader :period def initialize(start_date, end_date) - @period = date_range(start_date, end_date) + @date_range = date_range(start_date, end_date) + @period = list end def date_range(start_date, end_date) @@ -15,9 +16,14 @@ def date_range(start_date, end_date) return new_range end - def list(date_range) - + def list + dates = [] + @date_range.each {|date| dates << date } + #add in call to check availability of the room. + return dates end + + private def check_date(date) unless date.class == Date diff --git a/specs/block_spec.rb b/specs/block_spec.rb index f47c231cb..1945f5a6d 100644 --- a/specs/block_spec.rb +++ b/specs/block_spec.rb @@ -1,9 +1,13 @@ require_relative 'spec_helper' describe "Block" do +before do + dates = Hotel::Stay.new("apr4, 2018", "apr7, 2018") + @block1 = Hotel::Block.new(dates) +end it "creates a block" do # test that it creates a user - result = Hotel::Block.new + result = @block1 result.must_be_instance_of Hotel::Block end diff --git a/specs/user_spec.rb b/specs/user_spec.rb index f47c231cb..8c172063f 100644 --- a/specs/user_spec.rb +++ b/specs/user_spec.rb @@ -1,10 +1,10 @@ require_relative 'spec_helper' -describe "Block" do +describe "User" do it "creates a block" do # test that it creates a user - result = Hotel::Block.new - result.must_be_instance_of Hotel::Block + result = Hotel::User.new + result.must_be_instance_of Hotel::User end it "can do things" do From e14442616f3b06b0ad2b23edf3b45db9d6551aa0 Mon Sep 17 00:00:00 2001 From: Kat Date: Wed, 7 Mar 2018 21:49:25 -0800 Subject: [PATCH 22/33] Changed Stay class to Duration for better readability, refactoringed code --- lib/booking_manager.rb | 25 +++++++----------------- lib/{stay.rb => duration.rb} | 2 +- specs/block_spec.rb | 2 +- specs/{stay_spec.rb => duration_spec.rb} | 4 ++-- specs/spec_helper.rb | 2 +- 5 files changed, 12 insertions(+), 23 deletions(-) rename lib/{stay.rb => duration.rb} (98%) rename specs/{stay_spec.rb => duration_spec.rb} (70%) diff --git a/lib/booking_manager.rb b/lib/booking_manager.rb index 9ae7aa7ec..831562bc6 100644 --- a/lib/booking_manager.rb +++ b/lib/booking_manager.rb @@ -5,17 +5,15 @@ require_relative 'booking' require_relative 'room' require_relative 'block' -require_relative 'stay' +require_relative 'duration' module Hotel class BookingManager # should handle the business logic for bookings - # e.g. all methods related to tracking room availability - # and blocks and costs attr_reader :rooms, :reservations, :occupied_rooms def initialize - @rooms = load_rooms # method which populates all rooms on creation of the manager - @reservations = [] # user story, list all reservations + @rooms = load_rooms + @reservations = [] @occupied_rooms = [] @block_reservations = [] end @@ -30,21 +28,12 @@ def load_rooms end def set_booking(start_date, end_date) - dates = Stay.new(start_date, end_date) + dates = Duration.new(start_date, end_date) date_range = dates.period #(does this logic belong to room?) open_room = rooms.find { |room| room.status == :AVAILABLE } - if open_room == nil - raise StandardError.new("There are no available rooms") - else - @reservations << Booking.new(open_room, date_range) - end - - # Here for testing purposes, will find a better place or delete if unnecessary - # date_range.each do |date| - # get_availability_by_date(date) - # end + @reservations << Booking.new(open_room, date_range) end @@ -72,7 +61,7 @@ def get_availability_by_date(date) end # def set_availability - # #unneccesary function + # #unneccesary function, may reuse some logic elsewhere # today = Date.today # @occupied_rooms = get_bookings_by_date(today) # @occupied_rooms.each do |booking| @@ -81,7 +70,7 @@ def get_availability_by_date(date) # end def reserve_block(start_date, end_date) - block_dates = Stay.new(start_date, end_date) + block_dates = Duration.new(start_date, end_date) block = Block.new(block_dates) @block_reservations << block diff --git a/lib/stay.rb b/lib/duration.rb similarity index 98% rename from lib/stay.rb rename to lib/duration.rb index 2ea8db9ab..c3cd0d85c 100644 --- a/lib/stay.rb +++ b/lib/duration.rb @@ -4,7 +4,7 @@ require 'simplecov' module Hotel - class Stay + class Duration attr_reader :period def initialize(start_date, end_date) @date_range = date_range(start_date, end_date) diff --git a/specs/block_spec.rb b/specs/block_spec.rb index 1945f5a6d..612c73673 100644 --- a/specs/block_spec.rb +++ b/specs/block_spec.rb @@ -2,7 +2,7 @@ describe "Block" do before do - dates = Hotel::Stay.new("apr4, 2018", "apr7, 2018") + dates = Hotel::Duration.new("apr4, 2018", "apr7, 2018") @block1 = Hotel::Block.new(dates) end it "creates a block" do diff --git a/specs/stay_spec.rb b/specs/duration_spec.rb similarity index 70% rename from specs/stay_spec.rb rename to specs/duration_spec.rb index d061ac386..235017a2d 100644 --- a/specs/stay_spec.rb +++ b/specs/duration_spec.rb @@ -3,8 +3,8 @@ describe "Stay" do it "can be created" do # test that it creates a user - result = Hotel::Stay.new("apr4, 2018", "apr7, 2018") - result.must_be_instance_of Hotel::Stay + result = Hotel::Duration.new("apr4, 2018", "apr7, 2018") + result.must_be_instance_of Hotel::Duration end it "can do things" do diff --git a/specs/spec_helper.rb b/specs/spec_helper.rb index adcb090d8..c9ce27e7f 100644 --- a/specs/spec_helper.rb +++ b/specs/spec_helper.rb @@ -17,4 +17,4 @@ require_relative '../lib/room' require_relative '../lib/user' require_relative '../lib/block' -require_relative '../lib/stay' +require_relative '../lib/duration' From b7e6d1f4a712574276311a577a8263a6e92a22ce Mon Sep 17 00:00:00 2001 From: Kat Date: Fri, 9 Mar 2018 08:54:22 -0800 Subject: [PATCH 23/33] saving clean-up work before branching. --- lib/booking.rb | 14 ++++---------- lib/booking_manager.rb | 16 ++++++++++++++-- lib/room.rb | 3 +-- 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/lib/booking.rb b/lib/booking.rb index 0641ee474..e0fd5e3da 100644 --- a/lib/booking.rb +++ b/lib/booking.rb @@ -12,23 +12,17 @@ class Booking def initialize(open_room, date_range) @id = @@id_count += 1 @room = open_room - @period = reserve_room(date_range) - @cost_estimate = get_cost_estimate(period) # this may belong in BookingManager, we'll see + @period = date_range + @cost_estimate = get_cost_estimate(period) end def reserve_room(date_range) + # add dates to room + # set status for dates to available - #need to clean this up, took the logic and put it elsewhere, this may be a repeat - dates = [] - date_range.each {|date| dates << date } - #add in call to check availability of the room. - return dates end def get_cost_estimate(period) - # calculates the estimated total for a reservation - # does not include the last day of reservation in - # the calculation length = period.length subtotal = room.cost_per_night * length return subtotal diff --git a/lib/booking_manager.rb b/lib/booking_manager.rb index 831562bc6..8e69141a9 100644 --- a/lib/booking_manager.rb +++ b/lib/booking_manager.rb @@ -31,7 +31,8 @@ def set_booking(start_date, end_date) dates = Duration.new(start_date, end_date) date_range = dates.period - #(does this logic belong to room?) + # Here for testing purposes, will find a better place or delete if unnecessary + open_room = rooms.find { |room| room.status == :AVAILABLE } @reservations << Booking.new(open_room, date_range) @@ -44,6 +45,14 @@ def get_bookings_by_date(date) return bookings end + def available_rooms(date) + date_range.each do |day| + get_availability_by_date(day) + end + binding.pry + return available + end + def get_booking_by_id(id_to_find) find_booking = @reservations.find { |booking| booking.id == id_to_find} return find_booking @@ -52,6 +61,7 @@ def get_booking_by_id(id_to_find) def get_availability_by_date(date) unavailable_rooms = [] find_bookings = get_bookings_by_date(date) + find_bookings.each do |booking| unavailable_rooms << booking.room end @@ -69,7 +79,9 @@ def get_availability_by_date(date) # end # end - def reserve_block(start_date, end_date) + + + def reserve_block(start_date, end_date, number_of_rooms: 5) block_dates = Duration.new(start_date, end_date) block = Block.new(block_dates) diff --git a/lib/room.rb b/lib/room.rb index c0e41e1f7..1eea84114 100644 --- a/lib/room.rb +++ b/lib/room.rb @@ -28,8 +28,7 @@ def change_status(new_status: :RESERVED) end end - def self.open_room - end + end end From b490b184646bc5d5a838df70e8c777d59e1bc1fc Mon Sep 17 00:00:00 2001 From: Kat Date: Thu, 15 Mar 2018 00:45:11 -0700 Subject: [PATCH 24/33] Switched reservation logic to a hash. --- lib/block.rb | 19 +++++++++-- lib/booking.rb | 29 +++++++++++------ lib/booking_manager.rb | 60 +++++++++++++++++++++++++++-------- lib/room.rb | 9 ++++-- specs/block_spec.rb | 6 ++-- specs/booking_manager_spec.rb | 6 ++-- 6 files changed, 97 insertions(+), 32 deletions(-) diff --git a/lib/block.rb b/lib/block.rb index 05c68119d..5c60e8c04 100644 --- a/lib/block.rb +++ b/lib/block.rb @@ -7,12 +7,27 @@ module Hotel class Block @@block_count = 0 - def initialize(date_range) + def initialize(date_range, available_rooms) @id = @@block_count += 1 - @rooms = [] #check availability? + @rooms = reserve_block(date_range, available_rooms) @period = date_range end + def set_block_price(price) + block_price = price + return block_price + end + + def reserve_block(date_range, open_rooms, price: 150) + reserved = Hash[date_range.collect { |date| [date, :BLOCK]}] + rooms = [] + open_rooms.each do |open_room| + open_room.block_dates = reserved + open_room.block_price(price) + rooms << open_room + end + return rooms + end diff --git a/lib/booking.rb b/lib/booking.rb index e0fd5e3da..ebd9a240e 100644 --- a/lib/booking.rb +++ b/lib/booking.rb @@ -11,21 +11,32 @@ class Booking attr_reader :cost_estimate, :room, :period, :id, :id_count def initialize(open_room, date_range) @id = @@id_count += 1 - @room = open_room + @room = reserve_room(open_room, date_range) @period = date_range - @cost_estimate = get_cost_estimate(period) - end - - def reserve_room(date_range) - # add dates to room - # set status for dates to available - + @cost_estimate = get_cost_estimate(date_range) end def get_cost_estimate(period) - length = period.length + length = period.size subtotal = room.cost_per_night * length return subtotal end + + def reserve_room(open_room, date_range) + reserved = Hash[date_range.collect { |date| [date, :RESERVED]}] + if open_room.reserved_dates == nil + open_room.reserved_dates = reserved + return open_room + else + date_range.each do |date| + if open_room.reserved_dates.has_key?(date) + raise StandardError.new("Room is not available for this day: #{date}") + end + open_room.reserved_dates.merge!(reserved) + end + end + return open_room + end + end end diff --git a/lib/booking_manager.rb b/lib/booking_manager.rb index 8e69141a9..a690942e9 100644 --- a/lib/booking_manager.rb +++ b/lib/booking_manager.rb @@ -16,6 +16,7 @@ def initialize @reservations = [] @occupied_rooms = [] @block_reservations = [] + @available_rooms = [] end def load_rooms @@ -31,11 +32,13 @@ def set_booking(start_date, end_date) dates = Duration.new(start_date, end_date) date_range = dates.period - # Here for testing purposes, will find a better place or delete if unnecessary - - open_room = rooms.find { |room| room.status == :AVAILABLE } - @reservations << Booking.new(open_room, date_range) - + if @reservations.length == 0 + open_room = rooms.first + else + available_rooms = all_available(date_range) + open_room = available_rooms.first + end + @reservations << Booking.new(open_room, date_range) end def get_bookings_by_date(date) @@ -45,14 +48,30 @@ def get_bookings_by_date(date) return bookings end - def available_rooms(date) - date_range.each do |day| - get_availability_by_date(day) + # def available_rooms(date_range) + # available = [] + # date_range.each do |day| + # available << get_availability_by_date(day) + # end + # return available + # end + def all_available(date_range) + available_rooms = [] + date_range.each do |date| + rooms_check = get_availability_by_date(date) + + if available_rooms.length == 0 + available_rooms = rooms_check + else + temp_rooms = available_rooms & rooms_check + available_rooms = temp_rooms + end end - binding.pry - return available + + return available_rooms end + def get_booking_by_id(id_to_find) find_booking = @reservations.find { |booking| booking.id == id_to_find} return find_booking @@ -82,10 +101,24 @@ def get_availability_by_date(date) def reserve_block(start_date, end_date, number_of_rooms: 5) - block_dates = Duration.new(start_date, end_date) - block = Block.new(block_dates) + # binding.pry + # dates = Duration.new(start_date, end_date) + # block_dates = dates.period + # block = Block.new(block_dates, available_rooms) + # + # @block_reservations << block + + dates = Duration.new(start_date, end_date) + date_range = dates.period + + if @block_reservations.length == 0 + open_rooms = rooms.first(number_of_rooms) + else + available_rooms = all_available(date_range) + open_rooms = available_rooms.first(number_of_rooms) + end - @block_reservations << block + @block_reservations << Block.new(date_range, open_rooms) end def check_out(room_number) @@ -96,3 +129,4 @@ def check_out(room_number) end end +# binding.pry diff --git a/lib/room.rb b/lib/room.rb index 1eea84114..3872ef418 100644 --- a/lib/room.rb +++ b/lib/room.rb @@ -5,7 +5,7 @@ module Hotel class Room - attr_accessor :status + attr_accessor :status, :reserved_dates, :block_dates attr_reader :room_number, :cost_per_night def initialize(number) @@ -14,8 +14,11 @@ def initialize(number) # proofing reasons, maybe overcomplicating things @room_number = number @cost_per_night = 200 + + # remove status as a discrete attribute, use block dates and reserved dates instead @status = :AVAILABLE @block_dates = nil + @reserved_dates = nil end @@ -28,7 +31,9 @@ def change_status(new_status: :RESERVED) end end - + def block_price(price) + @cost_per_night = price + end end end diff --git a/specs/block_spec.rb b/specs/block_spec.rb index 612c73673..9f47abfed 100644 --- a/specs/block_spec.rb +++ b/specs/block_spec.rb @@ -2,12 +2,12 @@ describe "Block" do before do - dates = Hotel::Duration.new("apr4, 2018", "apr7, 2018") - @block1 = Hotel::Block.new(dates) + booking_manager = Hotel::BookingManager.new + @block1 = booking_manager.reserve_block("apr4, 2018", "apr7, 2018") end it "creates a block" do # test that it creates a user - result = @block1 + result = @block1.first result.must_be_instance_of Hotel::Block end diff --git a/specs/booking_manager_spec.rb b/specs/booking_manager_spec.rb index 2fc75a61d..1d0952d31 100644 --- a/specs/booking_manager_spec.rb +++ b/specs/booking_manager_spec.rb @@ -109,9 +109,9 @@ end - it "has business logic" do - # add as many tests as you need to test the business logic - end + # it "has business logic" do + # # add as many tests as you need to test the business logic + # end end end From 7054070ac51cb89972e93c870bef021019c3af99 Mon Sep 17 00:00:00 2001 From: Kat Date: Thu, 15 Mar 2018 00:52:59 -0700 Subject: [PATCH 25/33] cleaned up room status debris from refactor. --- lib/room.rb | 20 ++++++++++---------- lib/user.rb | 14 -------------- specs/booking_manager_spec.rb | 30 +++--------------------------- specs/user_spec.rb | 14 -------------- 4 files changed, 13 insertions(+), 65 deletions(-) delete mode 100644 lib/user.rb delete mode 100644 specs/user_spec.rb diff --git a/lib/room.rb b/lib/room.rb index 3872ef418..5901fcf3e 100644 --- a/lib/room.rb +++ b/lib/room.rb @@ -5,7 +5,7 @@ module Hotel class Room - attr_accessor :status, :reserved_dates, :block_dates + attr_accessor :reserved_dates, :block_dates attr_reader :room_number, :cost_per_night def initialize(number) @@ -16,20 +16,20 @@ def initialize(number) @cost_per_night = 200 # remove status as a discrete attribute, use block dates and reserved dates instead - @status = :AVAILABLE + # @status = :AVAILABLE @block_dates = nil @reserved_dates = nil end - def change_status(new_status: :RESERVED) - case new_status - when :RESERVED, :AVAILABLE, :BLOCK, :BLOCK_RESERVED - @status = new_status - else - raise ArgumentError.new("Cannot set status to: #{new_status}") - end - end + # def change_status(new_status: :RESERVED) + # case new_status + # when :RESERVED, :AVAILABLE, :BLOCK, :BLOCK_RESERVED + # @status = new_status + # else + # raise ArgumentError.new("Cannot set status to: #{new_status}") + # end + # end def block_price(price) @cost_per_night = price diff --git a/lib/user.rb b/lib/user.rb deleted file mode 100644 index f37e26550..000000000 --- a/lib/user.rb +++ /dev/null @@ -1,14 +0,0 @@ -require 'awesome_print' -require 'pry' -require 'date' -require 'simplecov' - -module Hotel - class User - # Needs user types to limit functionality, - # between a customer, a staff person and - # an administrator, possibly store username - # and password - @user = "admin" - end -end diff --git a/specs/booking_manager_spec.rb b/specs/booking_manager_spec.rb index 1d0952d31..d766186ad 100644 --- a/specs/booking_manager_spec.rb +++ b/specs/booking_manager_spec.rb @@ -59,41 +59,22 @@ end}.must_raise StandardError end - #Will likely be removed from final code - - #--- - # it "can set the availability of rooms each day" do - # @result.set_availability - # result = @result.occupied_rooms[0].room - # - # result.status.must_equal :RESERVED - # end - it "can get a list of available rooms by date" do result = @result.get_availability_by_date(@date) result.must_be_kind_of Array #--- result = @result.get_availability_by_date(@date).first + result2 = result.reserved_dates.include?(@date) result.must_be_instance_of Hotel::Room - result.status.must_equal :AVAILABLE + result2.must_equal false + end end describe "Date Handling" do - # it "can handle string dates" do #edge_case, too closely coupled - # date = "#{Date.today + 2}" - # expected_result = Date.today + 2 - # result = @result.get_bookings_by_date(date) - # - # result.must_be_kind_of Array - # result[0].must_be_instance_of Hotel::Booking - # result[0].period.must_include expected_result - # - # end - it "raises an error if an invalid date is used" do #this test doesn't seem to pass for the right reasons, investigate further today = Date.today @@ -108,11 +89,6 @@ proc{ @result.reserve_room(start_date, today)}.must_raise StandardError end - - # it "has business logic" do - # # add as many tests as you need to test the business logic - # end - end end end diff --git a/specs/user_spec.rb b/specs/user_spec.rb deleted file mode 100644 index 8c172063f..000000000 --- a/specs/user_spec.rb +++ /dev/null @@ -1,14 +0,0 @@ -require_relative 'spec_helper' - -describe "User" do -it "creates a block" do - # test that it creates a user - result = Hotel::User.new - result.must_be_instance_of Hotel::User -end - -it "can do things" do - # create as many tests as are needed to make sure - # that the user can actually navigate the program -end -end From 0a7a4e8ee3ff1a5a44ad3039318fb7df19f5f3d9 Mon Sep 17 00:00:00 2001 From: Kat Date: Thu, 15 Mar 2018 00:54:06 -0700 Subject: [PATCH 26/33] removed user from spec_helper --- specs/spec_helper.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/specs/spec_helper.rb b/specs/spec_helper.rb index c9ce27e7f..3148e2c6c 100644 --- a/specs/spec_helper.rb +++ b/specs/spec_helper.rb @@ -15,6 +15,5 @@ require_relative '../lib/booking' require_relative '../lib/booking_manager' require_relative '../lib/room' -require_relative '../lib/user' require_relative '../lib/block' require_relative '../lib/duration' From 14519f9d7d7b9d9b37339eb509ac2f385d172ec8 Mon Sep 17 00:00:00 2001 From: Kat Date: Thu, 15 Mar 2018 02:27:10 -0700 Subject: [PATCH 27/33] new tests for block --- lib/block.rb | 18 ++------ lib/booking.rb | 14 ++++--- lib/booking_manager.rb | 93 ++++++++++++++++-------------------------- lib/room.rb | 20 ++++++++- specs/block_spec.rb | 34 +++++++++++++-- specs/booking_spec.rb | 29 +++++++------ 6 files changed, 113 insertions(+), 95 deletions(-) diff --git a/lib/block.rb b/lib/block.rb index 5c60e8c04..c4ba0a607 100644 --- a/lib/block.rb +++ b/lib/block.rb @@ -7,6 +7,8 @@ module Hotel class Block @@block_count = 0 + + attr_reader :id, :rooms, :period def initialize(date_range, available_rooms) @id = @@block_count += 1 @rooms = reserve_block(date_range, available_rooms) @@ -22,25 +24,13 @@ def reserve_block(date_range, open_rooms, price: 150) reserved = Hash[date_range.collect { |date| [date, :BLOCK]}] rooms = [] open_rooms.each do |open_room| - open_room.block_dates = reserved + open_room.check_block_dates(date_range) + open_room.block_dates.merge!(reserved) open_room.block_price(price) rooms << open_room end return rooms end - - - # find {n} rooms that are near eachother and available for those dates - # requirements: - #=> date range, no more than 5 rooms at a discounted rate - #=> only include rooms available for the given date range - #=> a room in a block is not available or included in another block - - #needs: - #=> date_range - #=> availablity_checking - #=> uniqueness - end end diff --git a/lib/booking.rb b/lib/booking.rb index ebd9a240e..23041cb61 100644 --- a/lib/booking.rb +++ b/lib/booking.rb @@ -24,14 +24,16 @@ def get_cost_estimate(period) def reserve_room(open_room, date_range) reserved = Hash[date_range.collect { |date| [date, :RESERVED]}] - if open_room.reserved_dates == nil - open_room.reserved_dates = reserved - return open_room + + if open_room.reserved_dates.length == 0 + open_room.reserved_dates.merge!(reserved) else date_range.each do |date| - if open_room.reserved_dates.has_key?(date) - raise StandardError.new("Room is not available for this day: #{date}") - end + ##this belongs somewhere else, where open_rooms are being defined. + # if open_room.reserved_dates.has_key?(date) + # raise StandardError.new("Room is not available for this day: #{date}") + # end + binding.pry open_room.reserved_dates.merge!(reserved) end end diff --git a/lib/booking_manager.rb b/lib/booking_manager.rb index a690942e9..59b3af4cc 100644 --- a/lib/booking_manager.rb +++ b/lib/booking_manager.rb @@ -16,7 +16,7 @@ def initialize @reservations = [] @occupied_rooms = [] @block_reservations = [] - @available_rooms = [] + @available_rooms = nil end def load_rooms @@ -38,24 +38,27 @@ def set_booking(start_date, end_date) available_rooms = all_available(date_range) open_room = available_rooms.first end + @reservations << Booking.new(open_room, date_range) end - def get_bookings_by_date(date) - bookings = @reservations.find_all do |booking| - booking.period.include? date + def reserve_block(start_date, end_date, number_of_rooms: 5) + dates = Duration.new(start_date, end_date) + date_range = dates.period + + if @block_reservations.length == 0 + open_rooms = rooms.first(number_of_rooms) + else + available_rooms = all_available(date_range) + open_rooms = available_rooms.first(number_of_rooms) end - return bookings + + @block_reservations << Block.new(date_range, open_rooms) end - # def available_rooms(date_range) - # available = [] - # date_range.each do |day| - # available << get_availability_by_date(day) - # end - # return available - # end - def all_available(date_range) + + + def all_available(date_range) #actively using this available_rooms = [] date_range.each do |date| rooms_check = get_availability_by_date(date) @@ -71,6 +74,18 @@ def all_available(date_range) return available_rooms end + def get_bookings_by_date(date) + bookings = @reservations.find_all do |booking| + if booking.period.include? date + @occupied_rooms << booking + end + end + @available_rooms = @rooms - @occupied_rooms + if @available_rooms.length == 0 + raise StandardError.new("Room is not available for this day: #{date}") + end + return bookings + end def get_booking_by_id(id_to_find) find_booking = @reservations.find { |booking| booking.id == id_to_find} @@ -78,55 +93,19 @@ def get_booking_by_id(id_to_find) end def get_availability_by_date(date) - unavailable_rooms = [] - find_bookings = get_bookings_by_date(date) - - find_bookings.each do |booking| - unavailable_rooms << booking.room - end - - available_rooms = @rooms - unavailable_rooms - return available_rooms - end + get_bookings_by_date(date) + potential_rooms = @available_rooms + open_rooms = [] + potential_rooms.each do |room| - # def set_availability - # #unneccesary function, may reuse some logic elsewhere - # today = Date.today - # @occupied_rooms = get_bookings_by_date(today) - # @occupied_rooms.each do |booking| - # booking.room.change_status - # end - # end + unless room.reserved_dates.has_key?(date) || room.block_dates.has_key?(date) + open_rooms << room - - - def reserve_block(start_date, end_date, number_of_rooms: 5) - # binding.pry - # dates = Duration.new(start_date, end_date) - # block_dates = dates.period - # block = Block.new(block_dates, available_rooms) - # - # @block_reservations << block - - dates = Duration.new(start_date, end_date) - date_range = dates.period - - if @block_reservations.length == 0 - open_rooms = rooms.first(number_of_rooms) - else - available_rooms = all_available(date_range) - open_rooms = available_rooms.first(number_of_rooms) + end end + return open_rooms - @block_reservations << Block.new(date_range, open_rooms) end - def check_out(room_number) - find_room = @rooms.find { |room| room.room_number == room_number} - find_room.change_status(:AVAILABLE) - end - - end end -# binding.pry diff --git a/lib/room.rb b/lib/room.rb index 5901fcf3e..056157ab6 100644 --- a/lib/room.rb +++ b/lib/room.rb @@ -17,8 +17,8 @@ def initialize(number) # remove status as a discrete attribute, use block dates and reserved dates instead # @status = :AVAILABLE - @block_dates = nil - @reserved_dates = nil + @block_dates = {} + @reserved_dates = {} end @@ -35,5 +35,21 @@ def block_price(price) @cost_per_night = price end + def check_block_dates(date_range) + date_range.each do |date| + if @block_dates.has_key?(date) + raise StandardError.new("Room is reserved to a block on #{date}") + end + end + end + + def check_reserved_dates(date_range) + date_range.each do |date| + if @reserved_dates.has_key?(date) + raise StandardError.new("Room is already reserved on #{date}") + end + end + end + end end diff --git a/specs/block_spec.rb b/specs/block_spec.rb index 9f47abfed..ecee46f5d 100644 --- a/specs/block_spec.rb +++ b/specs/block_spec.rb @@ -2,17 +2,45 @@ describe "Block" do before do - booking_manager = Hotel::BookingManager.new - @block1 = booking_manager.reserve_block("apr4, 2018", "apr7, 2018") + @booking_manager = Hotel::BookingManager.new + @block1 = @booking_manager.reserve_block("apr4, 2018", "apr7, 2018") end -it "creates a block" do +describe "Block#initialize" do +it "creates a block with an id, rooms and a date_range" do # test that it creates a user result = @block1.first + result.must_be_instance_of Hotel::Block + + result.id.must_be_kind_of Integer + result.rooms.must_be_kind_of Array + result.period.length.wont_be_nil +end + +it "won't accept a block with rooms from another block" do + # proc{ + # @booking_manager.reserve_block("apr4, 2018", "apr7, 2018") + # }.must_raise StandardError + result = @booking_manager.reserve_block("apr4, 2018", "apr7, 2018") + result.must_be_nil +end + + end it "can do things" do # create as many tests as are needed to make sure # that the user can actually navigate the program end + +# find {n} rooms that are near eachother and available for those dates +# requirements: +#=> date range, no more than 5 rooms at a discounted rate +#=> only include rooms available for the given date range +#=> a room in a block is not available or included in another block + +#needs: +#=> date_range +#=> availablity_checking +#=> uniqueness end diff --git a/specs/booking_spec.rb b/specs/booking_spec.rb index 80ff8ab40..5dc27ba47 100644 --- a/specs/booking_spec.rb +++ b/specs/booking_spec.rb @@ -2,11 +2,11 @@ describe "Booking" do before do - date1 = Date.today - date2 = date1 + 4 + @date1 = Date.today + @date2 = @date1 + 4 @manager = Hotel::BookingManager.new - @booking = @manager.set_booking(date1.to_s, date2.to_s).first + @booking = @manager.set_booking(@date1.to_s, @date2.to_s).first end describe "Booking#initialize" do it "can be created" do @@ -15,17 +15,7 @@ end end - describe "Booking#reserve_room" do - # deprecated by later features - # it "changes the status to :RESERVED" do - # result = @booking.room.status - # result.must_equal :RESERVED - # end - end - describe "Booking#cost_estimate" do - # creates a cost estimate total for all nights stayed - # does not include last night in reservation it "creates a cost estimate" do result = @booking.cost_estimate days = @booking.period.length + 1 @@ -35,6 +25,19 @@ result.wont_equal days * 200 end + describe "Booking#reserve_room" do + it "reserves a room" do + + end + + it "raises an error if there are no available rooms" do + proc{ + 30.times do + @manager.set_booking(@date1.to_s, @date2.to_s) + end + }.must_raise StandardError + end + end end From 929502f7b41e8c324f4de0dab5b5201cb6d27cb0 Mon Sep 17 00:00:00 2001 From: Kat Date: Thu, 15 Mar 2018 02:45:46 -0700 Subject: [PATCH 28/33] Solved the block issue and test. --- lib/block.rb | 5 ----- lib/booking.rb | 14 +------------- lib/booking_manager.rb | 11 ++++------- lib/duration.rb | 7 ------- specs/block_spec.rb | 10 ++++------ 5 files changed, 9 insertions(+), 38 deletions(-) diff --git a/lib/block.rb b/lib/block.rb index c4ba0a607..c3419b82b 100644 --- a/lib/block.rb +++ b/lib/block.rb @@ -15,11 +15,6 @@ def initialize(date_range, available_rooms) @period = date_range end - def set_block_price(price) - block_price = price - return block_price - end - def reserve_block(date_range, open_rooms, price: 150) reserved = Hash[date_range.collect { |date| [date, :BLOCK]}] rooms = [] diff --git a/lib/booking.rb b/lib/booking.rb index 23041cb61..16e05fcb1 100644 --- a/lib/booking.rb +++ b/lib/booking.rb @@ -24,19 +24,7 @@ def get_cost_estimate(period) def reserve_room(open_room, date_range) reserved = Hash[date_range.collect { |date| [date, :RESERVED]}] - - if open_room.reserved_dates.length == 0 - open_room.reserved_dates.merge!(reserved) - else - date_range.each do |date| - ##this belongs somewhere else, where open_rooms are being defined. - # if open_room.reserved_dates.has_key?(date) - # raise StandardError.new("Room is not available for this day: #{date}") - # end - binding.pry - open_room.reserved_dates.merge!(reserved) - end - end + open_room.reserved_dates.merge!(reserved) return open_room end diff --git a/lib/booking_manager.rb b/lib/booking_manager.rb index 59b3af4cc..93e545dfe 100644 --- a/lib/booking_manager.rb +++ b/lib/booking_manager.rb @@ -46,14 +46,11 @@ def reserve_block(start_date, end_date, number_of_rooms: 5) dates = Duration.new(start_date, end_date) date_range = dates.period - if @block_reservations.length == 0 - open_rooms = rooms.first(number_of_rooms) - else - available_rooms = all_available(date_range) - open_rooms = available_rooms.first(number_of_rooms) - end + open_rooms = rooms.take(number_of_rooms) + block = Block.new(date_range, open_rooms) - @block_reservations << Block.new(date_range, open_rooms) + @block_reservations << block + return block end diff --git a/lib/duration.rb b/lib/duration.rb index c3cd0d85c..c0815a307 100644 --- a/lib/duration.rb +++ b/lib/duration.rb @@ -30,13 +30,6 @@ def check_date(date) parsed_date = Date.parse(date) date = parsed_date end - if date.class != Date - raise StandardError.new("Invalid reservation date entry: #{date}") - end - compare = date <=> Date.today.prev_day - if compare == -1 - raise StandardError.new("Invalid reservation date entry: #{date} has already passed.") - end return date end end diff --git a/specs/block_spec.rb b/specs/block_spec.rb index ecee46f5d..9bc13ccc8 100644 --- a/specs/block_spec.rb +++ b/specs/block_spec.rb @@ -8,7 +8,7 @@ describe "Block#initialize" do it "creates a block with an id, rooms and a date_range" do # test that it creates a user - result = @block1.first + result = @block1 result.must_be_instance_of Hotel::Block @@ -18,11 +18,9 @@ end it "won't accept a block with rooms from another block" do - # proc{ - # @booking_manager.reserve_block("apr4, 2018", "apr7, 2018") - # }.must_raise StandardError - result = @booking_manager.reserve_block("apr4, 2018", "apr7, 2018") - result.must_be_nil + proc{ + @booking_manager.reserve_block("apr4, 2018", "apr7, 2018") + }.must_raise StandardError end From eaf428a98ff293760cacbba67f0ed3729056f78a Mon Sep 17 00:00:00 2001 From: Kat Date: Fri, 23 Mar 2018 18:46:41 -0700 Subject: [PATCH 29/33] Answered design-activity questions. --- design-activity.md | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 design-activity.md diff --git a/design-activity.md b/design-activity.md new file mode 100644 index 000000000..8d621d4c9 --- /dev/null +++ b/design-activity.md @@ -0,0 +1,45 @@ +#### 1. What classes does each implementation include? Are the lists the same? +CartEntry, ShoppingCart & Order - yes, the lists are the same. +#### 2. Write down a sentence to describe each class. + +* CartEntry stores information about individual items, like price and quantity. + +* ShoppingCart holds a list of CartEntries. + +* Order applies sales tax to the subtotal derived from ShoppingCart. + +#### 3. How do the classes relate to each other? *It might be helpful to draw a diagram on a whiteboard or piece of paper*. + +CartEntry is an element in ShoppingCart (though that logic is invisible) - and Order takes information from ShoppingCart and adds the sales tax. + +#### 4. What data does each class store? How (if at all) does this differ between the two implementations? + +* In the first implementation CartEntry exists to hold the instance variables for @unit_price and @quanitity, in the second implementation it has a method for price that returns the @unit_price multiplied by the @quantity. + +* In the first implementation ShoppingCart holds the instance variable @entries which is assigned to an empty array, in the second implementation ShoppingCart has a method for price that returns the sum of elements in the @entries array. + +* In implementation A, Order holds a constant for SALES_TAX, an instance of ShoppingCart and a method for total price that adds the unit_price * quantity for each entry in the ShoppingCart @entries array, but in the second implementation the logic is much simpler for the total price method. + +#### 5. What methods does each class have? How (if at all) does this differ between the two implementations? +See previous answer. + +#### Consider the Order#total_price method. In each implementation: +* **Is logic to compute the price delegated to "lower level" classes like ShoppingCart and CartEntry, or is it retained in Order?** + +In Implementation A, it is retained in Order in Implementation B it is delegated to "lower level" classes. + +* **Does total_price directly manipulate the instance variables of other classes?** + +It doesn't change the values of other variables, but it uses them to calculate a new value. + +* **If we decide items are cheaper if bought in bulk, how would this change the code? Which implementation is easier to modify?** + +It would probably affect the price for CartEntry. The change for Implementation B requires less complicated logic because it's not as far removed from the source of the change. + +* **Which implementation better adheres to the single responsibility principle?** + +Implementation B seems to adhere to this better. + +* **Bonus question once you've read Metz ch. 3: Which implementation is more loosely coupled?** + +Implementation B is more loosely coupled, because it knows less information about other classes. In B, total_price only knows its own variable @cart has a price, in A, total_price knows that each entry has a unit_price and a quantity, if those values are changed, then it will no longer work. Whereas with A, if they were changed, as long as price remained as method that could be called there would be no difference for the program as a whole. From aad890f409e482d9ed7a1e4b580023b9d35170bd Mon Sep 17 00:00:00 2001 From: Kat Date: Fri, 23 Mar 2018 20:11:10 -0700 Subject: [PATCH 30/33] Answered Activity question in design-activity.md --- design-activity.md | 33 ++++++++++++++++++---------- lib/booking_manager.rb | 2 +- specs/booking_manager_spec.rb | 41 +++++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 12 deletions(-) diff --git a/design-activity.md b/design-activity.md index 8d621d4c9..dec35eb88 100644 --- a/design-activity.md +++ b/design-activity.md @@ -1,6 +1,8 @@ -#### 1. What classes does each implementation include? Are the lists the same? +> What classes does each implementation include? Are the lists the same? + CartEntry, ShoppingCart & Order - yes, the lists are the same. -#### 2. Write down a sentence to describe each class. + +> Write down a sentence to describe each class. * CartEntry stores information about individual items, like price and quantity. @@ -8,11 +10,11 @@ CartEntry, ShoppingCart & Order - yes, the lists are the same. * Order applies sales tax to the subtotal derived from ShoppingCart. -#### 3. How do the classes relate to each other? *It might be helpful to draw a diagram on a whiteboard or piece of paper*. +> How do the classes relate to each other? *It might be helpful to draw a diagram on a whiteboard or piece of paper*. CartEntry is an element in ShoppingCart (though that logic is invisible) - and Order takes information from ShoppingCart and adds the sales tax. -#### 4. What data does each class store? How (if at all) does this differ between the two implementations? +> What data does each class store? How (if at all) does this differ between the two implementations? * In the first implementation CartEntry exists to hold the instance variables for @unit_price and @quanitity, in the second implementation it has a method for price that returns the @unit_price multiplied by the @quantity. @@ -20,26 +22,35 @@ CartEntry is an element in ShoppingCart (though that logic is invisible) - and O * In implementation A, Order holds a constant for SALES_TAX, an instance of ShoppingCart and a method for total price that adds the unit_price * quantity for each entry in the ShoppingCart @entries array, but in the second implementation the logic is much simpler for the total price method. -#### 5. What methods does each class have? How (if at all) does this differ between the two implementations? +> What methods does each class have? How (if at all) does this differ between the two implementations? + See previous answer. -#### 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?** +> Consider the Order#total_price method. In each implementation: + +>Is logic to compute the price delegated to "lower level" classes like ShoppingCart and CartEntry, or is it retained in Order? In Implementation A, it is retained in Order in Implementation B it is delegated to "lower level" classes. -* **Does total_price directly manipulate the instance variables of other classes?** +> Does total_price directly manipulate the instance variables of other classes? It doesn't change the values of other variables, but it uses them to calculate a new value. -* **If we decide items are cheaper if bought in bulk, how would this change the code? Which implementation is easier to modify?** +> If we decide items are cheaper if bought in bulk, how would this change the code? Which implementation is easier to modify? It would probably affect the price for CartEntry. The change for Implementation B requires less complicated logic because it's not as far removed from the source of the change. -* **Which implementation better adheres to the single responsibility principle?** +> Which implementation better adheres to the single responsibility principle? Implementation B seems to adhere to this better. -* **Bonus question once you've read Metz ch. 3: Which implementation is more loosely coupled?** +> **Bonus question once you've read Metz ch. 3: Which implementation is more loosely coupled?** Implementation B is more loosely coupled, because it knows less information about other classes. In B, total_price only knows its own variable @cart has a price, in A, total_price knows that each entry has a unit_price and a quantity, if those values are changed, then it will no longer work. Whereas with A, if they were changed, as long as price remained as method that could be called there would be no difference for the program as a whole. + +## Activity +> Based on the answers to the above questions, identify one place in your Hotel project where a class takes on multiple roles, or directly modifies the attributes of another class. + +> Describe in design-activity.md what changes you would need to make to improve this design, and how the resulting design would be an improvement. + +My BookingManager class takes on multiple responsibilities when it should delegate them. I need to change all of the places where I chain to an instance method so that those classes handle the logic themselves. diff --git a/lib/booking_manager.rb b/lib/booking_manager.rb index 93e545dfe..2eb34e968 100644 --- a/lib/booking_manager.rb +++ b/lib/booking_manager.rb @@ -36,7 +36,7 @@ def set_booking(start_date, end_date) open_room = rooms.first else available_rooms = all_available(date_range) - open_room = available_rooms.first + open_room = available_rooms.pop end @reservations << Booking.new(open_room, date_range) diff --git a/specs/booking_manager_spec.rb b/specs/booking_manager_spec.rb index d766186ad..a3d3cd97b 100644 --- a/specs/booking_manager_spec.rb +++ b/specs/booking_manager_spec.rb @@ -90,5 +90,46 @@ end end + + + end +end + +describe "Instructor Suggested Test Cases" do + describe "Instructor Test Cases (without before block)" do + it "handles no reservations" do + + end + end + + describe "Instructor Test Cases (with before block)" do + + it "allows reservations that do not overlap on dates" do + + end + + it "handles dates that overlap in the front" do + + end + + it "handles dates that overlap in the back" do + + end + + it "handles dates that completely contain others" do + + end + + it "handles dates completely contained by others" do + + end + + it "allows dates that end on the checkin date" do + + end + + it "allows reservations that start on the checkout date" do + op + end end end From e8832d97cccccabfbfa1b5827fb422770d053a4a Mon Sep 17 00:00:00 2001 From: Kat Date: Sun, 25 Mar 2018 04:53:19 -0700 Subject: [PATCH 31/33] checkin last stable version before coupling revisions. --- lib/booking_manager.rb | 4 ++ lib/room.rb | 13 +---- specs/booking_manager_spec.rb | 92 +++++++++++++++++++++++++++++++++-- specs/booking_spec.rb | 8 +++ specs/spec_helper.rb | 1 + 5 files changed, 103 insertions(+), 15 deletions(-) diff --git a/lib/booking_manager.rb b/lib/booking_manager.rb index 2eb34e968..e951e6e49 100644 --- a/lib/booking_manager.rb +++ b/lib/booking_manager.rb @@ -68,6 +68,10 @@ def all_available(date_range) #actively using this end end + available_rooms.each do |room| + room.check_reserved_dates(date_range) + end + return available_rooms end diff --git a/lib/room.rb b/lib/room.rb index 056157ab6..0bfaec182 100644 --- a/lib/room.rb +++ b/lib/room.rb @@ -12,25 +12,14 @@ def initialize(number) # rooms that know their room number and cost # make more sense as objects than a hash, for future # proofing reasons, maybe overcomplicating things + @room_number = number @cost_per_night = 200 - - # remove status as a discrete attribute, use block dates and reserved dates instead - # @status = :AVAILABLE @block_dates = {} @reserved_dates = {} end - # def change_status(new_status: :RESERVED) - # case new_status - # when :RESERVED, :AVAILABLE, :BLOCK, :BLOCK_RESERVED - # @status = new_status - # else - # raise ArgumentError.new("Cannot set status to: #{new_status}") - # end - # end - def block_price(price) @cost_per_night = price end diff --git a/specs/booking_manager_spec.rb b/specs/booking_manager_spec.rb index a3d3cd97b..e3a0b3493 100644 --- a/specs/booking_manager_spec.rb +++ b/specs/booking_manager_spec.rb @@ -98,38 +98,124 @@ describe "Instructor Suggested Test Cases" do describe "Instructor Test Cases (without before block)" do it "handles no reservations" do + bookingmanager1 = Hotel::BookingManager.new + result = bookingmanager1.reservations + + result.must_be_kind_of Array + result.length.must_equal 0 end end describe "Instructor Test Cases (with before block)" do + before do + @date1 = Date.today + @date2 = @date1 + 3 + + @result = Hotel::BookingManager.new + end it "allows reservations that do not overlap on dates" do + 20.times do + booking1 = @result.set_booking(@date1.to_s, @date2.to_s) + end + + 20.times do + booking2 = @result.set_booking((@date2 + 3).to_s, (@date2 + 7).to_s) + end + + result = @result.reservations + result.length.must_equal 40 + result.first.must_be_kind_of Hotel::Booking + result.last.must_be_kind_of Hotel::Booking end it "handles dates that overlap in the front" do + 20.times do + booking1 = @result.set_booking(@date1.to_s, @date2.to_s) + end + + proc { + 20.times do + booking2 = @result.set_booking((@date1 - 1).to_s, (@date2 - 1).to_s) + end + }.must_raise StandardError + + result = @result.reservations + + result.length.must_equal 20 + result.first.must_be_kind_of Hotel::Booking + result.last.must_be_kind_of Hotel::Booking end it "handles dates that overlap in the back" do + 20.times do + booking1 = @result.set_booking(@date1.to_s, @date2.to_s) + end + + proc { + 20.times do + booking2 = @result.set_booking((@date2 - 2).to_s, (@date2 + 4).to_s) + end + }.must_raise StandardError + result = @result.reservations + + result.length.must_equal 20 + result.first.must_be_kind_of Hotel::Booking + result.last.must_be_kind_of Hotel::Booking end it "handles dates that completely contain others" do + 20.times do + booking1 = @result.set_booking(@date1.to_s, @date2.to_s) + end - end + proc { + 20.times do + booking2 = @result.set_booking((@date1 + 1).to_s, (@date2 - 1).to_s) + end + }.must_raise StandardError - it "handles dates completely contained by others" do + result = @result.reservations + result.length.must_equal 20 + result.first.must_be_kind_of Hotel::Booking + result.last.must_be_kind_of Hotel::Booking end it "allows dates that end on the checkin date" do + 20.times do + booking1 = @result.set_booking(@date1.to_s, @date2.to_s) + end + + 20.times do + booking2 = @result.set_booking((@date1 - 3).to_s, @date1.to_s) + end + + result = @result.reservations + result.length.must_equal 40 + result.first.must_be_kind_of Hotel::Booking + result.last.must_be_kind_of Hotel::Booking end it "allows reservations that start on the checkout date" do - op + 20.times do + booking1 = @result.set_booking(@date1.to_s, @date2.to_s) + end + + 20.times do + booking2 = @result.set_booking(@date2.to_s, (@date2 + 2).to_s) + end + + result = @result.reservations + + result.length.must_equal 40 + result.first.must_be_kind_of Hotel::Booking + result.last.must_be_kind_of Hotel::Booking end end end diff --git a/specs/booking_spec.rb b/specs/booking_spec.rb index 5dc27ba47..5aa0caba9 100644 --- a/specs/booking_spec.rb +++ b/specs/booking_spec.rb @@ -37,6 +37,14 @@ end }.must_raise StandardError end + + it "won't accept a reservation for a room that is reserved" do + proc{ + 30.times do + @booking_manager.reserve_room("apr4, 2018", "apr7, 2018") + end + }.must_raise StandardError + end end end diff --git a/specs/spec_helper.rb b/specs/spec_helper.rb index 3148e2c6c..3d00bdad6 100644 --- a/specs/spec_helper.rb +++ b/specs/spec_helper.rb @@ -8,6 +8,7 @@ require 'minitest/autorun' require 'minitest/reporters' require 'minitest/skip_dsl' +require 'minitest/pride' Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new From d311c0a8039b1ae49454673d9fad83cb5a9d1761 Mon Sep 17 00:00:00 2001 From: Kat Date: Sun, 25 Mar 2018 05:56:43 -0700 Subject: [PATCH 32/33] added room method free? to decouple BookingManager. --- lib/booking_manager.rb | 8 +++----- lib/room.rb | 9 ++++++++- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/lib/booking_manager.rb b/lib/booking_manager.rb index e951e6e49..11cec020c 100644 --- a/lib/booking_manager.rb +++ b/lib/booking_manager.rb @@ -95,17 +95,15 @@ def get_booking_by_id(id_to_find) def get_availability_by_date(date) get_bookings_by_date(date) - potential_rooms = @available_rooms open_rooms = [] - potential_rooms.each do |room| - unless room.reserved_dates.has_key?(date) || room.block_dates.has_key?(date) + @available_rooms.each do |room| + unless room.free?(date) open_rooms << room - end end - return open_rooms + return open_rooms end end diff --git a/lib/room.rb b/lib/room.rb index 0bfaec182..9d2fbdaed 100644 --- a/lib/room.rb +++ b/lib/room.rb @@ -12,7 +12,7 @@ def initialize(number) # rooms that know their room number and cost # make more sense as objects than a hash, for future # proofing reasons, maybe overcomplicating things - + @room_number = number @cost_per_night = 200 @block_dates = {} @@ -40,5 +40,12 @@ def check_reserved_dates(date_range) end end + def free?(date) + if @block_dates.has_key?(date) || @reserved_dates.has_key?(date) + return true + end + return false + end + end end From 9cf48483da8bc7bf87cfd892bfd40603ade6fe13 Mon Sep 17 00:00:00 2001 From: Kat Date: Sun, 25 Mar 2018 06:41:28 -0700 Subject: [PATCH 33/33] removed unnecessary error flag. --- lib/booking_manager.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/booking_manager.rb b/lib/booking_manager.rb index 11cec020c..591d5e07a 100644 --- a/lib/booking_manager.rb +++ b/lib/booking_manager.rb @@ -82,9 +82,7 @@ def get_bookings_by_date(date) end end @available_rooms = @rooms - @occupied_rooms - if @available_rooms.length == 0 - raise StandardError.new("Room is not available for this day: #{date}") - end + return bookings end