diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 000000000..5ebc6dbc4 Binary files /dev/null and b/.DS_Store differ diff --git a/.gitignbore b/.gitignbore new file mode 100644 index 000000000..e69de29bb 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/Hotel.rb b/lib/Hotel.rb new file mode 100644 index 000000000..1aae686d6 --- /dev/null +++ b/lib/Hotel.rb @@ -0,0 +1,61 @@ +require_relative "Reservation" + +class Hotel + attr_reader :reservations, :rooms + + def initialize + @reservations = [] + @rooms = (1..20).to_a + end + + def make_reservation(check_in:, check_out:, room: nil) + if room == nil + room = available_rooms(check_in: check_in, check_out: check_out).first + end + if available_rooms(check_in: check_in, check_out: check_out).include?(room) == false + raise ArgumentError, "that room is not available" + end + reservation = Reservation.new(check_in: check_in, check_out: check_out, room: room) + @reservations << reservation + end + + def list_rooms() + return @rooms + end + + def reservation_by_date(date) + raise ArgumentError, "must pass in a Date object" if date.instance_of?(Date) == false + res_by_date = @reservations.select do |x| + x.check_in <= date && date < x.check_out + end + end + + def available_rooms(check_in:, check_out:) + #why is it if I include check out above, it doesn't work below + dates = (check_in..(check_out - 1)).to_a + booked_rooms = [] + dates.each do |date| + reservation_by_date(date).each do |res| + booked_rooms << res.room + end + end + available_rooms = (@rooms - booked_rooms) + return available_rooms + end + + def reserve_available_room(check_in:, check_out:, room: nil) + available = available_rooms(check_in: check_in, check_out: check_out) + raise ArgumentError, "no available rooms" if available.length == 0 + if room == nil + make_reservation(check_in: check_in, check_out: check_out, room: available.first) + else + make_reservation(check_in: check_in, check_out: check_out, room: room) + end + end + + def create_hotel_block(check_in:, check_out:, block_size:, block_name:, block_discount: nil) + raise ArgumentError, "block cannot be larger than 5" if block_size > 5 + available = available_rooms(check_in: check_in, check_out: check_out) + raise ArgumentError, "there are not enough available rooms to reserve the block" if available.length < block_size + end +end diff --git a/lib/Reservation.rb b/lib/Reservation.rb new file mode 100644 index 000000000..d81d08a8b --- /dev/null +++ b/lib/Reservation.rb @@ -0,0 +1,26 @@ +require "date" + +class Reservation + attr_reader :check_in, :check_out, :room, :block + attr_accessor :block_room_status + + COST = 200 + #discount actually means after discount, for example. 20% off would be .8 (100-20) + + def initialize(check_in:, check_out:, room: nil, block: nil, block_room_status: :AVAILABLE, discount: 1.0) + raise ArgumentError, "must pass in a Date object" if check_in.instance_of?(Date) == false + @check_in = check_in + @check_out = check_out + raise ArgumentError, "invalid date range, check out must be after check in" if @check_out <= @check_in + @room = room + @block = block + status_options = [:AVAILABLE, :UNAVAILABLE] + raise ArgumentError, "invalid status" if status_options.include?(block_room_status) == false + @block_room_status = block_room_status + @discount = discount + end + + def cost + return (@check_out - @check_in).to_i * (200 * @discount) + end +end diff --git a/refactors.txt b/refactors.txt new file mode 100644 index 000000000..03f1bca8c --- /dev/null +++ b/refactors.txt @@ -0,0 +1 @@ +I'd like to get wave 3 working. Especially clean up reservations and play with an idea I have about having a reservations class, and also a block class. diff --git a/spec/hotel_spec.rb b/spec/hotel_spec.rb new file mode 100644 index 000000000..8355a0b34 --- /dev/null +++ b/spec/hotel_spec.rb @@ -0,0 +1,95 @@ +require_relative "spec_helper" + +describe "Hotel class" do + let (:hotel) do + Hotel.new + end + + describe "initialize" do + it "Creates an instance of Hotel" do + expect(hotel).must_be_instance_of Hotel + end + end + + describe "creating a reservation" do + it "creates an object instance of Reservation" do + hotel.make_reservation(check_in: Date.new(2005, 2, 2), check_out: Date.new(2005, 2, 4)) + expect(hotel.reservations[0]).must_be_kind_of Reservation + expect(hotel.reservations).must_be_kind_of Array + end + + it "returns a list of rooms" do + expect(hotel.list_rooms().length).must_equal 20 + end + + it "it returns reservations by date" do + hotel.make_reservation(check_in: Date.new(2005, 2, 2), check_out: Date.new(2005, 2, 4)) + hotel.make_reservation(check_in: Date.new(2005, 2, 5), check_out: Date.new(2005, 2, 7)) + hotel.make_reservation(check_in: Date.new(2005, 2, 2), check_out: Date.new(2005, 2, 4)) + expect((hotel.reservation_by_date(Date.new(2005, 2, 3))).length).must_equal 2 + end + + it "throws argument error if not passed a Date" do + expect do + hotel.make_reservation("poop") + end.must_raise ArgumentError + end + + it "throws an argument error if you book the same room for the same time" do + hotel.make_reservation(check_in: Date.new(2005, 2, 5), check_out: Date.new(2005, 2, 7), room: 2) + expect do + hotel.make_reservation(check_in: Date.new(2005, 2, 5), check_out: Date.new(2005, 2, 7), room: 2) + end.must_raise ArgumentError + end + + it "lets you book a reservation on the same day as a checkout" do + hotel.make_reservation(check_in: Date.new(2005, 2, 5), check_out: Date.new(2005, 2, 7), room: 2) + hotel.make_reservation(check_in: Date.new(2005, 2, 7), check_out: Date.new(2005, 2, 9), room: 2) + expect(hotel.reservations.length).must_equal 2 + end + + it "it wont let you book a reservation on the same day before a checkout" do + hotel.make_reservation(check_in: Date.new(2005, 2, 5), check_out: Date.new(2005, 2, 7), room: 2) + + expect do + hotel.make_reservation(check_in: Date.new(2005, 2), check_out: Date.new(2005, 2, 9), room: 2) + end.must_raise ArgumentError + end + end + + describe "reserve/available room method" do + it "returns an array of available rooms" do + 5.times do + hotel.reserve_available_room(check_in: Date.new(2005, 2, 3), check_out: Date.new(2005, 2, 9)) + end + expect(hotel.available_rooms(check_in: Date.new(2005, 2, 3), check_out: Date.new(2005, 2, 9)).length).must_equal 15 + end + + it "throws an argument error if there is no available room" do + 20.times do + hotel.reserve_available_room(check_in: Date.new(2005, 2, 6), check_out: Date.new(2005, 2, 8)) + end + + expect do + hotel.reserve_available_room(check_in: Date.new(2005, 2, 6), check_out: Date.new(2005, 2, 8)) + end.must_raise ArgumentError + end + + describe "it tests the block reservations" do + it "throws an argument error if block size is larger than 5" do + expect do + hotel.create_hotel_block(check_in: Date.new(2005, 2, 6), check_out: Date.new(2005, 2, 8), block_size: 6) + end.must_raise ArgumentError + end + + it "throws an argument error if there aren't enough available rooms for block" do + 16.times do + hotel.reserve_available_room(check_in: Date.new(2005, 2, 3), check_out: Date.new(2005, 2, 9)) + end + expect do + hotel.create_hotel_block(check_in: Date.new(2005, 2, 3), check_out: Date.new(2005, 2, 9), block_size: 5, block_name: "ecc") + end.must_raise ArgumentError + end + end + end +end diff --git a/spec/reservation_spec.rb b/spec/reservation_spec.rb new file mode 100644 index 000000000..8c8f826be --- /dev/null +++ b/spec/reservation_spec.rb @@ -0,0 +1,32 @@ +require_relative "spec_helper" + +describe "Reservation" do + before do + @res = Reservation.new(check_in: Date.new(2005, 2, 2), check_out: Date.new(2005, 2, 4)) + end + + it "is an instance of Reservation" do + expect(@res).must_be_kind_of Reservation + end + + it "calculates the right cost" do + expect(@res.cost).must_equal 400 + end + + it "throw exception with invalid date range" do + expect do + Reservation.new(check_in: Date.new(2005, 2, 2), check_out: Date.new(2005, 2, 2)) + end.must_raise ArgumentError + end + + it "throws argument error if not passed a Date" do + expect do + Reservation.new("poo", "poo") + end.must_raise ArgumentError + end + + it "properly returns the right discount price" do + res = Reservation.new(check_in: Date.new(2005, 2, 2), check_out: Date.new(2005, 2, 4), room: 5, block: "block", block_room_status: :AVAILABLE, discount: 0.8) + expect(res.cost).must_equal 320.0 + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 218b49458..898f26502 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,8 +1,12 @@ -# Add simplecov -require 'minitest' -require 'minitest/autorun' -require 'minitest/reporters' +require "simplecov" +SimpleCov.start +require "minitest" +require "minitest/autorun" +require "minitest/reporters" Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new # Require_relative your lib files here! +require_relative "../lib/Reservation" +require_relative "../lib/Hotel" +require_relative "../lib/Rooms"