@@ -74,4 +74,75 @@ defmodule KeywordTest do
7474 # any key in keywords1 is removed if key is present in keyword2
7575 assert Keyword . merge ( [ a: 1 , b: 2 , c: 3 , c: 4 ] , [ c: 11 , c: 12 , d: 13 ] ) == [ a: 1 , b: 2 , c: 11 , c: 12 , d: 13 ]
7676 end
77+
78+ test "merge/3" do
79+ fun = fn _key , value1 , value2 -> value1 + value2 end
80+
81+ assert Keyword . merge ( [ a: 1 , b: 2 ] , [ c: 11 , d: 12 ] , fun ) == [ a: 1 , b: 2 , c: 11 , d: 12 ]
82+ assert Keyword . merge ( [ ] , [ c: 11 , d: 12 ] , fun ) == [ c: 11 , d: 12 ]
83+ assert Keyword . merge ( [ a: 1 , b: 2 ] , [ ] , fun ) == [ a: 1 , b: 2 ]
84+
85+ assert_raise ArgumentError , "expected a keyword list as the first argument, got: [1, 2]" , fn ->
86+ Keyword . merge ( [ 1 , 2 ] , [ c: 11 , d: 12 ] , fun )
87+ end
88+
89+ assert_raise ArgumentError , "expected a keyword list as the first argument, got: [1 | 2]" , fn ->
90+ Keyword . merge ( [ 1 | 2 ] , [ c: 11 , d: 12 ] , fun )
91+ end
92+
93+ assert_raise ArgumentError , "expected a keyword list as the second argument, got: [{:x, 1}, :y, :z]" , fn ->
94+ Keyword . merge ( [ a: 1 , b: 2 ] , [ { :x , 1 } , :y , :z ] , fun )
95+ end
96+
97+ assert_raise ArgumentError , "expected a keyword list as the second argument, got: [:x | :y]" , fn ->
98+ Keyword . merge ( [ a: 1 , b: 2 ] , [ :x | :y ] , fun )
99+ end
100+
101+ assert_raise ArgumentError , "expected a keyword list as the second argument, got: [{:x, 1} | :y]" , fn ->
102+ Keyword . merge ( [ a: 1 , b: 2 ] , [ { :x , 1 } | :y ] , fun )
103+ end
104+
105+ # duplicate keys in keywords1 are left untouched if key is not present in keywords2
106+ assert Keyword . merge ( [ a: 1 , b: 2 , a: 3 ] , [ c: 11 , d: 12 ] , fun ) == [ a: 1 , b: 2 , a: 3 , c: 11 , d: 12 ]
107+ assert Keyword . merge ( [ a: 1 , b: 2 , a: 3 ] , [ a: 11 ] , fun ) == [ b: 2 , a: 12 ]
108+
109+ # duplicate keys in keywords2 are always kept
110+ assert Keyword . merge ( [ a: 1 , b: 2 ] , [ c: 11 , c: 12 , d: 13 ] , fun ) == [ a: 1 , b: 2 , c: 11 , c: 12 , d: 13 ]
111+
112+ # every key in keywords1 is replaced with fun result if key is present in keyword2
113+ assert Keyword . merge ( [ a: 1 , b: 2 , c: 3 , c: 4 ] , [ c: 11 , c: 50 , d: 13 ] , fun ) == [ a: 1 , b: 2 , c: 14 , c: 54 , d: 13 ]
114+ end
115+
116+ test "merge/2 and merge/3 behave exactly the same way" do
117+ fun = fn _key , _value1 , value2 -> value2 end
118+
119+ args = [
120+ { [ a: 1 , b: 2 ] , [ c: 11 , d: 12 ] } ,
121+ { [ ] , [ c: 11 , d: 12 ] } ,
122+ { [ a: 1 , b: 2 ] , [ ] } ,
123+ { [ a: 1 , b: 2 , a: 3 ] , [ c: 11 , d: 12 ] } ,
124+ { [ a: 1 , b: 2 , a: 3 ] , [ a: 11 ] } ,
125+ { [ a: 1 , b: 2 ] , [ c: 11 , c: 12 , d: 13 ] } ,
126+ { [ a: 1 , b: 2 , c: 3 , c: 4 ] , [ c: 11 , c: 12 , d: 13 ] } ,
127+ ]
128+
129+ args_error = [
130+ { [ 1 , 2 ] , [ c: 11 , d: 12 ] } ,
131+ { [ 1 | 2 ] , [ c: 11 , d: 12 ] } ,
132+ { [ a: 1 , b: 2 ] , [ 11 , 12 , 0 ] } ,
133+ { [ a: 1 , b: 2 ] , [ 11 | 12 ] } ,
134+ { [ a: 1 , b: 2 ] , [ { :x , 1 } , :y , :z ] } ,
135+ { [ a: 1 , b: 2 ] , [ :x | :y ] } ,
136+ { [ a: 1 , b: 2 ] , [ { :x , 1 } | :y ] } ,
137+ ]
138+
139+ for { arg1 , arg2 } <- args do
140+ assert Keyword . merge ( arg1 , arg2 ) == Keyword . merge ( arg1 , arg2 , fun )
141+ end
142+
143+ for { arg1 , arg2 } <- args_error do
144+ error = assert_raise ArgumentError , fn -> Keyword . merge ( arg1 , arg2 ) end
145+ assert_raise ArgumentError , error . message , fn -> Keyword . merge ( arg1 , arg2 , fun ) end
146+ end
147+ end
77148end
0 commit comments