Skip to content

Instantly share code, notes, and snippets.

@caike
Forked from dtzitz/cart.exs
Created August 30, 2016 21:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save caike/82c0a7a2357f5b32cd9340b9635bdb41 to your computer and use it in GitHub Desktop.
Save caike/82c0a7a2357f5b32cd9340b9635bdb41 to your computer and use it in GitHub Desktop.
# 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