diff --git a/elixir/lib/gilded_rose.ex b/elixir/lib/gilded_rose.ex index a6e32287..4da7f921 100644 --- a/elixir/lib/gilded_rose.ex +++ b/elixir/lib/gilded_rose.ex @@ -1,140 +1,83 @@ defmodule GildedRose do - @max_quality 50 - def update_quality(items) do - Enum.map(items, &update_item_new/1) + Enum.map(items, &update_item/1) end - # Passes + def update_item(item = %{ name: name }) do + cond do + PassesHandler.is_handled?(name) -> + PassesHandler.handle(item) - @ticket "Backstage passes to a TAFKAL80ETC concert" - def update_item_new(item = %{ name: @ticket , sell_in: days }) when days - 1 < 0, do: - %{item | sell_in: days - 1, quality: 0 } + BrieHandler.is_handled?(name) -> + BrieHandler.handle(item) - def update_item_new(item = %{ name: @ticket , sell_in: days, quality: quality }) when days - 1 < 5, do: - %{item | sell_in: days - 1, quality: updated_quality(quality + 3) } + SulfurasHandler.is_handled?(name) -> + SulfurasHandler.handle(item) - def update_item_new(item = %{ name: @ticket , sell_in: days, quality: quality }) when days - 1 < 10, do: - %{item | sell_in: days - 1, quality: updated_quality(quality + 2) } + ConjuredHandler.is_handled?(name) -> + ConjuredHandler.handle(item) - def update_item_new(item = %{ name: @ticket , sell_in: days, quality: quality }), do: - %{item | sell_in: days - 1, quality: updated_quality(quality + 1) } + DefaultHandler.is_handled?(name) -> + DefaultHandler.handle(item) + end + end + + # # Passes + + # @ticket "Backstage passes to a TAFKAL80ETC concert" + # def update_item_new(item = %{ name: @ticket , sell_in: days }) when days - 1 < 0, do: + # %{item | sell_in: days - 1, quality: 0 } + + # def update_item_new(item = %{ name: @ticket , sell_in: days, quality: quality }) when days - 1 < 5, do: + # %{item | sell_in: days - 1, quality: updated_quality(quality + 3) } + + # def update_item_new(item = %{ name: @ticket , sell_in: days, quality: quality }) when days - 1 < 10, do: + # %{item | sell_in: days - 1, quality: updated_quality(quality + 2) } + + # def update_item_new(item = %{ name: @ticket , sell_in: days, quality: quality }), do: + # %{item | sell_in: days - 1, quality: updated_quality(quality + 1) } - # Brie + # # Brie - @brie "Aged Brie" - def update_item_new(item = %{ name: @brie, sell_in: days, quality: quality }) when days - 1 < 0, do: - %{item | sell_in: days - 1, quality: updated_quality(quality + 2) } + # @brie "Aged Brie" + # def update_item_new(item = %{ name: @brie, sell_in: days, quality: quality }) when days - 1 < 0, do: + # %{item | sell_in: days - 1, quality: updated_quality(quality + 2) } - def update_item_new(item = %{ name: @brie, sell_in: days, quality: quality }), do: - %{item | sell_in: days - 1, quality: updated_quality(quality + 1) } + # def update_item_new(item = %{ name: @brie, sell_in: days, quality: quality }), do: + # %{item | sell_in: days - 1, quality: updated_quality(quality + 1) } - # Legendary + # # Legendary - @sulfuras "Sulfuras, Hand of Ragnaros" - def update_item_new(item = %{ name: @sulfuras }), do: - %{item | quality: 80 } + # @sulfuras "Sulfuras, Hand of Ragnaros" + # def update_item_new(item = %{ name: @sulfuras }), do: + # %{item | quality: 80 } - # Conjured + # # Conjured - @conjured "Conjured" - def update_item_new(item = %{name: @conjured, sell_in: sell_in }) when sell_in - 1 < 0, do: - %{item | sell_in: sell_in - 1, quality: updated_quality(item.quality - 4) } + # @conjured "Conjured" + # def update_item_new(item = %{name: @conjured, sell_in: sell_in }) when sell_in - 1 < 0, do: + # %{item | sell_in: sell_in - 1, quality: updated_quality(item.quality - 4) } - def update_item_new(item = %{name: @conjured}), do: - %{item | sell_in: item.sell_in - 1, quality: updated_quality(item.quality - 2) } + # def update_item_new(item = %{name: @conjured}), do: + # %{item | sell_in: item.sell_in - 1, quality: updated_quality(item.quality - 2) } - # Normal + # # Normal - def update_item_new(item = %{sell_in: sell_in }) when sell_in - 1 < 0, do: - %{item | sell_in: sell_in - 1, quality: updated_quality(item.quality - 2) } + # def update_item_new(item = %{sell_in: sell_in }) when sell_in - 1 < 0, do: + # %{item | sell_in: sell_in - 1, quality: updated_quality(item.quality - 2) } - def update_item_new(item), do: - %{item | sell_in: item.sell_in - 1, quality: updated_quality(item.quality - 1) } + # def update_item_new(item), do: + # %{item | sell_in: item.sell_in - 1, quality: updated_quality(item.quality - 1) } - # Utils + # # Utils - defp updated_quality(new_amount) - defp updated_quality(new_amount) when new_amount < 0, do: 0 - defp updated_quality(new_amount) when new_amount > @max_quality, do: @max_quality - defp updated_quality(new_amount), do: new_amount + # defp updated_quality(new_amount) + # defp updated_quality(new_amount) when new_amount < 0, do: 0 + # defp updated_quality(new_amount) when new_amount > @max_quality, do: @max_quality + # defp updated_quality(new_amount), do: new_amount - - def update_item(item) do - item = cond do - item.name != "Aged Brie" && item.name != "Backstage passes to a TAFKAL80ETC concert" -> - if item.quality > 0 do - if item.name != "Sulfuras, Hand of Ragnaros" do - %{item | quality: item.quality - 1} - else - item - end - else - item - end - true -> - cond do - item.quality < 50 -> - item = %{item | quality: item.quality + 1} - cond do - item.name == "Backstage passes to a TAFKAL80ETC concert" -> - item = cond do - item.sell_in < 11 -> - cond do - item.quality < 50 -> - %{item | quality: item.quality + 1} - true -> item - end - true -> item - end - cond do - item.sell_in < 6 -> - cond do - item.quality < 50 -> - %{item | quality: item.quality + 1} - true -> item - end - true -> item - end - true -> item - end - true -> item - end - end - item = cond do - item.name != "Sulfuras, Hand of Ragnaros" -> - %{item | sell_in: item.sell_in - 1} - true -> item - end - cond do - item.sell_in < 0 -> - cond do - item.name != "Aged Brie" -> - cond do - item.name != "Backstage passes to a TAFKAL80ETC concert" -> - cond do - item.quality > 0 -> - cond do - item.name != "Sulfuras, Hand of Ragnaros" -> - %{item | quality: item.quality - 1} - true -> item - end - true -> item - end - true -> %{item | quality: item.quality - item.quality} - end - true -> - cond do - item.quality < 50 -> - %{item | quality: item.quality + 1} - true -> item - end - end - true -> item - end - end end diff --git a/elixir/lib/guilded_rose/handlers/brie_handler.ex b/elixir/lib/guilded_rose/handlers/brie_handler.ex new file mode 100644 index 00000000..3da5a6b1 --- /dev/null +++ b/elixir/lib/guilded_rose/handlers/brie_handler.ex @@ -0,0 +1,14 @@ +defmodule BrieHandler do + alias Utils.Quality + @behaviour ItemHandler + @item_name "Aged Brie" + + def is_handled?(item_name), do: item_name == @item_name + + def handle(item = %{ name: @item_name, sell_in: days, quality: quality }) when days - 1 < 0, do: + %{item | sell_in: days - 1, quality: Quality.calculate(quality + 2) } + + def handle(item = %{ name: @item_name, sell_in: days, quality: quality }), do: + %{item | sell_in: days - 1, quality: Quality.calculate(quality + 1) } + +end \ No newline at end of file diff --git a/elixir/lib/guilded_rose/handlers/conjured_handler.ex b/elixir/lib/guilded_rose/handlers/conjured_handler.ex new file mode 100644 index 00000000..920cd521 --- /dev/null +++ b/elixir/lib/guilded_rose/handlers/conjured_handler.ex @@ -0,0 +1,14 @@ +defmodule ConjuredHandler do + alias Utils.Quality + @behaviour ItemHandler + @item_name "Conjured" + + def is_handled?(item_name), do: item_name == @item_name + + def handle(item = %{name: @item_name, sell_in: sell_in }) when sell_in - 1 < 0, do: + %{item | sell_in: sell_in - 1, quality: Quality.calculate(item.quality - 4) } + + def handle(item = %{name: @item_name}), do: + %{item | sell_in: item.sell_in - 1, quality: Quality.calculate(item.quality - 2) } + +end \ No newline at end of file diff --git a/elixir/lib/guilded_rose/handlers/default_handler.ex b/elixir/lib/guilded_rose/handlers/default_handler.ex new file mode 100644 index 00000000..61605ca7 --- /dev/null +++ b/elixir/lib/guilded_rose/handlers/default_handler.ex @@ -0,0 +1,13 @@ +defmodule DefaultHandler do + alias Utils.Quality + @behaviour ItemHandler + + def is_handled?(item_name), do: true + + def handle(item = %{ sell_in: sell_in }) when sell_in - 1 < 0, do: + %{item | sell_in: sell_in - 1, quality: Quality.calculate(item.quality - 2) } + + def handle(item), do: + %{item | sell_in: item.sell_in - 1, quality: Quality.calculate(item.quality - 1) } + +end \ No newline at end of file diff --git a/elixir/lib/guilded_rose/handlers/passes_handler.ex b/elixir/lib/guilded_rose/handlers/passes_handler.ex new file mode 100644 index 00000000..5f191d16 --- /dev/null +++ b/elixir/lib/guilded_rose/handlers/passes_handler.ex @@ -0,0 +1,20 @@ +defmodule PassesHandler do + alias Utils.Quality + @behaviour ItemHandler + @item_name "Backstage passes to a TAFKAL80ETC concert" + + def is_handled?(item_name), do: item_name == @item_name + + def handle(item = %{ name: @item_name , sell_in: days }) when days - 1 < 0, do: + %{item | sell_in: days - 1, quality: 0 } + + def handle(item = %{ name: @item_name , sell_in: days, quality: quality }) when days - 1 < 5, do: + %{item | sell_in: days - 1, quality: Quality.calculate(quality + 3) } + + def handle(item = %{ name: @item_name , sell_in: days, quality: quality }) when days - 1 < 10, do: + %{item | sell_in: days - 1, quality: Quality.calculate(quality + 2) } + + def handle(item = %{ name: @item_name , sell_in: days, quality: quality }), do: + %{item | sell_in: days - 1, quality: Quality.calculate(quality + 1) } + +end \ No newline at end of file diff --git a/elixir/lib/guilded_rose/handlers/sulfuras_handler.ex b/elixir/lib/guilded_rose/handlers/sulfuras_handler.ex new file mode 100644 index 00000000..4e5f9031 --- /dev/null +++ b/elixir/lib/guilded_rose/handlers/sulfuras_handler.ex @@ -0,0 +1,10 @@ +defmodule SulfurasHandler do + @behaviour ItemHandler + @item_name "Sulfuras, Hand of Ragnaros" + + def is_handled?(item_name), do: item_name == @item_name + + def handle(item = %{ name: @item_name }), do: + %{item | quality: 80 } + +end \ No newline at end of file diff --git a/elixir/lib/guilded_rose/item_handler.ex b/elixir/lib/guilded_rose/item_handler.ex new file mode 100644 index 00000000..1633a4dd --- /dev/null +++ b/elixir/lib/guilded_rose/item_handler.ex @@ -0,0 +1,4 @@ +defmodule ItemHandler do + @callback handle(Item) :: Item + @callback is_handled?(String.t()) :: boolean() +end \ No newline at end of file diff --git a/elixir/lib/guilded_rose/utils/quality.ex b/elixir/lib/guilded_rose/utils/quality.ex new file mode 100644 index 00000000..3088a2e9 --- /dev/null +++ b/elixir/lib/guilded_rose/utils/quality.ex @@ -0,0 +1,8 @@ +defmodule Utils.Quality do + + def calculate(amount, max \\ 50) + def calculate(amount, _) when amount < 0, do: 0 + def calculate(amount, max) when amount > max, do: max + def calculate(amount, _), do: amount + +end \ No newline at end of file diff --git a/elixir/test/gilded_rose_test.exs b/elixir/test/gilded_rose_test.exs index 456789a6..2df72a46 100644 --- a/elixir/test/gilded_rose_test.exs +++ b/elixir/test/gilded_rose_test.exs @@ -39,6 +39,8 @@ defmodule GildedRoseTest do ] end + # Normal items + test "normal item quality _ any day greater than 0" do days_left = 10 initial_quality = 10 @@ -71,6 +73,7 @@ defmodule GildedRoseTest do assert normal === %Item{name: @normal, sell_in: -4, quality: 0} end + # Conjured items test "conjured item quality _ any day greater than 0" do days_left = 10 @@ -104,29 +107,35 @@ defmodule GildedRoseTest do assert conjured === %Item{name: @conjured, sell_in: -4, quality: 0} end - test "ticket quality _ 10 days or less" do + + # Passes + + + test "passes quality _ 10 days or less" do days_left = 10 initial_quality = 0 - [_, ticket, _, _, _] = create_items(days_left, initial_quality) |> elapse_days(1) + [_, passes, _, _, _] = create_items(days_left, initial_quality) |> elapse_days(1) - assert ticket === %Item{name: @passes, sell_in: 9, quality: 2} + assert passes === %Item{name: @passes, sell_in: 9, quality: 2} end - test "ticket quality _ 5 days or less" do + test "passes quality _ 5 days or less" do days_left = 5 initial_quality = 0 - [_, ticket, _, _, _] = create_items(days_left, initial_quality) |> elapse_days(1) + [_, passes, _, _, _] = create_items(days_left, initial_quality) |> elapse_days(1) - assert ticket === %Item{name: @passes, sell_in: 4, quality: 3} + assert passes === %Item{name: @passes, sell_in: 4, quality: 3} end - test "ticket quality _ after concert" do + test "passes quality _ after concert" do days_left = 0 initial_quality = 0 - [_, ticket, _, _, _] = create_items(days_left, initial_quality) |> elapse_days(1) + [_, passes, _, _, _] = create_items(days_left, initial_quality) |> elapse_days(1) - assert ticket === %Item{name: @passes, sell_in: -1, quality: 0} + assert passes === %Item{name: @passes, sell_in: -1, quality: 0} end + + # Brie test "brie quality _ greater than 0 days left " do days_left = 1 @@ -136,7 +145,6 @@ defmodule GildedRoseTest do assert brie === %Item{name: @brie, sell_in: 0, quality: 1} end - test "brie quality _ past sell in day" do days_left = 0 initial_quality = 0 @@ -145,6 +153,8 @@ defmodule GildedRoseTest do assert brie === %Item{name: @brie, sell_in: -1, quality: 2} end + # Sulfuras + test "sulfuras quality _ any days left" do days_left = 20 initial_quality = 40 @@ -161,6 +171,8 @@ defmodule GildedRoseTest do assert sulfuras === %Item{name: @sulfuras, sell_in: 20, quality: 80} end + # Max quality + test "all items quality _ reaching max quality" do days_left = 5 initial_quality = 49 @@ -174,6 +186,4 @@ defmodule GildedRoseTest do %Item{name: @conjured, sell_in: 0, quality: 39}, ] end - - end