-
Notifications
You must be signed in to change notification settings - Fork 49
Leaves - Yitgop #37
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Leaves - Yitgop #37
Changes from 7 commits
4dd4933
429ef08
5839fca
99065a9
d17fa77
0f46617
cc01dc7
e1ed08d
26d497c
027fb07
e3901ee
3a39c68
83b0002
03b0557
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,128 @@ | ||
| require "date" | ||
|
|
||
| require_relative "room" | ||
| require_relative "reservation" | ||
| require_relative "block" | ||
|
|
||
| module Hotel | ||
| class Booker | ||
| attr_reader :inventory, :rooms, :reservations | ||
|
|
||
| def initialize(inventory:) | ||
| @inventory = inventory | ||
| @rooms = [] | ||
| @reservations = [] | ||
|
|
||
| if @inventory.class != Integer | ||
| raise ArgumentError, "inventory has to be an integer" | ||
| elsif @inventory < 1 | ||
| raise ArgumentError, "inventory can't be less than 1" | ||
| else | ||
| n = 1 | ||
| @inventory.times do | ||
| @rooms << Hotel::Room.new(number: n) | ||
| n += 1 | ||
| end | ||
|
|
||
| end | ||
|
|
||
| end | ||
|
|
||
| def all_rooms | ||
|
||
| return @rooms | ||
| end | ||
|
|
||
| def available_rooms(check_in:, check_out:) | ||
| start_date = Date.parse(check_in.to_s) | ||
| end_date = Date.parse(check_out.to_s) | ||
| available_rooms = [] | ||
|
|
||
| availability = 0 | ||
| @rooms.each do |room| | ||
| if room.bookings == nil | ||
| available_rooms << room | ||
|
|
||
| else | ||
| no_overlap = 0 | ||
| room.bookings.each do |booking| | ||
| if end_date <= booking.check_in || start_date >= booking.check_out | ||
| no_overlap += 1 | ||
| end | ||
| end | ||
|
|
||
| if no_overlap == room.bookings.length | ||
| available_rooms << room | ||
| availability += 1 | ||
| end | ||
| end | ||
| end | ||
|
|
||
| if availability == 0 | ||
| raise ArgumentError, "There are no available room" | ||
| else | ||
| return available_rooms | ||
| end | ||
|
|
||
| end | ||
|
|
||
| def make_reservation(check_in:, check_out:) | ||
| start_date = Date.parse(check_in.to_s) | ||
| end_date = Date.parse(check_out.to_s) | ||
|
|
||
| @rooms.each do |room| | ||
|
|
||
| if room.bookings.length == 0 | ||
| new_reservation = Reservation.new(check_in: start_date, check_out: end_date, room: room) | ||
| room_bookings << new_reservation | ||
| return new_reservation | ||
|
|
||
| else | ||
| no_overlap = 0 | ||
| room.bookings.each do |booking| | ||
|
|
||
| if end_date <= booking.check_in || start_date >= booking.check_out | ||
| no_overlap += 1 | ||
| end | ||
|
|
||
| if no_overlap == room.bookings.length | ||
| new_reservation = Reservation.new(check_in: start_date, check_out: end_date, room: room) | ||
| room.bookings << new_reservation | ||
| return new_reservation | ||
| else | ||
| raise ArgumentError, "There are no available rooms for this date range" | ||
| end | ||
|
|
||
| end | ||
|
|
||
| end | ||
|
|
||
| end | ||
|
|
||
| end | ||
|
|
||
| def search_reservation(date:) | ||
| search_date = Date.parse(date.to_s) | ||
| search_result = [] | ||
|
|
||
| @rooms.each do |room| | ||
|
|
||
| if room.bookings.length != 0 | ||
| room.bookings.each do |booking| | ||
|
|
||
| if search_date.between?(booking.check_in, booking.check_out) == true | ||
| search_result << booking | ||
| end | ||
|
|
||
| end | ||
|
|
||
| end | ||
|
|
||
| end | ||
|
|
||
| return search_result | ||
|
|
||
| end | ||
|
|
||
| end | ||
|
|
||
| end | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| require "date" | ||
|
|
||
| require_relative "room" | ||
| require_relative "booker" | ||
| require_relative "block" | ||
|
|
||
| module Hotel | ||
| class Reservation | ||
| attr_reader :check_in, :check_out, :total_cost, :room | ||
|
|
||
| def initialize(check_in:, check_out:, room: nil) | ||
| @check_in = Date.parse(check_in.to_s) | ||
| @check_out = Date.parse(check_out.to_s) | ||
| @total_cost = (@check_out - @check_in).to_i * 200 | ||
| @room = room || nil | ||
|
|
||
| if @check_out <= @check_in | ||
| raise ArgumentError, "End time can't be earlier than or equal to start time" | ||
| end | ||
|
|
||
| end | ||
|
|
||
| def total_cost | ||
| return @total_cost | ||
| end | ||
|
|
||
| end | ||
|
|
||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| require "date" | ||
|
|
||
| require_relative "reservation" | ||
| require_relative "booker" | ||
| require_relative "block" | ||
|
|
||
| module Hotel | ||
| class Room | ||
| attr_reader :number, :bookings | ||
|
|
||
| def initialize(number:, booking: nil) | ||
| @number = number | ||
| @bookings = booking || [] | ||
|
|
||
| if @number.class != Integer | ||
| raise ArgumentError, "room number must be an interger" | ||
| elsif @number < 1 | ||
| raise ArgumentError, "room number can not be less than 1" | ||
| end | ||
|
|
||
| end | ||
|
|
||
| # would create a add_room method if the hotel would expand rooms in the future | ||
|
|
||
| end | ||
|
|
||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| Simplify "make_reservation" method for Booker by utilizing its "available_room" method | ||
| Research Date gem ~ current code requires user input in string for "check_in" & "check_out" | ||
| Update all syntax from "instance_variable_get" to "." in all files | ||
| Update test files to reach 100% code coverage | ||
| Finish Wave_3 (& additional enhancement as time allows) | ||
| Remove "@reservations" from Booker if no longer useful/necessary for the design | ||
| Keep practicing and get really comfortable with VS code debugging tool, guard, and SimpleCov |
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,165 @@ | ||||||||
| require_relative "test_helper" | ||||||||
|
|
||||||||
| describe "Booker class" do | ||||||||
|
|
||||||||
| describe "Booker initialization" do | ||||||||
|
|
||||||||
| it "throws argument erros for invalid inventory input" do | ||||||||
| expect{Hotel::Booker.new(inventory: '20')}.must_raise ArgumentError | ||||||||
| expect{Hotel::Booker.new(inventory: 0)}.must_raise ArgumentError | ||||||||
| end | ||||||||
|
|
||||||||
| before do | ||||||||
| @new_booker = Hotel::Booker.new(inventory: 20) | ||||||||
| end | ||||||||
|
|
||||||||
| it "is an instance of Booker" do | ||||||||
| expect(@new_booker).must_be_kind_of Hotel::Booker | ||||||||
| end | ||||||||
|
|
||||||||
| it "has an empty array for reservations" do | ||||||||
| expect(@new_booker.reservations).must_be_kind_of Array | ||||||||
| expect(@new_booker.reservations.length).must_equal 0 | ||||||||
| end | ||||||||
|
|
||||||||
| it "has an array of Room instances matching with the inventory number" do | ||||||||
| expect(@new_booker.rooms).must_be_kind_of Array | ||||||||
| expect(@new_booker.rooms.first).must_be_kind_of Hotel::Room | ||||||||
| expect(@new_booker.rooms.last).must_be_kind_of Hotel::Room | ||||||||
| expect(@new_booker.rooms.length).must_equal 20 | ||||||||
| end | ||||||||
|
|
||||||||
| end | ||||||||
|
|
||||||||
| describe "all_rooms method" do | ||||||||
|
||||||||
| it "must return an array of Room instances matching with the inventory number" do | ||||||||
| expect(Hotel::Booker.new(inventory: 33).all_rooms).must_be_kind_of Array | ||||||||
| expect(Hotel::Booker.new(inventory: 33).all_rooms.first).must_be_kind_of Hotel::Room | ||||||||
| expect(Hotel::Booker.new(inventory: 33).all_rooms.last).must_be_kind_of Hotel:: Room | ||||||||
| expect(Hotel::Booker.new(inventory: 33).all_rooms.length).must_equal 33 | ||||||||
| end | ||||||||
|
|
||||||||
| end | ||||||||
|
|
||||||||
| describe "available_rooms method" do | ||||||||
| before do | ||||||||
| @new_booker = Hotel::Booker.new(inventory: 2) | ||||||||
| end | ||||||||
|
|
||||||||
| it "throws ArgumentError for invalid check_in and check_out dates" do | ||||||||
| expect{ @new_booker.make_reservation(check_in: "2019-09-01", check_out: "2019-09-01") }.must_raise ArgumentError | ||||||||
| expect{ @new_booker.make_reservation(check_in: "2019-09-02", check_out: "2019-09-01") }.must_raise ArgumentError | ||||||||
| end | ||||||||
|
|
||||||||
| it "throws ArgumentError when there is no available rooms during the given date range" do | ||||||||
| rooms = @new_booker.rooms | ||||||||
| rooms[0].bookings << Hotel::Reservation.new(check_in: "2019-09-01", check_out: "2019-09-04", room: 1) | ||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider storing the dates in variables so it is clear what you are testing.
Suggested change
|
||||||||
| rooms[1].bookings << Hotel::Reservation.new(check_in: "2019-09-02", check_out: "2019-09-05", room: 2) | ||||||||
|
|
||||||||
| expect{ @new_booker.make_reservation(check_in: "2019-09-02", check_out: "2019-09-04") }.must_raise ArgumentError | ||||||||
| expect{ @new_booker.make_reservation(check_in: "2019-09-01", check_out: "2019-09-05") }.must_raise ArgumentError | ||||||||
| expect{ @new_booker.make_reservation(check_in: "2019-08-30", check_out: "2019-09-03") }.must_raise ArgumentError | ||||||||
| expect{ @new_booker.make_reservation(check_in: "2019-09-03", check_out: "2019-09-07") }.must_raise ArgumentError | ||||||||
| end | ||||||||
|
|
||||||||
| it "will add room with no bookings to the avaliable rooms search result" do | ||||||||
| search = @new_booker.available_rooms(check_in: "2019-09-08", check_out: "2019-09-09") | ||||||||
| expect(search.length).must_equal 2 | ||||||||
| end | ||||||||
|
|
||||||||
| it "returns an array of all Room instances avaliable during the given date range" do | ||||||||
| rooms = @new_booker.rooms | ||||||||
| rooms[0].bookings << Hotel::Reservation.new(check_in: "2019-09-01", check_out: "2019-09-04", room: 1) | ||||||||
| rooms[1].bookings << Hotel::Reservation.new(check_in: "2019-09-02", check_out: "2019-09-05", room: 2) | ||||||||
|
|
||||||||
| search_1 = @new_booker.available_rooms(check_in: "2019-09-04", check_out: "2019-09-07") | ||||||||
| search_2 = @new_booker.available_rooms(check_in: "2019-08-30", check_out: "2019-09-01") | ||||||||
|
|
||||||||
| expect(search_1).must_be_kind_of Array | ||||||||
| expect(search_2).must_be_kind_of Array | ||||||||
|
|
||||||||
| expect(search_1.length).must_equal 1 | ||||||||
| expect(search_2.length).must_equal 2 | ||||||||
|
|
||||||||
| expect(search_1[0]).must_be_kind_of Hotel::Room | ||||||||
| expect(search_2.first).must_be_kind_of Hotel::Room | ||||||||
| expect(search_2.last).must_be_kind_of Hotel::Room | ||||||||
| end | ||||||||
|
|
||||||||
| end | ||||||||
|
|
||||||||
| describe "make_reservation method" do | ||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice, comprehensive tests. |
||||||||
| before do | ||||||||
| @new_booker = Hotel::Booker.new(inventory: 2) | ||||||||
| end | ||||||||
|
|
||||||||
| it "throws ArgumentError for invalid check_in and check_out dates" do | ||||||||
| expect{ @new_booker.make_reservation(check_in: "2019-09-01", check_out: "2019-09-01") }.must_raise ArgumentError | ||||||||
| expect{ @new_booker.make_reservation(check_in: "2019-09-02", check_out: "2019-09-01") }.must_raise ArgumentError | ||||||||
| end | ||||||||
|
|
||||||||
| it "throws ArgumentError when there is no available rooms during the given date range" do | ||||||||
| rooms = @new_booker.rooms | ||||||||
| rooms[0].bookings << Hotel::Reservation.new(check_in: "2019-09-01", check_out: "2019-09-04", room: 1) | ||||||||
| rooms[1].bookings << Hotel::Reservation.new(check_in: "2019-09-02", check_out: "2019-09-05", room: 2) | ||||||||
|
|
||||||||
| expect{ @new_booker.make_reservation(check_in: "2019-09-02", check_out: "2019-09-04") }.must_raise ArgumentError | ||||||||
| expect{ @new_booker.make_reservation(check_in: "2019-09-01", check_out: "2019-09-05") }.must_raise ArgumentError | ||||||||
| expect{ @new_booker.make_reservation(check_in: "2019-08-30", check_out: "2019-09-03") }.must_raise ArgumentError | ||||||||
| expect{ @new_booker.make_reservation(check_in: "2019-09-03", check_out: "2019-09-07") }.must_raise ArgumentError | ||||||||
| end | ||||||||
|
|
||||||||
| it "creats a Resveration instance with the correct Room instance(s)" do | ||||||||
| rooms = @new_booker.rooms | ||||||||
| rooms[0].bookings << Hotel::Reservation.new(check_in: "2019-09-01", check_out: "2019-09-04", room: 1) | ||||||||
| rooms[1].bookings << Hotel::Reservation.new(check_in: "2019-09-02", check_out: "2019-09-05", room: 2) | ||||||||
| new_reservation = @new_booker.make_reservation(check_in: "2019-09-04", check_out: "2019-09-07") | ||||||||
| reserved_room = new_reservation.room | ||||||||
| updated_room_bookings = reserved_room.bookings | ||||||||
|
|
||||||||
| expect(new_reservation).must_be_kind_of Hotel::Reservation | ||||||||
| expect(reserved_room.number).must_equal 1 | ||||||||
| expect(updated_room_bookings.length).must_equal 2 | ||||||||
|
|
||||||||
| end | ||||||||
|
|
||||||||
| end | ||||||||
|
|
||||||||
| describe "search_reservation method" do | ||||||||
| before do | ||||||||
| @new_booker = Hotel::Booker.new(inventory: 2) | ||||||||
| end | ||||||||
|
|
||||||||
| it "throws ArgumentError when there is no available rooms during the given date range" do | ||||||||
| rooms = @new_booker.rooms | ||||||||
| rooms[0].bookings << Hotel::Reservation.new(check_in: "2019-09-07", check_out: "2019-09-08", room: 1) | ||||||||
| rooms[1].bookings << Hotel::Reservation.new(check_in: "2019-09-08", check_out: "2019-09-09", room: 2) | ||||||||
|
|
||||||||
| expect{ @new_booker.make_reservation(check_in: "2019-09-02", check_out: "2019-09-08") }.must_raise ArgumentError | ||||||||
|
|
||||||||
| end | ||||||||
|
|
||||||||
| it "creates an array of all reservations on that date" do | ||||||||
| rooms = @new_booker.rooms | ||||||||
| rooms[0].bookings << Hotel::Reservation.new(check_in: "2019-10-20", check_out: "2019-10-25", room: 1) | ||||||||
| rooms[1].bookings << Hotel::Reservation.new(check_in: "2019-09-30", check_out: "2019-10-20", room: 2) | ||||||||
| result_1 = @new_booker.search_reservation(date: '2019-10-03') | ||||||||
| result_2 = @new_booker.search_reservation(date: '2019-10-20') | ||||||||
| result_3 = @new_booker.search_reservation(date: '2019-10-26') | ||||||||
|
|
||||||||
| expect(result_1).must_be_kind_of Array | ||||||||
| expect(result_2).must_be_kind_of Array | ||||||||
| expect(result_3).must_be_kind_of Array | ||||||||
|
|
||||||||
| expect(result_1.length).must_equal 1 | ||||||||
| expect(result_2.length).must_equal 2 | ||||||||
| expect(result_3.length).must_equal 0 | ||||||||
|
|
||||||||
| expect(result_1[0]).must_be_kind_of Hotel::Reservation | ||||||||
| expect(result_2[1]).must_be_kind_of Hotel::Reservation | ||||||||
| end | ||||||||
|
|
||||||||
| end | ||||||||
|
|
||||||||
| end | ||||||||
|
|
||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| { | ||
| "result": { | ||
| "covered_percent": 100.0 | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| { | ||
| "MiniTest": { | ||
| "coverage": { | ||
| }, | ||
| "timestamp": 1567911677 | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This error checking should go ahead of the assignment to @inventory