diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 000000000..67bfd45a2 Binary files /dev/null and b/.DS_Store differ diff --git a/.gitignore b/.gitignore index 5e1422c9c..c0ac3dc53 100644 --- a/.gitignore +++ b/.gitignore @@ -48,3 +48,4 @@ build-iPhoneSimulator/ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this: .rvmrc +coverage diff --git a/lib/.DS_Store b/lib/.DS_Store new file mode 100644 index 000000000..b9445a8a8 Binary files /dev/null and b/lib/.DS_Store differ diff --git a/lib/reservation.rb b/lib/reservation.rb new file mode 100644 index 000000000..8b43f6e3d --- /dev/null +++ b/lib/reservation.rb @@ -0,0 +1,24 @@ + +module Hotel + class Reservation + attr_reader :id, :room, :start_date, :end_date, :discount, :status + + def initialize(id, room, start_date, end_date, discount = nil, status = :CONFIRMED) + @id = id + @room = room + @start_date = Date.parse(start_date) + @end_date = Date.parse(end_date) + @discount = discount + @status = status + + # Check for requirementsand raise error if not met + raise StandardError.new("The end date cannot be before the start date") if @start_date >= @end_date + end + + # Calculate total reservation cost based on nightly rate with discount if applied + def total_cost + nights_cost = ((end_date - start_date) * room.nightly_rate) + discount ? nights_cost - (nights_cost * discount) : nights_cost + end + end +end \ No newline at end of file diff --git a/lib/reservation_manager.rb b/lib/reservation_manager.rb new file mode 100644 index 000000000..be8b0c714 --- /dev/null +++ b/lib/reservation_manager.rb @@ -0,0 +1,52 @@ +module Hotel + class ReservationManager + attr_reader :all_rooms, :all_reservations + + def initialize + @all_rooms = Hotel::Room.all + @all_reservations = Array.new + end + + # Check and find available room by date + def available?(start_date, end_date, room) + room.reservations.each do |reservation| + + first_day = Date.parse(start_date) + last_day = Date.parse(end_date) + + # Check that there is no overlap in date + while first_day != last_day + return false if (reservation.start_date...reservation.end_date).include?(first_day) + first_day += 1 + end + end + return true + end + + # List available rooms that meet requirement + def available_rooms(start_date, end_date) + all_rooms.select { |room| available?(start_date, end_date, room) } + end + + # Make a new reservation or raise error if room is unavailable + def make_reservation(start_date, end_date) + id = all_reservations.length + 1 + room = available_rooms(start_date, end_date)[0] + raise StandardError if !room + + reservation = Hotel::Reservation.new(id, room, start_date, end_date) + all_reservations << reservation + room.reservations << reservation + return reservation + end + + # Look-up a reservation that meet requirement + def find_reservation(date) + all_reservations.select do |reservation| + first_day = reservation.start_date + last_day = reservation.end_date + (first_day...last_day).include? Date.parse(date) + end + end + end +end \ No newline at end of file diff --git a/lib/room.rb b/lib/room.rb new file mode 100644 index 000000000..5c0df70f0 --- /dev/null +++ b/lib/room.rb @@ -0,0 +1,25 @@ +module Hotel + class Room + ROOMS = 20 + attr_reader :id, :nightly_rate + + def initialize(id) + # (Guard clause) raise error if requirement not met + raise StandardError.new("Not a real room") if id <= 0 || id > 20 + + @id = id + @nightly_rate = 200 + end + + # Set as empty array if no instance variable was instantiated + def reservations + @reservations ||= [] + end + + def self.all + all_rooms = Array.new + ROOMS.times { |room| all_rooms << self.new(room + 1) } + return all_rooms + end + end +end \ No newline at end of file diff --git a/lib/room_block.rb b/lib/room_block.rb new file mode 100644 index 000000000..e61864d83 --- /dev/null +++ b/lib/room_block.rb @@ -0,0 +1,26 @@ +module Hotel + class RoomBlock + attr_reader :name, :start_date, :end_date, :discount, :how_many_rooms, :list_rooms + + def initialize(name, start_date, end_date, discount, how_many_rooms, list_rooms) + @name = name + @start_date = Date.parse(start_date) + @end_date = Date.parse(end_date) + @discount = discount / 100.0 + @how_many_rooms = how_many_rooms + @list_rooms = list_rooms + + # Check for requirements and raise error if not met for dates + raise StandardError.new("The end date cannot be before the start date") if @start_date >= @end_date + # Check for requirements and raise error if block of rooms does not pass + raise StandardError.new("Invalid amount of rooms for block") if how_many_rooms <= 0 || how_many_rooms > 5 + # Check that requested rooms match block + raise StandardError.new("Room amount is invalid") if list_rooms.length != how_many_rooms + end + + # Set as empty array if no instance variable was instantiated + def reservations + @reservations ||= [] + end + end +end \ No newline at end of file diff --git a/refactors.txt b/refactors.txt new file mode 100644 index 000000000..fd0311160 --- /dev/null +++ b/refactors.txt @@ -0,0 +1,23 @@ +# Current thoughts + +- review variable names +- use more S in all waves +- make more classes and method +- read/ask update error types +- let on test files +- keyword arguments vs positional +- make long rows more readable +- Code: ++ reservation_manager.rb: +- add status & discount to defaults +- make method to make a block & it's tests ++ room_block.rb +- remove list_rooms once method above is created +- update the test file for above ++ booking_manager.rb +- update for blocks +- make method to find reservations ++ booking_manager_test.rb +- clean w/let +- add tests for blocks + diff --git a/test/.DS_Store b/test/.DS_Store new file mode 100644 index 000000000..dd46da134 Binary files /dev/null and b/test/.DS_Store differ diff --git a/test/reservation_manager_test.rb b/test/reservation_manager_test.rb new file mode 100644 index 000000000..ff4086642 --- /dev/null +++ b/test/reservation_manager_test.rb @@ -0,0 +1,85 @@ +require_relative "test_helper" + +describe "ReservationManager" do + let (:manager) { Hotel::ReservationManager.new } + + describe "Initialize" do + it "Create an instance of ReservationManager" do + # Assert + expect(manager).must_be_kind_of Hotel::ReservationManager + end + + it "Respond to all_rooms" do + # Assert + expect(manager).must_respond_to :all_rooms + expect(manager.all_rooms).must_be_kind_of Array + expect(manager.all_rooms.length).must_equal 20 + end + + it "Respond to reservations" do + # Assert + expect(manager).must_respond_to :all_reservations + expect(manager.all_reservations).must_be_kind_of Array + expect(manager.all_reservations).must_equal [] + end + end + + describe "available_rooms" do + it "When no rooms have been booked return 20 available rooms" do + rooms = manager.available_rooms("March 3, 2020", "March 5, 2020") + # Assert + expect(rooms.length).must_equal 20 + end + + it "When one room has been booked return 19 available rooms" do + manager.make_reservation("March 3, 2020", "March 5, 2020") + rooms = manager.available_rooms("March 3, 2020", "March 5, 2020") + # Assert + expect(rooms.length).must_equal 19 + end + + it "Returns the available room" do + manager.available_rooms("March 3, 2020", "March 5, 2020") + rooms = manager.available_rooms("March 13, 2020", "March 15, 2020") + # Assert + expect(rooms.length).must_equal 20 + end + end + + describe "make_reservation" do + it "Creates a new reservation" do + reservation = manager.make_reservation("March 3, 2020", "March 5, 2020") + # Assert + expect(reservation).must_be_kind_of Hotel::Reservation + expect(manager.all_reservations.include?(reservation)).must_equal true + expect(reservation.room.reservations.include?(reservation)).must_equal true + end + + it "Raises an error if there are no rooms available" do + 20.times do + manager.make_reservation("March 3, 2020", "March 5, 2020") + end + # Assert + expect { manager.make_reservation("March 3, 2020", "March 5, 2020") }.must_raise StandardError + end + end + + describe "find_reservation" do + it "Finds reservations for a specific date" do + manager.make_reservation("March 1, 2020", "March 3, 2020") + manager.make_reservation("March 1, 2020", "March 8, 2020") + manager.make_reservation("March 3, 2020", "March 6, 2020") + manager.make_reservation("March 3, 2020", "March 5, 2020") + manager.make_reservation("March 15, 2020", "March 18, 2020") + date = "March 3, 2020" + specific_reservation = manager.find_reservation(date) + # Assert + expect(specific_reservation).must_be_kind_of Array + expect(specific_reservation.length).must_equal 3 + + specific_reservation.each do |reservation| + _(reservation).must_be_kind_of Hotel::Reservation + end + end + end +end \ No newline at end of file diff --git a/test/reservation_test.rb b/test/reservation_test.rb new file mode 100644 index 000000000..a1dce205f --- /dev/null +++ b/test/reservation_test.rb @@ -0,0 +1,84 @@ +require_relative "test_helper" + +describe "Reservation" do + let (:room) { Hotel::Room.new(3) } + let (:reservation) { Hotel::Reservation.new(1, room, "March 3, 2020", "March 5, 2020")} + # Arrange + describe "initialize" do + #Act + it "Create an instance of Reservation" do + # Assert + expect(reservation).must_be_kind_of Hotel::Reservation + end + #Act + it "Room id tracker" do + # Assert + expect(reservation).must_respond_to :id + expect(reservation.id).must_equal 1 + end + # Act + it "Keeps track of room" do + # Assert + expect(reservation).must_respond_to :room + expect(reservation.room).must_equal room + end + # Act + it "Keeps track of the first day" do + # Assert + expect(reservation).must_respond_to :start_date + expect(reservation.start_date).must_equal Date.parse("March 3, 2020") + end + # Act + it "Keeps track of the last day" do + # Assert + expect(reservation).must_respond_to :end_date + expect(reservation.end_date).must_equal Date.parse("March 5, 2020") + end + # Act + it "Throws error if end date is before start date" do + start_date = "March 5, 2020" + end_date = "March 3, 2020" + # Assert + expect{ Hotel::Reservation.new(1, room, start_date, end_date) }.must_raise StandardError + end + # Act + it "Discount tracker" do + reservation = Hotel::Reservation.new(1, room, "March 3, 2020", "March 5, 2020", 0.50, :CONFIRMED) + # Assert + expect(reservation).must_respond_to :discount + expect(reservation.discount).must_equal 0.50 + end + # Act + it "Set discount to a default of nil" do + # Assert + assert_nil(reservation.discount) + end + # Act + it "Status tracker" do + # Assert + expect(reservation).must_respond_to :status + end + # Act + it "Status default set to 'confirmed' " do + # Assert + expect(reservation.status).must_equal :CONFIRMED + end + end + + # Arrange + describe "total_cost" do + # Act + it "Returns total cost for reservation" do + room = Hotel::Room.new(3) + # Assert + expect(reservation.total_cost).must_equal 400 + end + # Act + it "Returns total_cost with discount if processed" do + room = Hotel::Room.new(3) + reservation = Hotel::Reservation.new(1, room, "March 3, 2020", "March 5, 2020", 0.50, :CONFIRMED) + # Assert + expect(reservation.total_cost).must_equal 200 + end + end +end \ No newline at end of file diff --git a/test/room_block_test.rb b/test/room_block_test.rb new file mode 100644 index 000000000..a86aef79b --- /dev/null +++ b/test/room_block_test.rb @@ -0,0 +1,80 @@ +require_relative "test_helper" + +describe "RoomBlock" do + let (:block_room_1) { Hotel::Room.new(1) } + let (:block_room_2) { Hotel::Room.new(2) } + let (:block_room_3) { Hotel::Room.new(3) } + let (:block_room_4) { Hotel::Room.new(4) } + let (:block_room_5) { Hotel::Room.new(5) } + let (:block) { Hotel::RoomBlock.new("Anaya", "March 3, 2020", "March 5, 2020", 50, 3,[block_room_1, block_room_2, block_room_3]) } + # Arrange + describe "initialize" do + # Act + it "Create instance of RoomBlock" do + # Assert + expect(block).must_be_kind_of Hotel::RoomBlock + end + # Act + it "Name tracker" do + # Assert + expect(block).must_respond_to :name + expect(block.name).must_equal "Anaya" + end + # Act + it "start_date tracker" do + # Assert + expect(block).must_respond_to :start_date + expect(block.start_date).must_equal Date.parse("March 3, 2020") + end + # Act + it "end_date tracker" do + # Assert + expect(block).must_respond_to :end_date + expect(block.end_date).must_equal Date.parse("March 5, 2020") + end + # Act + it "discount tracker" do + # Assert + expect(block).must_respond_to :discount + expect(block.discount).must_equal 0.50 + end + # Act + it "how_many_rooms' tracker" do + # Assert + expect(block).must_respond_to :how_many_rooms + expect(block.how_many_rooms).must_equal 3 + end + # Act + it "1 - 5 rooms allowed per block" do + block_a = Hotel::RoomBlock.new("Anaya", "March 3, 2020", "March 5, 2020", 50, 1, [block_room_1]) + block_b = Hotel::RoomBlock.new("Anaya", "March 3, 2020", "March 5, 2020", 50, 5, [block_room_1, block_room_2, block_room_3, block_room_4, block_room_5]) + # Assert + expect(block_a.how_many_rooms).must_equal 1 + expect(block_b.how_many_rooms).must_equal 5 + end + # Act + it "Raise error for blocks of rooms that don't meet requirements" do + # Assert + expect { Hotel::RoomBlock.new("Anaya", "March 3, 2020", "March 5, 2020", 50, 0, [block_room_1]) }.must_raise StandardError + expect { Hotel::RoomBlock.new("Anaya", "March 3, 2020", "March 5, 2020", 50, 6, [block_room_1]) }.must_raise StandardError + end + # Act + it "list_rooms' tracker" do + # Assert + expect(block).must_respond_to :list_rooms + expect(block.list_rooms).must_be_kind_of Array + expect(block.list_rooms.include?(block_room_1)).must_equal true + expect(block.list_rooms.include?(block_room_2)).must_equal true + expect(block.list_rooms.include?(block_room_3)).must_equal true + end + # Act + it "reservations' tracker" do + # Assert + expect(block).must_respond_to :reservations + expect(block.reservations).must_be_kind_of Array + block.reservations.each do |reservation| + expect(reservation).must_be_kind_of Hotel::Reservation + end + end + end +end \ No newline at end of file diff --git a/test/room_test.rb b/test/room_test.rb new file mode 100644 index 000000000..f9d2becf7 --- /dev/null +++ b/test/room_test.rb @@ -0,0 +1,57 @@ +require_relative "test_helper" + +describe "Room" do + let (:room) { Hotel::Room.new(1) } + describe "Initialize" do + it "Create instance of Room" do + # Assert + expect(room).must_be_kind_of Hotel::Room + end + + it "Room id tracker" do + # Assert + expect(room).must_respond_to :id + expect(room.id).must_equal 1 + end + + it "Rooms numbers 1 - 20 only" do + # Assert + expect(room.id).must_equal 1 + expect(Hotel::Room.new(20).id).must_equal 20 + end + + it "Raises an StandardError if id is outside of 1 - 20" do + # Assert + expect{Hotel::Room.new(0)}.must_raise StandardError + expect{Hotel::Room.new(21)}.must_raise StandardError + end + + it "Same nightly cost for all" do + # Assert + expect(room.nightly_rate).must_equal 200 + end + + it "Reservations is an empty array" do + # Assert + expect(room.reservations).must_be_kind_of Array + expect(room.reservations).must_equal [] + end + end + + describe "self.all" do + it "Returns an array of 20 room objects" do + all_rooms = Hotel::Room.all + # Assert + expect(all_rooms).must_be_kind_of Array + expect(all_rooms.length).must_equal 20 + + all_rooms.each do |room| + # Assert + expect(room).must_be_kind_of Hotel::Room + end + # Assert + expect(all_rooms.first.id).must_equal 1 + expect(all_rooms.last.id).must_equal 20 + end + end +end \ No newline at end of file diff --git a/test/stay_range_test.rb b/test/stay_range_test.rb new file mode 100644 index 000000000..b1dd74c56 --- /dev/null +++ b/test/stay_range_test.rb @@ -0,0 +1,25 @@ +# require_relative "test_helper" + +# describe "StayRange" do +# describe "Initialize" do +# it "Create an instance of StayRange" do +# range = Hotel::StayRange.new("March 3, 2020", "March 5, 2020") +# # Assert +# expect(range).must_be_kind_of Hotel::StayRange +# end + +# it "Keeps track of the first day" do +# range = Hotel::StayRange.new("March 3, 2020", "March 5, 2020") +# # Assert +# expect(range).must_respond_to :start_date +# expect(range.start_date).must_equal Date.parse("March 3, 2020") +# end + +# it "Keeps track of the last day" do +# range = Hotel::StayRange.new("March 3, 2020", "March 5, 2020") +# # Assert +# expect(range).must_respond_to :end_date +# expect(range.end_date).must_equal Date.parse("March 5, 2020") +# end +# end +# end \ No newline at end of file diff --git a/test/test_helper.rb b/test/test_helper.rb index c3a7695cf..388a21390 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -1,8 +1,16 @@ -# Add simplecov +require "simplecov" +SimpleCov.start do + add_filter "test/" +end + require "minitest" require "minitest/autorun" require "minitest/reporters" +require "date" Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new -# require_relative your lib files here! +require_relative "../lib/room" +require_relative "../lib/reservation" +require_relative "../lib/reservation_manager" +require_relative "../lib/room_block"