diff --git a/.gitignore b/.gitignore index 5e1422c9c..f5bec6af3 100644 --- a/.gitignore +++ b/.gitignore @@ -48,3 +48,59 @@ build-iPhoneSimulator/ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this: .rvmrc + + + +# date_range_1 = Hotel::DateRange.new('2018-09-01', '2018-09-05') +# # # # date_range_2 = Hotel::DateRange.new('2018-09-15', '2018-09-20') +# # # date_range_3 = Hotel::DateRange.new('2018-08-29', '2018-09-02') +# # # # date_range_4 = Hotel::DateRange.new('2018-10-01', '2018-10-20') +# reservation = Hotel::BookingSystem.new() +# # # +# # # # reservation_1 = Hotel::BookingSystem.new() +# # # # +# 10.times do +# reservation.make_reservation(date_range_1) +# end +# +# 1.times do +# reservation.reserve_block_rooms(date_range_1) +# end +# + +# reservation.reserve_block_rooms(date_range_1) +# +# # 3.times do +# # block_room.make_reservation_from_block(date_range_1) +# # end +# # # +# p reservation + +# p reservation.find_available_rooms(date_range_1) +# # puts "#{reservation.list_available_rooms(date_range_1)}" +# # puts "#{reservation_1.list_available_rooms(date_range_1)}" +# # puts "#{reservation.list_available_rooms(date_range_4)}" +# +# +# # +# # puts reservation.list_reservations(date_range_1).first.room_number +# # puts reservation.list_reservations(date_range_1).last.room_number +# +# # reservation.list_reservations(date_range_1).each_with_index do |res, i| +# # puts "#{i}. Room ##{res.room_number}, Start Date: #{res.date_range.start_date}" +# # end +# # # +# # +# # reservation.list_reservations(date_range_2).each_with_index do |res, i| +# # puts "#{i}. Room ##{res.room_number}, Start Date: #{res.date_range.start_date}" +# # end +# # +# # reservation.list_reservations(date_range_3).each_with_index do |res, i| +# # puts "#{i}. Room ##{res.room_number}, Start Date: #{res.date_range.start_date}" +# # end +# # array = reservation.reservations +# # array.each_with_index do |res, i| +# # puts "#{i}. Room ##{res.room_number}, Start Date: #{res.date_range.start_date}" +# # end +# # +# # puts "#{Hotel::BookingSystem.available_rooms}" diff --git a/Guardfile b/Guardfile index 6760f9177..fa59fc3ef 100644 --- a/Guardfile +++ b/Guardfile @@ -1,4 +1,4 @@ -guard :minitest, bundler: false, rubygems: false do +guard :minitest, bundler: false, autorun: false, rubygems: false do # with Minitest::Spec watch(%r{^spec/(.*)_spec\.rb$}) watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" } diff --git a/design-activity.md b/design-activity.md new file mode 100644 index 000000000..34e7f1e0c --- /dev/null +++ b/design-activity.md @@ -0,0 +1,112 @@ +# Comprehension Questions + +#### 1. What classes does each implementation include? Are the lists the same? +Both implementations include the same three classes, CartEntry, ShoppingCart, and Order. Yes, each implementation returns the same list in the Order class. The other classes however does not return the same list because Implementation B has instance methods that call on the `price` method for each class. Implementation A only has attributes in the other two classes. + + +#### 2. Write down a sentence to describe each class. +The CartEntry class creates an instance of an order item, which has the attributes unit price and quantity. In the second implementation, it contains the method price, which calculates the price of the item by multiplying the price of the item by the quantity of items ordered. + +The ShoppingCart class creates an instance of a cart, which stores an array of cart item objects as an instance variable `@entries`. The second implementation contains the method price, which calculates the total of all cart items in the shopping cart. + +The Order class creates an instance of an order, which stores an instance of a shopping cart object as an instance variable `@cart`. It calculates the total price of the order by getting the subtotal of the cart and adding the subtotal with the subtotal multiplied by the sales tax. + + + +#### 3. How do the classes relate to each other? It might be helpful to draw a diagram on a whiteboard or piece of paper. +The Order class stores an instance of ShoppingCart object, which we can use to calculate the total price of a cart including the sales tax. Each ShoppingCart stores instances of CartEntry, and we can get the total price of the shopping cart by calling the method price on the cart (this method gets the subtotal of the cart without taxes). The CartEntry class stores an instance of a cart item which has the attributes unit price and quantity. We can get the price of a cart item entry by calling on the price method which multiplies the price of the item by the quantity ordered. + + In other words, an Order has one shopping cart, a ShoppingCart has many cart entries, and a CartEntry has one entry item. + + +#### 4. What data does each class store? How (if at all) does this differ between the two implementations? + +The CartEntry class stores a cart entry item. +The ShoppingCart class stores instances of CartEntry objects. +The Order class stores an instance of ShoppingCart. + +Both implementations store the same data, but the behaviors of the classes differ. The second implementation wraps the attributes in an instance method, while the first implementation uses the attr_accessor to access the instance variables of the class. + +#### 5. What methods does each class have? How (if at all) does this differ between the two implementations? + + +|**Implementation A** | CartEntry | ShoppingCart | Order | +| --- | --- | --- | --- | +| Methods | `initialize`, `attr_accessor` | `initialize`, `attr_accessor` | `initialize`, `total_price` | + + +| **Implementation B** | CartEntry | ShoppingCart | Order | +| --- | --- | --- | --- | +| Methods | `initialize`, `price` | `initialize`, `price` | `initialize`, `total_price` | + +The two implementations differ in that the second implementation wraps the instance variables in an instance method and calls on that instance method to determine price in each class. On the other hand, the first implementation calls on the attr_accessor method from the other classes to determine the price in just one class, the Order class. + + +#### 6. 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? + + - First implementation: price is retained in Order + - Second implementation: price is delegated to lower level classes, ShoppingCart and CartEntry + +* Does total_price directly manipulate the instance variables of other classes? + + - First implementation: directly manipulates the instance variables of other classes + - Second implementation: does not manipulate the instance variables, but uses the instance methods to get price + + +#### 7. If we decide items are cheaper if bought in bulk, how would this change the code? Which implementation is easier to modify? +The second implementation is easier to change because we can add a conditional to the `price` method to lower the unit price if quantity is greater than or equal to a set amount. + +The first implementation would be harder to change because all the logic is in the Order class, and is too dependent on the CartEntry and ShoppingCart classes. + + + +#### 8. Which implementation better adheres to the single responsibility principle? +Implementation B better adheres to the single responsibility principle because each class has one responsibility and the class's dependencies on each other are minimal. They are loosely coupled, and implementing changes are easier compared to Implementation A. + + + +#### 9. Bonus question once you've read Metz ch. 3: Which implementation is more loosely coupled? +Implementation B is more loosely coupled. + + + +## Improvements on Hotel Project + + + + +### Notes on Class Responsibilities: +* Reservation: + - Responsible for holding one reservation instance + - BookingSystem calls on the reservation's instance variable `date_range`, but thought it was appropriate because `date_range` is an instance of class DateRange. This way, I can call on a method on DateRange and do the work there instead of in the BookingSystem class. + +* DateRange: + - Responsible for validating available dates + - Instance variables are not directly manipulated, methods used to validate dates + +* BookingSystem: + - Responsible for creating all reservations (room and blocks) + - Knows about all other class, but the other classes know little about each other + +* BlockRoom: + - Responsible for holding a block of rooms with a discounted rate + - Like Reservation, the instance variable `date_range` in BlockRoom is called in BookingSystem + + +### Hotel Refactors: + * Updated logic of the `dates_overlap` method in DateRange class. Helps clean up code/readability + * Created custom error exceptions within the DateRange and BookingSystem class, instead of raising StandardError + * Removed `list_rooms` method in the BookingSystem class since the method was redundant and attr_reader returns the same thing + * Fixed logic error in BookingSystem method `find_available_rooms` where there were nil inputs being populated in the array diff --git a/lib/block_room.rb b/lib/block_room.rb new file mode 100644 index 000000000..662f219b8 --- /dev/null +++ b/lib/block_room.rb @@ -0,0 +1,21 @@ +module Hotel + class BlockRoom + BLOCK_ROOM_RATE = 100.00 + attr_reader :date_range, :block_rooms + + def initialize(date_range, block_rooms) + @date_range = date_range + @block_rooms = block_rooms + end + + def block_dates_duration + return (@date_range.end_date - @date_range.start_date).to_i + end + + def block_cost + return ("%.2f" % (block_dates_duration * BLOCK_ROOM_RATE)).to_f + end + + + end +end diff --git a/lib/booking_system.rb b/lib/booking_system.rb new file mode 100644 index 000000000..bd81eb2e9 --- /dev/null +++ b/lib/booking_system.rb @@ -0,0 +1,86 @@ +require_relative 'reservation' +require_relative 'block_room' +require_relative 'date_range' +require 'awesome_print' + +module Hotel + class BookingSystem + class ValidateRoomsError < StandardError ; end + + attr_reader :rooms, :reservations, :block_rooms + + def initialize + @rooms = (1..20).to_a + @reservations = [] + @block_rooms = [] + end + + def list_reservations(date_range) + return @reservations.select { |res| res.date_range == date_range } + end + + def list_available_rooms(date_range) + return @rooms if @reservations.empty? + return find_available_rooms(date_range) + end + + def find_available_rooms(date_range) + return @rooms if @reservations.empty? + + unavailable_rooms = @reservations.map { + |res| res.room_number if date_range.dates_overlap?(res.date_range) + }.flatten.compact + + + unavailable_rooms_block = @block_rooms.map { + |res| res.block_rooms if date_range.dates_overlap?(res.date_range) + }.flatten.compact + + + all_unavailable_rooms = unavailable_rooms + unavailable_rooms_block + + available_rooms = @rooms.reject { + |r| all_unavailable_rooms.include?(r) + } + + raise ValidateRoomsError, "No rooms available for those dates." if available_rooms.empty? + return available_rooms + end + + def make_reservation(date_range) + room = find_available_rooms(date_range).first + reservation = Reservation.new(date_range, room) + @reservations << reservation + return reservation + end + + def reserve_block_rooms(date_range) + rooms = find_available_rooms(date_range).first(5) + block_reservation = BlockRoom.new(date_range, rooms) + @block_rooms << block_reservation + return block_reservation + end + + def find_block(date_range) + raise ValidateRoomsError, "No block rooms found for those dates" if @block_rooms.empty? + return @block_rooms.select { |block| block.date_range == date_range } + end + + def find_room_in_block(date_range) + found_block = find_block(date_range) + room_block_rooms = found_block.first.block_rooms + available_rooms = find_available_rooms(date_range) + rooms = available_rooms.select { |room| room if room_block_rooms.include? available_rooms } + return rooms + end + + def make_reservation_from_block(date_range) + room = find_room_in_block(date_range).first + reservation = Reservation.new(date_range, room) + @reservations << reservation + return reservation + end + + + end +end diff --git a/lib/date_range.rb b/lib/date_range.rb new file mode 100644 index 000000000..d2f4cd9d6 --- /dev/null +++ b/lib/date_range.rb @@ -0,0 +1,39 @@ +require 'date' + +module Hotel + class DateRange + class ValidateDatesError < StandardError ; end + + attr_reader :start_date, :end_date + + def initialize(start_date, end_date) + @start_date = Date.parse(start_date) + @end_date = Date.parse(end_date) + end + + def check_valid_dates + + raise ValidateDatesError, "Invalid dates entered" if @start_date == nil || @end_date == nil + + raise ValidateDatesError, "End date cannot be before start date" if (@end_date - @start_date) <= 0 + end + + def dates_overlap?(date_range) + + booked_dates = [*date_range.start_date..date_range.end_date] + new_dates = [*@start_date..@end_date] + + + if !(new_dates.first >= booked_dates.last || new_dates.last <= booked_dates.first) + # dates overlap + return true + elsif new_dates.first < booked_dates.first && new_dates.last >= booked_dates.last + # dates are containing + return true + end + + return false + end + + end +end diff --git a/lib/reservation.rb b/lib/reservation.rb new file mode 100644 index 000000000..601e539ac --- /dev/null +++ b/lib/reservation.rb @@ -0,0 +1,21 @@ +module Hotel + class Reservation + PRICE_PER_NIGHT = 200.00 + + attr_reader :date_range, :room_number + + def initialize(date_range, room_number) + @date_range = date_range + @room_number = room_number + end + + def number_of_nights + return (@date_range.end_date - @date_range.start_date).to_i + end + + def total_cost + return ("%.2f" % (number_of_nights * PRICE_PER_NIGHT)).to_f + end + + end +end diff --git a/refactors.txt b/refactors.txt new file mode 100644 index 000000000..ebdaf6cb1 --- /dev/null +++ b/refactors.txt @@ -0,0 +1,5 @@ +Changes to make in the future: +- Change start_date and end_date to check_in and check_out +- If more attributes added to rooms (like different prices, suites, King vs Queen beds, etc), create a separate Room class. +- Refactor the dates_overlap? method +- Work on BlockRoom class/methods + Tests diff --git a/spec/block_room_spec.rb b/spec/block_room_spec.rb new file mode 100644 index 000000000..bc1564fcc --- /dev/null +++ b/spec/block_room_spec.rb @@ -0,0 +1,26 @@ +require_relative 'spec_helper' + +describe 'BlockRoom class' do + describe 'Initializer' do + + before do + @date_range_1 = Hotel::DateRange.new('2018-09-01', '2018-09-05') + @block_room = Hotel::BlockRoom.new(@date_range_1, [1,2,3,4,5]) + end + + it 'Creates an instance of BlockRoom' do + expect(@block_room).must_be_kind_of Hotel::BlockRoom + end + + it 'Takes date range as an instance of DateRange' do + expect(@block_room.date_range).must_be_kind_of Hotel::DateRange + end + + it 'Takes block rooms as an array' do + expect(@block_room.block_rooms).must_equal [*1..5] + end + + end + + +end diff --git a/spec/booking_system_spec.rb b/spec/booking_system_spec.rb new file mode 100644 index 000000000..deca596aa --- /dev/null +++ b/spec/booking_system_spec.rb @@ -0,0 +1,190 @@ +require_relative 'spec_helper' +require 'date' +require 'pry' + +describe "BookingSystem Class" do + before do + @date_range_1 = Hotel::DateRange.new('2018-09-01', '2018-09-05') + @date_range_2 = Hotel::DateRange.new('2018-09-15', '2018-09-20') + @date_range_3 = Hotel::DateRange.new('2018-08-29', '2018-09-02') + @reservation = Hotel::BookingSystem.new() + + + 5.times do + @reservation.make_reservation(@date_range_1) + end + + 2.times do + @reservation.make_reservation(@date_range_2) + end + + 3.times do + @reservation.make_reservation(@date_range_3) + end + + @reservation.reserve_block_rooms(@date_range_1) + end + + describe "Initializer" do + it 'Creates an array of room numbers' do + expect(@reservation.rooms).must_be_kind_of Array + expect(@reservation.rooms.length).must_equal 20 + end + + it 'Creates an array of reservation instances' do + expect(@reservation.reservations.length).must_equal 10 + all_rervations = @reservation.reservations + all_rervations.each do |r| + expect(r).must_be_kind_of Hotel::Reservation + end + end + + it 'Creates an array of block room instances' do + expect(@reservation.block_rooms).must_be_kind_of Array + expect(@reservation.block_rooms.first).must_be_kind_of Hotel::BlockRoom + expect(@reservation.block_rooms.first.block_rooms).must_equal [*9..13] + end + end + + describe "list_rooms method" do + it 'Returns an array of room numbers' do + expect(@reservation.rooms).must_be_kind_of Array + expect(@reservation.rooms.length).must_equal 20 + end + end + + describe 'list_reservations method' do + let (:reservations_list_1) { + @reservation.list_reservations(@date_range_1) + } + + let (:reservations_list_2) { + @reservation.list_reservations(@date_range_2) + } + + let (:reservations_list_3) { + @reservation.list_reservations(@date_range_3) + } + + it 'Returns an array of reservation instances' do + expect(reservations_list_1).must_be_kind_of Array + reservations_list_1.each do |r| + expect(r).must_be_kind_of Hotel::Reservation + end + end + + it 'Returns the correct length of the array' do + expect(reservations_list_1.length).must_equal 5 + end + + it 'Correctly returns the reservations for that date range' do + expect(reservations_list_1).must_equal reservations_list_1 + end + + it 'Correctly returns the first reservation on the list for that date range' do + first_on_list_1 = reservations_list_1.first + date_1 = @date_range_1.start_date + + first_on_list_2= reservations_list_2.first + date_2 = @date_range_2.start_date + + first_on_list_3 = reservations_list_3.first + date_3 = @date_range_3.start_date + + expect(first_on_list_1.room_number).must_equal 1 + expect(first_on_list_1.date_range.start_date).must_equal date_1 + + expect(first_on_list_2.room_number).must_equal 1 + expect(first_on_list_2.date_range.start_date).must_equal date_2 + + expect(first_on_list_3.room_number).must_equal 6 + expect(first_on_list_3.date_range.start_date).must_equal date_3 + end + + it 'Correctly returns the last reservation on the list for that date range' do + last_on_list_1 = reservations_list_1.last + date_1 = @date_range_1.start_date + + last_on_list_2= reservations_list_2.last + date_2 = @date_range_2.start_date + + last_on_list_3 = reservations_list_3.last + date_3 = @date_range_3.start_date + + expect(last_on_list_1.room_number).must_equal 5 + expect(last_on_list_1.date_range.start_date).must_equal date_1 + + expect(last_on_list_2.room_number).must_equal 2 + expect(last_on_list_2.date_range.start_date).must_equal date_2 + + expect(last_on_list_3.room_number).must_equal 8 + expect(last_on_list_3.date_range.start_date).must_equal date_3 + end + end + + describe 'list_available_rooms method' do + let (:reservation_2) { Hotel::BookingSystem.new() } + + it 'Correcly lists the available rooms by date' do + expect(@reservation.list_available_rooms(@date_range_1)).must_equal [*14..20] + end + + it 'Returns all the rooms if there are no reservations' do + expect(reservation_2.list_available_rooms(@date_range_1)).must_equal [*1..20] + end + end + + describe 'find_available_rooms method' do + let (:reservation_3) { Hotel::BookingSystem.new() } + + it 'Returns 1 if there have been no reservations made' do + expect(reservation_3.reservations).must_be_empty + expect(reservation_3.find_available_rooms(@date_range_1).first).must_equal 1 + end + + it 'Correctly returns an array of available rooms for the date range' do + expect(@reservation.find_available_rooms(@date_range_1)).must_equal [*14..20] + end + + it 'Raises an error if there are no available rooms for the date range' do + hotel_booked = Hotel::BookingSystem.new() + + 20.times do + hotel_booked.make_reservation(@date_range_1) + end + + expect{hotel_booked.find_available_rooms(@date_range_1)}.must_raise StandardError + end + end + + describe 'make_reservation method' do + it 'Creates an instance of Reservation' do + expect(@reservation.make_reservation(@date_range_1)).must_be_kind_of Hotel::Reservation + end + + it 'Adds the correct available room to the reservation' do + expect(@reservation.make_reservation(@date_range_1).room_number).must_equal 14 + end + + it 'Adds each instance of reservation into the @reservations instance variable' do + new_res = @reservation.make_reservation(@date_range_1) + + expect(@reservation.reservations.length).must_equal 11 + end + end + + describe 'reserve_block_rooms method' do + end + + describe 'find_block method' do + end + + describe 'find_room_in_block method' do + end + + describe 'make_reservation_from_block' do + end + + + +end diff --git a/spec/date_range_spec.rb b/spec/date_range_spec.rb new file mode 100644 index 000000000..5905100ab --- /dev/null +++ b/spec/date_range_spec.rb @@ -0,0 +1,101 @@ +require_relative 'spec_helper' + +describe 'DateRange Class' do + before do + @date_range_1 = Hotel::DateRange.new('2018-09-01', '2018-09-05') + @reservation_1 = Hotel::BookingSystem.new() + @reservation_1.make_reservation(@date_range_1) + end + + let (:date_range_2) { Hotel::DateRange.new('2018-09-01', '2018-09-05') } + let (:reservation_2) { + Hotel::BookingSystem.new().make_reservation(date_range_2) + } + + let (:date_range_3) { Hotel::DateRange.new('2018-08-31', '2018-09-02') } + let (:date_range_4) { Hotel::DateRange.new('2018-09-04', '2018-09-07') } + let (:date_range_5) { Hotel::DateRange.new('2018-09-02', '2018-09-03') } + let (:date_range_6) { Hotel::DateRange.new('2018-08-30', '2018-09-10') } + + let (:date_range_7) { Hotel::DateRange.new('2018-08-25', '2018-08-30') } + let (:date_range_8) { Hotel::DateRange.new('2018-09-10', '2018-09-15') } + let (:date_range_9) { Hotel::DateRange.new('2018-08-30', '2018-09-01') } + let (:date_range_10) { Hotel::DateRange.new('2018-09-05', '2018-09-10') } + + describe 'Initializer' do + it 'Creates an instance of DateRange' do + expect(@date_range_1).must_be_kind_of Hotel::DateRange + end + + it 'Stores start date and end date as date objects' do + expect(@date_range_1.start_date).must_be_kind_of Date + expect(@date_range_1.end_date).must_be_kind_of Date + end + end + + describe "check_valid_dates method" do + it 'Raises a StandardError for invalid date ranges' do + + expect{ + @date_range_1.check_valid_dates('2018-09-05', '2018-09-01') + }.must_raise StandardError + + expect{ + @date_range_1.check_valid_dates('', '2018-09-01') + }.must_raise StandardError + + expect{ + @date_range_1.check_valid_dates('2018-09-01', '') + }.must_raise StandardError + + expect{ + @date_range_1.check_valid_dates('', '') + }.must_raise StandardError + + end + end + + + describe 'dates_overlap? method' do + before do + @date_range = @reservation_1.reservations[0].date_range + end + + it 'overlaps if both date range are the same' do + expect(date_range_2.dates_overlap?(@date_range)).must_equal true + end + + it 'overlaps if new date range overlaps in the front of booked date range' do + expect(date_range_3.dates_overlap?(@date_range)).must_equal true + end + + it 'overlaps if new date range overlaps in the back of booked dates range' do + expect(date_range_4.dates_overlap?(@date_range)).must_equal true + end + + it 'overlaps if new date range is contained within the booked dates range' do + expect(date_range_5.dates_overlap?(@date_range)).must_equal true + end + + it 'overlaps if the new date range are completely containing the booked dates range' do + expect(date_range_6.dates_overlap?((@date_range))).must_equal true + end + + it 'does not overlap if new date range are completely before the booked dates' do + expect(date_range_7.dates_overlap?(@date_range)).must_equal false + end + + it 'does not overlap if new date range are completely after the booked dates' do + expect(date_range_8.dates_overlap?(@date_range)).must_equal false + end + + it 'does not overlap if new date range ends on check-in date of booked date range' do + expect(date_range_9.dates_overlap?(@date_range)).must_equal false + end + + it 'does not overlap if new date ranges starts on check-out date of the booked date range' do + expect(date_range_10.dates_overlap?(@date_range)).must_equal false + end + end + +end diff --git a/spec/reservation_spec.rb b/spec/reservation_spec.rb new file mode 100644 index 000000000..05f7ac78f --- /dev/null +++ b/spec/reservation_spec.rb @@ -0,0 +1,34 @@ +require_relative 'spec_helper' +require 'pry' + +describe "Reservation Class" do + let (:date_range) { Hotel::DateRange.new('2018-09-01', '2018-09-05') } + let (:reservation) { Hotel::Reservation.new(date_range, 1)} + + describe "Initializer" do + it 'Is an instance of Reservation' do + expect(reservation).must_be_kind_of Hotel::Reservation + end + + it 'Takes date range as an instance of DateRange' do + expect(reservation.date_range).must_be_kind_of Hotel::DateRange + end + + it 'Takes room number as an integer' do + expect(reservation.room_number).must_equal 1 + end + end + + describe 'number_of_nights method' do + it 'Returns the correct number of nights' do + expect(reservation.number_of_nights).must_equal 4 + end + end + + describe "total_cost" do + it 'Calculates total cost of an entire stay' do + expect(reservation.total_cost).must_equal 800.00 + end + + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 4d1e3fdc8..7ab96d3dc 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,3 +1,6 @@ +require 'simplecov' +SimpleCov.start + require 'minitest' require 'minitest/autorun' require 'minitest/reporters' @@ -6,3 +9,7 @@ Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new # Require_relative your lib files here! +require_relative '../lib/date_range.rb' +require_relative '../lib/reservation.rb' +require_relative '../lib/booking_system.rb' +require_relative '../lib/block_room.rb'