forked from AdaGold/hotel
-
Notifications
You must be signed in to change notification settings - Fork 49
Branches - Eve #34
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
Open
tofuandeve
wants to merge
40
commits into
Ada-C12:master
Choose a base branch
from
tofuandeve:master
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Branches - Eve #34
Changes from 34 commits
Commits
Show all changes
40 commits
Select commit
Hold shift + click to select a range
0cb10a8
Verify Setup for Hotel project
tofuandeve 8687b6b
Add tests for DateRange class
tofuandeve 445808c
Implement DateRange class
tofuandeve c8068b1
Add HotelSystem class to Hotel module
tofuandeve c5d74d1
Add test for Reservation class
tofuandeve 8f2873a
Implement Reservation class
tofuandeve 534f647
Add @cost as a instance variable to Reservation class and update test…
tofuandeve 143997a
Add .gitignore to Hotel project
tofuandeve 995c898
Implement constructor and readers and add tests for HotelSystem class
tofuandeve 84c293a
Add SimpleCov to test_helper.rb
tofuandeve d906e6e
Implement make_reservation and reservation_ids methods for HotelSyste…
tofuandeve a5d964b
Fix naming for HotelSystem class
tofuandeve ad5ce90
Add create_unique_id to simplify make_reservation for HotelSystem class
tofuandeve 33a7bf1
Implement find_reservation_by_date for HotelSystem and add tests
tofuandeve c625670
Implement get_reservation_total_cost method for HotelSystem class and…
tofuandeve 193e1ad
Implement .overlap? method for DateRange class and add tests
tofuandeve e942693
Add tests for find_available_rooms method and update tests for make_r…
tofuandeve 108868e
Add find_available_rooms method and update make_reservation method fo…
tofuandeve 713ef49
Fix naming warning for get_reservation_total_cost method for HotelSys…
tofuandeve 933482f
Refactor HotelSystem class, update make_reservation method and tests
tofuandeve e0ee9ba
Implement HotelBlock class and add test
tofuandeve 247d181
Implement create_hotel_block for HotelSystem class and add tests
tofuandeve 9417e81
Update tests for Reservation class
tofuandeve cdef348
Implement available_rooms_by_hotel_block method for HotelSystem class…
tofuandeve 3dd3948
Implement reserve_room by room number for HotelSystem class and add t…
tofuandeve 6e88015
Update Hotel project to use keyword arguments
tofuandeve 46e5feb
Refactor Hotel project: remove all unnecessary variables out of Hotel…
tofuandeve 7f90d6d
Fix date data for test files for Hotel project
tofuandeve bed1710
Update tests: remove hardcode data
tofuandeve b1c89c0
Update test for hotel_block_test.rb
tofuandeve b9dd275
Update minor naming for hotel_system.rb and hotel_block.rb
tofuandeve 3304f14
Fix bug for find_available_rooms when hotel does not have 0 reservati…
tofuandeve 8c666d6
Update indentation for hotel project
tofuandeve 6c8317c
Add refactors.txt for hotel project
tofuandeve faaaa69
Create CLI for HotelSystem
tofuandeve 450c973
Update unit tests to be compatible with Minitest 6
tofuandeve 9e6b6a3
Update HotelSystem#make_reservation to raise appropriate exceptions
tofuandeve 650e780
Update Reservation class to take in room number as argument
tofuandeve c463113
Add CLI for user to interact with HotelSystem
tofuandeve 11119ac
Fix naming issue for hotel_system_test.rb
tofuandeve File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| require 'date' | ||
|
|
||
| module Hotel | ||
| class DateRange | ||
| attr_reader :start_date, :end_date | ||
|
|
||
| def initialize(input_start_date, input_end_date) | ||
| @start_date = input_start_date | ||
| @end_date = input_end_date | ||
| current_time = Date.today() | ||
|
|
||
| if (@start_date < current_time) || | ||
| (@end_date < current_time) || | ||
| (@end_date <= @start_date) | ||
| raise ArgumentError.new("Invalid date input: Check-in: #{input_start_date}, check_out: #{input_end_date}") | ||
| end | ||
| end | ||
|
|
||
| def overlap?(date_range) | ||
| return @start_date < date_range.end_date && @end_date > date_range.start_date | ||
| end | ||
| end | ||
| end | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| module Hotel | ||
| class HotelBlock | ||
| MAX_NUMBER_OF_ROOMS = 5 | ||
| @@current_id = 0 | ||
| attr_reader :id, :rooms, :discount_rate, :date_range | ||
|
|
||
| def initialize(rooms:, date_range:, discount_rate:) | ||
| @@current_id += 1 | ||
| @id = @@current_id | ||
| @rooms = rooms.dup | ||
| @date_range = date_range | ||
| @discount_rate = discount_rate | ||
|
|
||
| if rooms.length <= 0 || rooms.length > MAX_NUMBER_OF_ROOMS | ||
| raise ArgumentError.new("Can only add up to #{MAX_NUMBER_OF_ROOMS} rooms to a block!") | ||
| end | ||
| end | ||
| end | ||
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,137 @@ | ||
| module Hotel | ||
| class HotelSystem | ||
| RATE = 200.00 | ||
| NUMBER_OF_ROOMS = 20 | ||
| DISCOUNT = 0.20 | ||
|
|
||
| attr_reader :hotel_blocks, :rooms | ||
|
|
||
| def initialize(input_number_of_rooms = NUMBER_OF_ROOMS) | ||
| @room_reservation_data = Hash.new | ||
| input_number_of_rooms.times do |index| | ||
| @room_reservation_data[(index + 1)] = Array.new | ||
| end | ||
| @rooms = @room_reservation_data.keys | ||
| @hotel_blocks = Array.new | ||
| end | ||
|
|
||
| def number_of_rooms | ||
| return NUMBER_OF_ROOMS | ||
| end | ||
|
|
||
| def reservations | ||
| return @room_reservation_data.values.flatten | ||
| end | ||
|
|
||
| def make_reservation(start_date, end_date) | ||
| date_range = DateRange.new(start_date, end_date) | ||
| available_rooms = find_available_rooms(date_range) | ||
|
|
||
| if available_rooms.empty? | ||
| raise ArgumentError.new("No rooms available in this date range: #{start_date} - #{end_date}!") | ||
| end | ||
|
|
||
| reservation = create_reservation(date_range, RATE) | ||
| @room_reservation_data[available_rooms.first] << reservation | ||
| end | ||
|
|
||
| def find_reservation_by_date(date) | ||
| output = reservations.select do |reservation| | ||
| (reservation.date_range.start_date <= date) && | ||
| (date < reservation.date_range.end_date) | ||
| end | ||
| return output | ||
| end | ||
|
|
||
| def get_reservation_total_cost(reservation_id) | ||
| output_reservation = reservations.find { |reservation| reservation.id == reservation_id } | ||
| if !output_reservation | ||
| return nil | ||
| end | ||
| return output_reservation.cost | ||
| end | ||
|
|
||
| def find_available_rooms(date_range) | ||
| raise ArgumentError.new('Date range cannot be nil') if !date_range | ||
|
|
||
| blocked_rooms = find_overlapping_rooms_in_hotel_blocks(date_range) | ||
| available_rooms = @rooms.select do |number| | ||
| !has_overlapping(@room_reservation_data[number], date_range) && | ||
| !blocked_rooms.include?(number) | ||
|
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. This |
||
| end | ||
| return available_rooms | ||
| end | ||
|
|
||
| def create_hotel_block(rooms:, date_range:, discount: DISCOUNT) | ||
| if rooms == nil || | ||
| rooms.uniq != rooms || | ||
| rooms.any? { |room| [email protected]?(room)} | ||
|
|
||
| raise ArgumentError.new("Rooms cannot be duplicate or nil") | ||
| end | ||
|
|
||
| available_rooms = find_available_rooms(date_range) | ||
| unavailable_room = rooms.find { |room| !available_rooms.include?(room) } | ||
| if unavailable_room | ||
| raise ArgumentError.new( | ||
| "Room number #{unavailable_room} is not available on this date range!" | ||
| ) | ||
| end | ||
|
|
||
| hotel_block = create_block(rooms: rooms, date_range: date_range, discount: discount) | ||
| @hotel_blocks << hotel_block | ||
| end | ||
|
|
||
| def available_rooms_in_block(block_id) | ||
| hotel_block = @hotel_blocks.find do |block| | ||
| block.id == block_id | ||
| end | ||
|
|
||
| raise ArgumentError.new("Block #{block_id} doesn't exist") if !hotel_block | ||
| return hotel_block.rooms | ||
| end | ||
|
|
||
| def reserve_room(room_number) | ||
| hotel_block_index = find_block_index(room_number) | ||
| if !hotel_block_index | ||
| raise ArgumentError.new("Room #{room_number} doesn't belong to any block") | ||
| end | ||
|
|
||
| block = @hotel_blocks[hotel_block_index] | ||
|
|
||
| # add make new reservation for the input room | ||
| reservation = create_reservation(block.date_range, RATE * (1 - block.discount_rate)) | ||
| @room_reservation_data[room_number] << reservation | ||
|
|
||
| # remove room out of block's room list | ||
| @hotel_blocks[hotel_block_index].rooms.delete(room_number) | ||
| end | ||
|
|
||
| private | ||
| def has_overlapping(reservations, date_range) | ||
| return reservations.any? {|reservation| reservation.date_range.overlap?(date_range) } | ||
| end | ||
|
|
||
| def find_overlapping_rooms_in_hotel_blocks(date_range) | ||
| blocked_rooms = Array.new | ||
| @hotel_blocks.each do |block| | ||
| if block.date_range.overlap?(date_range) | ||
| blocked_rooms += block.rooms | ||
| end | ||
| end | ||
| return blocked_rooms | ||
| end | ||
|
|
||
| def find_block_index(room_number) | ||
| return @hotel_blocks.find_index { |block| block.rooms.include?(room_number)} | ||
| end | ||
|
|
||
| def create_reservation(date_range, rate) | ||
| return Reservation.new(date_range: date_range, rate: rate) | ||
| end | ||
|
|
||
| def create_block(rooms:, date_range:, discount:) | ||
| return HotelBlock.new(rooms: rooms, date_range: date_range, discount_rate: discount) | ||
| end | ||
| end | ||
| end | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| module Hotel | ||
| class Reservation | ||
| @@current_id = 0 | ||
| attr_reader :id, :date_range, :rate, :cost | ||
|
|
||
| def initialize(date_range:, rate:) | ||
| @@current_id += 1 | ||
| @date_range = date_range | ||
| @rate = rate | ||
| @id = @@current_id | ||
| @cost = (date_range.start_date - date_range.end_date).abs * rate | ||
| end | ||
| end | ||
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| 1. Naming: | ||
| - Replacing start_date with checkin_date, end_date with checkout_date. | ||
| - Find a better name for @room_reservation_data | ||
|
|
||
| 2. Implementation | ||
| - Refactor HotelSystem class to reduce dependency on other classes (DateRange, HotelBlock, Reservation) | ||
| - Should HotelBlock be removed? | ||
| - Should there be a Rate class? or Room class where rate will be passed in to constructor as argument? | ||
| - Implement read_data() and write_data() methods for @room_reservation_data and @hotel_blocks | ||
| - Create main.rb to interact with HotelSystem |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,65 @@ | ||
| require_relative 'test_helper' | ||
|
|
||
| describe Hotel::DateRange do | ||
| before do | ||
| @current_date = Date.today() | ||
| @duration = 10 | ||
|
|
||
| @start_date = @current_date + 30 | ||
| @end_date = @start_date + @duration | ||
| @date_range = Hotel::DateRange.new(@start_date, @end_date) | ||
| end | ||
| describe "Constructor" do | ||
| it "can construct a DateRange object" do | ||
| expect (@date_range).must_be_instance_of Hotel::DateRange | ||
| end | ||
|
|
||
| it "raises ArgumentError for invalid start date and end date" do | ||
| invalid_start_date = @end_date + 10 | ||
| invalid_end_date = @start_date - 10 | ||
| invalid_past_date = @current_date - 10 | ||
|
|
||
| expect {Hotel::DateRange.new(invalid_start_date, @end_date)}.must_raise ArgumentError | ||
| expect {Hotel::DateRange.new(@start_date, invalid_end_date)}.must_raise ArgumentError | ||
| expect {Hotel::DateRange.new(invalid_past_date, @end_date)}.must_raise ArgumentError | ||
| end | ||
| end | ||
|
|
||
| describe "overlap? method" do | ||
| it "returns true if 2 date ranges overlap" do | ||
| start_date1 = @start_date - 1 | ||
| end_date1 = @end_date - 1 | ||
| date1 = Hotel::DateRange.new(start_date1, end_date1) | ||
|
|
||
| start_date2 = @start_date + 1 | ||
| end_date2 = @end_date - 1 | ||
| date2 = Hotel::DateRange.new(start_date2, end_date2) | ||
|
|
||
| start_date3 = @start_date + 1 | ||
| end_date3 = @end_date + 1 | ||
| date3 = Hotel::DateRange.new(start_date3, end_date3) | ||
|
|
||
| expect (@date_range.overlap?(date1)).must_equal true | ||
| expect (@date_range.overlap?(date2)).must_equal true | ||
| expect (@date_range.overlap?(date3)).must_equal true | ||
| end | ||
|
|
||
| it "returns false if 2 date ranges don't overlap" do | ||
| start_date1 = @start_date - 10 | ||
| end_date1 = start_date1 + 5 | ||
| date1 = Hotel::DateRange.new(start_date1, end_date1) | ||
|
|
||
| start_date2 = @end_date + 5 | ||
| end_date2 = start_date2 + 5 | ||
| date2 = Hotel::DateRange.new(start_date2, end_date2) | ||
|
|
||
| start_date3 = @start_date + 15 | ||
| end_date3 = start_date3 + 5 | ||
| date3 = Hotel::DateRange.new(start_date3, end_date3) | ||
|
|
||
| expect (@date_range.overlap?(date1)).must_equal false | ||
| expect (@date_range.overlap?(date2)).must_equal false | ||
| expect (@date_range.overlap?(date3)).must_equal false | ||
| end | ||
| end | ||
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| require_relative 'test_helper' | ||
|
|
||
| describe Hotel::HotelBlock do | ||
| before do | ||
| current_date = Date.today() | ||
| duration = 10 | ||
|
|
||
| start_date = current_date + 30 | ||
| end_date = start_date + duration | ||
| @date_range = Hotel::DateRange.new(start_date, end_date) | ||
| @discount_rate = 0.2 | ||
| end | ||
| describe "Constructor" do | ||
| it "can create a HotelBlock object for valid input" do | ||
| rooms = [2, 3, 4] | ||
| hotel_block = Hotel::HotelBlock.new( | ||
| rooms: rooms, date_range: @date_range, discount_rate: @discount_rate | ||
| ) | ||
|
|
||
| expect (hotel_block).must_be_instance_of Hotel::HotelBlock | ||
| end | ||
|
|
||
| it "raises ArgumentError if list of rooms has more than 5 rooms" do | ||
| rooms = [2, 3, 4, 5, 6, 7] | ||
| expect{Hotel::HotelBlock.new( | ||
| rooms: rooms, date_range: @date_range, discount_rate: @discount_rate | ||
| )}.must_raise ArgumentError | ||
| end | ||
| end | ||
| end |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Nice touch!