Add BuyXGetOneFreeDiscount
This commit is contained in:
@@ -0,0 +1,10 @@
|
|||||||
|
class BuyXGetOneFreeDiscount
|
||||||
|
def initialize(unit_price:, trigger_quantity: 2)
|
||||||
|
@unit_price = unit_price
|
||||||
|
@trigger_quantity = trigger_quantity.to_f
|
||||||
|
end
|
||||||
|
|
||||||
|
def discount_for_quantity(quantity)
|
||||||
|
return (quantity / @trigger_quantity).floor * @unit_price
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
class NoDiscount
|
||||||
|
def discount_for_quantity(quantity)
|
||||||
|
return 0.00
|
||||||
|
end
|
||||||
|
end
|
||||||
+7
-1
@@ -1,8 +1,10 @@
|
|||||||
|
require 'no_discount.rb'
|
||||||
class Product
|
class Product
|
||||||
def initialize(price: 0.00, id:, description: '')
|
def initialize(price: 0.00, id:, discount: nil, description: '')
|
||||||
@price = price
|
@price = price
|
||||||
@id = id
|
@id = id
|
||||||
@description = description
|
@description = description
|
||||||
|
@discount = discount || NoDiscount.new
|
||||||
end
|
end
|
||||||
|
|
||||||
def price
|
def price
|
||||||
@@ -13,6 +15,10 @@ class Product
|
|||||||
@id
|
@id
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def discount
|
||||||
|
@discount
|
||||||
|
end
|
||||||
|
|
||||||
def description
|
def description
|
||||||
@description
|
@description
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -17,6 +17,6 @@ class ProductInCheckout
|
|||||||
end
|
end
|
||||||
|
|
||||||
def total
|
def total
|
||||||
@product.price * quantity
|
(@product.price * quantity) - @product.discount.discount_for_quantity(@quantity)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
require "minitest/autorun"
|
||||||
|
|
||||||
|
require 'buy_x_get_one_free_discount.rb'
|
||||||
|
|
||||||
|
class BuyXGetOneFreeDiscountTest < Minitest::Test
|
||||||
|
def test_appropriate_discount_is_applied
|
||||||
|
unit_price = 4.00
|
||||||
|
(2..4).each do |trigger_quantity|
|
||||||
|
discount = BuyXGetOneFreeDiscount.new(unit_price: unit_price, trigger_quantity: trigger_quantity)
|
||||||
|
|
||||||
|
# Single discount at and above trigger quantity
|
||||||
|
assert_equal unit_price, discount.discount_for_quantity(trigger_quantity)
|
||||||
|
assert_equal unit_price, discount.discount_for_quantity(trigger_quantity + 1)
|
||||||
|
assert_equal unit_price, discount.discount_for_quantity(trigger_quantity + trigger_quantity - 1)
|
||||||
|
|
||||||
|
|
||||||
|
# No discount if less than trigger quantity
|
||||||
|
assert_equal 0.00, discount.discount_for_quantity(trigger_quantity - 1)
|
||||||
|
|
||||||
|
# Double discount if double trigger quantity
|
||||||
|
assert_equal unit_price * 2, discount.discount_for_quantity(trigger_quantity * 2)
|
||||||
|
assert_equal unit_price * 2, discount.discount_for_quantity((trigger_quantity * 2) + 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
+22
-13
@@ -1,13 +1,30 @@
|
|||||||
require "minitest/autorun"
|
require "minitest/autorun"
|
||||||
|
|
||||||
require "checkout.rb"
|
require "checkout.rb"
|
||||||
|
require "buy_x_get_one_free_discount.rb"
|
||||||
|
|
||||||
class CheckoutTest < Minitest::Test
|
class CheckoutTest < Minitest::Test
|
||||||
def setup
|
def setup
|
||||||
@shop = Shop.new
|
@shop = Shop.new
|
||||||
@shop.add_product(Product.new(id: 'PI5', price: 60.00))
|
@shop.add_product(
|
||||||
@shop.add_product(Product.new(id: 'ZERO2W', price: 15.00))
|
Product.new(
|
||||||
@shop.add_product(Product.new(id: 'PICO2', price: 4.00))
|
id: 'PI5',
|
||||||
|
price: 60.00
|
||||||
|
)
|
||||||
|
)
|
||||||
|
@shop.add_product(
|
||||||
|
Product.new(
|
||||||
|
id: 'ZERO2W',
|
||||||
|
price: 15.00,
|
||||||
|
discount: BuyXGetOneFreeDiscount.new(unit_price: 15.00, trigger_quantity: 2)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
@shop.add_product(
|
||||||
|
Product.new(
|
||||||
|
id: 'PICO2',
|
||||||
|
price: 4.00
|
||||||
|
)
|
||||||
|
)
|
||||||
@checkout = Checkout.new(shop: @shop)
|
@checkout = Checkout.new(shop: @shop)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -69,21 +86,13 @@ class CheckoutTest < Minitest::Test
|
|||||||
# Discounts
|
# Discounts
|
||||||
|
|
||||||
def test_that_bogof_applied
|
def test_that_bogof_applied
|
||||||
skip
|
@checkout.add(product_id: 'ZERO2W', quantity: 4) # Should remove 2 Zeros
|
||||||
|
|
||||||
4.times do
|
|
||||||
@checkout.add(:ZERO2W) # Should remove 2 Zeros
|
|
||||||
end
|
|
||||||
|
|
||||||
assert_equal 30.00, @checkout.total
|
assert_equal 30.00, @checkout.total
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_that_bogof_applied_with_odd_number
|
def test_that_bogof_applied_with_odd_number
|
||||||
skip
|
@checkout.add(product_id: 'ZERO2W', quantity: 5) # Should still remove 2 Zeros, 5th is full price
|
||||||
|
|
||||||
5.times do
|
|
||||||
@checkout.add(:ZERO2W) # Should still remove 2 Zeros, 5th is full price
|
|
||||||
end
|
|
||||||
|
|
||||||
assert_equal 45.00, @checkout.total
|
assert_equal 45.00, @checkout.total
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user