-
Notifications
You must be signed in to change notification settings - Fork 40
Space - Nora #20
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?
Space - Nora #20
Changes from all commits
70dcbcc
8b3e435
c55bccd
b6a5f71
d560747
a4b07d0
e4e57f6
03aebc0
6854cef
252baa3
e0ae660
c51a21f
2fd31ba
31a03e0
3368bbb
43dfd5f
82efcb2
05ee43a
f8a8697
b3e818f
abf10d6
fefa070
7494369
1a692d1
533fa64
bcb9fd6
eaf2905
4609df7
4a0867d
9bb1251
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,35 @@ | ||||||||||||||
| module Hotel | ||||||||||||||
| class DateRange | ||||||||||||||
| attr_reader :start_date, :end_date | ||||||||||||||
| attr_accessor :dates | ||||||||||||||
|
|
||||||||||||||
| def initialize(start_date:, end_date:) | ||||||||||||||
| @start_date = start_date | ||||||||||||||
| @end_date = end_date | ||||||||||||||
| @dates = Array(@start_date .. @end_date) | ||||||||||||||
|
|
||||||||||||||
| # User: I want an exception raised when an invalid date range is provided, so that I can't make a reservation for an invalid date range | ||||||||||||||
| if @end_date < @start_date || @start_date == @end_date | ||||||||||||||
| raise ArgumentError.new("Your check-out date must be after your check-in.") | ||||||||||||||
|
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. It's helpful to include the bad arguments in your error messages:
Suggested change
|
||||||||||||||
| end | ||||||||||||||
| end | ||||||||||||||
|
|
||||||||||||||
| def overlap?(daterange_instance) | ||||||||||||||
| overlap = !(daterange_instance.start_date >= end_date || daterange_instance.end_date <= start_date) | ||||||||||||||
| return overlap | ||||||||||||||
|
Comment on lines
+18
to
+19
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. You don't have to assign this to a variable before you return it:
Suggested change
Also, you can simplify/clarify this using DeMorgan's Law and reversing the comparisons:
Suggested change
|
||||||||||||||
| end | ||||||||||||||
|
|
||||||||||||||
| def include?(date) | ||||||||||||||
| if date >= @start_date && date < @end_date | ||||||||||||||
| return true | ||||||||||||||
| else | ||||||||||||||
| return false | ||||||||||||||
| end | ||||||||||||||
|
Comment on lines
+23
to
+27
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. You can directly return the condition here:
Suggested change
|
||||||||||||||
| end | ||||||||||||||
|
|
||||||||||||||
| # calculate the number of nights for a reservation (end date is not a night) | ||||||||||||||
| def nights | ||||||||||||||
| return @dates.length - 1 | ||||||||||||||
| end | ||||||||||||||
| end | ||||||||||||||
| end | ||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,105 @@ | ||||||||||||||||||||||||||||||||||||||||||
| require_relative 'reservation' | ||||||||||||||||||||||||||||||||||||||||||
| require_relative 'date_range' | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| module Hotel | ||||||||||||||||||||||||||||||||||||||||||
| class FrontDesk | ||||||||||||||||||||||||||||||||||||||||||
| attr_accessor :reservations, :rooms, :calendar | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| def initialize | ||||||||||||||||||||||||||||||||||||||||||
| @rooms = (1..20).map { |i| i } | ||||||||||||||||||||||||||||||||||||||||||
|
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. It looks like you're just using
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||
| @reservations = [] | ||||||||||||||||||||||||||||||||||||||||||
| @calendar = {} | ||||||||||||||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| def populate_calendar(reservation) | ||||||||||||||||||||||||||||||||||||||||||
| temp = reservation.date_range.dates | ||||||||||||||||||||||||||||||||||||||||||
| temp.pop | ||||||||||||||||||||||||||||||||||||||||||
| temp.each do |date| | ||||||||||||||||||||||||||||||||||||||||||
| if !@calendar.key?(date) | ||||||||||||||||||||||||||||||||||||||||||
| @calendar[date] =[] | ||||||||||||||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||||||||||||||
| @calendar[date] << reservation | ||||||||||||||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||||||||||||||
| return @calendar | ||||||||||||||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+14
to
+24
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. I think you probably meant to copy the array here. This doesn't do that so you wind up changing dates. Cleaner would be to ask for a range that excludes the end of
Suggested change
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. Also, since this method doesn't directly address a user story I'd recommend making it private. |
||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| # User: I can access the list of all of the rooms in the hotel | ||||||||||||||||||||||||||||||||||||||||||
| def list_rooms | ||||||||||||||||||||||||||||||||||||||||||
| return @rooms | ||||||||||||||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+27
to
+29
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. You don't need this and the |
||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| # User: I can make a reservation of a room for a given date range, and that room will not be part of any other reservation overlapping that date range | ||||||||||||||||||||||||||||||||||||||||||
| def reserve_room(requested_dates) | ||||||||||||||||||||||||||||||||||||||||||
| available_rooms = available_rooms(requested_dates) | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| book_room = available_rooms.first | ||||||||||||||||||||||||||||||||||||||||||
| new_reservation = Hotel::Reservation.new( | ||||||||||||||||||||||||||||||||||||||||||
| room: book_room, | ||||||||||||||||||||||||||||||||||||||||||
| date_range: requested_dates, | ||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||
| @reservations.push(new_reservation) | ||||||||||||||||||||||||||||||||||||||||||
| populate_calendar(new_reservation) | ||||||||||||||||||||||||||||||||||||||||||
| return new_reservation | ||||||||||||||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| # User: I can access the list of reservations for a specific date, so that I can track reservations by date | ||||||||||||||||||||||||||||||||||||||||||
| def date_reservations(date) | ||||||||||||||||||||||||||||||||||||||||||
| date_resv = @calendar[date] | ||||||||||||||||||||||||||||||||||||||||||
| return date_resv | ||||||||||||||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| # User: I access the list of reservations for a specified room and a given date range | ||||||||||||||||||||||||||||||||||||||||||
| # I split this user story into a handful of separate methods to perform different parts of the request | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| # returns an array of reservations for requested dates | ||||||||||||||||||||||||||||||||||||||||||
| def range_reservations(requested_dates) | ||||||||||||||||||||||||||||||||||||||||||
| range_resv = [] | ||||||||||||||||||||||||||||||||||||||||||
| requested_dates.dates.each do |date| | ||||||||||||||||||||||||||||||||||||||||||
| if @calendar.key?(date) | ||||||||||||||||||||||||||||||||||||||||||
| range_resv.push(*@calendar[date]) | ||||||||||||||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||||||||||||||
| range_resv = range_resv.uniq | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| return range_resv | ||||||||||||||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+55
to
+65
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. You can clean this up using
Suggested change
(Since it's kind of obscure: |
||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| # search an array of reservations and return only the reservations for the specified room | ||||||||||||||||||||||||||||||||||||||||||
| def find_room_res(room_num, range_resv) | ||||||||||||||||||||||||||||||||||||||||||
| room_res = [] | ||||||||||||||||||||||||||||||||||||||||||
| range_resv.each do |res| | ||||||||||||||||||||||||||||||||||||||||||
| if res.room == room_num | ||||||||||||||||||||||||||||||||||||||||||
| room_res.push(res) | ||||||||||||||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||||||||||||||
| room_res = room_res.uniq | ||||||||||||||||||||||||||||||||||||||||||
| return room_res | ||||||||||||||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| # User: I can view a list of rooms that are not reserved for a given date range, so that I can see all available rooms for that day | ||||||||||||||||||||||||||||||||||||||||||
| def available_rooms(requested_dates) | ||||||||||||||||||||||||||||||||||||||||||
| occupied_rooms = [] | ||||||||||||||||||||||||||||||||||||||||||
| select_res = range_reservations(requested_dates) | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| select_res.each do |reservation| | ||||||||||||||||||||||||||||||||||||||||||
| occupied_rooms << reservation.room | ||||||||||||||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| empty_rooms = [] | ||||||||||||||||||||||||||||||||||||||||||
| @rooms.each do |room| | ||||||||||||||||||||||||||||||||||||||||||
| unless occupied_rooms.include?(room) | ||||||||||||||||||||||||||||||||||||||||||
| empty_rooms << room | ||||||||||||||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||||||||||||||
| empty_rooms = empty_rooms.uniq | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| # User: I want an exception raised if I try to reserve a room during a date range when all rooms are reserved, so that I cannot make two reservations for the same room that overlap by date | ||||||||||||||||||||||||||||||||||||||||||
| if empty_rooms.length > 0 | ||||||||||||||||||||||||||||||||||||||||||
| return empty_rooms | ||||||||||||||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||||||||||||||
| raise ArgumentError.new("Sorry, there are no rooms available. Please try other dates.") | ||||||||||||||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| require_relative "date_range" | ||
|
|
||
| module Hotel | ||
| class Reservation | ||
| attr_reader :room, :date_range | ||
|
|
||
| def initialize(date_range:, room: nil) | ||
| @room = room | ||
| @date_range = date_range | ||
|
|
||
| end | ||
|
|
||
| # User: I can get the total cost for a given reservation | ||
| def cost | ||
| room_rate = 200 | ||
| cost = @date_range.nights * room_rate | ||
| return cost | ||
| end | ||
| end | ||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| TO DO: | ||
|
|
||
| Front Desk: | ||
|
|
||
| date_reservations | ||
| * Add raise argument error if date is not a date | ||
| * Add raise argument error if there are no reservations for the date | ||
|
|
||
| range_reservations | ||
| * Add raise argument error if date range is not a date range | ||
| * Add raise argument error if there are no reservations for the date range | ||
|
|
||
| available_rooms | ||
| * argument error if no rooms available isn't working in test | ||
|
|
||
| Front Desk Test: | ||
|
|
||
| available_rooms | ||
| * argument error if no rooms available isn't working in test | ||
|
|
||
| reserve_room | ||
| * add more nominal and edge tests | ||
|
|
||
| date_reservations | ||
| * add more nominal and edge tests | ||
|
|
||
| range_reservations | ||
| * add more nominal and edge tests | ||
|
|
||
| find_room_res | ||
| * add more nominal and edge tests | ||
|
|
||
| available_rooms | ||
| * raise argument error test not working - currently skipped | ||
|
|
||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,162 @@ | ||
| require_relative "test_helper" | ||
|
|
||
|
|
||
| describe Hotel::DateRange do | ||
| before do | ||
| @start_date = Date.new(2021, 01, 01) | ||
| @end_date = Date.new(2021, 01, 03) | ||
| @start_date2 = Date.new(2021, 01, 01) | ||
| @end_date2 = Date.new(2021, 01, 02) | ||
| @range_inst = Hotel::DateRange.new(start_date: @start_date, end_date: @end_date) | ||
| @range_inst2 = Hotel::DateRange.new(start_date: @start_date2, end_date: @end_date2) | ||
| end | ||
|
|
||
| describe "constructor" do | ||
| it "is an instance of DateRange" do | ||
| expect(@range_inst).must_be_kind_of Hotel::DateRange | ||
| end | ||
|
|
||
| it "start_date is a Date" do | ||
| expect(@range_inst.start_date).must_be_kind_of Date | ||
| end | ||
|
|
||
| it "end_date is a Date" do | ||
| expect(@range_inst.end_date).must_be_kind_of Date | ||
| end | ||
|
|
||
| it "dates is an array" do | ||
| expect(@range_inst.dates).must_be_kind_of Array | ||
| end | ||
|
|
||
| it "can be initialized with two dates" do | ||
| expect(@range_inst.start_date).must_equal @start_date | ||
| expect(@range_inst.end_date).must_equal @end_date | ||
| end | ||
|
|
||
| it "raises an error if the end date is before the start date" do | ||
| expect { Hotel::DateRange.new( | ||
| start_date: Date.new(2021, 01, 01), | ||
| end_date: Date.new(2020, 12, 31) | ||
| ) }.must_raise ArgumentError | ||
| end | ||
|
|
||
| it "raises an error if the end date is the same as the start date" do | ||
| expect { Hotel::DateRange.new( | ||
| start_date: Date.new(2021, 01, 01), | ||
| end_date: Date.new(2021, 01, 01) | ||
| ) }.must_raise ArgumentError | ||
| end | ||
| end | ||
|
|
||
| describe "overlap?" do | ||
| it "returns true for the same range" do | ||
| start_date = Date.new(2021, 01, 01) | ||
| end_date = Date.new(2021, 01, 03) | ||
| test_range = Hotel::DateRange.new( | ||
| start_date: start_date, | ||
| end_date: end_date | ||
| ) | ||
|
|
||
| expect(@range_inst.overlap?(test_range)).must_equal true | ||
| end | ||
|
|
||
| it "returns true for a contained range" do | ||
| test_range = Hotel::DateRange.new( | ||
| start_date: Date.new(2021, 01, 01), | ||
| end_date: Date.new(2021, 01, 02) | ||
| ) | ||
|
|
||
| expect(@range_inst.overlap?(test_range)).must_equal true | ||
| end | ||
|
|
||
| it "returns true for a range that overlaps in front" do | ||
| test_range = Hotel::DateRange.new( | ||
| start_date: Date.new(2020, 12, 01), | ||
| end_date: Date.new(2021, 01, 02) | ||
| ) | ||
|
|
||
| expect(@range_inst.overlap?(test_range)).must_equal true | ||
| end | ||
|
|
||
| it "returns true for a range that overlaps in the back" do | ||
| test_range = Hotel::DateRange.new( | ||
| start_date: Date.new(2021, 1, 02), | ||
| end_date: Date.new(2021, 01, 06) | ||
| ) | ||
|
|
||
| expect(@range_inst.overlap?(test_range)).must_equal true | ||
| end | ||
|
|
||
| it "returns true for a containing range" do | ||
| test_range = Hotel::DateRange.new( | ||
| start_date: Date.new(2020, 12, 01), | ||
| end_date: Date.new(2021, 01, 12) | ||
| ) | ||
|
|
||
| expect(@range_inst.overlap?(test_range)).must_equal true | ||
| end | ||
|
|
||
| it "returns false for a range starting on the end_date date" do | ||
| test_range = Hotel::DateRange.new( | ||
| start_date: Date.new(2021, 01, 03), | ||
| end_date: Date.new(2021, 01, 06) | ||
| ) | ||
|
|
||
| expect(@range_inst.overlap?(test_range)).must_equal false | ||
| end | ||
|
|
||
| it "returns false for a range ending on the start_date date" do | ||
| test_range = Hotel::DateRange.new( | ||
| start_date: Date.new(2020, 12, 03), | ||
| end_date: Date.new(2021, 01, 01) | ||
| ) | ||
|
|
||
| expect(@range_inst.overlap?(test_range)).must_equal false | ||
| end | ||
|
|
||
| it "returns false for a range completely before" do | ||
| test_range = Hotel::DateRange.new( | ||
| start_date: Date.new(2020, 01, 03), | ||
| end_date: Date.new(2020, 01, 06) | ||
| ) | ||
|
|
||
| expect(@range_inst.overlap?(test_range)).must_equal false | ||
| end | ||
|
|
||
| it "returns false for a date completely after" do | ||
| test_range = Hotel::DateRange.new( | ||
| start_date: Date.new(2022, 01, 03), | ||
| end_date: Date.new(2022, 01, 06) | ||
| ) | ||
|
|
||
| expect(@range_inst.overlap?(test_range)).must_equal false | ||
| end | ||
| end | ||
|
|
||
| describe "include?" do | ||
| it "returns false if the date is clearly out" do | ||
| date = Date.new(2022,1,1) | ||
| expect(@range_inst.include?(date)).must_equal false | ||
| end | ||
|
|
||
| it "returns true for dates in the range" do | ||
| date = @start_date | ||
| expect(@range_inst.include?(date)).must_equal true | ||
| end | ||
|
|
||
| it "returns false for the end_date date" do | ||
| date = @end_date | ||
| expect(@range_inst.include?(date)).must_equal false | ||
| end | ||
| end | ||
|
|
||
| describe "nights" do | ||
| it "returns the correct number of nights" do | ||
| expect(@range_inst.nights).must_equal 2 | ||
| end | ||
|
|
||
| it "returns a number" do | ||
| expect(@range_inst.nights).must_be_kind_of Numeric | ||
| end | ||
| end | ||
| end |
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.
I like including the user stories as comments. 😄