22
33import pytest
44
5- from pyathena .converter import DefaultTypeConverter , _to_struct
5+ from pyathena .converter import DefaultTypeConverter , _to_array , _to_struct
66
77
88@pytest .mark .parametrize (
@@ -74,6 +74,38 @@ def test_to_map_athena_numeric_keys():
7474 assert result == expected
7575
7676
77+ def test_to_array_athena_numeric_elements ():
78+ """Test Athena array with numeric elements"""
79+ array_value = "[1, 2, 3, 4]"
80+ result = _to_array (array_value )
81+ expected = [1 , 2 , 3 , 4 ]
82+ assert result == expected
83+
84+
85+ def test_to_array_athena_mixed_elements ():
86+ """Test Athena array with mixed type elements"""
87+ array_value = "[1, hello, true, null]"
88+ result = _to_array (array_value )
89+ expected = [1 , "hello" , True , None ]
90+ assert result == expected
91+
92+
93+ def test_to_array_athena_struct_elements ():
94+ """Test Athena array with struct elements"""
95+ array_value = "[{name=John, age=30}, {name=Jane, age=25}]"
96+ result = _to_array (array_value )
97+ expected = [{"name" : "John" , "age" : 30 }, {"name" : "Jane" , "age" : 25 }]
98+ assert result == expected
99+
100+
101+ def test_to_array_athena_unnamed_struct_elements ():
102+ """Test Athena array with unnamed struct elements"""
103+ array_value = "[{Alice, 25}, {Bob, 30}]"
104+ result = _to_array (array_value )
105+ expected = [{"0" : "Alice" , "1" : 25 }, {"0" : "Bob" , "1" : 30 }]
106+ assert result == expected
107+
108+
77109@pytest .mark .parametrize (
78110 "input_value" ,
79111 [
@@ -88,6 +120,101 @@ def test_to_struct_non_dict_json(input_value):
88120 assert result is None
89121
90122
123+ @pytest .mark .parametrize (
124+ "input_value,expected" ,
125+ [
126+ (None , None ),
127+ (
128+ "[1, 2, 3, 4, 5]" ,
129+ [1 , 2 , 3 , 4 , 5 ],
130+ ),
131+ (
132+ '["apple", "banana", "cherry"]' ,
133+ ["apple" , "banana" , "cherry" ],
134+ ),
135+ (
136+ "[true, false, null]" ,
137+ [True , False , None ],
138+ ),
139+ (
140+ '[{"name": "John", "age": 30}, {"name": "Jane", "age": 25}]' ,
141+ [{"name" : "John" , "age" : 30 }, {"name" : "Jane" , "age" : 25 }],
142+ ),
143+ ("not valid json" , None ),
144+ ("" , None ),
145+ ("[]" , []),
146+ ],
147+ )
148+ def test_to_array_json_formats (input_value , expected ):
149+ """Test ARRAY conversion for various JSON formats and edge cases."""
150+ result = _to_array (input_value )
151+ assert result == expected
152+
153+
154+ @pytest .mark .parametrize (
155+ "input_value,expected" ,
156+ [
157+ ("[1, 2, 3]" , [1 , 2 , 3 ]),
158+ ("[]" , []),
159+ ("[apple, banana, cherry]" , ["apple" , "banana" , "cherry" ]),
160+ ("[{Alice, 25}, {Bob, 30}]" , [{"0" : "Alice" , "1" : 25 }, {"0" : "Bob" , "1" : 30 }]),
161+ (
162+ "[{name=John, age=30}, {name=Jane, age=25}]" ,
163+ [{"name" : "John" , "age" : 30 }, {"name" : "Jane" , "age" : 25 }],
164+ ),
165+ ("[true, false, null]" , [True , False , None ]),
166+ ("[1, 2.5, hello]" , [1 , 2.5 , "hello" ]),
167+ ],
168+ )
169+ def test_to_array_athena_native_formats (input_value , expected ):
170+ """Test ARRAY conversion for Athena native formats."""
171+ result = _to_array (input_value )
172+ assert result == expected
173+
174+
175+ @pytest .mark .parametrize (
176+ "input_value,expected" ,
177+ [
178+ ("[ARRAY[1, 2], ARRAY[3, 4]]" , None ), # Nested arrays (native format)
179+ ("[[1, 2], [3, 4]]" , [[1 , 2 ], [3 , 4 ]]), # Nested arrays (JSON format - parseable)
180+ ("[MAP(ARRAY['key'], ARRAY['value'])]" , None ), # Complex nested structures
181+ ],
182+ )
183+ def test_to_array_complex_nested_cases (input_value , expected ):
184+ """Test complex nested array cases behavior."""
185+ result = _to_array (input_value )
186+ assert result == expected
187+
188+
189+ @pytest .mark .parametrize (
190+ "input_value" ,
191+ [
192+ '"just a string"' , # String JSON
193+ "42" , # Number JSON
194+ '{"key": "value"}' , # Object JSON
195+ ],
196+ )
197+ def test_to_array_non_array_json (input_value ):
198+ """Test that non-array JSON formats return None."""
199+ result = _to_array (input_value )
200+ assert result is None
201+
202+
203+ @pytest .mark .parametrize (
204+ "input_value" ,
205+ [
206+ "not an array" , # Not bracketed
207+ "[unclosed array" , # Malformed
208+ "closed array]" , # Malformed
209+ "[{malformed struct}" , # Malformed struct
210+ ],
211+ )
212+ def test_to_array_invalid_formats (input_value ):
213+ """Test that invalid array formats return None."""
214+ result = _to_array (input_value )
215+ assert result is None
216+
217+
91218class TestDefaultTypeConverter :
92219 @pytest .mark .parametrize (
93220 "input_value,expected" ,
@@ -104,3 +231,21 @@ def test_struct_conversion(self, input_value, expected):
104231 converter = DefaultTypeConverter ()
105232 result = converter .convert ("row" , input_value )
106233 assert result == expected
234+
235+ @pytest .mark .parametrize (
236+ "input_value,expected" ,
237+ [
238+ ("[1, 2, 3]" , [1 , 2 , 3 ]),
239+ ('["a", "b", "c"]' , ["a" , "b" , "c" ]),
240+ (None , None ),
241+ ("" , None ),
242+ ("invalid json" , None ),
243+ ("[apple, banana]" , ["apple" , "banana" ]),
244+ ("[]" , []),
245+ ],
246+ )
247+ def test_array_conversion (self , input_value , expected ):
248+ """Test DefaultTypeConverter ARRAY conversion for various input formats."""
249+ converter = DefaultTypeConverter ()
250+ result = converter .convert ("array" , input_value )
251+ assert result == expected
0 commit comments