exercism/elixir/bread-and-potions/test/rpg_test.exs

134 lines
3.7 KiB
Elixir

defmodule RPGTest do
use ExUnit.Case
alias RPG.{Edible, Character, LoafOfBread, ManaPotion, Poison, EmptyBottle}
defmodule NewItem do
defstruct []
end
describe "Edible" do
@tag task_id: 1
test "is a protocol" do
assert Edible.__protocol__(:functions) == [eat: 2]
end
@tag task_id: 1
test "cannot eat a completely new item" do
assert_raise Protocol.UndefinedError, fn ->
Edible.eat(%NewItem{}, %Character{})
end
end
end
describe "LoafOfBread" do
@tag task_id: 2
test "implements the Edible protocol" do
{:consolidated, modules} = Edible.__protocol__(:impls)
assert LoafOfBread in modules
end
@tag task_id: 2
test "eating it increases health" do
character = %Character{health: 50}
{_byproduct, %Character{} = character} = Edible.eat(%LoafOfBread{}, character)
assert character.health == 55
end
@tag task_id: 2
test "eating it has no byproduct" do
character = %Character{}
{byproduct, %Character{}} = Edible.eat(%LoafOfBread{}, character)
assert byproduct == nil
end
@tag task_id: 2
test "eating it does not affect mana" do
character = %Character{mana: 77}
{_byproduct, %Character{} = character} = Edible.eat(%LoafOfBread{}, character)
assert character.mana == 77
end
end
describe "ManaPotion" do
@tag task_id: 3
test "implements the Edible protocol" do
{:consolidated, modules} = Edible.__protocol__(:impls)
assert ManaPotion in modules
end
@tag task_id: 3
test "eating it increases mana" do
character = %Character{mana: 10}
{_byproduct, %Character{} = character} = Edible.eat(%ManaPotion{strength: 6}, character)
assert character.mana == 16
{_byproduct, %Character{} = character} = Edible.eat(%ManaPotion{strength: 9}, character)
assert character.mana == 25
end
@tag task_id: 3
test "eating it produces an empty bottle" do
character = %Character{}
{byproduct, %Character{}} = Edible.eat(%ManaPotion{}, character)
assert byproduct == %EmptyBottle{}
end
@tag task_id: 3
test "eating it does not affect health" do
character = %Character{health: 4}
{_byproduct, %Character{} = character} = Edible.eat(%ManaPotion{strength: 6}, character)
assert character.health == 4
end
end
describe "Poison" do
@tag task_id: 4
test "implements the Edible protocol" do
{:consolidated, modules} = Edible.__protocol__(:impls)
assert Poison in modules
end
@tag task_id: 4
test "eating it brings health down to 0" do
character = %Character{health: 120}
{_byproduct, %Character{} = character} = Edible.eat(%Poison{}, character)
assert character.health == 0
end
@tag task_id: 4
test "eating it produces an empty bottle" do
character = %Character{}
{byproduct, %Character{}} = Edible.eat(%Poison{}, character)
assert byproduct == %EmptyBottle{}
end
@tag task_id: 4
test "eating it does not affect mana" do
character = %Character{mana: 99}
{_byproduct, %Character{} = character} = Edible.eat(%Poison{}, character)
assert character.mana == 99
end
end
@tag task_id: 4
test "eating many things one after another" do
items = [
%LoafOfBread{},
%ManaPotion{strength: 10},
%ManaPotion{strength: 2},
%LoafOfBread{}
]
character = %Character{health: 100, mana: 100}
character =
Enum.reduce(items, character, fn item, character ->
{_, character} = Edible.eat(item, character)
character
end)
assert character.health == 110
assert character.mana == 112
end
end