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/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..1b2b12d6b --- /dev/null +++ b/design-activity.md @@ -0,0 +1,53 @@ +What classes does each implementation include? Are the lists the same? + Both implementations have the same classes - CartEntry, ShoppingCart, and Order. + +Write down a sentence to describe each class. + CartEntry creates entries (items to be purchased). + ShoppingCart keeps track of a collection of entries. + Order calculates the total price of a ShoppingCart. + +How do the classes relate to each other? It might be helpful to draw a diagram on a whiteboard or piece of paper. + An Order has one ShoppingCart. + A ShoppingCart has many CartEntries. + +What data does each class store? How (if at all) does this differ between the two implementations? + Both implementations store the same data. + CartEntry stores unit_price and quantity in instance variables. + ShoppingCart stores instances of CartEntry in an array. + Order stores SALES_TAX in a constant. + +What methods does each class have? How (if at all) does this differ between the two implementations? + Implementation A: + CartEntry has a unit_price and quantity method. + ShoppingCart has an entries method. + Order has a total_price method. + Implementation B: + CartEntry and ShoppingCart have price methods. + Order has a total_price method. + All classes in both implementations have constructor methods. + +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: + All logic to compute the price is retained in Order. + Implementation B: + Logic to compute the price is delegated to the lower level classes CartEntry and ShoppingCart in the price methods. + +Does total_price directly manipulate the instance variables of other classes? + Implementation A: + Order#total_price directly manipulates the entries instance variable from ShoppingCart by iterating over the array. + Implementation B: + This implementation doesn't directly manipulate instance variables of other classes and instead uses the price instance methods to achieve the same result as implementation A. + +If we decide items are cheaper if bought in bulk, how would this change the code? Which implementation is easier to modify? + Adding a discount for items bought in bulk could be achieved by storing additional data in the CartEntry class - perhaps a hash with quantities as keys and discounts as values. + I think it would be easier to modify implementation B; you could add the hash to CartEntry and wouldn't need to change anything else. Since the price calculation is done in the CartEntry class (not in the Order class as in implementation A), this shouldn't cause unexpected changes in other classes. + +Which implementation better adheres to the single responsibility principle? + I think implementation B better adheres to SRP, because each class calculates it's own price. + +Bonus question once you've read Metz ch. 3: Which implementation is more loosely coupled? + I struggled with tight coupling in Hotel, but I think implementation B is more loosely coupled, because it doesn't directly manipulate the instance variables of other classes. Only the public price methods are used to send messages between objects, rather than the instance variables/methods in implementation A. + +Improve Hotel design: + There are many changes I'd like to make, and I added more notes to refactor.txt based on the instructor feedback. However, I think the most significant item to focus on is the tight coupling where BookingManager directly manipulates instance variables in Calendar and Block. To do this, I'll remove these lines of code from BookingManager and move them to new methods in Calendar and Block, then call those methods from BookingManager. Removing these unnecessary dependencies will achieve looser coupling, and the application will be easier to change in the future. diff --git a/lib/block.rb b/lib/block.rb new file mode 100644 index 000000000..c2c6104eb --- /dev/null +++ b/lib/block.rb @@ -0,0 +1,37 @@ +require_relative 'reservation' + +module Hotel + class Block < Reservation + + attr_reader :number_of_rooms, :cost, :rooms + + def initialize(check_in, check_out, number_of_rooms) + super(check_in, check_out) + + @number_of_rooms = number_of_rooms + if number_of_rooms < 2 || number_of_rooms > 5 + raise ArgumentError, "Number of rooms must be between 2 and 5" + end + + size_discounts = { + 2 => 0.05 * PRICE, + 3 => 0.1 * PRICE, + 4 => 0.15 * PRICE, + 5 => 0.2 * PRICE + } + + @cost -= size_discounts[number_of_rooms] + + @rooms = {} + end + + def set_available_status(room) + rooms[room] = :available + end + + def set_unavailable_status(room) + rooms[room] = :unavailable + end + + end +end diff --git a/lib/booking_manager.rb b/lib/booking_manager.rb new file mode 100644 index 000000000..4ce74933a --- /dev/null +++ b/lib/booking_manager.rb @@ -0,0 +1,42 @@ +module Hotel + class BookingManager + class NoAvailabilityError < StandardError ; end + + attr_reader :calendar, :reservations, :blocks + + def initialize(calendar) + @calendar = calendar + @reservations = [] + @blocks = [] + end + + def reserve_room(check_in, check_out) + reservation = Hotel::Reservation.new(check_in, check_out) + room = calendar.add_reservation(reservation) + @reservations << [reservation, room] + end + + def reserve_block(check_in, check_out, number_of_rooms) + block = Hotel::Block.new(check_in, check_out, number_of_rooms) + rooms = calendar.add_block(block) + @blocks << block + end + + def reserve_block_room(block) + available = block.rooms.select do |room, status| + status == :available + end + + if available.empty? + raise NoAvailabilityError.new("No availability.") + end + + reserved_room = available.first[0] + + block.set_unavailable_status(reserved_room) + + return reserved_room + end + + end +end diff --git a/lib/calendar.rb b/lib/calendar.rb new file mode 100644 index 000000000..609e4ca00 --- /dev/null +++ b/lib/calendar.rb @@ -0,0 +1,60 @@ +module Hotel + class Calendar + + attr_reader :rooms, :room_assignments + + def initialize(number_of_rooms) + @rooms = [*1..(number_of_rooms)] + @room_assignments = Hash[ @rooms.collect { |room| [room, []] } ] + end + + def add_reservation(reservation) + room = available_rooms(reservation).first + + raise StandardError, "No availability." if room.nil? + + reservation.get_all_dates.each do |date| + room_assignments[room] << date + end + + return room + end + + def add_block(block) + available_rooms = available_rooms(block) + block_size = block.number_of_rooms + + if available_rooms.length < block_size + raise StandardError, "No availability." + end + + block_rooms = available_rooms.first(block_size) + + block_rooms.each do |room| + room_assignments[room] << block.get_all_dates + block.set_available_status(room) + end + + return block_rooms + end + + def reservations(date) + date = Date.parse(date) + reservations = room_assignments.select { |room, dates| dates.flatten.include? (date) }.keys + end + + def available_room?(room, reservation) + dates = reservation.get_all_dates + if dates.any? { |date| room_assignments[room].flatten.include? (date)} + return false + end + + return true + end + + def available_rooms(reservation) + available_rooms = rooms.select { |room| available_room?(room, reservation)} + end + + end +end diff --git a/lib/reservation.rb b/lib/reservation.rb new file mode 100644 index 000000000..927c49e82 --- /dev/null +++ b/lib/reservation.rb @@ -0,0 +1,48 @@ +require 'date' +module Hotel + class Reservation + class InvalidDateError < StandardError ; end + + PRICE = 200 + + attr_reader :check_in, :check_out, :cost + + def initialize(check_in, check_out) + @check_in = date_format(check_in) + @check_out = date_format(check_out) + + if number_of_nights <= 0 + raise Hotel::Reservation::InvalidDateError.new("Invalid date range.") + end + + @cost = PRICE * number_of_nights + end + + def date_format(date) + pattern = /^\d{6}$/ + + if pattern.match(date).nil? + raise ArgumentError.new("Date format: YYMMDD.") + else + Date.parse(date) + end + end + + def number_of_nights + nights = check_out - check_in + return nights.numerator + end + + def get_all_dates + all_dates = [] + date = check_in + + number_of_nights.times do + all_dates << date + date += 1 + end + + return all_dates + end + end +end diff --git a/refactor.txt b/refactor.txt new file mode 100644 index 000000000..af497b0fc --- /dev/null +++ b/refactor.txt @@ -0,0 +1,39 @@ +Notes from original submission - 9.9.18: + +BookingManager methods need to be refactored. A lot of logic is repeated, but I had trouble writing the methods so that both blocks and reservations can use them. + +Wrap classes in Hotel module. + +Change Reservation#get_all_dates to #all_dates. + +Find a better way to organize test data. + + + +Notes from instructor feedback - 9.29.18: + +BookingManager and Calendar need the most work. The responsibilities need to be split differently, and they're too tightly coupled. + +BookingManager and Block are also tightly coupled. + +BookingManager needs a factory method to create Reservations and assign room numbers to them. + +One of the classes needs to store the reservations and their room numbers - I think it should be BookingManager. + +Replace StandardErrors with custom exceptions in BookingManager and Reservation. + +Refactor Reservation#number_of_nights. + +Change Block discount case statement to hash. + + + +Second submission notes - 10.1.18: + +Is there a better way to attach the room to the reservation? + +Is Calendar#reservations or BookingManager#reservations better for providing a list of reservations? + +Test data is cleaned up a bit, but could still use improvement. + +I think some methods and variables could be named better. diff --git a/spec/block_spec.rb b/spec/block_spec.rb new file mode 100644 index 000000000..015b86f58 --- /dev/null +++ b/spec/block_spec.rb @@ -0,0 +1,50 @@ +require_relative 'spec_helper' + +describe Hotel::Block do + let(:calendar) { + Hotel::Calendar.new(20) + } + let(:block2) { + Hotel::Block.new('181202', '181206', 2) + } + let(:block3) { + Hotel::Block.new('181202', '181206', 3) + } + let(:block4) { + Hotel::Block.new('181202', '181206', 4) + } + let(:block5) { + Hotel::Block.new('181202', '181206', 5) + } + let(:block6) { + Hotel::Block.new('181202', '181206', 6) + } + let(:block1) { + Hotel::Block.new('181202', '181206', 1) + } + let(:reservation1) { + Hotel::Reservation.new('181202', '181204') + } + + describe "#initalize" do + it "can be instantiated" do + expect(block2).must_be_kind_of Hotel::Block + rooms = block2.number_of_rooms + end + it "raises ArgumentError if number_of_rooms not in range" do + expect{Hotel::Block.new('181202', '181206', 6)}.must_raise ArgumentError + expect{Hotel::Block.new('181202', '181206', 1)}.must_raise ArgumentError + end + it "calculates cost with discount based on number_of_rooms" do + expect(block2.cost).must_equal 790 + expect(block3.cost).must_equal 780 + expect(block4.cost).must_equal 770 + expect(block5.cost).must_equal 760 + end + it "stores hash of rooms and status" do + expect(block2.rooms).must_be_kind_of Hash + expect(block2.rooms).must_be_empty + end + end + +end diff --git a/spec/booking_manager_spec.rb b/spec/booking_manager_spec.rb new file mode 100644 index 000000000..438c86f4e --- /dev/null +++ b/spec/booking_manager_spec.rb @@ -0,0 +1,90 @@ +require_relative 'spec_helper' +require 'pry' + +describe Hotel::BookingManager do + let(:calendar) { + Hotel::Calendar.new(20) + } + let(:manager) { + Hotel::BookingManager.new(calendar) + } + let(:reservation1) { + Hotel::Reservation.new('181202', '181204') + } + let(:block2) { + Hotel::Block.new('181202', '181206', 2) + } + + describe "#initialize" do + it "can be instantiated" do + expect(manager).must_be_kind_of Hotel::BookingManager + end + it "takes a calendar" do + expect(manager.calendar).must_be_kind_of Hotel::Calendar + end + end + + describe "#reserve_room" do + before do + manager.reserve_room('181202','181204') + @first_res = manager.reservations.first[0] + end + it "increases length of @reservations array" do + before = manager.reservations.length + manager.reserve_room('181202','181204') + expect(manager.reservations.length).must_equal before + 1 + end + it "adds accurate Reservation instance to array" do + expect(@first_res).must_be_kind_of Hotel::Reservation + expect(@first_res.check_in).must_equal Date.parse('181202') + expect(@first_res.check_out).must_equal Date.parse('181204') + end + it "adds accurate reservation room number to array" do + expect(manager.reservations.first[1]).must_equal 1 + end + end + + describe "#reserve_block" do + before do + manager.reserve_block('181202','181204', 2) + @first_block = manager.blocks[0] + end + it "increases length of @blocks array" do + before = manager.blocks.length + manager.reserve_block('181202','181204', 2) + expect(manager.blocks.length).must_equal before + 1 + end + it "adds accurate Block instance to array" do + expect(@first_block).must_be_kind_of Hotel::Block + expect(@first_block.check_in).must_equal Date.parse('181202') + expect(@first_block.check_out).must_equal Date.parse('181204') + expect(@first_block.rooms.length).must_equal 2 + end + end + + describe "#reserve_block_room" do + before do + calendar.add_reservation(reservation1) + calendar.add_block(block2) + end + it "returns reserved room if block isn't full" do + expect(manager.reserve_block_room(block2)).must_equal 2 + end + it "raises exception if block is full" do + 2.times do + manager.reserve_block_room(block2) + end + expect{manager.reserve_block_room(block2)}.must_raise Hotel::BookingManager::NoAvailabilityError + end + it "reserves first available room in a block" do + expect(manager.reserve_block_room(block2)).must_equal 2 + expect(block2.rooms[2]).must_equal :unavailable + end + it "reserves last available room in a block" do + manager.reserve_block_room(block2) + + expect(manager.reserve_block_room(block2)).must_equal 3 + expect(block2.rooms[3]).must_equal :unavailable + end + end +end diff --git a/spec/calendar_spec.rb b/spec/calendar_spec.rb new file mode 100644 index 000000000..5c1ffcad9 --- /dev/null +++ b/spec/calendar_spec.rb @@ -0,0 +1,231 @@ +require_relative 'spec_helper' + +describe Hotel::Calendar do + let(:calendar) { + Hotel::Calendar.new(20) + } + let(:manager) { + Hotel::BookingManager.new(calendar) + } + let(:reservation1) { + Hotel::Reservation.new('181202', '181204') + } + let(:reservation2) { + Hotel::Reservation.new('181204', '181206') + } + let(:reservation3) { + Hotel::Reservation.new('181203', '181204') + } + let(:reservation4) { + Hotel::Reservation.new('181130', '181202') + } + let(:reservation5) { + Hotel::Reservation.new('181130', '181206') + } + let(:block2) { + Hotel::Block.new('181202', '181204', 2) + } + let(:block3) { + Hotel::Block.new('181204', '181206', 3) + } + let(:block4) { + Hotel::Block.new('181129', '181201', 4) + } + let(:block5) { + Hotel::Block.new('181203', '181204', 5) + } + let(:block6) { + Hotel::Block.new('181201', '181205', 5) + } + let(:block7) { + Hotel::Block.new('181202', '181203', 4) + } + let(:block8) { + Hotel::Block.new('181206', '181210', 3) + } + let(:block9) { + Hotel::Block.new('181206', '181208', 5) + } + + describe "#initalize" do + it "can be instantiated" do + expect(calendar).must_be_kind_of Hotel::Calendar + end + it "creates accurate array of rooms" do + expect(calendar.rooms).must_be_kind_of Array + expect(calendar.rooms[-1]).must_equal calendar.rooms.length + expect(calendar.rooms[0]).must_equal 1 + end + it "creates accurate room_assignments hash" do + expect(calendar.room_assignments).must_be_kind_of Hash + expect(calendar.room_assignments.keys).must_equal calendar.rooms + + calendar.room_assignments.values.each do |v| + expect(v).must_be_kind_of Array + expect(v).must_be_empty + end + end + end + + describe "#add_reservation" do + before do + calendar.add_reservation(reservation1) + calendar.add_reservation(reservation2) + calendar.add_reservation(reservation3) + calendar.add_reservation(reservation4) + calendar.add_reservation(reservation5) + end + it "adds all reservation dates to first available room" do + expect(calendar.room_assignments[1]).must_equal reservation1.get_all_dates + reservation2.get_all_dates + reservation4.get_all_dates + + expect(calendar.room_assignments[2]).must_equal reservation3.get_all_dates + + expect(calendar.room_assignments[3]).must_equal reservation5.get_all_dates + end + it "returns assigned room" do + expect(calendar.add_reservation(reservation1)).must_equal 4 + end + it "raises exception if no rooms available" do + 17.times do + calendar.add_reservation(reservation1) + end + expect{calendar.add_reservation(reservation1)}.must_raise StandardError + end + it "correctly adds reservation dates when blocks are on calendar" do + calendar.add_block(block2) + + expect(calendar.add_reservation(reservation3)).must_equal 6 + expect(calendar.room_assignments[6]).must_equal reservation3.get_all_dates + end + end + + describe "#add_block" do + before do + calendar.add_reservation(reservation1) + calendar.add_reservation(reservation2) + calendar.add_reservation(reservation3) + calendar.add_reservation(reservation4) + calendar.add_reservation(reservation5) + calendar.add_block(block2) + calendar.add_block(block7) + end + it "returns array of block rooms" do + expect(calendar.add_block(block8)).must_equal [1, 2, 3] + end + it "raises exception if not enough available rooms" do + 4.times do + calendar.add_block(block9) + end + + expect{calendar.add_block(block9)}.must_raise StandardError + end + it "adds rooms hash to block object" do + calendar.add_block(block8) + + expect(block8.rooms).must_be_kind_of Hash + expect(block8.rooms.keys).must_equal [1, 2, 3] + expect(block8.rooms.values).must_equal [:available, :available, :available] + end + it "adds block dates to calendar as array" do + before = calendar.room_assignments[1].length + + calendar.add_block(block8) + + expect(calendar.room_assignments[1].length).must_equal before + 1 + expect(calendar.room_assignments[1].length).wont_equal before + block8.get_all_dates.length + expect(calendar.room_assignments[1].include? block8.get_all_dates).must_equal true + end + it "adds all reservation dates to all block rooms" do + expect(calendar.room_assignments[4][0]).must_equal block2.get_all_dates + expect(calendar.room_assignments[4][0].length).must_equal block2.number_of_nights + expect(calendar.room_assignments[5][0]).must_equal block2.get_all_dates + expect(calendar.room_assignments[5][0].length).must_equal block2.number_of_nights + end + end + + describe "#reservations" do + before do + calendar.add_reservation(reservation1) + calendar.add_reservation(reservation1) + calendar.add_reservation(reservation2) + calendar.add_reservation(reservation3) + calendar.add_reservation(reservation4) + end + it "returns list of reserved rooms for given date" do + reservations = calendar.reservations('181203') + + expect(reservations.length).must_equal 3 + expect(reservations[0]).must_equal 1 + expect(reservations[2]).must_equal 3 + end + it "returns accurate list when blocks are on calendar" do + calendar.add_block(block2) + calendar.add_block(block3) + calendar.add_block(block4) + + reservations = calendar.reservations('181130') + + expect(reservations.length).must_equal 5 + (1..5).each do |i| + expect(reservations[i - 1]).must_equal i + end + end + end + + describe "#available_room?" do + before do + calendar.add_reservation(reservation1) + calendar.add_block(block2) + end + it "returns false if room is reserved for all given dates" do + expect(calendar.available_room?(1, reservation1)).must_equal false + end + it "returns false if block is reserved for all given dates" do + expect(calendar.available_room?(2, block2)).must_equal false + end + it "returns true if room isn't reserved for any given dates" do + expect(calendar.available_room?(1, reservation2)).must_equal true + expect(calendar.available_room?(1, reservation4)).must_equal true + end + it "returns true if block isn't reserved for any given dates" do + (1..3).each do |i| + expect(calendar.available_room?(i, block3)).must_equal true + end + (1..4).each do |i| + expect(calendar.available_room?(2, block4)).must_equal true + end + end + it "returns false if room is reserved for any given dates" do + expect(calendar.available_room?(1, reservation3)).must_equal false + expect(calendar.available_room?(1, reservation5)).must_equal false + end + it "returns false if block is reserved for any given dates" do + (1..3).each do |i| + expect(calendar.available_room?(i, block5)).must_equal false + end + (1..3).each do |i| + expect(calendar.available_room?(i, block6)).must_equal false + end + end + end + + describe "#available_rooms" do + before do + calendar.add_reservation(reservation1) + end + it "returns array of available rooms" do + available_rooms = calendar.available_rooms(reservation1) + expect(available_rooms).must_be_kind_of Array + expect(available_rooms.length).must_equal 19 + expect(available_rooms.first).must_equal 2 + end + it "returns accurate list when blocks are on calendar" do + calendar.add_block(block2) + calendar.add_block(block3) + available_rooms = calendar.available_rooms(block5) + expect(available_rooms).must_be_kind_of Array + expect(available_rooms.length).must_equal 17 + expect(available_rooms.first).must_equal 4 + end + end +end diff --git a/spec/reservation_spec.rb b/spec/reservation_spec.rb new file mode 100644 index 000000000..646089859 --- /dev/null +++ b/spec/reservation_spec.rb @@ -0,0 +1,104 @@ +require_relative 'spec_helper' + +describe Hotel::Reservation do + let (:reservation) { + Hotel::Reservation.new('181202', '181204') + } + let (:error_reservation) { + Hotel::Reservation.new('181204', '181202') + } + let (:months_reservation) { + Hotel::Reservation.new('181130', '181204') + } + let (:same_reservation) { + Hotel::Reservation.new('181130', '181130') + } + let (:years_reservation) { + Hotel::Reservation.new('181230', '190103') + } + let (:date_error1) { + Hotel::Reservation.new('181202', '1812045') + } + let (:date_error2) { + Hotel::Reservation.new('18120', '181204') + } + let (:date_error3) { + Hotel::Reservation.new('18-12-02', '1812045') + } + + describe "#initialize" do + it "can be instantiated" do + expect(reservation).must_be_kind_of Hotel::Reservation + end + it "stores number of nights" do + expect(reservation.number_of_nights).must_equal 2 + end + it "calculates and stores cost" do + expect(reservation.cost).must_equal 400 + end + end + + describe "#date_format" do + before do + + end + it "converts check_in and check_out strings to Date objects" do + expect(reservation.check_in).must_be_kind_of Date + expect(reservation.check_out).must_be_kind_of Date + end + it "raises ArgumentError if date is not 6 digits" do + expect{Hotel::Reservation.new('181202', '1812045')}.must_raise ArgumentError, "Date format: YYMMDD." + + expect{Hotel::Reservation.new('18120', '181204')}.must_raise ArgumentError, "Date format: YYMMDD." + end + it "raises ArgumentError if date contains non-numeric characters" do + expect{Hotel::Reservation.new('18-12-02', '1812045')}.must_raise ArgumentError, "Date format: YYMMDD." + end + end + + describe "#number_of_nights" do + it "calculates accurate number of nights" do + expect(reservation.number_of_nights).must_equal 2 + expect(months_reservation.number_of_nights).must_equal 4 + end + it "raises StandardError if check_out is earlier than check_in" do + expect{Hotel::Reservation.new('181204', '181202')}.must_raise Hotel::Reservation::InvalidDateError, "Invalid date range." + end + it "raises StandardError if check_out is the same as check_in" do + expect{Hotel::Reservation.new('181130', '181130')}.must_raise Hotel::Reservation::InvalidDateError, "Invalid date range." + end + end + + describe "#get_all_dates" do + it "returns Array" do + expect(reservation.get_all_dates).must_be_kind_of Array + end + it "contains all dates for reservation in same month" do + reservation.get_all_dates.each do |date| + expect(date).must_be_kind_of Date + end + + expect(reservation.get_all_dates.length).must_equal 2 + expect(reservation.get_all_dates[0]).must_equal reservation.check_in + expect(reservation.get_all_dates[-1]).must_equal reservation.check_out - 1 + end + it "contains all dates for reservation spanning 2 months" do + months_reservation.get_all_dates.each do |date| + expect(date).must_be_kind_of Date + end + + expect(months_reservation.get_all_dates.length).must_equal 4 + expect(months_reservation.get_all_dates[0]).must_equal months_reservation.check_in + expect(months_reservation.get_all_dates[-1]).must_equal months_reservation.check_out - 1 + end + it "contains all dates for reservation spanning 2 years" do + years_reservation.get_all_dates.each do |date| + expect(date).must_be_kind_of Date + end + + expect(years_reservation.get_all_dates.length).must_equal 4 + expect(years_reservation.get_all_dates[0]).must_equal years_reservation.check_in + expect(years_reservation.get_all_dates[-1]).must_equal years_reservation.check_out - 1 + end + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 4d1e3fdc8..0ecb7d7fd 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/reservation.rb' +require_relative '../lib/calendar.rb' +require_relative '../lib/booking_manager.rb' +require_relative '../lib/block.rb'