diff --git a/Ada-C8_hotel.pdf b/Ada-C8_hotel.pdf new file mode 100644 index 000000000..c8d98b76b Binary files /dev/null and b/Ada-C8_hotel.pdf 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..bb332ad61 --- /dev/null +++ b/design-activity.md @@ -0,0 +1,49 @@ + + +What classes does each implementation include? Are the lists the same? + Both implementations use these classes: CartEntry, ShoppingCart, Order. + +Write down a sentence to describe each class. + Implementation A: + CartEntry - stores the unit price and quantity for an item + ShoppingCart - stores an array of CartEntry objects + Order - creates a new ShoppingCart object and calculates the total cost, including tax, of the items in the ShoppingCart. + +Implementation B: + CartEntry - stores the unit price and quantity for an item (same as A) + ShoppingCart - stores an array of CartEntry objects and calculates the total cost of the items, independent of sales tax. + Order - creates a new ShoppingCart object and calculates the total cost of the items in the Shopping Cart by calling the ShoppingCart.price method and applying a 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. + See attached photo called "shopping_cart_diagram.JPG" (photo of doodle diagram). + +What data does each class store? How (if at all) does this differ between the two implementations? + CartEntry- stores unit_price and quantity data for each CartEntry object. + ShoppingCart- stores array of entries objects. + Order- stores cart object but no data. + +What methods does each class have? How (if at all) does this differ between the two implementations? + Implementation A includes initialize methods for all three classes; only the Order class has an additional method, which calculates the total price of an order. Implementation B differs in that all classes have an additional method that calculates 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? + In Implementation A, the logic to compute price is retained by the Order class. In Implementation B, it is delegated to the ShoppingCart class and the Order class. + + Does total_price directly manipulate the instance variables of other classes? + In Implementation A, total_pice manipulates instance variables of other classes, but Implementation B does not. + + If we decide items are cheaper if bought in bulk, how would this change the code? Which implementation is easier to modify? + Implementation B would be easier to modify because the user can do a cost comparison of the price of the item at the item level, since there is a price method in the CartEntry class. If bulk ordering is being considered, it might help to add another class that stores the bulk ordering requirements for a specific item. For example, there may be different prices for an item that is ordered in quantities of 1-25 vs. 26-100. + + Which implementation better adheres to the single responsibility principle? + Implementation B. + +Bonus question once you've read Metz ch. 3: Which implementation is more loosely coupled? + Implementation B. + + +Notes on Changes I've made to Hotel: +-created new names that make more sense if the future data structure changes: i.e. "array_of_rooms" was changed to "rooms", and "array_of_reservations" was changed to "reservations." etc. +-changed MyHotel class to be called simply Hotel +-in Block class, removed :check-in-date and :check-out attr_readers as they were not being used/referenced +-moved "find_reservations_by_date" method from Hotel class to Reservations class. Per Chris' suggestion, changed method to first calculate the date outside of the loop that generates the available rooms. changed corresponding tests. diff --git a/lib/block.rb b/lib/block.rb new file mode 100644 index 000000000..82f70af3f --- /dev/null +++ b/lib/block.rb @@ -0,0 +1,21 @@ +#block.rb + +require 'awesome_print' +require 'date' +require 'pry' + +module Hotel_Chain + class Block + + attr_reader :party_name, :room_rate, :reservations + + def initialize(party_name, check_in_date, check_out_date, room_rate, reservations) + @party_name = party_name + @check_in_date = Date.strptime(check_in_date, "%m/%d/%Y") + @check_out_date = Date.strptime(check_out_date, "%m/%d/%Y") + @room_rate = room_rate + @reservations = reservations #array of reservation objects + end + + end #end of class +end #end of module diff --git a/lib/custom_exceptions.rb b/lib/custom_exceptions.rb new file mode 100644 index 000000000..dbcf21341 --- /dev/null +++ b/lib/custom_exceptions.rb @@ -0,0 +1,31 @@ +#custom_exceptions.rb + +class WrongDateFormatError < ArgumentError + def initialize + super ("You've entered the date in the wrong format. Please use MM/DD/YY") + end +end + +class ReservationNotAvailableError < ArgumentError + def initialize + super ("A reservation is not available for the date range you have entered.") + end +end + +class NoPartyByThatNameError < ArgumentError + def initialize + super ("There is no block of rooms reserved under that name. Please make sure you have the exact party name.") + end +end + +class AllBlockRoomsAssignedError < ArgumentError + def initialize + super ("All the reservations made for that block of room have been assigned. You may check to see if there is a room available at the standard rate.") + end +end + +class ExceededRoomLimitForBlocksError < ArgumentError + def initialize + super ("There is a 5-room maximum limit for block reservations.") + end +end diff --git a/lib/hotel.rb b/lib/hotel.rb new file mode 100644 index 000000000..42c6a3dab --- /dev/null +++ b/lib/hotel.rb @@ -0,0 +1,181 @@ +#Hotel.rb +require 'awesome_print' +require 'date' +require 'pry' + +module Hotel_Chain + class Hotel + + attr_reader :rooms, :reservations, :blocks + + def initialize(no_of_rooms = 20) + @rooms = Array.new(no_of_rooms) + no_of_rooms.times do |room| + @rooms[room] = Room.new(room+1) + @reservations = [] + @blocks = [] #an array of block objects + end + end + + def list_rooms + list_array = [] + i = 0 + @rooms.each do |object| + list_array << "#{i+1}. Room #{object.room_id} - $#{object.rate}/night" + i += 1 + end + return list_array + end + + def find_reservations_by_date(date) + reservations_on_date = [] + @reservations.each do |reservation| + if (reservation.check_in_date...reservation.check_out_date).cover?(Date.strptime(date, "%m/%d/%Y")) + reservations_on_date << reservation + end + end + return reservations_on_date + end + + def print_reservations_by_date(date) + array = [] + reservations_on_date = self.find_reservations_by_date(date) + reservations_on_date.each do |reservation| + array << "Room #{reservation.room.room_id} is reserved from #{reservation.check_in_date} to #{reservation.check_out_date}" + end + return array + end + + def store_reservation(check_in_date, check_out_date) + available_rooms = [] + #ap "STORE_RESERVATION START: reservations: #{reservations}" + if @reservations.length == 0 #i.e. there are no reservations at all + new_reservation = Hotel_Chain::Reservation.new(check_in_date, check_out_date) + new_reservation.room = @rooms[0] + @reservations << new_reservation + return new_reservation + elsif @reservations.length > 0 + available_rooms = find_rooms_available(check_in_date, check_out_date) + if available_rooms.length == 0 + raise ReservationNotAvailableError + else + new_reservation = Hotel_Chain::Reservation.new(check_in_date, check_out_date) + new_reservation.room = available_rooms[0] + @reservations << new_reservation + return new_reservation + end + end + end + + def find_rooms_available(check_in_date, check_out_date) + unavailable_rooms = [] + + check_in = Date.strptime(check_in_date, "%m/%d/%Y") + check_out = Date.strptime(check_out_date, "%m/%d/%Y") + + @rooms.each do |room| + @reservations.each do |reservation| + # checks for unavailable rooms + if room.room_id == reservation.room.room_id && reservation.block_reserved == true + unavailable_rooms << room + elsif room.room_id == reservation.room.room_id && reservation.check_in_date < check_in && (reservation.check_out_date < check_out && reservation.check_out_date > check_in) + unavailable_rooms << room + elsif room.room_id == reservation.room.room_id && (reservation.check_in_date < check_out && reservation.check_in_date > check_in) && reservation.check_out_date > check_out + unavailable_rooms << room + elsif room.room_id == reservation.room.room_id && (reservation.check_in_date > check_in && reservation.check_in_date < check_out) && (reservation.check_out_date < check_out && reservation.check_out_date > check_in) + unavailable_rooms << room + elsif room.room_id == reservation.room.room_id && reservation.check_in_date < check_in && reservation.check_out_date > check_out + unavailable_rooms << room + elsif room.room_id == reservation.room.room_id && reservation.check_in_date == check_in + unavailable_rooms << room + elsif room.room_id == reservation.room.room_id && (reservation.check_in_date > check_in && reservation.check_in_date < check_out) && reservation.check_out_date == check_out + unavailable_rooms << room + end + end + end + final_available_rooms = @rooms - unavailable_rooms + return final_available_rooms + end + + + def reserve_block(party_name, check_in, check_out, no_of_rooms, room_rate) + if no_of_rooms > 5 + raise ExceededRoomLimitForBlocksError + end + + local_reservation_array = [] + available_rooms = find_rooms_available(check_in, check_out) + + if available_rooms.length < no_of_rooms + raise ArgumentError.new("There are not enough rooms available to reserve that block") + else + no_of_rooms.times do |room| + new_reservation = store_reservation(check_in, check_out) + new_reservation.room.rate = room_rate + new_reservation.block_reserved = true + new_reservation.status = "unassigned" + @reservations << new_reservation + local_reservation_array << new_reservation + end + end + + #I want the block object to have these attributes for ease of reference. + new_block = Block.new(party_name, check_in, check_out, room_rate, local_reservation_array) + @blocks << new_block + return new_block + end + + def find_unassigned_block_reservations(party_name) + #if the block has the party name, then return that block + this_block = nil + @blocks.each do |block| + if block.party_name == party_name + this_block = block + end + end + + if this_block == nil + raise NoPartyByThatNameError + end + + unassigned_reservations = [] + this_block.reservations.each do |reservation| + if reservation.status == "unassigned" + unassigned_reservations << reservation + end + end + + if unassigned_reservations.empty? + raise AllBlockRoomsAssignedError + end + + return unassigned_reservations + end + + def assign_block_reservation(party_name) + unassigned_reservations = find_unassigned_block_reservations(party_name) + unassigned_reservations[0].status = "assigned" + return unassigned_reservations[0] + end + + #this can be used to find if there is a block reservation party name in the system + def match_block_partyname(party_name) + reserved_under = [] + @blocks.each do |block| + if (block.party_name.downcase).match(party_name.downcase) + reserved_under << block.party_name + ap block.party_name + end + end + return reserved_under + end + + #Allow a user to set different rates for different rooms + def create_custom_rate(check_in_date, check_out_date, rate) + new_reservation = store_reservation(check_in_date, check_out_date) + new_reservation.room.rate = rate + return new_reservation + end + + end #end of class +end #end of module diff --git a/lib/reservation.rb b/lib/reservation.rb new file mode 100644 index 000000000..0f75dba33 --- /dev/null +++ b/lib/reservation.rb @@ -0,0 +1,31 @@ +#reservation.rb + +require 'awesome_print' +require 'date' + +module Hotel_Chain + class Reservation + + attr_accessor :check_in_date, :check_out_date, :room, :HOTEL, :cost, :status, :block_reserved + + HOTEL = Hotel_Chain::Hotel.new + + #A new reservation object can be initialized by providing the check_in_date and check_out_date + #Initialization converts the admin's date inputs to convert to Ruby Date objects, and stores them in instance variables. + #After a reservation is created, this program randomly assigns a room object (without checking to see if it's available). + #I may also like to have the program assign a reservation_id (this info can live in a spreadsheet)- then I will need a method to look up a reservation by reservation_id + #reservation_ID would be set as default value of 0 here and then set in the store_reservation method based on existing reservations. + def initialize(check_in_date, check_out_date, status = "assigned") + begin + @check_in_date = Date.strptime(check_in_date, "%m/%d/%Y") + @check_out_date = Date.strptime(check_out_date, "%m/%d/%Y") + @room = HOTEL.rooms.sample + @status = "assigned" #all reservations default to "assigned", unless they are reservations made in a block + @block_reserved = false #defaults to false. the reserve_block method changes this to true. + rescue ArgumentError + raise WrongDateFormatError + end + end + + end +end diff --git a/lib/room.rb b/lib/room.rb new file mode 100644 index 000000000..7dad98421 --- /dev/null +++ b/lib/room.rb @@ -0,0 +1,16 @@ +#Room.rb +require 'awesome_print' + +module Hotel_Chain + class Room + + attr_reader :room_id + attr_accessor :rate + + def initialize(room_id, rate = 200) + @room_id = room_id + @rate = rate + end + + end +end diff --git a/shopping_cart_diagram.JPG b/shopping_cart_diagram.JPG new file mode 100644 index 000000000..343fc0c79 Binary files /dev/null and b/shopping_cart_diagram.JPG differ diff --git a/specs/block_spec.rb b/specs/block_spec.rb new file mode 100644 index 000000000..ecfd73ebd --- /dev/null +++ b/specs/block_spec.rb @@ -0,0 +1,21 @@ +#block_spec.rb + +require_relative 'spec_helper.rb' +require 'date' +require 'pry' + +describe "The Block class" do + + before do + @hotel = Hotel_Chain::Hotel.new + end + + describe "Initializing the Block" do + + it "can be initialized" do + block_A = Hotel_Chain::Block.new("Mary Smith", "9/25/17", "9/29/17", 150, []) + block_A.class.must_be_kind_of Class + end + + end #end describe +end #final end diff --git a/specs/hotel_spec.rb b/specs/hotel_spec.rb new file mode 100644 index 000000000..08c90aaab --- /dev/null +++ b/specs/hotel_spec.rb @@ -0,0 +1,320 @@ +#hotel_spec.rb +require_relative 'spec_helper.rb' +require 'date' +require 'pry' +describe "The Hotel class" do + + before do + @hotel = Hotel_Chain::Hotel.new + end + + describe "Initializing the Hotel" do + + it "can be initialized" do + @hotel.class.must_be_kind_of Class + end + + it "The hotel can be initialized with a set number of room objects" do + @hotel.rooms.length.must_equal 20 + end + + it "Returns an array" do + @hotel.rooms.must_be_kind_of Array + end + + it "Hotel object contains an array of room objects" do + @hotel.rooms[0].must_be_instance_of Hotel_Chain::Room + end + + end # end describe + + describe "list_of_rooms method" do + + it "Prints a statement to the user" do + proc {@hotel.list_rooms}.wont_be_nil + end + + it "Returns an array with length 20" do + @hotel.list_rooms.length.must_equal 20 + + end + + it "gives expected statement at 0 position" do + @hotel.list_rooms[0].must_equal "1. Room 1 - $200/night" + end + end #end describe list of rooms method + + describe "it stores reservation objects" do + + it "it stores a reservation and returns the array length" do + #every time a new reservation is created in the reservation class, it calls the store_reservation method and stores that reservation object" + @hotel.store_reservation("8/13/17", "8/16/17") + @hotel.store_reservation("9/25/17", "9/29/17") + @hotel.reservations.length.must_equal 2 + end + + end + + + describe "find_reservations_by_date method" do + #you can input a specific date + #it returns any reservations which occur on a specific date + #it iterates through all reservation object + + it "returns an array" do + @hotel.store_reservation("8/13/17", "8/16/17") + @hotel.store_reservation("9/25/17", "9/29/17") + @hotel.find_reservations_by_date("8/14/17").must_be_kind_of Array + end + + it "it can list all reservations by date - range middle date" do + @hotel.store_reservation("8/13/17", "8/16/17") + @hotel.store_reservation("9/25/17", "9/29/17") + @hotel.find_reservations_by_date("8/14/17").length.must_equal 1 + end + + it "it can list all reservations by date - range start date" do + @hotel.store_reservation("8/13/17", "8/16/17") + @hotel.store_reservation("9/25/17", "9/29/17") + @hotel.find_reservations_by_date("9/25/17").length.must_equal 1 + end + + it "it returns an empty array for searches on the reservation's end date" do + @hotel.store_reservation("8/13/17", "8/16/17") + @hotel.store_reservation("9/25/17", "9/29/17") + @hotel.find_reservations_by_date("8/16/17").length.must_equal 0 + end + + it "it returns an empty array for searches outside the range of any reservations" do + @hotel.store_reservation("8/13/17", "8/16/17") + @hotel.find_reservations_by_date("8/12/17").length.must_equal 0 + end + + end + + describe "print_reservations_by_date method" do + + it "prints a formatted list of reservations for a particular date" do + @hotel.store_reservation("8/13/17", "8/16/17") + @hotel.store_reservation("9/25/17", "9/29/17") + @hotel.store_reservation("8/15/17", "8/30/17") + @hotel.find_reservations_by_date("8/15/17").length.must_equal 2 + @hotel.print_reservations_by_date("8/15/17").length.must_equal 2 + end + + end + + describe "find_rooms_available method" do + + it "takes in a start date and end date and returns an array of rooms available" do + @hotel.store_reservation("8/13/17", "8/16/17") + @hotel.store_reservation("9/25/17", "9/29/17") + @hotel.store_reservation("8/15/17", "8/30/17") + @hotel.store_reservation("8/10/17", "8/13/17") + @hotel.store_reservation("8/09/17", "8/14/17") + @hotel.find_rooms_available("8/11/17", "8/12/17").must_be_kind_of Array + end + + it "returns an array of room objects" do + @hotel.store_reservation("8/13/17", "8/16/17") + @hotel.find_rooms_available("8/11/17", "8/12/17")[0].must_be_instance_of Hotel_Chain::Room + end + + it "returns an array of 20 objects when searching for a date range that does not overlap with existing reservations" do + @hotel.store_reservation("8/13/17", "8/16/17") + @hotel.store_reservation("9/25/17", "9/29/17") + @hotel.store_reservation("8/15/17", "8/30/17") + @hotel.find_rooms_available("8/11/17", "8/12/17").length.must_equal 20 + end + + it "returns an array of 20 objects when searching for a date range that overlaps with the last day of an existing reservations" do + @hotel.store_reservation("8/9/17", "8/11/17") + @hotel.find_rooms_available("8/11/17", "8/12/17").length.must_equal 20 + end + + it "returns an array of 20 objects when searching for a date range that overlaps with the first day of an existing reservations" do + @hotel.store_reservation("8/9/17", "8/11/17") + @hotel.find_rooms_available("8/5/17", "8/9/17").length.must_equal 20 + end + + it "returns an array of 19 objects when searching for a date range that overlaps with 1 existing reservations" do + @hotel.store_reservation("8/9/17", "8/11/17") + @hotel.find_rooms_available("8/8/17", "8/10/17").length.must_equal 19 + end + + it "returns an array of 18 objects when searching for a date range that overlaps with 2 existing reservations" do + @hotel.store_reservation("8/9/17", "8/11/17") + @hotel.store_reservation("8/10/17", "8/14/17") + @hotel.find_rooms_available("8/8/17", "8/15/17").length.must_equal 18 + end + + it "returns an array of 15 objects when searching for a date range that overlaps with 5 overlapping existing reservations" do + @hotel.store_reservation("8/13/17", "8/15/17") + @hotel.store_reservation("8/13/17", "8/15/17") + @hotel.store_reservation("8/13/17", "8/15/17") + @hotel.store_reservation("8/13/17", "8/14/17") + @hotel.store_reservation("8/13/17", "8/16/17") + @hotel.find_rooms_available("8/13/17", "8/15/17").length.must_equal 15 + end + + end #end of describe "find_rooms_available method" + + describe "make a reservation for date range for an available room" do + + it "adds a reservation to the @reservations" do + @hotel.store_reservation("8/9/17", "8/11/17") + @hotel.reservations.length.must_equal 1 + @hotel.store_reservation("8/13/17", "8/14/17") + @hotel.reservations.length.must_equal 2 + end + + it "it books room 1 if the only reservation ends on the requested reservation start date" do + @hotel.store_reservation("8/13/17", "8/15/17") + @hotel.store_reservation("8/15/17", "8/15/17") + @hotel.reservations[1].room.room_id.must_equal 1 + end + + it "adds reservations for different available rooms for overlapping reservation dates" do + @hotel.store_reservation("8/13/17", "8/15/17") + @hotel.store_reservation("8/13/17", "8/15/17") + @hotel.reservations[1].room.room_id + @hotel.reservations[1].room.room_id.must_equal 2 + @hotel.store_reservation("8/13/17", "8/15/17") + @hotel.reservations[2].room.room_id.must_equal 3 + @hotel.store_reservation("8/13/17", "8/14/17") + @hotel.reservations[3].room.room_id.must_equal 4 + @hotel.store_reservation("8/13/17", "8/17/17") + @hotel.reservations[4].room.room_id.must_equal 5 + end + + end # end of describe + + describe "Error handling for trying to reserve an unavailable room" do + + it "gives an error if the room is not available" do + 20.times do + @hotel.store_reservation("8/13/17", "8/15/17") + end + proc {@hotel.store_reservation("8/13/17", "8/15/17")}.must_raise ReservationNotAvailableError + + end + + end #end of describe + + describe "Reserve_block method" do + it "Returns an instance of the Block class" do + newblock= @hotel.reserve_block("Mary Smith", "9/25/17", "9/29/17", 4, 150) + newblock.must_be_instance_of Hotel_Chain::Block + + end + + it "returns a block with a reservations array with the correct number of reservations" do + block = @hotel.reserve_block("Mary Smith", "9/25/17", "9/29/17", 4, 150) + block.reservations.length.must_equal 4 + end + + it "returns the correct cost for the reservation made inside a block" do + block = @hotel.reserve_block("Mary Smith", "9/25/17", "9/29/17", 4, 150) + block.reservations + end + + it "blocks" do + newblock= @hotel.reserve_block("Mary Smith", "9/25/17", "9/29/17", 4, 150) + @hotel.blocks.must_be_kind_of Array + @hotel.blocks[0].must_equal newblock + end + + it "only allows a maximum of 5 rooms to be reserved in a block" do + proc {@hotel.reserve_block("Harvey Hello", "11/2/17", "11/4/17", 6, 150)}.must_raise ExceededRoomLimitForBlocksError + end + + end #end describe + + describe "find_unassigned_block_reservations method" do + + before do + @hotel.reserve_block("John Smith", "10/25/17", "10/29/17", 5, 175) + @hotel.reserve_block("Harriet McDuck", "11/12/17", "11/14/17", 3, 150) + end + + it "returns an array" do + @hotel.find_unassigned_block_reservations("John Smith").must_be_kind_of Array + end + + it "returns an array of reservation objects" do + @hotel.find_unassigned_block_reservations("John Smith")[0].must_be_instance_of Hotel_Chain::Reservation + end + + it "returns an array of reservation objects which have a status of unassigned" do + 5.times do |x| + @hotel.find_unassigned_block_reservations("John Smith")[x].status.must_equal "unassigned" + end + end + + it "returns an error if there are no block reservations found by a given party name" do + proc {@hotel.find_unassigned_block_reservations("Nancy Smith")}.must_raise NoPartyByThatNameError + end + + end #end describe + + describe "assign a room within a block of rooms - assign_block_reservation method" do + + it "returns a reservation object" do + @hotel.reserve_block("John Smith", "10/25/17", "10/29/17", 5, 175) + @hotel.assign_block_reservation("John Smith").must_be_instance_of Hotel_Chain::Reservation + end + + it "returns a reservation object with the status changed to assigned" do + @hotel.reserve_block("Mary Smith", "9/25/17", "9/29/17", 4, 150) + @hotel.find_unassigned_block_reservations("Mary Smith")[0].status.must_equal "unassigned" + @hotel.assign_block_reservation("Mary Smith") + marysmith = @hotel.blocks[0] + marysmith.reservations[0].status.must_equal "assigned" + x = 1 + 3.times do + marysmith.reservations[x].status.must_equal "unassigned" + end + end + + it "if 3 of 4 reservations in a block are assigned, the find_unassigned_block_reservations method returns only 1 reservation" do + @hotel.reserve_block("Mary Smith", "9/25/17", "9/29/17", 4, 150) + 3.times do + @hotel.assign_block_reservation("Mary Smith") + end + @hotel.find_unassigned_block_reservations("Mary Smith").length.must_equal 1 + end + + + it "returns an error if there are no unassigned rooms for a given block" do + @hotel.reserve_block("John Smith", "10/25/17", "10/29/17", 4, 175) + 4.times do + @hotel.assign_block_reservation("John Smith") + end + proc {@hotel.find_unassigned_block_reservations("John Smith")}.must_raise AllBlockRoomsAssignedError + end + + end #end describe + + describe "match_block_partyname method" do + + it "prints and returns an array the names of all blocks party names that may be a match" do + @hotel.reserve_block("John Smith", "10/25/17", "10/29/17", 4, 175) + @hotel.reserve_block("Mary Smith", "9/25/17", "9/29/17", 4, 150) + @hotel.reserve_block("Smithy Dickens", "11/12/17", "11/14/17", 3, 150) + @hotel.reserve_block("Harriet McDuck", "11/12/17", "11/14/17", 3, 150) + @hotel.reserve_block("McDuck and McMary Wedding", "12/5/17", "12/7/17", 5, 150) + @hotel.match_block_partyname("McDuck").length.must_equal 2 + @hotel.match_block_partyname("Smith").length.must_equal 3 + @hotel.match_block_partyname("smith").length.must_equal 3 + @hotel.match_block_partyname("wedding").length.must_equal 1 + end + end + + describe "Allow a user to set different rates for different rooms" do + it "makes a reservation and sets a custom date" do + new_reservation = @hotel.create_custom_rate("11/12/17", "11/14/17", 160) + new_reservation.room.rate.must_equal 160 + end + end + +end #end of testing diff --git a/specs/reservation_spec.rb b/specs/reservation_spec.rb new file mode 100644 index 000000000..b2a2678d0 --- /dev/null +++ b/specs/reservation_spec.rb @@ -0,0 +1,51 @@ +#reservation_spec.rb +require 'date' +require_relative 'spec_helper.rb' + +describe "Reservation Class" do + + describe "Initializing the Reservation Class" do + + before do + check_in_date = "8/13/17" + check_out_date = "8/16/17" + @reservation = Hotel_Chain::Reservation.new(check_in_date, check_out_date) + end + + it "can be initialized" do + @reservation.class.must_be_kind_of Class + end + + it "creates a room object and assigns it to the reservation" do + @reservation.room.room_id.must_be_kind_of Integer + end + + it "a reservation has a check-in date" do + @reservation.check_in_date.must_be_kind_of Date + + end + + it "can return a check-in date" do + @reservation.check_in_date.must_equal Date.strptime("8/13/17", "%m/%d/%Y") + #@reservation.check_in_date.to_date.must_equal 0017-08-13 + end + + #removed this test because it doesn't work for reservations made from a block (ie discounted) + #I added tests to check the cost value in the hotel and block specs instead. + # it "returns the correct cost for the reservation" do + # @reservation.cost.must_equal 600 + # end + + end + + describe "error handling" do + it "raises an error if an incorrect date format is inputted" do + check_in_date = "2017/08/13" + check_out_date = "8/16/17" + proc {Hotel_Chain::Reservation.new(check_in_date, check_out_date)}.must_raise WrongDateFormatError + + end + end + + +end diff --git a/specs/room_spec.rb b/specs/room_spec.rb new file mode 100644 index 000000000..16370a5b0 --- /dev/null +++ b/specs/room_spec.rb @@ -0,0 +1,18 @@ +#room_spec.rb +require_relative 'spec_helper.rb' +describe "The Room class" do + + describe "Initializing the room roster" do + + it "can be initialized" do + @room_roster = Hotel_Chain::Room.new(5) + @room_roster.class.must_be_kind_of Class + @room_roster.room_id.must_equal 5 + @room_roster.room_id.must_be_kind_of Integer + @room_roster.rate.must_equal 200 + @room_roster.rate.must_be_kind_of Integer + end + + end + +end diff --git a/specs/spec_helper.rb b/specs/spec_helper.rb new file mode 100644 index 000000000..b20c29644 --- /dev/null +++ b/specs/spec_helper.rb @@ -0,0 +1,15 @@ +require 'simplecov' +SimpleCov.start + +require 'minitest/autorun' +require 'minitest/reporters' +require 'minitest/skip_dsl' +require 'minitest/pride' +require 'pry' +require_relative '../lib/room' +require_relative '../lib/hotel' +require_relative '../lib/reservation' +require_relative '../lib/block' +require_relative '../lib/custom_exceptions' + +Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new