diff --git a/lib/menu.rb b/lib/menu.rb new file mode 100644 index 0000000000..53dd37f760 --- /dev/null +++ b/lib/menu.rb @@ -0,0 +1,21 @@ +class Menu + + attr_reader :dishes + + def initialize(dishes) + @dishes = dishes + end + + def print_menu + dishes.map { |item, price| "%s: £%.2f" % [item.capitalize, price]}.join(', ') + end + + def has_dish?(dish) + !dishes[dish].nil? + end + + def price(dish) + dishes[dish] + end + +end \ No newline at end of file diff --git a/lib/message.rb b/lib/message.rb new file mode 100644 index 0000000000..e69de29bb2 diff --git a/lib/order.rb b/lib/order.rb new file mode 100644 index 0000000000..7da2bccf43 --- /dev/null +++ b/lib/order.rb @@ -0,0 +1,26 @@ +class Order + + attr_reader :dishes + + def initialize(menu) + @dishes = {} + @menu = menu + end + + def add(dish, quantity) + fail NoItemError, "#{dish.capitalize} is not on the menu!" unless @menu.has_dish?(dish) + dishes[dish] = quantity + end + + def total + item_totals.reduce(:+) + end + + private + + def item_totals + dishes.map { |dish, quantity| @menu.price(dish) * quantity} + end +end + +class NoItemError < StandardError; end \ No newline at end of file diff --git a/lib/takeaway.rb b/lib/takeaway.rb new file mode 100644 index 0000000000..24a72f2b5b --- /dev/null +++ b/lib/takeaway.rb @@ -0,0 +1,20 @@ +class TakeAway + +def initialize(menu:, order: nil) + @menu = menu + @order = order || Order.new +end + +def view_menu + menu.print +end + +def place_order(dishes) + dishes.each { |dish, quantity| order.add(dish, quantity) } + order.total +end +private + +attr_reader :menu, :order + +end diff --git a/runner.rb b/runner.rb new file mode 100644 index 0000000000..e264e12dc8 --- /dev/null +++ b/runner.rb @@ -0,0 +1,4 @@ +require './lib/takeaway.rb' +require './lib/menu.rb' +require './lib/order.rb' +require './lib/message.rb' \ No newline at end of file diff --git a/spec/menu_spec.rb b/spec/menu_spec.rb new file mode 100644 index 0000000000..c1f68d5d26 --- /dev/null +++ b/spec/menu_spec.rb @@ -0,0 +1,26 @@ +require 'menu' + +describe Menu do + subject(:menu) { described_class.new(dishes)} + let(:dishes) { { + "Prawn Toast": 5.5, + "Siu Mai": 4.0, + "Singapore Vermicelli": 6.6 + } } + it 'contains a list of dishes with prices' do + expect(menu.dishes).to eq(dishes) + end + + it "prints a list of dishes with prices" do + printed_menu = "Prawn toast: £5.50, Siu mai: £4.00, Singapore vermicelli: £6.60" + expect(menu.print_menu).to eq(printed_menu) + end + + it 'tells if a dish is on the menu' do + expect(menu.has_dish?(:"Prawn Toast")).to be true + end + + it 'claculates a price' do + expect(menu.price(:"Prawn Toast")).to eq(dishes[:"Prawn Toast"]) + end +end \ No newline at end of file diff --git a/spec/message_spec.rb b/spec/message_spec.rb new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/order_spec.rb b/spec/order_spec.rb new file mode 100644 index 0000000000..6bde45eed4 --- /dev/null +++ b/spec/order_spec.rb @@ -0,0 +1,43 @@ +require 'order' +require 'menu' + +describe Order do + subject(:order) {described_class.new(menu)} + let(:menu) {instance_double("Menu")} + let(:dishes) { + { + "Prawn Toast": 2, + "Siu Mai": 1 + }} + + before do + allow(menu).to receive(:has_dish?).with(:"Prawn Toast").and_return(true) + allow(menu).to receive(:has_dish?).with(:"Siu Mai").and_return(true) + allow(menu).to receive(:price).with(:"Prawn Toast").and_return(5.50) + allow(menu).to receive(:price).with(:"Siu Mai").and_return(4.00) + end + + it "selects several dishes from the menu" do + create_order + expect(order.dishes).to eq(dishes) + end + + it "doesn't allow items to be added that are not on the menu" do + allow(menu).to receive(:has_dish?).with(:"Onion Bhaji").and_return(false) + expect { order.add(:"Onion Bhaji", 2) }.to raise_error NoItemError, "Onion bhaji is not on the menu!" + end + + it "calculates the total of the order" do + + total = 15.00 + expect(order.total).to eq(total) + end + + + + def create_order + order.add(:"Prawn Toast", 2) + order.add(:"Siu Mai", 1) + end +end + diff --git a/spec/takeaway_spec.rb b/spec/takeaway_spec.rb new file mode 100644 index 0000000000..9851d18e82 --- /dev/null +++ b/spec/takeaway_spec.rb @@ -0,0 +1,36 @@ +require 'takeaway' +require 'order' + +describe TakeAway do + + subject(:takeaway) { described_class.new(menu: menu, order: order) } + + let(:menu) {double(:menu, print: printed_menu)} + let(:order) {instance_double("Order", total: 15.60)} + + let(:printed_menu) { "Prawn Toast: £5.50"} + + let(:dishes) { { + "Prawn Toast": 1, + "Siu Mai": 2, + } } + + it "can create an instance of itself" do + expect(subject).to be_kind_of(TakeAway) + end + + it "can print a list of dishes and prices" do + expect(takeaway.view_menu).to eq (printed_menu) + end + + it "can order some number of several available dishes" do + allow(order).to receive(:add).twice + expect(takeaway.place_order(dishes)).to eq(dishes) + end + + it "knows the order total" do + allow(order).to receive(:add) + total = takeaway.place_order(dishes) + expect(total).to eq(15.60) + end +end \ No newline at end of file