diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 000000000..1dcc9a098 Binary files /dev/null and b/.DS_Store differ 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/design-activity.md b/design-activity.md new file mode 100644 index 000000000..7e57f49b0 --- /dev/null +++ b/design-activity.md @@ -0,0 +1,44 @@ +Prompts +Once you have read through the above code, add a file to your Hotel project called design-activity.md. This file will be submitted with the rest of this exercise. In that file, please respond to the following prompts: + +What classes does each implementation include? Are the lists the same? + The two implementations have the same classes; CartEntry, ShoppingCart and Order. The methods within are different. + +Write down a sentence to describe each class. + CartEntry contains data on each item and its price. + ShoppingCart class contains an array of all items. + Order gives the total for all items in the Shopping card calculated with sales tax. + +How do the classes relate to each other? It might be helpful to draw a diagram on a whiteboard or piece of paper. + CartEntry seems to be independent of the two other classes. + ShoppingCart seems like it will be a collection of CartEntries. + Orders have ShoppingCarts. + +What data does each class store? How (if at all) does this differ between the two implementations? + CartEntry stores: @unit_price and @quantity + ShoppingCart stores: @entries + Order stores: @cart and SALES_TAX + +What methods does each class have? How (if at all) does this differ between the two implementations? + Implementation A: total_price + Implementation B: price, price, total_price + +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? + Implementation A: retained in Order + Implementation B: Delated to other classes. + +Does total_price directly manipulate the instance variables of other classes? + Implementation A: Yes + Implementation B: No + +If we decide items are cheaper if bought in bulk, how would this change the code? Which implementation is easier to modify? + We could use a conditional to on quantity and a discount rate or bulk price. + Both implementations seems like they are of similar amounts of work to modify. + +Which implementation better adheres to the single responsibility principle? + Implementation B follows the single responsibility principle more than A. + +Bonus question once you've read Metz ch. 3: Which implementation is more loosely coupled? + Implementation B is more loosely coupled. +Once you've responded to the prompts, git add design-activity.md and git commit! diff --git a/lib/block.rb b/lib/block.rb new file mode 100644 index 000000000..7b2c99988 --- /dev/null +++ b/lib/block.rb @@ -0,0 +1,24 @@ + require_relative 'reception' + +require 'pry' +require 'date' + +# block is-a reception item +# block inherits from reception + +module Hotel + class Block < Reception + + def initialize(check_in, check_out, number_of_rooms) + @check_in = check_in + @check_out = check_out + @number_of_rooms = number_of_rooms + + availability_by_date_range(check_in, check_out) + end + + def hold_block + + end + end +end diff --git a/lib/reception.rb b/lib/reception.rb new file mode 100644 index 000000000..6754b38ec --- /dev/null +++ b/lib/reception.rb @@ -0,0 +1,61 @@ +require_relative 'reservation' +require 'pry' +require 'date' + +module Hotel + class Reception + attr_reader :reservation_list + def initialize + @reservation_list = [] + end + +# Checks for availabl rooms, assigns room to new_reservation and adds new reservation to reservations array + def add_reservation(check_in, check_out) + + assigned_room = availability_by_date_range(check_in, check_out).first + + new_reservation = Hotel::Reservation.new(check_in, check_out, assigned_room) + if check_in >= check_out + raise ArgumentError.new "invalid date range" + end + + @reservation_list << new_reservation + return new_reservation + end + +# Searches through reservatsions to generate reservations for a given day + def reservations_by_date(date) + reservations_on_date = [] + @reservation_list.each do |reservation| + if reservation.date_range.include? date + reservations_on_date << reservation + end + end + return reservations_on_date + end + +# compares each reservation to date range in question and returns an array of rooms available for the given period. + def availability_by_date_range(check_in, check_out) + occupied_rooms = [] + range = (check_in...check_out)#.to_a + @reservation_list.each do |reservation| + if (range.include? reservation.check_in) || (range.include? reservation.check_out - 1) + occupied_rooms << reservation.assigned_room + end + end + + available_rooms = [] + ROOMS.each do |room| + if !(occupied_rooms.include? room) + available_rooms << room + end + end + return available_rooms + end + +# # Creates room blocks based on availability_by_date_range +# def room_block +# +# end + end +end diff --git a/lib/reservation.rb b/lib/reservation.rb new file mode 100644 index 000000000..184ca95aa --- /dev/null +++ b/lib/reservation.rb @@ -0,0 +1,38 @@ +# require_relative 'reception' +require 'pry' +require 'date' + +module Hotel + COST = 200 + ROOMS = Array(1..20) + class Reservation + + attr_reader :check_in, :check_out, :assigned_room + + def initialize(check_in, check_out, assigned_room) + + @check_in = check_in + @check_out = check_out + @assigned_room = assigned_room + @range = date_range + @length_of_stay = @range.length + @total_cost = total_cost + end + +# Creates array of dates from given check_in and check_out dates + def date_range + @range = (@check_in...@check_out).to_a + return @range + end + + def length_of_stay + nights = (@check_out - @check_in).to_i + return nights + end + + def total_cost + total_cost = (COST * length_of_stay).to_f.round(2) + return total_cost + end + end +end diff --git a/specs/block_spec.rb b/specs/block_spec.rb new file mode 100644 index 000000000..ea1c13dc2 --- /dev/null +++ b/specs/block_spec.rb @@ -0,0 +1,19 @@ +require_relative 'spec_helper' +require 'pry' + +describe 'Bock class' do + + describe "room_block" do + it "returns an array with the requeted number of rooms" do + + end + + it "it gives a discoutnd price for reservation" do + + end + + it "it can only be reserved through the block request" do + + end + end +end diff --git a/specs/reception_spec.rb b/specs/reception_spec.rb new file mode 100644 index 000000000..9af368334 --- /dev/null +++ b/specs/reception_spec.rb @@ -0,0 +1,81 @@ + +require_relative 'spec_helper' +require 'pry' + +describe 'Reception class' do + before do + @receptionist = Hotel::Reception.new + @new_reservation = @receptionist.add_reservation(Date.new(2018,3,5), Date.new(2018,3,10)) + end + + # ***IDEAS*** validate_date check for calendar date, check for date after today, check for valid date_range + + describe "initialize" do + it 'creates a new instance of Reception' do + @receptionist.must_be_instance_of Hotel::Reception + end + end + + describe "add_reservation" do + it "returns an array of all reservations" do + @receptionist.reservation_list.must_be_kind_of Array + end + + it "assaigns an available room" do + @new_reservation.assigned_room.must_equal 1 + end + + it "raises an error when date range is invalid" do + proc {@receptionist.add_reservation(Date.new(2018,3,11), Date.new(2018,3,5))}.must_raise ArgumentError + end + end + + describe 'reservation_by_date' do + it "returns the number of reservations for given day" do + @receptionist.reservations_by_date(Date.new(2018,3,8)).length.must_equal 1 + @receptionist.reservations_by_date(Date.new(2018,3,6)).length.must_equal 1 + + 4.times do + @receptionist.add_reservation(Date.new(2018,3,5), Date.new(2018,3,10)) + end + @receptionist.reservations_by_date(Date.new(2018,3,6)).length.must_equal 5 + + 15.times do + @receptionist.add_reservation(Date.new(2018,3,5), Date.new(2018,3,10)) + end + @receptionist.reservations_by_date(Date.new(2018,3,6)).length.must_equal 20 + end + + it 'retruns an empty array when no reservations on given date' do + @receptionist.reservations_by_date(Date.new(2018,3,16)).must_equal [] + @receptionist.reservations_by_date(Date.new(2018,3,16)).must_be_empty + @receptionist.reservations_by_date(Date.new(2018,3,4)).must_be_empty + end + end + + describe "availability_by_date_range" do + it "returns an array of all available rooms for given range" do + @receptionist.availability_by_date_range(Date.new(2018,3,5), Date.new(2018,3,10)).length.must_equal 19 + + 4.times do + @receptionist.add_reservation(Date.new(2018,3,5), Date.new(2018,3,10)) + end + @receptionist.availability_by_date_range(Date.new(2018,3,5), Date.new(2018,3,10)).length.must_equal 15 + + end + + it "returns an empty array if no rooms available for a given date range" do + 20.times do + @receptionist.add_reservation(Date.new(2018,3,5), Date.new(2018,3,10)) + end + + @receptionist.availability_by_date_range(Date.new(2018,3,5), Date.new(2018,3,10)).must_equal [] + @receptionist.availability_by_date_range(Date.new(2018,3,5), Date.new(2018,3,10)).must_be_empty + end + + it "will return array of all rooms if no bookings during given range" do + @receptionist.availability_by_date_range(Date.new(2018,3,11), Date.new(2018,3,21)).length.must_equal 20 + end + end + +end diff --git a/specs/reservation_spec.rb b/specs/reservation_spec.rb new file mode 100644 index 000000000..f86b9baab --- /dev/null +++ b/specs/reservation_spec.rb @@ -0,0 +1,40 @@ +require_relative 'spec_helper' +require 'pry' + +describe 'Reservation class' do + + before do + @new_reservation = Hotel::Reservation.new(Date.new(2018,3,5), Date.new(2018,3,10), 1) + + @room = @new_reservation.assigned_room + end + + it "creates a new instance of Reservation" do + @new_reservation.must_be_instance_of Hotel::Reservation + end + + it "assigns a valid room" do + Hotel::ROOMS.must_include @room + end + + it "calculates number of nights" do + @new_reservation.length_of_stay.must_be_kind_of Integer + @new_reservation.length_of_stay.must_equal 5 + + Hotel::Reservation.new(Date.new(2018,3,2), Date.new(2018,3,10), 1).length_of_stay.must_equal 8 + + # Hotel::Reservation.new(Date.new(2018,3,2), Date.new(2018,3,2), 1).length_of_stay.must_equal 0 + end + + describe "date_range" do + it "calculates accurate date range" do + @new_reservation.date_range.must_be_kind_of Array + end + end + it "calculatesthe total cost of stay" do + @new_reservation.total_cost.must_be_kind_of Float + + @new_reservation.total_cost.must_be_within_delta 1000, 0.5 + end + +end diff --git a/specs/spec_helper.rb b/specs/spec_helper.rb new file mode 100644 index 000000000..0fb7cde1e --- /dev/null +++ b/specs/spec_helper.rb @@ -0,0 +1,15 @@ +require 'time' + +require 'simplecov' +SimpleCov.start + +require 'minitest' +require 'minitest/autorun' +require 'minitest/reporters' +# Add simplecov + +Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new + +# Require_relative your lib files here! +require_relative '../lib/reservation' +require_relative '../lib/reception'