@@ -5,7 +5,7 @@ defmodule PhoenixTest.FormData do
55 alias PhoenixTest.Element.Field
66 alias PhoenixTest.Element.Select
77
8- defstruct data: % { }
8+ defstruct data: [ ]
99
1010 def new , do: % __MODULE__ { }
1111
@@ -35,82 +35,106 @@ defmodule PhoenixTest.FormData do
3535
3636 def add_data ( % __MODULE__ { } = form_data , name , value ) do
3737 if allows_multiple_values? ( name ) do
38- new_data =
39- Map . update ( form_data . data , name , List . wrap ( value ) , fn existing_value ->
40- if value in existing_value do
41- existing_value
42- else
43- existing_value ++ List . wrap ( value )
44- end
45- end )
38+ existing_values = values_for_name ( form_data . data , name )
39+
40+ new_entries =
41+ value
42+ |> List . wrap ( )
43+ |> Enum . reject ( & ( & 1 in existing_values ) )
44+ |> Enum . map ( & { name , & 1 } )
4645
47- % __MODULE__ { form_data | data: new_data }
46+ % __MODULE__ { form_data | data: form_data . data ++ new_entries }
4847 else
49- % __MODULE__ { form_data | data: Map . put ( form_data . data , name , value ) }
48+ put_data ( form_data , name , value )
5049 end
5150 end
5251
53- def merge ( % __MODULE__ { data: data1 } , % __MODULE__ { data: data2 } ) do
54- data =
55- Map . merge ( data1 , data2 , fn k , v1 , v2 ->
56- if allows_multiple_values? ( k ) do
57- Enum . uniq ( v1 ++ v2 )
58- else
59- v2
60- end
61- end )
62-
63- % __MODULE__ { data: data }
52+ def merge ( % __MODULE__ { } = form_data1 , % __MODULE__ { } = form_data2 ) do
53+ form_data2
54+ |> field_names ( )
55+ |> Enum . reduce ( form_data1 , fn name , acc ->
56+ if allows_multiple_values? ( name ) do
57+ add_data ( acc , name , get_data ( form_data2 , name ) )
58+ else
59+ put_data ( acc , name , get_data ( form_data2 , name ) )
60+ end
61+ end )
6462 end
6563
66- def override ( % __MODULE__ { data: data1 } , % __MODULE__ { data: data2 } ) do
67- % __MODULE__ { data: Map . merge ( data1 , data2 ) }
64+ def override ( % __MODULE__ { } = form_data1 , % __MODULE__ { } = form_data2 ) do
65+ form_data2
66+ |> field_names ( )
67+ |> Enum . reduce ( form_data1 , fn name , acc ->
68+ put_data ( acc , name , get_data ( form_data2 , name ) )
69+ end )
6870 end
6971
7072 def get_data ( % __MODULE__ { data: data } , name ) do
71- Map . get ( data , name )
73+ values = values_for_name ( data , name )
74+
75+ cond do
76+ values == [ ] -> nil
77+ allows_multiple_values? ( name ) or length ( values ) > 1 -> values
78+ true -> hd ( values )
79+ end
7280 end
7381
7482 def put_data ( % __MODULE__ { } = form_data , name , value ) when is_nil ( name ) or is_nil ( value ) , do: form_data
7583
7684 def put_data ( % __MODULE__ { } = form_data , name , value ) do
77- % __MODULE__ { form_data | data: Map . put ( form_data . data , name , value ) }
85+ new_entries =
86+ value
87+ |> List . wrap ( )
88+ |> Enum . reject ( & is_nil / 1 )
89+ |> Enum . map ( & { name , & 1 } )
90+
91+ % __MODULE__ { form_data | data: replace_entries ( form_data . data , name , new_entries ) }
7892 end
7993
8094 defp allows_multiple_values? ( field_name ) , do: String . ends_with? ( field_name , "[]" )
8195
8296 def filter ( % __MODULE__ { data: data } , fun ) do
83- data =
84- data
85- |> Enum . filter ( fn { name , value } -> fun . ( % { name: name , value: value } ) end )
86- |> Map . new ( )
87-
88- % __MODULE__ { data: data }
97+ % __MODULE__ {
98+ data:
99+ Enum . filter ( data , fn { name , value } ->
100+ fun . ( % { name: name , value: value } )
101+ end )
102+ }
89103 end
90104
91105 def empty? ( % __MODULE__ { data: data } ) do
92106 Enum . empty? ( data )
93107 end
94108
95- def has_data? ( % __MODULE__ { data: data } , name , value ) do
96- field_data = Map . get ( data , name , [ ] )
109+ def has_data? ( % __MODULE__ { } = form_data , name , value ) do
110+ field_data = get_data ( form_data , name )
97111
98112 value == field_data or value in List . wrap ( field_data )
99113 end
100114
101115 def field_names ( % __MODULE__ { data: data } ) do
102- Map . keys ( data )
116+ data
117+ |> Enum . map ( & elem ( & 1 , 0 ) )
118+ |> Enum . uniq ( )
103119 end
104120
105- def to_list ( % __MODULE__ { data: data } ) do
106- data
107- |> Enum . map ( fn
108- { key , values } when is_list ( values ) ->
109- Enum . map ( values , & { key , & 1 } )
121+ def to_list ( % __MODULE__ { data: data } ) , do: data
110122
111- { _key , _value } = field ->
112- field
113- end )
114- |> List . flatten ( )
123+ defp replace_entries ( data , name , new_entries ) do
124+ case Enum . find_index ( data , fn { n , _ } -> n == name end ) do
125+ nil ->
126+ data ++ new_entries
127+
128+ first_index ->
129+ filtered_data = Enum . reject ( data , fn { n , _ } -> n == name end )
130+ { before , after_entries } = Enum . split ( filtered_data , first_index )
131+ before ++ new_entries ++ after_entries
132+ end
133+ end
134+
135+ defp values_for_name ( data , name ) do
136+ data
137+ |> Enum . filter ( fn { n , _ } -> n == name end )
138+ |> Enum . map ( fn { _ , v } -> v end )
115139 end
116140end
0 commit comments