require "minitest/autorun" require "./checkout.rb" class TestCheckout < Minitest::Test def setup @checkout = Checkout.new end def test_that_unknown_items_cannot_be_added assert_raises Checkout::InvalidItem do @checkout.add(:foo) end end def test_that_nil_is_not_allowed_to_be_added assert_raises Checkout::InvalidItem do @checkout.add(nil) end end def test_that_allowed_items_are_added @checkout.add(:PI5) @checkout.add(:ZERO2W) @checkout.add(:PICO2) assert_equal [:PI5, :ZERO2W, :PICO2].sort, @checkout.items.sort end def test_that_total_is_the_sum_of_all_items_when_no_discounts_apply @checkout.add(:PI5) # 60.00 @checkout.add(:ZERO2W) # 15.00 @checkout.add(:PICO2) # 4.00 # ----- # 79.00 total assert_equal 79.00, @checkout.total end def test_that_an_empty_checkout_total_is_zero assert_equal 0.00, @checkout.total end def test_that_we_can_empty_the_checkout @checkout.add(:PI5) @checkout.add(:ZERO2W) @checkout.add(:PICO2) refute_empty @checkout.items @checkout.clear assert_empty @checkout.items end # Discounts def test_that_bogof_applied 4.times do @checkout.add(:ZERO2W) # Should remove 2 Zeros end assert_equal 30.00, @checkout.total end def test_that_bogof_applied_with_odd_number 5.times do @checkout.add(:ZERO2W) # Should still remove 2 Zeros, 5th is full price end assert_equal 45.00, @checkout.total end def test_that_price_is_reduced_for_3_picos 3.times do @checkout.add(:PICO2) # 3.50 * 3 = 10.50 end assert_equal 10.50, @checkout.total end def test_that_price_is_reduced_for_more_than_3_picos 4.times do @checkout.add(:PICO2) # 3.50 * 4 = 14 end assert_equal 14.00, @checkout.total end def test_that_price_is_not_reduced_for_less_than_3_picos 2.times do @checkout.add(:PICO2) # 4.00 * 2 = 8 end assert_equal 8.00, @checkout.total end def test_that_both_discounts_apply_at_the_same_time 4.times do @checkout.add(:ZERO2W) # 30.00 with BOGOF end 3.times do @checkout.add(:PICO2) # 10.50 with bulk discount end assert_equal (30.00 + 10.50), @checkout.total end # Item removal def test_that_removing_an_item_not_in_the_checkout_removes_nothing @checkout.add(:PICO2) @checkout.remove(:PI5) assert_equal [:PICO2], @checkout.items end def test_that_items_are_removed_one_by_one 4.times do @checkout.add(:ZERO2W) end 3.times do @checkout.add(:PICO2) end assert_equal [:ZERO2W, :ZERO2W, :ZERO2W, :ZERO2W, :PICO2, :PICO2, :PICO2].sort, @checkout.items.sort @checkout.remove(:ZERO2W) assert_equal [:ZERO2W, :ZERO2W, :ZERO2W, :PICO2, :PICO2, :PICO2].sort, @checkout.items.sort @checkout.remove(:PICO2) assert_equal [:ZERO2W, :ZERO2W, :ZERO2W, :PICO2, :PICO2].sort, @checkout.items.sort 2.times do @checkout.remove(:PICO2) end assert_equal [:ZERO2W, :ZERO2W, :ZERO2W].sort, @checkout.items.sort end def test_that_total_is_correctly_recalculated_when_items_are_added 2.times do @checkout.add(:PICO2) end assert_equal 8.00, @checkout.total @checkout.add(:PICO2) # 3 in total now, so discount applies assert_equal 10.50, @checkout.total 4.times do @checkout.add(:ZERO2W) # 30.00 with BOGOF end assert_equal 40.50, @checkout.total end def test_that_total_is_correctly_recalculated_when_items_are_removed 3.times do @checkout.add(:PICO2) # Bulk discount applies end assert_equal 10.50, @checkout.total @checkout.remove(:PICO2) # Bulk discount no longer applies assert_equal 8.00, @checkout.total end end