Current section

Files

Jump to
phoenix_test lib phoenix_test form_data.ex
Raw

lib/phoenix_test/form_data.ex

defmodule PhoenixTest.FormData do
@moduledoc false
alias PhoenixTest.Element.Button
alias PhoenixTest.Element.Field
alias PhoenixTest.Element.Select
defstruct data: %{}
def new, do: %__MODULE__{}
def add_data(%__MODULE__{} = form_data, {name, value}) do
add_data(form_data, name, value)
end
def add_data(%__MODULE__{} = form_data, %Button{} = button) do
add_data(form_data, button.name, button.value)
end
def add_data(%__MODULE__{} = form_data, %Field{} = field) do
add_data(form_data, field.name, field.value)
end
def add_data(%__MODULE__{} = form_data, %Select{value: values} = field) when is_list(values) do
add_data(form_data, field.name, values)
end
def add_data(form_data, data) when is_list(data) do
Enum.reduce(data, form_data, fn new_data, acc ->
add_data(acc, new_data)
end)
end
def add_data(%__MODULE__{} = form_data, name, value) when is_nil(name) or is_nil(value), do: form_data
def add_data(%__MODULE__{} = form_data, name, value) do
if allows_multiple_values?(name) do
new_data =
Map.update(form_data.data, name, List.wrap(value), fn existing_value ->
if value in existing_value do
existing_value
else
existing_value ++ List.wrap(value)
end
end)
%__MODULE__{form_data | data: new_data}
else
%__MODULE__{form_data | data: Map.put(form_data.data, name, value)}
end
end
def merge(%__MODULE__{data: data1}, %__MODULE__{data: data2}) do
data =
Map.merge(data1, data2, fn k, v1, v2 ->
if allows_multiple_values?(k) do
Enum.uniq(v1 ++ v2)
else
v2
end
end)
%__MODULE__{data: data}
end
defp allows_multiple_values?(field_name), do: String.ends_with?(field_name, "[]")
def filter(%__MODULE__{data: data}, fun) do
data =
data
|> Enum.filter(fn {name, value} -> fun.(%{name: name, value: value}) end)
|> Map.new()
%__MODULE__{data: data}
end
def empty?(%__MODULE__{data: data}) do
Enum.empty?(data)
end
def has_data?(%__MODULE__{data: data}, name, value) do
field_data = Map.get(data, name, [])
value == field_data or value in List.wrap(field_data)
end
def to_list(%__MODULE__{data: data}) do
data
|> Enum.map(fn
{key, values} when is_list(values) ->
Enum.map(values, &{key, &1})
{_key, _value} = field ->
field
end)
|> List.flatten()
end
end