-
Notifications
You must be signed in to change notification settings - Fork 48
Daniela Sanchez - Leaves #28
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?
Changes from all commits
afeab4b
d56bff6
dda8663
e10b307
51ef114
8cbef0b
d4f38d8
b65dcb6
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,15 @@ | ||
| require 'date' | ||
|
|
||
| module HotelBooking | ||
| class Block | ||
| attr_reader :check_in, :check_out, :rooms, :discounted_rate | ||
|
|
||
| def initialize(check_in, check_out, rooms = [], discounted_rate) | ||
| @check_in = check_in | ||
| @check_out = check_out | ||
| @rooms = rooms | ||
| @discounted_rate = discounted_rate | ||
| end | ||
| end | ||
| end | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,137 @@ | ||
| require_relative 'reservation' | ||
| require_relative 'block' | ||
| require 'pry' | ||
|
|
||
| module HotelBooking | ||
| class Manager | ||
| COST = 200 | ||
|
|
||
| def initialize | ||
| @rooms = [] | ||
| (1..20).each do |room_number| | ||
| @rooms << room_number | ||
| end | ||
| @rooms.freeze | ||
| @id = 0 | ||
| @reservation_by_id = {} | ||
| @reservations_by_date = {} | ||
| @blocks_by_date = {} | ||
| end | ||
|
|
||
| def list_rooms | ||
| return @rooms | ||
| end | ||
|
|
||
| def reserve_room(check_in , check_out) | ||
| validate_dates(check_in, check_out) | ||
| room = available_rooms(check_in, check_out).first | ||
| id = get_next_id | ||
| cost = ((check_out - check_in).to_i) * COST | ||
| reservation = Reservation.new(check_in, check_out, id, room, cost) | ||
| (check_in...check_out).each do |date| | ||
| if @reservations_by_date.has_key?(date) == false | ||
| reservations = [] | ||
| reservations << reservation | ||
| @reservations_by_date.store(date, reservations) | ||
| @reservation_by_id.store(id,reservation) | ||
| else | ||
| @reservations_by_date[date] << reservation | ||
| @reservation_by_id.store(id,reservation) | ||
| end | ||
| end | ||
| return reservation | ||
| end | ||
|
|
||
| def get_reservation_by_date(date) | ||
| if @reservations_by_date[date] != nil | ||
| result = @reservations_by_date[date] | ||
| else | ||
| result = [] | ||
| end | ||
| return result | ||
| end | ||
|
|
||
| def get_cost(id) | ||
| return @reservation_by_id[id].cost | ||
| end | ||
|
|
||
| def available_rooms(check_in, check_out) | ||
| available_rooms = Array.new(20, true) | ||
| (check_in...check_out).each do |date| | ||
| if @reservations_by_date[date] != nil | ||
| @reservations_by_date[date].each do |reservation| | ||
| available_rooms[reservation.room - 1] = false | ||
|
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 code is looking inside each of the reservations to make its decision, so it is probably doing something outside its responsibilities. |
||
| end | ||
| end | ||
| if @blocks_by_date[date] != nil | ||
| @blocks_by_date[date].each do |block| | ||
| block.rooms.each do |room| | ||
| available_rooms[room - 1] = false | ||
| end | ||
| end | ||
| end | ||
| end | ||
| if available_rooms.include?(true) == true | ||
| available_rooms = available_rooms.each_index.select { |index| available_rooms[index] == true} | ||
| available_rooms.map! do |index| | ||
| index + 1 | ||
| end | ||
| else | ||
| raise ArgumentError.new("No available room") | ||
| end | ||
| return available_rooms | ||
| end | ||
|
|
||
| def get_rooms_in_block(check_in, check_out) | ||
| if @blocks_by_date[check_in] != nil | ||
| @blocks_by_date[check_in].each do |block| | ||
| block.rooms | ||
| end | ||
| else | ||
| raise ArgumentError.new("Invalid block") | ||
|
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 line doesn't get hit by your tests. |
||
| end | ||
| end | ||
|
|
||
| def create_block(check_in , check_out, num_rooms, discounted_rate) | ||
| validate_dates(check_in, check_out) | ||
| validate_less_6_rooms(num_rooms) | ||
|
|
||
| if available_rooms(check_in, check_out).count >= num_rooms | ||
| rooms = [] | ||
| num_rooms.times do |index| | ||
| rooms << available_rooms(check_in, check_out)[index] | ||
| end | ||
| else | ||
| raise ArgumentError.new("No available room") | ||
| end | ||
| block = Block.new(check_in, check_out, rooms, discounted_rate) | ||
| (check_in...check_out).each do |date| | ||
| if @blocks_by_date.has_key?(date) == false | ||
| blocks = [] | ||
| blocks << block | ||
| @blocks_by_date.store(date, blocks) | ||
| else | ||
| @blocks_by_date[date] << block | ||
| end | ||
| end | ||
| return block | ||
| end | ||
|
|
||
| private | ||
| def get_next_id | ||
| return @id += 1 | ||
| end | ||
|
|
||
| def validate_dates(check_in, check_out) | ||
| unless check_out > check_in | ||
| raise ArgumentError.new("Invalid dates") | ||
| end | ||
| end | ||
|
|
||
| def validate_less_6_rooms(num_rooms) | ||
| unless num_rooms <= 5 | ||
| raise ArgumentError.new("A block can contain a maximum of 5 rooms") | ||
| end | ||
|
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're validating for the block here. |
||
| end | ||
| end | ||
| end | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| require 'date' | ||
|
|
||
| module HotelBooking | ||
| class Reservation | ||
| attr_reader :check_in, :check_out, :id, :room, :cost | ||
|
|
||
| def initialize(check_in, check_out, id, room, cost) | ||
| @check_in = check_in | ||
| @check_out = check_out | ||
| @id = id | ||
| @room = room | ||
| @cost = cost | ||
| end | ||
|
|
||
| end | ||
| end | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| require_relative 'test_helper' | ||
|
|
||
| describe "Block" do | ||
| describe "initialize" do | ||
|
|
||
| it "is an instance of Block" do | ||
| block = HotelBooking::Block.new("01/12/2019", "03/12/2019", 3, 150) | ||
| block.must_be_kind_of HotelBooking::Block | ||
| end | ||
| end | ||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,106 @@ | ||
| require_relative 'test_helper' | ||
|
|
||
| describe "Manager class" do | ||
| describe "initialize" do | ||
| before do | ||
| @manager = HotelBooking::Manager.new | ||
| end | ||
|
|
||
| it "has 20 rooms" do | ||
| expect(@manager.list_rooms.length).must_equal 20 | ||
| end | ||
|
|
||
| it "has rooms from 1 to 20" do | ||
| (1..20).each do |number| | ||
| expect(@manager.list_rooms[number-1]).must_equal number | ||
| end | ||
| end | ||
|
|
||
| it "raises argument error for invalid dates" do | ||
| proc { | ||
| @manager.reserve_room(Date.new(2019, 12, 5), Date.new(2019, 12, 1)) | ||
| }.must_raise ArgumentError | ||
| end | ||
|
|
||
| it "creates a reservation" do | ||
| reservation = @manager.reserve_room(Date.new(2019, 12, 1), Date.new(2019, 12, 3)) | ||
| reservation.must_be_kind_of HotelBooking::Reservation | ||
| end | ||
|
|
||
| it "gets cost by reservation id" do | ||
| @manager.reserve_room(Date.new(2019, 12, 1), Date.new(2019, 12, 3)) | ||
| expect @manager.get_cost(1).must_equal 400 | ||
| end | ||
|
|
||
| it "gets reservation by date" do | ||
| reservation = @manager.reserve_room(Date.new(2019, 12, 1), Date.new(2019, 12, 2)) | ||
| reservation2 = @manager.reserve_room(Date.new(2019, 12, 1), Date.new(2019, 12, 3)) | ||
| expect @manager.get_reservation_by_date(Date.new(2019, 11, 30)).must_equal [] | ||
| expect @manager.get_reservation_by_date(Date.new(2019, 12, 1))[0].must_equal reservation | ||
| expect @manager.get_reservation_by_date(Date.new(2019, 12, 1))[1].must_equal reservation2 | ||
| expect @manager.get_reservation_by_date(Date.new(2019, 12, 1))[1].room.must_equal 2 | ||
| expect @manager.get_reservation_by_date(Date.new(2019, 12, 1)).length.must_equal 2 | ||
| expect @manager.get_reservation_by_date(Date.new(2019, 12, 2))[0].must_equal reservation2 | ||
| expect @manager.get_reservation_by_date(Date.new(2019, 12, 2)).length.must_equal 1 | ||
| expect @manager.get_reservation_by_date(Date.new(2019, 12, 3)).must_equal [] | ||
| end | ||
|
|
||
| it "assigns correct room number" do | ||
| @manager.reserve_room(Date.new(2019, 12, 1), Date.new(2019, 12, 2)) | ||
| @manager.reserve_room(Date.new(2019, 12, 1), Date.new(2019, 12, 3)) | ||
| @manager.reserve_room(Date.new(2019, 12, 1), Date.new(2019, 12, 3)) | ||
| expect @manager.get_reservation_by_date(Date.new(2019, 12, 1))[0].room.must_equal 1 | ||
| expect @manager.get_reservation_by_date(Date.new(2019, 12, 1))[1].room.must_equal 2 | ||
| expect @manager.get_reservation_by_date(Date.new(2019, 12, 2))[0].room.must_equal 2 | ||
| expect @manager.get_reservation_by_date(Date.new(2019, 12, 2))[1].room.must_equal 3 | ||
| end | ||
|
|
||
| it "shows available rooms for a given date range" do | ||
| @manager.reserve_room(Date.new(2019, 12, 1), Date.new(2019, 12, 2)) | ||
| @manager.reserve_room(Date.new(2019, 12, 1), Date.new(2019, 12, 3)) | ||
| @manager.reserve_room(Date.new(2019, 12, 1), Date.new(2019, 12, 4)) | ||
| expect @manager.available_rooms(Date.new(2019, 12, 1), Date.new(2019, 12, 04)).count.must_equal 17 | ||
| expect @manager.available_rooms(Date.new(2019, 12, 10), Date.new(2019, 12, 11)).count.must_equal 20 | ||
| end | ||
|
|
||
| it "raises exception if someone tries to do a reservation and there are no available rooms" do | ||
| 20.times do |reservation| | ||
| @manager.reserve_room(Date.new(2019, 11, 10 ), Date.new(2019, 11, 13)) | ||
| end | ||
|
|
||
| proc { | ||
| @manager.reserve_room(Date.new(2019, 11, 10 ), Date.new(2019, 11, 13)) | ||
| }.must_raise ArgumentError | ||
| end | ||
|
|
||
| it "creates a block of rooms" do | ||
| @manager.create_block(Date.new(2019, 12, 1), Date.new(2019, 12, 3), 3, 150) | ||
| @manager.available_rooms(Date.new(2019, 12, 1), Date.new(2019, 12, 3)).count.must_equal 17 | ||
| @manager.available_rooms(Date.new(2019, 11, 29), Date.new(2019, 12, 2)).count.must_equal 17 | ||
| @manager.available_rooms(Date.new(2019, 12, 3), Date.new(2019, 12, 4)).count.must_equal 20 | ||
| end | ||
|
|
||
| it "raises an error for more than 5 rooms in a block" do | ||
| proc { | ||
| @manager.create_block(Date.new(2019, 12, 1), Date.new(2019, 12, 3), 6, 150) | ||
| }.must_raise ArgumentError | ||
| end | ||
|
|
||
| it "raises error if there aren't enough rooms available for a block" do | ||
| 16.times do |reservation| | ||
| @manager.reserve_room(Date.new(2019, 11, 10 ), Date.new(2019, 11, 13)) | ||
| end | ||
| proc { | ||
| @manager.create_block(Date.new(2019, 11, 10), Date.new(2019, 11, 13), 5, 150) | ||
| }.must_raise ArgumentError | ||
| end | ||
|
|
||
| it "shows rooms in a block" do | ||
| @manager.create_block(Date.new(2019, 12, 1), Date.new(2019, 12, 3), 3, 150) | ||
| @manager.create_block(Date.new(2019, 12, 1), Date.new(2019, 12, 3), 5, 150) | ||
| @manager.get_rooms_in_block(Date.new(2019, 12, 1), Date.new(2019, 12, 3))[0].rooms.must_equal [1,2,3] | ||
| @manager.get_rooms_in_block(Date.new(2019, 12, 1), Date.new(2019, 12, 3))[1].rooms.must_equal [4,5,6,7,8] | ||
| end | ||
|
|
||
| end | ||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| require_relative 'test_helper' | ||
| require "pry" | ||
|
|
||
| describe "Reservation" do | ||
| describe "initialize" do | ||
|
|
||
| it "is an instance of Reservation" do | ||
| reservation = HotelBooking::Reservation.new("01/12/2019", "03/12/2019", "a", "a", "a") | ||
| reservation.must_be_kind_of HotelBooking::Reservation | ||
| 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.
When a class only has instance variables and no methods, either it doesn't need to be a class, or you're doing that class's work somewhere else. This class should be able to make its own reservations, and report information about when it is available.