refactor created factory

This commit is contained in:
Nelson 2021-01-29 23:38:18 -07:00
parent 2e077bb447
commit 20e91e35e9
9 changed files with 161 additions and 125 deletions

View File

@ -1,140 +1,83 @@
defmodule GildedRose do defmodule GildedRose do
@max_quality 50
def update_quality(items) do def update_quality(items) do
Enum.map(items, &update_item_new/1) Enum.map(items, &update_item/1)
end end
# Passes def update_item(item = %{ name: name }) do
@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 "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) }
# Legendary
@sulfuras "Sulfuras, Hand of Ragnaros"
def update_item_new(item = %{ name: @sulfuras }), do:
%{item | quality: 80 }
# 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) }
def update_item_new(item = %{name: @conjured}), do:
%{item | sell_in: item.sell_in - 1, quality: updated_quality(item.quality - 2) }
# 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), do:
%{item | sell_in: item.sell_in - 1, quality: updated_quality(item.quality - 1) }
# 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
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 cond do
item.sell_in < 0 -> PassesHandler.is_handled?(name) ->
cond do PassesHandler.handle(item)
item.name != "Aged Brie" ->
cond do BrieHandler.is_handled?(name) ->
item.name != "Backstage passes to a TAFKAL80ETC concert" -> BrieHandler.handle(item)
cond do
item.quality > 0 -> SulfurasHandler.is_handled?(name) ->
cond do SulfurasHandler.handle(item)
item.name != "Sulfuras, Hand of Ragnaros" ->
%{item | quality: item.quality - 1} ConjuredHandler.is_handled?(name) ->
true -> item ConjuredHandler.handle(item)
end
true -> item DefaultHandler.is_handled?(name) ->
end DefaultHandler.handle(item)
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 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 "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) }
# # Legendary
# @sulfuras "Sulfuras, Hand of Ragnaros"
# def update_item_new(item = %{ name: @sulfuras }), do:
# %{item | quality: 80 }
# # 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) }
# def update_item_new(item = %{name: @conjured}), do:
# %{item | sell_in: item.sell_in - 1, quality: updated_quality(item.quality - 2) }
# # 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), do:
# %{item | sell_in: item.sell_in - 1, quality: updated_quality(item.quality - 1) }
# # 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
end end

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,4 @@
defmodule ItemHandler do
@callback handle(Item) :: Item
@callback is_handled?(String.t()) :: boolean()
end

View File

@ -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

View File

@ -39,6 +39,8 @@ defmodule GildedRoseTest do
] ]
end end
# Normal items
test "normal item quality _ any day greater than 0" do test "normal item quality _ any day greater than 0" do
days_left = 10 days_left = 10
initial_quality = 10 initial_quality = 10
@ -71,6 +73,7 @@ defmodule GildedRoseTest do
assert normal === %Item{name: @normal, sell_in: -4, quality: 0} assert normal === %Item{name: @normal, sell_in: -4, quality: 0}
end end
# Conjured items
test "conjured item quality _ any day greater than 0" do test "conjured item quality _ any day greater than 0" do
days_left = 10 days_left = 10
@ -104,30 +107,36 @@ defmodule GildedRoseTest do
assert conjured === %Item{name: @conjured, sell_in: -4, quality: 0} assert conjured === %Item{name: @conjured, sell_in: -4, quality: 0}
end end
test "ticket quality _ 10 days or less" do
# Passes
test "passes quality _ 10 days or less" do
days_left = 10 days_left = 10
initial_quality = 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: 9, quality: 2} assert passes === %Item{name: @passes, sell_in: 9, quality: 2}
end end
test "ticket quality _ 5 days or less" do test "passes quality _ 5 days or less" do
days_left = 5 days_left = 5
initial_quality = 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: 4, quality: 3} assert passes === %Item{name: @passes, sell_in: 4, quality: 3}
end end
test "ticket quality _ after concert" do test "passes quality _ after concert" do
days_left = 0 days_left = 0
initial_quality = 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 end
# Brie
test "brie quality _ greater than 0 days left " do test "brie quality _ greater than 0 days left " do
days_left = 1 days_left = 1
initial_quality = 0 initial_quality = 0
@ -136,7 +145,6 @@ defmodule GildedRoseTest do
assert brie === %Item{name: @brie, sell_in: 0, quality: 1} assert brie === %Item{name: @brie, sell_in: 0, quality: 1}
end end
test "brie quality _ past sell in day" do test "brie quality _ past sell in day" do
days_left = 0 days_left = 0
initial_quality = 0 initial_quality = 0
@ -145,6 +153,8 @@ defmodule GildedRoseTest do
assert brie === %Item{name: @brie, sell_in: -1, quality: 2} assert brie === %Item{name: @brie, sell_in: -1, quality: 2}
end end
# Sulfuras
test "sulfuras quality _ any days left" do test "sulfuras quality _ any days left" do
days_left = 20 days_left = 20
initial_quality = 40 initial_quality = 40
@ -161,6 +171,8 @@ defmodule GildedRoseTest do
assert sulfuras === %Item{name: @sulfuras, sell_in: 20, quality: 80} assert sulfuras === %Item{name: @sulfuras, sell_in: 20, quality: 80}
end end
# Max quality
test "all items quality _ reaching max quality" do test "all items quality _ reaching max quality" do
days_left = 5 days_left = 5
initial_quality = 49 initial_quality = 49
@ -174,6 +186,4 @@ defmodule GildedRoseTest do
%Item{name: @conjured, sell_in: 0, quality: 39}, %Item{name: @conjured, sell_in: 0, quality: 39},
] ]
end end
end end