-
Notifications
You must be signed in to change notification settings - Fork 297
Time - Jocelyn #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
Open
wangjoc
wants to merge
43
commits into
AdaGold:master
Choose a base branch
from
wangjoc: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
Time - Jocelyn #37
Changes from all commits
Commits
Show all changes
43 commits
Select commit
Hold shift + click to select a range
b1eb7b4
created new reservation class and test for initialization, tested wit…
wangjoc 3cdf2cc
Add coverage directory to .gitignore file and psuedocode
wangjoc 98111fc
Add coverage directory to .gitignore file, second attempt
wangjoc 5edd847
created initial tests and code for res class
wangjoc a580e7d
added initial room class and tests
wangjoc 3da32e8
added in reservation manager class and related tests
wangjoc e87d650
implemented search by date range function and error checking for room…
wangjoc 67ee9eb
cleaned up some comments and spacing
wangjoc 72a1b8d
wrote out pseudocode for wave 3 (hotel block)
wangjoc f568610
initial update to reservation manager to accomodate reservation blocks
wangjoc fd9cce8
refactored some guard clauses
wangjoc 5576ca6
moved search date validation to separate method
wangjoc 2e9819e
updated search by room/date range function for reservation blocks
wangjoc 234dbb4
updated search by date function for block reservation
wangjoc eae6465
updaated list by room range function for registration block
wangjoc d115215
refactored reservation class
wangjoc 6bf7df6
refactored code to get rid of warning messages from minitest
wangjoc 8556ff7
cleaned up require relative requests
wangjoc 954cda2
removed hotel file
wangjoc 78161ca
refactored reservation block
wangjoc df14352
consolidated add reservation and add reservation block. Updated test …
wangjoc 76281e7
added in initial tests for assigning first available room to new rese…
wangjoc 32bc695
added functionality to create new reservation given only dates
wangjoc 564b097
added more tests for reservation class
wangjoc e44d9cd
added in csv files with dummy data (reservations, reservation blocks,…
wangjoc 435462a
cleaned up test for csv record instantiation
wangjoc 199e02e
updated load all section to pass tests
wangjoc 4adadc2
updated load all test to require implementation in child class
wangjoc 89f0332
updated load all tests and removed the original template code
wangjoc 77473d3
updates to comments
wangjoc 2225275
updated tests and related code to look off reservation block rather t…
wangjoc 1e00923
migrate reservation methods over to reservation block
wangjoc 00dfcea
deleted reservation class and related code
wangjoc e731461
removed reservations holder and related code
wangjoc 683adf1
updated add reservation to only work with reservation blocks
wangjoc 407eb0a
modified main tests for adding reservations
wangjoc 5337847
added in test for if no rooms are available through list
wangjoc 805f644
moved order of test sections around
wangjoc 1f54f6a
changed name of reservation block to reservation
wangjoc d8cf487
removed data validation code from reservation manager
wangjoc c2e1e7f
cleaned out some extra comments
wangjoc 0fd096b
fixed build_path test
wangjoc 17c3016
finished csv record testing by creating a test class
wangjoc 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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -48,3 +48,4 @@ build-iPhoneSimulator/ | |
|
|
||
| # unless supporting rvm < 1.11.0 or doing something fancy, ignore this: | ||
| .rvmrc | ||
| coverage | ||
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,53 @@ | ||
| ################################ | ||
| ## ADAPTED FROM OO-RIDE-SHARE ## | ||
| ################################ | ||
|
|
||
| require 'csv' | ||
| require 'pry' | ||
|
|
||
| module HotelManager | ||
| class CsvRecord | ||
| attr_reader :id | ||
|
|
||
| def initialize(id) | ||
| self.class.validate_id(id) | ||
| @id = id | ||
| end | ||
|
|
||
| # Takes either full_path or directory and optional file_name | ||
| # Default file name matches class name | ||
| def self.load_all(full_path: nil, directory: nil, file_name: nil) | ||
|
|
||
| full_path ||= build_path(directory, file_name) | ||
|
|
||
| return CSV.read( | ||
| full_path, | ||
| headers: true, | ||
| header_converters: :symbol, | ||
| converters: :numeric | ||
| ).map { |record| from_csv(record) } | ||
| end | ||
|
|
||
| def self.validate_id(id) | ||
| if id.nil? || id <= 0 | ||
| raise ArgumentError, 'ID cannot be blank or less than one.' | ||
| end | ||
| end | ||
|
|
||
| def self.from_csv(record) | ||
| raise NotImplementedError, 'Implement me in a child class!' | ||
| end | ||
|
|
||
| def self.build_path(directory, file_name) | ||
| raise ArgumentError, "Either full_path or directory is required" if directory.nil? | ||
|
|
||
| if file_name.nil? | ||
| class_name = self.to_s.split('::').last | ||
| file_name = "#{class_name.downcase}s.csv" | ||
| end | ||
|
|
||
| return "#{directory}/#{file_name}" | ||
| 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,67 @@ | ||
| require 'date' | ||
| require 'pry' | ||
|
|
||
| require_relative 'room' | ||
|
|
||
| module HotelManager | ||
| class Reservation | ||
|
|
||
| attr_reader :id, :customer_id, :start_date, :end_date, :room_cost, :rooms, :room_ids | ||
|
|
||
| # Room default cost of $200 | ||
| def initialize id: , | ||
| customer_id: , | ||
| start_date: , | ||
| end_date: , | ||
| room_cost: 200, | ||
| rooms: nil, | ||
| room_ids: nil | ||
|
|
||
| @id = id | ||
| @customer_id = customer_id | ||
| @start_date = start_date | ||
| @end_date = end_date | ||
| @room_cost = room_cost | ||
| @rooms = rooms | ||
| @room_ids = room_ids | ||
|
|
||
| validate_date | ||
| @rooms.nil? ? validate_room(@room_ids) : validate_room(@rooms) | ||
| end | ||
|
|
||
| def validate_room(attribute) | ||
| raise ArgumentError, "Room or room_id is required" if @rooms.nil? && @room_ids.nil? | ||
|
|
||
| if attribute.length < 1 || attribute.length > 5 | ||
| raise ArgumentError, "#{attribute.length} is an invalid number of rooms for a hotel block" | ||
| end | ||
| end | ||
|
|
||
| # Check input validation | ||
| def validate_date | ||
| if !@start_date.is_a?(Date) || !@end_date.is_a?(Date) | ||
| raise ArgumentError, "Expected #{@start_date} and #{@end_date} to be date" | ||
| elsif @start_date >= @end_date | ||
| raise ArgumentError, "#{@start_date} must be before #{@end_date}" | ||
| end | ||
| end | ||
|
|
||
| # Calculate cost of reservation, exclusive of last date | ||
| def total_cost | ||
| @room_cost * (@end_date - @start_date - 1) * @rooms.length | ||
| end | ||
|
|
||
| # Checks if reservation exists on a specific date | ||
| def check_date(search_date) | ||
| (search_date >= @start_date) && (search_date <= @end_date) | ||
| end | ||
|
|
||
| # Checks whether reservation is within a given date range | ||
| def check_reservation_range(date_one, date_two) | ||
| first_date = date_one < date_two ? date_one : date_two | ||
| second_date = date_one < date_two ? date_two : date_one | ||
| first_date < @end_date && second_date > @start_date | ||
|
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. Remember the ada way is to use explicit return :) |
||
| 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,103 @@ | ||
| require 'pry' | ||
| require 'date' | ||
|
|
||
| require_relative 'reservation' | ||
| require_relative 'room' | ||
|
|
||
| module HotelManager | ||
| class ReservationManager | ||
|
|
||
| attr_reader :rooms, :reservation_blocks | ||
|
|
||
| # Populate hotel with 20 rooms upon initialization | ||
| def initialize | ||
| @rooms = [] | ||
| @reservation_blocks = [] | ||
|
|
||
| 20.times do |index| | ||
| @rooms << HotelManager::Room.new(id: index + 1) | ||
| end | ||
| end | ||
|
|
||
| # Creates and saves new reservation/block to instance variables | ||
| def save_reservation(first_date, second_date, num_of_rooms: 1, customer_id: nil, room_cost: 200) | ||
|
|
||
| # change list_room_by_range to return argument rather than string | ||
| available_rooms = list_room_by_range(first_date,second_date) | ||
| chosen_rooms = available_rooms.take(num_of_rooms) | ||
|
|
||
| raise ArgumentError, "No rooms available" if chosen_rooms.empty? | ||
|
|
||
| chosen_rooms.map!{|room| room.id} | ||
|
|
||
| new_reservation = HotelManager::Reservation.new( | ||
| id: @reservation_blocks.length + 1, | ||
| customer_id: customer_id, | ||
| start_date: first_date, | ||
| end_date: second_date, | ||
| room_cost: room_cost, | ||
| room_ids: chosen_rooms | ||
| ) | ||
|
|
||
| @reservation_blocks << new_reservation | ||
| end | ||
|
|
||
| def find_room(id) | ||
| @rooms.find { |room| room.id == id } | ||
| end | ||
|
|
||
| # List out all rooms in hotel | ||
| def rooms_list | ||
| @rooms.map {|room| "Room: #{room.id}"}.join(", ") | ||
| end | ||
|
|
||
| # List out all reservations by room and date range | ||
| def search_by_room_date(room, first_date, second_date) | ||
| raise ArgumentError, "Room #{room} does not exist" if @rooms.last.id < room | ||
|
|
||
| reservation_room_date = [] | ||
|
|
||
| @reservation_blocks.each do |reservation_block| | ||
| found_room = reservation_block.room_ids.include? room | ||
| if reservation_block.check_reservation_range(first_date,second_date) && found_room | ||
| reservation_room_date << reservation_block | ||
| end | ||
| end | ||
|
|
||
| return reservation_found?(reservation_room_date, "reservations") | ||
| end | ||
|
|
||
| # List out reservations by specific date | ||
| def search_by_date(date) | ||
| reservation_by_date = [] | ||
|
|
||
| @reservation_blocks.each do |reservation_block| | ||
| reservation_by_date << reservation_block if reservation_block.check_date(date) | ||
| end | ||
|
|
||
| return reservation_found?(reservation_by_date, "reservations") | ||
| end | ||
|
|
||
| def list_room_by_range(first_date, second_date) | ||
| available_rooms = @rooms.dup | ||
|
|
||
| @reservation_blocks.each do |reservation_block| | ||
| if reservation_block.check_reservation_range(first_date, second_date) | ||
| reservation_block.room_ids.each do |room_id| | ||
| available_rooms -= [find_room(room_id)] | ||
| end | ||
| end | ||
| end | ||
|
|
||
| return reservation_found?(available_rooms, "rooms") | ||
| end | ||
|
|
||
| # Raise argument error if no items found | ||
| def reservation_found? tracker, type | ||
| raise ArgumentError, "No #{type} available in date range." if tracker.empty? | ||
|
|
||
| return tracker | ||
| 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,11 @@ | ||
| module HotelManager | ||
| class Room | ||
|
|
||
| attr_reader :id | ||
|
|
||
| def initialize id: | ||
| @id = id | ||
| 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,97 @@ | ||
| ################################ | ||
| ## ADAPTED FROM OO-RIDE-SHARE ## | ||
| ################################ | ||
|
|
||
| require_relative 'test_helper' | ||
|
|
||
| TEST_DATA_DIR = 'test/test_data' | ||
|
|
||
| describe 'CSV Record Class' do | ||
| it 'is an instance of CSV Record' do | ||
| record = HotelManager::CsvRecord.new(1) | ||
| expect(record.id).must_equal 1 | ||
| end | ||
|
|
||
| it 'raises error if invalid id is used' do | ||
| expect {HotelManager::CsvRecord.new(-7)}.must_raise ArgumentError | ||
| expect {HotelManager::CsvRecord.new("One")}.must_raise ArgumentError | ||
| end | ||
|
|
||
| it 'validates that id accepts natural numbers' do | ||
| [1, 10, 9999].each {|id| HotelManager::CsvRecord.validate_id(id)} | ||
| end | ||
|
|
||
| it 'raises for negative numbers and 0' do | ||
| [0, -1, -10, -9999].each {|id| expect { HotelManager::CsvRecord.validate_id(id) }.must_raise ArgumentError} | ||
| end | ||
|
|
||
| it 'raises for nil' do | ||
| expect {HotelManager::CsvRecord.validate_id(nil)}.must_raise ArgumentError | ||
| end | ||
| end | ||
|
|
||
| describe 'CSV Record Class - Load All' do | ||
| it "raise argument error if invalid file path" do | ||
| expect {HotelManager::CsvRecord.load_all}.must_raise ArgumentError | ||
| end | ||
|
|
||
| it "raises an error if missing directory or file path" do | ||
| expect {HotelManager::CsvRecord.build_path(nil,"")}.must_raise ArgumentError | ||
| end | ||
|
|
||
| it "raises an error if invoked directly (without subclassing)" do | ||
| full_path = "#{TEST_DATA_DIR}/testrecords.csv" | ||
| expect {HotelManager::CsvRecord.load_all(full_path: full_path)}.must_raise NotImplementedError | ||
| end | ||
| end | ||
|
|
||
| describe 'CSV Record Class - Test Class' do | ||
| class TestRecord < HotelManager::CsvRecord | ||
| attr_reader :call_count | ||
|
|
||
| def initialize(id:, customer_id:, start_date:, end_date: , num_of_rooms:) | ||
| super(id) | ||
| end | ||
|
|
||
| def self.load_all(*args, **kwargs) | ||
| @call_count = 0 | ||
| super | ||
| end | ||
|
|
||
| def self.from_csv(record) | ||
| new(**record) | ||
| @call_count += 1 | ||
| end | ||
|
|
||
| def self.call_count | ||
| @call_count | ||
| end | ||
| end | ||
|
|
||
| describe 'load_all' do | ||
| file_name = 'testrecords.csv' | ||
| record_count = CSV.read("#{TEST_DATA_DIR}/#{file_name}", headers: true).length | ||
|
|
||
| it 'finds data given just a directory' do | ||
| records = TestRecord.load_all(directory: TEST_DATA_DIR) | ||
| expect(records.length).must_equal record_count | ||
| end | ||
|
|
||
| it 'finds data given a directory and filename' do | ||
| records = TestRecord.load_all(directory: TEST_DATA_DIR, file_name: file_name) | ||
|
|
||
| expect(records.length).must_equal record_count | ||
| end | ||
|
|
||
| it 'finds data given a full path' do | ||
| records = TestRecord.load_all(full_path: "#{TEST_DATA_DIR}/#{file_name}") | ||
|
|
||
| expect(records.length).must_equal record_count | ||
| end | ||
|
|
||
| it 'calls `from_csv` for each record in the file' do | ||
| TestRecord.load_all(directory: TEST_DATA_DIR) | ||
| expect(TestRecord.call_count).must_equal record_count | ||
| 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.
Consider giving this method a name like
validate_blockor adding a comment to increase readability.