diff --git a/Rakefile b/Rakefile index 0c2d13fe8..3319583aa 100644 --- a/Rakefile +++ b/Rakefile @@ -3,7 +3,7 @@ require 'rake/testtask' Rake::TestTask.new do |t| t.libs = ["lib"] t.warning = true - t.test_files = FileList['test/*_test.rb'] + t.test_files = FileList['test/*_spec.rb'] end task default: :test diff --git a/lib/calendar.rb b/lib/calendar.rb new file mode 100644 index 000000000..f1004897a --- /dev/null +++ b/lib/calendar.rb @@ -0,0 +1,111 @@ +require 'date' +require_relative 'reservation' +require_relative 'calendar_date' +require_relative 'room' + +class Calendar + attr_accessor :all_reservations_store, :date_store + + def initialize + @date_store = {} + @all_reservations_store = [] + end + + + def make_reservation(start_date, end_date) + reservation = Reservation.new(start_date, end_date) + + return reservation + end + + + def list_available_rooms_entire_stay(reservation) + date_range = [] + available_rooms_all_dates = [] + + + if (reservation.total_nights == 1) && (@date_store[(reservation.start_date).iso8601].all_available_rooms.length == 20) + available_rooms = [1] + return available_rooms + end + + (reservation.total_nights).times do |i| + if @date_store[(reservation.start_date + i).iso8601].nil? + date = CalendarDate.new + else + raise NoRoomsError.new "There are no rooms available for the duration of this stay." if @date_store[(reservation.start_date + i).iso8601].unavailable? + date_range << (@date_store[(reservation.start_date + i).iso8601]).all_available_rooms + end + + end + + + date_range.each do |i| + if (date_range[0] & date_range[i]).any? + available_rooms_all_dates << (date_range[0] & date_range[i]) + end + end + + raise NoRoomsError.new "There are no rooms available for the duration of this stay." if available_rooms_all_dates.empty? + + available_rooms = available_rooms_all_dates.flatten.uniq! + + return available_rooms + end + + + def is_available?(room_number, date) + date = Date.parse(date).iso8601 + return @date_store[date].room_available?(room_number) + end + + + def reservations_on_date(date) + date = Date.parse(date).iso8601 + return @date_store[date].reservations + end + + + def rooms_on_date(date) + date = Date.parse(date).iso8601 + if @date_store[date].nil? + date = CalendarDate.new + else + date = @date_store[date] + end + + raise NoRoomError.new("There are no available rooms on the specified date.") if date.unavailable? + + return date.all_available_rooms + end + + + def find_by_id(reservation_id) + reservation = @all_reservations_store.find { |reservation| reservation[:id] == reservation_id} + raise NoReservationError.new("There is no existing reservation with given ID.") if reservation == nil + + return reservation + end + + + def total_cost_reservation(reservation_id) + reservation = find_by_id(reservation_id) + return reservation[:cost] + end + + + def add_to_calendar(reservation) + @all_reservations_store << reservation.details + + reservation.total_nights.times do |i| + if !@date_store.key?(reservation.start_date) + date = CalendarDate.new + date.add_reservation(reservation) + @date_store[(reservation.start_date + i).iso8601] = date + else + @date_store[(reservation.start_date + i).iso8601].add_reservation(reservation) + raise NoRoomError.new "Sorry, there is no availability on that date." if @date_store[(reservation.start_date + i).iso8601].unavailable? + end + end + end +end \ No newline at end of file diff --git a/lib/calendar_date.rb b/lib/calendar_date.rb new file mode 100644 index 000000000..4c09a1c64 --- /dev/null +++ b/lib/calendar_date.rb @@ -0,0 +1,41 @@ +require 'date' + +require_relative 'room' +require_relative 'reservation' + +class CalendarDate + attr_accessor :day_reservation_store, :available_rooms + + def initialize + @day_reservation_store = [] + @available_rooms = Rooms.new + end + + def reservations + return @day_reservation_store + end + + + def unavailable? + return @day_reservation_store.length == 20 + end + + + def room_available?(room_number) + return @available_rooms.rooms.include?(room_number) + end + + + def all_available_rooms + return @available_rooms.rooms + end + + + def add_reservation(reservation) + @day_reservation_store << reservation.details + @available_rooms.room_reserved(reservation.room_number) + + return @day_reservation_store + end + +end \ No newline at end of file diff --git a/lib/reservation.rb b/lib/reservation.rb new file mode 100644 index 000000000..0b39576b1 --- /dev/null +++ b/lib/reservation.rb @@ -0,0 +1,48 @@ +require 'date' +require 'securerandom' + +require_relative 'room' + + +class Reservation + attr_accessor :id, :start_date, :end_date, :total_nights, :cost, :room_number + + def initialize(start_date, end_date) + @id = (SecureRandom.alphanumeric).slice(0...7).upcase + @start_date = Date.parse(start_date) + @end_date = Date.parse(end_date) + @total_nights = (@end_date - @start_date).to_i + @cost = @total_nights * 200 + @room_number = room_number + + def valid_date?(date) + date_format = '%Y-%m-%d' + DateTime.strptime(date, date_format) + true + rescue ArgumentError + false + end + + valid_date?(start_date) + valid_date?(end_date) + + raise InvalidDateRangeError.new ("The given date range is invalid.") if (@end_date - @start_date) <= 0 + end + + def assign_room_number + room_number = available_rooms[0] + return room_number + end + + def details + { + :id => @id, + :start_date => @start_date.iso8601, + :end_date => @end_date.iso8601, + :total_nights => @total_nights, + :cost => @cost, + :room_number => @room_number + } + end + +end \ No newline at end of file diff --git a/lib/room.rb b/lib/room.rb new file mode 100644 index 000000000..8053fe62c --- /dev/null +++ b/lib/room.rb @@ -0,0 +1,20 @@ +require 'date' + +class Rooms + attr_accessor :all_rooms + + def initialize + @all_rooms = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20] + end + + + def room_reserved(room_number) + @all_rooms.delete(room_number) + end + + + def rooms + @all_rooms + end + +end \ No newline at end of file diff --git a/test/calendar_date_spec.rb b/test/calendar_date_spec.rb new file mode 100644 index 000000000..089c00e21 --- /dev/null +++ b/test/calendar_date_spec.rb @@ -0,0 +1,22 @@ +require_relative 'test_helper' + +describe "Manages calendar and it's various duties" do + before do + @reservation1 = Reservation.new("2020/05/04", "2020/05/07") + @reservation2 = Reservation.new("2020/05/07", "2020/05/09") + @reservation3 = Reservation.new("2020/05/06", "2020/05/11") + + @calendar = Calendar.new + + @calendar.add_to_calendar(@reservation1) + @calendar.add_to_calendar(@reservation2) + @calendar.add_to_calendar(@reservation3) + end + + it "has an array that keeps track of the available rooms" do + + hopefully_an_array = @date_store[Date.parse("2020/05/04").iso8601].all_available_rooms + + expect hopefully_an_array.must_be_instance_of Array + end +end \ No newline at end of file diff --git a/test/calendar_spec.rb b/test/calendar_spec.rb new file mode 100644 index 000000000..6587847ba --- /dev/null +++ b/test/calendar_spec.rb @@ -0,0 +1,82 @@ +require_relative 'test_helper' + + +describe "Manages calendar and it's various duties" do + before do + @reservation1 = Reservation.new("2020/05/04", "2020/05/07") + @reservation2 = Reservation.new("2020/05/07", "2020/05/09") + @reservation3 = Reservation.new("2020/05/06", "2020/05/11") + + @calendar = Calendar.new + @calendar.add_to_calendar(@reservation1) + @calendar.add_to_calendar(@reservation2) + @calendar.add_to_calendar(@reservation3) + + + # puts "\n" + # puts @calendar.date_store + # puts "\n" + + end + + it "gives correct cost of requested reservation" do + reservation1 = @reservation1.details + id = reservation1[:id] + cost = @calendar.total_cost_reservation(id) + + expect (reservation1[:cost]).must_equal cost + end + + it "lists all reservations for specific date" do + reservation1 = @reservation1.details + expected_outcome = [reservation1] + actual_outcome = @calendar.reservations_on_date("2020/05/04") + assert_equal(actual_outcome, expected_outcome) + end + + it "accesses list of available rooms on a given date" do + expected_outcome = [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20] + actual_outcome = @calendar.rooms_on_date("2020/05/04") + assert_equal(actual_outcome, expected_outcome) + end + + it "returns an array of all 1-20 rooms if there are no reservations on a given date" do + expected_outcome = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20] + actual_outcome = @calendar.rooms_on_date("2020/05/02") + assert_equal(actual_outcome, expected_outcome) + end + + it "returns an array of the open rooms during a date range" do + @calendar.list_available_rooms_entire_stay(@reservation2) + expect available_rooms.must_be_instance_of Array + end + + # it "raises NoRoomError if all rooms on a given date are booked" do + + # raise NoRoomError + # end + + it 'accesses correct reservation when searching by id' do + reservation1 = @reservation1.details + id = reservation1[:id] + + expected_outcome = reservation1 + actual_outcome = @calendar.find_by_id(id) + assert_equal(actual_outcome, expected_outcome) + end + + it 'creates a new reservation' do + expected_outcome = Reservation.new("2020/05/04", "2020/05/07") + actual_outcome = expected_outcome + + assert_equal(actual_outcome, expected_outcome) + end + + it "returns true/false if given room is available on a given date" do + yesorno = @calendar.is_available?(5, "2020/05/07") + + expect yesorno.must_equal true + end + +end + diff --git a/test/reservation_spec.rb b/test/reservation_spec.rb new file mode 100644 index 000000000..e69de29bb diff --git a/test/room_spec.rb b/test/room_spec.rb new file mode 100644 index 000000000..e69de29bb diff --git a/test/test_helper.rb b/test/test_helper.rb index c3a7695cf..80aa07bde 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -1,8 +1,11 @@ -# Add simplecov +require 'simplecov' require "minitest" require "minitest/autorun" require "minitest/reporters" Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new -# require_relative your lib files here! +require_relative '../lib/calendar' +require_relative '../lib/reservation' +require_relative '../lib/room' +require_relative '../lib/calendar_date'