# from ounce of elixir | |
#https://www.meetup.com/Women-Who-Code-Tampa/events/233014583/ | |
ExUnit.start | |
defmodule CartTest do | |
use ExUnit.Case | |
test "starts with empty count" do | |
assert Cart.count_items([]) == 0 | |
end | |
test "with one add event then count items is one" do | |
events = [{:add, "book"}] | |
assert Cart.count_items(events) == 1 | |
end | |
test "we should have zero items if we added and removed" do | |
events = [{:add, "book"}, {:remove, "book"}] | |
assert Cart.count_items(events) == 0 | |
end | |
test "we should have 2 items when we add two items" do | |
events = [{:add, "book"}, {:add, "book"}] | |
assert Cart.count_items(events) == 2 | |
end | |
test "we should raise an error when we remove from an empty cart" do | |
events = [{:remove, "book"}] | |
assert_raise Cart.InvalidOperation, fn -> Cart.count_items(events) end | |
events = [{:remove, "book"}, {:add, "book"}] | |
assert_raise Cart.InvalidOperation, fn -> Cart.count_items(events) end | |
events = [{:add, "book"}, {:remove, "book"}, {:remove, "book"}] | |
assert_raise Cart.InvalidOperation, fn -> Cart.count_items(events) end | |
end | |
test "keeps track type of items for each operation" do | |
events = [{:add, "banana"}, {:add, "book"}] | |
assert Cart.count_items(events, "banana") == 1 | |
events = [{:add, "banana"}, {:add, "banana"}] | |
assert Cart.count_items(events, "banana") == 2 | |
events = [{:add, "banana"}, {:add, "banana"}, {:remove, "banana"}] | |
assert Cart.count_items(events, "banana") == 1 | |
end | |
end | |
defmodule Cart.InvalidOperation do | |
defexception message: "Cannot do this" | |
end | |
defmodule Cart do | |
def count_items([{:remove, _item} | _tail]) do | |
raise Cart.InvalidOperation | |
end | |
def count_items(events) do | |
Enum.reduce events, 0, fn(event, count) -> | |
case {event, count} do | |
{{:add, _item}, _count} -> count + 1 | |
{{:remove, _item}, count} when count <= 0 -> raise Cart.InvalidOperation | |
{{:remove, _item}, _count} -> count - 1 | |
end | |
end | |
end | |
def count_items(events, product) do | |
Enum.filter(events, filter_events_by_product_type(product)) | |
|> count_items | |
end | |
def filter_events_by_product_type(product) do | |
fn({_action, event_product}) -> event_product == product end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment