diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 000000000..5008ddfcf Binary files /dev/null and b/.DS_Store differ diff --git a/Rakefile b/Rakefile new file mode 100644 index 000000000..deb52f2cd --- /dev/null +++ b/Rakefile @@ -0,0 +1,9 @@ +require 'rake/testtask' + +Rake::TestTask.new do |t| + t.libs = ["lib"] + t.warning = true + t.test_files = FileList['specs/*_spec.rb'] +end + +task default: :test diff --git a/design_activity.md b/design_activity.md new file mode 100644 index 000000000..95adff1f9 --- /dev/null +++ b/design_activity.md @@ -0,0 +1,52 @@ +What classes does each implementation include? Are the lists the same? +Each implementation includes the CartEntry, ShoppingCart, Order. the list of the classes are the same. + + +Write down a sentence to describe each class. +CartEntry is the product and the price of the product +ShoppingCart is the actual list of products +Order is the total price of everything in the ShoppingCart + + +How do the classes relate to each other? It might be helpful to draw a diagram on a whiteboard or piece of paper. + +the CartEntry is what populates the list of the ShoppingCart and the order totals the cost of the ShoppingCart list. + + +What data does each class store? How (if at all) does this differ between the two implementations? +implementation A : +CartEntry stores the price and quantity of product +ShoppingCart stores the list of items +Order stores a new instance of shopping cart and sales tax and sum + +implementation B : +CartEntry stores the price and quantity of product +ShoppingCart stores the list of items and sum +Order stores a new instance of shopping cart and sales tax and subtotal + + +What methods does each class have? How (if at all) does this differ between the two implementations? + +implementation A has 4 methods: + 3 are initialize methods and 1 is a total price method. + +implementation B has 6 methods: + +3 are initialize and there are 2 price methods and 1 total_price method. + +Consider the Order#total_price method. In each implementation: +Is logic to compute the price delegated to "lower level" classes like ShoppingCart and CartEntry, or is it retained in Order? + +In implementation A the logic to compute price is retained in Order class in implementation B the logic to compute price seems to be broken up into two smaller price methods on CartEntry and ShoppingCart + + +Does total_price directly manipulate the instance variables of other classes? No + + +If we decide items are cheaper if bought in bulk, how would this change the code? Yes, Which implementation is easier to modify? implementation B + + +Which implementation better adheres to the single responsibility principle? implementation A + + +Bonus question once you've read Metz ch. 3: Which implementation is more loosely coupled? implementation B diff --git a/lib/administrator.rb b/lib/administrator.rb new file mode 100644 index 000000000..cd6aac50f --- /dev/null +++ b/lib/administrator.rb @@ -0,0 +1,83 @@ +require_relative 'reservation' +require_relative 'hotel_room' +# require 'pry' + +module Hotel + class Administrator + attr_reader :room_list, :reservation_list + + def initialize + @room_list = all_rooms + @reservation_list = [] + + if reservation_list == [] + puts "All rooms are available for reservation." + end + end + + def available_rooms + rm_nums = [] + @room_list.each do |room| + if room.status == nil || room.status == :AVAILABLE + rm_nums << room.rm_number + end + puts rm_nums + return rm_nums + end + end + + def reserved_rooms(res_list, new_res) + res_list.each do |reservation| + if new_res.start_date == reservation.end_date + reservation.room.each do |unit| + unit.status = :AVAILABLE + end + end + end + end + + + # can create reservation + def new_reservation(name, start_res, end_res) + # this method should add the newly created reservation to reservation_list + while @reservation_list == [] + new_res = Hotel::Reservation.new(guest: name, start_date: start_res, end_date: end_res) + @reservation_list << new_res + end + new_res = Hotel::Reservation.new(guest: name, start_date: start_res, end_date: end_res) + reserved_rooms(@reservation_list, new_res) + @reservation_list << new_res + return new_res + end + + + + + # can see total cost of a reservation + def reservation_cost(res_name) + @reservation_list.each do |reservation| + if reservation.guest == res_name + res_cost = reservation.total_cost + # puts res_cost + return res_cost + elsif reservation.guest != res_name + return ' Sorry! We do not have your reservation on file. Please contact customer service.' + end + end + end + + def all_rooms + rooms = [] + 20.times do |count| + room = Hotel::HotelRoom.new(count) + # room.rm_number = count + + rooms << room + end + return rooms + end + + end #class end +end + +# puts Hotel::Administrator.new.room_list diff --git a/lib/hotel_date.rb b/lib/hotel_date.rb new file mode 100644 index 000000000..d07383458 --- /dev/null +++ b/lib/hotel_date.rb @@ -0,0 +1,11 @@ +require_relative 'administrator' +module Hotel + class Date + # What would this class do? + # I think validate everything to do with dates. + # What would it need to do that? + # dates from made reservations + # to get access to those dates need the reservation list + + end +end diff --git a/lib/hotel_room.rb b/lib/hotel_room.rb new file mode 100644 index 000000000..e3b1ca158 --- /dev/null +++ b/lib/hotel_room.rb @@ -0,0 +1,70 @@ +# require 'pry' +module Hotel + class HotelRoom + attr_accessor :rm_number, :status + attr_reader :cost_pr_day + # need to refactor this so it is using hash ? make the data clearer + def initialize(rm_number) + @rm_number = rm_number + @cost_pr_day = 200 + @status = nil + end + + def change_status + @status = :UNAVAILABLE + end + end +end + + + + + +# def all_rooms +# +# rooms = [] +# 20.times do |count| +# room = Hotel::HotelRoom.new(count) +# @rm_number = count +# +# rooms << room +# end +# return rooms +# end + +# room = Hotel::HotelRoom +# puts room + +# binding.pry +# @room = { +# rm_number: count, cost_pr_day: 200, status: :AVILABLE +# } + +# @rm_number = rm_number +# @cost_pr_day = 200 +# @status = :AVILABLE + + +# def all_rooms +# rooms = [] +# 20.times do +# rooms << HotelRoom.new +# end +# return room +# +# end + +# def room_generator +# all_rooms = [] +# count = 1 +# +# 20.times do +# a_room = {} +# a_room[:rm_number] = count +# a_room[:cost_pr_day] = 200 +# a_room[:status] = :AVILABLE +# +# count += 1 +# +# room = HotelRoom.new() +# end diff --git a/lib/reservation.rb b/lib/reservation.rb new file mode 100644 index 000000000..4027570d6 --- /dev/null +++ b/lib/reservation.rb @@ -0,0 +1,49 @@ +require_relative 'hotel_room' +require 'date' +# require_relative 'administrator' +module Hotel + class Reservation + attr_reader :guest, :total_cost + attr_accessor :start_date, :end_date, :room + + def initialize(guest:, start_date:, end_date:) + @guest = guest + @start_date = Date.parse(start_date) + @end_date = Date.parse(end_date) + # code from date class to validate dates should go here? + # this code bit can be moved into a date class maybe? + # generate a random room num based on whats available for the timeframe + @room = open_rooms(1) + @total_cost = stay_price + if @end_date < @start_date + raise StandardError.new('Invalid reservation dates!') + end + end + + def stay_price + res_start = @start_date + res_end = @end_date + cost = ((res_end.mday - res_start.mday) - 1) * 200 + return cost + end + + def open_rooms(num_of_rooms) + reserved_units = [] + admin = Hotel::Administrator.new + rm_units = admin.room_list + (num_of_rooms).times do + reserved_unit = rm_units.sample + if reserved_unit.status == :UNAVAILABLE + while reserved_unit.status == :UNAVAILABLE + reserved_unit = rm_units.sample + end + end + reserved_unit.change_status + reserved_units << reserved_unit + end + return reserved_units + end + + end + +end diff --git a/specs/.DS_Store b/specs/.DS_Store new file mode 100644 index 000000000..f11dc2828 Binary files /dev/null and b/specs/.DS_Store differ diff --git a/specs/administrator_spec.rb b/specs/administrator_spec.rb new file mode 100644 index 000000000..86a5a9f3e --- /dev/null +++ b/specs/administrator_spec.rb @@ -0,0 +1,66 @@ +require_relative 'spec_helper' + +describe 'Administrator class' do + it "creates an array of rooms" do + admin = Hotel::Administrator.new + + admin.room_list.must_be_kind_of Array + + end + + it "can access individual rooms" do + admin = Hotel::Administrator.new + + rm_1 = admin.room_list + rm_2 = rm_1 + + rm_1[0].rm_number.must_equal 0 + rm_2[1].rm_number.must_equal 1 + + + end + + it "can access a list of reservations" do + admin = Hotel::Administrator.new + + admin.reservation_list.must_be_kind_of Array + + end + + it "reservation_list contains instances of reservation" do + # this also checks the new_reservation method because if it didnt work + # the reservation list would be empty. + admin = Hotel::Administrator.new + admin.new_reservation('Liam', '18th April 2018 ', '22nd April 2018') + admin.new_reservation( 'Mikaila', '12th December 2018','18th December 2018') + + admin.reservation_list.sample.must_be_instance_of Hotel::Reservation + + end + + it "can get total_cost" do + admin = Hotel::Administrator.new + admin.new_reservation( 'Mikaila', '12th December 2018','18th December 2018') + admin.new_reservation('Liam', '18th April 2018 ', '22nd April 2018') + admin.new_reservation('Miclah', '9th March 2018 ', '11th March 2018') + + + name = 'Mikaila' + name_1 = 'Mikah' + + admin.reservation_cost(name).must_equal 1000 + admin.reservation_cost(name_1).must_equal ' Sorry! We do not have your reservation on file. Please contact customer service.' + + end + + it "can assign rervations with overlapping dates" do + admin = Hotel::Administrator.new + res_1 = admin.new_reservation('Liam', '18th April 2018 ', '22nd April 2018') + res_2 = admin.new_reservation( 'Mikaila', '12th December 2018','18th December 2018') + res_3 = admin.new_reservation('Miclah', '18th March 2018 ', '22nd March 2018') + + admin.reservation_list.must_include res_2 + admin.reservation_list.must_include res_3 + admin.reservation_list.must_include res_1 + end +end diff --git a/specs/hotel_room_spec.rb b/specs/hotel_room_spec.rb new file mode 100644 index 000000000..f35ea3be1 --- /dev/null +++ b/specs/hotel_room_spec.rb @@ -0,0 +1,18 @@ +require_relative 'spec_helper' + +describe 'hotel_room class' do + it "creates an instance of a room" do + room = Hotel::HotelRoom.new(17) + + room.must_be_instance_of Hotel::HotelRoom + + end + + it "has a cost and room number" do + room = Hotel::HotelRoom.new(20) + + room.rm_number.must_be_kind_of Integer + room.cost_pr_day.must_equal 200 + + end +end diff --git a/specs/reservation_spec.rb b/specs/reservation_spec.rb new file mode 100644 index 000000000..f6ece9350 --- /dev/null +++ b/specs/reservation_spec.rb @@ -0,0 +1,49 @@ +require_relative 'spec_helper' + + +describe 'Reservation class' do + it "creates a reservation" do + reservation = Hotel::Reservation.new( + guest: 'John', start_date: '8th March 2018', end_date: '10th March 2018' + ) + + reservation.must_be_instance_of Hotel::Reservation + + end + + it "the reservation must have a room" do + reservation = Hotel::Reservation.new( + guest: 'Malcom', start_date: '12th May 2018', end_date: '14th May 2018' + ) + + room = reservation.room + + room[0].must_be_instance_of Hotel::HotelRoom + + end + + it "the reservation must have a start and end" do + reservation = Hotel::Reservation.new( + guest: 'Terri', start_date: '8th April 2018', end_date: '12th April 2018' + ) + + reservation.start_date.mday.must_equal 8 + reservation.end_date.mday.must_equal 12 + + end + + it "the reservation must have a total cost" do + reservation = Hotel::Reservation.new( + guest: 'Asrah', start_date: '6th October 2018', end_date: '9th October 2018' + ) + + reservation.total_cost.must_equal 400 + + end + + it "handles invalid start date and end_date" do + proc { + Hotel::Reservation.new(guest: 'Asrah', start_date: '9th October 2018', end_date: '6th October 2018') + }.must_raise StandardError + end +end diff --git a/specs/spec_helper.rb b/specs/spec_helper.rb new file mode 100644 index 000000000..11bdf1da3 --- /dev/null +++ b/specs/spec_helper.rb @@ -0,0 +1,15 @@ +require 'simplecov' +SimpleCov.start +# require 'time' +# require 'date' +require 'minitest' +require 'minitest/autorun' +require 'minitest/reporters' +# add my spec files as i create them for each class +require_relative '../lib/reservation' +require_relative '../lib/hotel_room' +require_relative '../lib/administrator' +# require_relative '../lib/' + + +Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new