diff --git a/lib/date_range.rb b/lib/date_range.rb index da2197f22..98921eaf7 100644 --- a/lib/date_range.rb +++ b/lib/date_range.rb @@ -1,20 +1,38 @@ module Hotel class DateRange + attr_accessor :start_date, :end_date def initialize(start_date, end_date) + @start_date = start_date + @end_date = end_date + if @end_date <= @start_date + raise DateError "Invalid date. Your start date cannot be after your end date." + end end - - def overlap?(other) - return false + + # checks if a reservation overlaps with another + def overlap?(date_range) + if (end_date < date_range.start_date || start_date > date_range.end_date) + return false + else + return true + end end - def include?(date) - return false + # checks if date is included in a reservation + def include?(date) + if date >= start_date && date <= end_date + return true + else + return false + end end - + + # find the total of nights stayed def nights - return 3 + length_of_stay = (@end_date - @start_date).to_i + return length_of_stay end end end diff --git a/lib/hotel_controller.rb b/lib/hotel_controller.rb index accca6de4..c6e495199 100644 --- a/lib/hotel_controller.rb +++ b/lib/hotel_controller.rb @@ -1,24 +1,44 @@ module Hotel - class HotelController - # Wave 1 - def rooms - # You might want to replace this method with an attr_reader - return [] - end + class HotelController - def reserve_room(start_date, end_date) - # start_date and end_date should be instances of class Date - return Reservation.new(start_date, end_date, nil) - end + attr_accessor :hotel_rooms, :reservations + attr_reader - def reservations(date) - return [] + def initialize() + @hotel_rooms = (1..20).to_a + @reservations = [] end - # Wave 2 - def available_rooms(start_date, end_date) - # start_date and end_date should be instances of class Date - return [] + # Wave 1 + # creates a reservation of a room for a given date range + def reserve_room(start_date, end_date, room_number, rate) + if !available_rooms(start_date, end_date).include?(room_number) + raise ArgumentError.new "Sorry, there is no room available on those days." + else + reservation = Hotel::Reservation.new(start_date, end_date, room_number, rate) + @reservations << reservation + return reservation + end + end + + # takes a date and returns an array of reservations + def reservations_by_date(date = Date.today) + @reservations.select do |reservation| + date_range = DateRange.new(reservation.start_date, reservation.end_date) + date_range.include?(date) + end + end + + # Wave 2 + # locate available rooms by two dates and returns an array + def available_rooms(start_date, end_date) + reserved_rooms = @reservations.select do |reservation| + date_range = DateRange.new(start_date, end_date) + date_range.overlap?(reservation.date_range) + end.map do |reservation| + reservation.room_number + end + return @hotel_rooms - reserved_rooms end end end diff --git a/lib/refactors.txt b/lib/refactors.txt new file mode 100644 index 000000000..d638ba038 --- /dev/null +++ b/lib/refactors.txt @@ -0,0 +1,7 @@ +Despite HotelController doing a bulk of the work, I would try to see how I can condense this to two classes +Raise more exceptions to account for user input error +I would consider trying to make more helper methods +Save the reservations and it's room number in a array of hashes +Get better at writing tests +Understand how to get the program to pass 95% test coverage +Move onto Wave 3 \ No newline at end of file diff --git a/lib/reservation.rb b/lib/reservation.rb index 7587837e7..102755210 100644 --- a/lib/reservation.rb +++ b/lib/reservation.rb @@ -1,11 +1,20 @@ module Hotel class Reservation - # Feel free to change this method signature as needed. Make sure to update the tests! - def initialize(start_date, end_date, room) + + attr_reader :room_number, :rate, :date_range, :start_date, :end_date + + def initialize(start_date, end_date, room_number, rate = 200) + @start_date = start_date + @end_date = end_date + @date_range = DateRange.new(start_date, end_date) + @room_number = room_number + @rate = rate end + # calculates the total of each reservation def cost - return 3 + total_cost = @date_range.nights.to_i * rate + return total_cost end end end diff --git a/test/date_range_test.rb b/test/date_range_test.rb index 70bd65115..ccb8864c0 100644 --- a/test/date_range_test.rb +++ b/test/date_range_test.rb @@ -12,10 +12,10 @@ expect(range.end_date).must_equal end_date end - xit "is an an error for negative-lenght ranges" do + it "is an an error for negative-lenght ranges" do end - xit "is an error to create a 0-length range" do + it "is an error to create a 0-length range" do end end @@ -35,32 +35,32 @@ expect(@range.overlap?(test_range)).must_equal true end - xit "returns true for a contained range" do + it "returns true for a contained range" do end - xit "returns true for a range that overlaps in front" do + it "returns true for a range that overlaps in front" do end - xit "returns true for a range that overlaps in the back" do + it "returns true for a range that overlaps in the back" do end - xit "returns true for a containing range" do + it "returns true for a containing range" do end - xit "returns false for a range starting on the end_date date" do + it "returns false for a range starting on the end_date date" do end - xit "returns false for a range ending on the start_date date" do + it "returns false for a range ending on the start_date date" do end - xit "returns false for a range completely before" do + it "returns false for a range completely before" do end - xit "returns false for a date completely after" do + it "returns false for a date completely after" do end end - xdescribe "include?" do + describe "include?" do it "reutrns false if the date is clearly out" do end @@ -71,7 +71,7 @@ end end - xdescribe "nights" do + describe "nights" do it "returns the correct number of nights" do end end diff --git a/test/hotel_controller_test.rb b/test/hotel_controller_test.rb index bd50dece0..a1e6586a8 100644 --- a/test/hotel_controller_test.rb +++ b/test/hotel_controller_test.rb @@ -6,26 +6,23 @@ @date = Date.parse("2020-08-04") end describe "wave 1" do - describe "rooms" do - it "returns a list" do - rooms = @hotel_controller.rooms - expect(rooms).must_be_kind_of Array - end - end describe "reserve_room" do it "takes two Date objects and returns a Reservation" do start_date = @date end_date = start_date + 3 + room_number = 10 + rate = 200 - reservation = @hotel_controller.reserve_room(start_date, end_date) + reservation = @hotel_controller.reserve_room(start_date, end_date, room_number, rate) expect(reservation).must_be_kind_of Hotel::Reservation + expect(@hotel_controller.reservations.size).must_equal(1) end end describe "reservations" do it "takes a Date and returns a list of Reservations" do - reservation_list = @hotel_controller.reservations(@date) + reservation_list = @hotel_controller.reservations_by_date(@date) expect(reservation_list).must_be_kind_of Array reservation_list.each do |res| @@ -37,14 +34,44 @@ describe "wave 2" do describe "available_rooms" do + before do + @room_number = 1 + #@hotel_controller.rooms + end + it "takes two dates and returns a list" do start_date = @date end_date = start_date + 3 room_list = @hotel_controller.available_rooms(start_date, end_date) + + expect(room_list).must_be_kind_of Array + expect(room_list).must_equal((1..20).to_a) + end + + it "doesn't return reserved room" do + start_date = @date + end_date = start_date + 3 + + + @hotel_controller.reserve_room(start_date, end_date, 10, 200) + room_list = @hotel_controller.available_rooms(start_date, end_date) + + expect(room_list).must_be_kind_of Array + expect(room_list.size).must_equal(19) + end + + it "returns room if booking date isn't overlap" do + start_date = @date + end_date = start_date + 3 + + @hotel_controller.reserve_room(@date + 4, @date + 5, 8, 200) + room_list = @hotel_controller.available_rooms(start_date, end_date) + expect(room_list).must_be_kind_of Array + expect(room_list.size).must_equal(20) end end end -end +end \ No newline at end of file diff --git a/test/reservation_test.rb b/test/reservation_test.rb index ec4204774..03c47a421 100644 --- a/test/reservation_test.rb +++ b/test/reservation_test.rb @@ -5,7 +5,9 @@ it "returns a number" do start_date = Date.new(2017, 01, 01) end_date = start_date + 3 - reservation = Hotel::Reservation.new(start_date, end_date, nil) + room_number = 7 + rate = 200 + reservation = Hotel::Reservation.new(start_date, end_date, room_number, rate) expect(reservation.cost).must_be_kind_of Numeric end end diff --git a/test/test_helper.rb b/test/test_helper.rb index cbf8c253e..b88f4abe7 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -1,9 +1,9 @@ -# Add simplecov +require "simplecov" +SimpleCov.start require "minitest" require "minitest/autorun" require "minitest/reporters" require "minitest/skip_dsl" - require "date" Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new @@ -12,3 +12,32 @@ require_relative "../lib/hotel_controller.rb" require_relative "../lib/reservation.rb" require_relative "../lib/date_range.rb" + + + + +# wave 1 user stories + +# I can access the list of all of the rooms in the hotel X hotel_controller.rb + +# I access the list of reservations for a specified room and a given date range X hotel_controller.rb + +# I can access the list of reservations for a specific date, so that I can track reservations by date + +# I can get the total cost for a given reservation X reservation.rb + +# I want exception raised when an invalid date range is provided, +# so that I can't make a reservation for an invalid date range X + + +# wave 2 user stories + +# I can view a list of rooms that are not reserved for a given date range, +# so that I can see all available rooms for that day + +# I can make a reservation of a room for a given date range, +# and that room will not be part of any other reservation overlapping that date range + +# I want an exception raised if I try to reserve a room during a date range when all rooms are reserved, +# so that I cannot make two reservations for the same room that overlap by date +