1 // Licensed to the Apache Software Foundation (ASF) under one
2 // or more contributor license agreements.  See the NOTICE file
3 // distributed with this work for additional information
4 // regarding copyright ownership.  The ASF licenses this file
5 // to you under the Apache License, Version 2.0 (the
6 // "License"); you may not use this file except in compliance
7 // with the License.  You may obtain a copy of the License at
8 //
9 //   http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing,
12 // software distributed under the License is distributed on an
13 // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 // KIND, either express or implied.  See the License for the
15 // specific language governing permissions and limitations
16 // under the License.
17 
18 #include "arrow/json/converter.h"
19 
20 #include <gtest/gtest.h>
21 
22 #include <string>
23 
24 #include "arrow/json/options.h"
25 #include "arrow/json/test_common.h"
26 
27 namespace arrow {
28 namespace json {
29 
Convert(std::shared_ptr<DataType> type,std::shared_ptr<Array> unconverted)30 Result<std::shared_ptr<Array>> Convert(std::shared_ptr<DataType> type,
31                                        std::shared_ptr<Array> unconverted) {
32   std::shared_ptr<Array> converted;
33   // convert the array
34   std::shared_ptr<Converter> converter;
35   RETURN_NOT_OK(MakeConverter(type, default_memory_pool(), &converter));
36   RETURN_NOT_OK(converter->Convert(unconverted, &converted));
37   RETURN_NOT_OK(converted->ValidateFull());
38   return converted;
39 }
40 
41 // bool, null are trivial pass throughs
42 
TEST(ConverterTest,Integers)43 TEST(ConverterTest, Integers) {
44   for (auto int_type : {int8(), int16(), int32(), int64()}) {
45     ParseOptions options;
46     options.explicit_schema = schema({field("", int_type)});
47 
48     std::string json_source = R"(
49     {"" : -0}
50     {"" : null}
51     {"" : -1}
52     {"" : 32}
53     {"" : -45}
54     {"" : 12}
55     {"" : -64}
56     {"" : 124}
57   )";
58 
59     std::shared_ptr<StructArray> parse_array;
60     ASSERT_OK(ParseFromString(options, json_source, &parse_array));
61 
62     // call to convert
63     ASSERT_OK_AND_ASSIGN(auto converted,
64                          Convert(int_type, parse_array->GetFieldByName("")));
65 
66     // assert equality
67     auto expected = ArrayFromJSON(int_type, R"([
68           -0, null, -1, 32, -45, 12, -64, 124])");
69 
70     AssertArraysEqual(*expected, *converted);
71   }
72 }
73 
TEST(ConverterTest,UnsignedIntegers)74 TEST(ConverterTest, UnsignedIntegers) {
75   for (auto uint_type : {uint8(), uint16(), uint32(), uint64()}) {
76     ParseOptions options;
77     options.explicit_schema = schema({field("", uint_type)});
78 
79     std::string json_source = R"(
80     {"" : 0}
81     {"" : null}
82     {"" : 1}
83     {"" : 32}
84     {"" : 45}
85     {"" : 12}
86     {"" : 64}
87     {"" : 124}
88   )";
89 
90     std::shared_ptr<StructArray> parse_array;
91     ASSERT_OK(ParseFromString(options, json_source, &parse_array));
92 
93     // call to convert
94     ASSERT_OK_AND_ASSIGN(auto converted,
95                          Convert(uint_type, parse_array->GetFieldByName("")));
96 
97     // assert equality
98     auto expected = ArrayFromJSON(uint_type, R"([
99           0, null, 1, 32, 45, 12, 64, 124])");
100 
101     AssertArraysEqual(*expected, *converted);
102   }
103 }
104 
TEST(ConverterTest,Floats)105 TEST(ConverterTest, Floats) {
106   for (auto float_type : {float32(), float64()}) {
107     ParseOptions options;
108     options.explicit_schema = schema({field("", float_type)});
109 
110     std::string json_source = R"(
111     {"" : 0}
112     {"" : -0.0}
113     {"" : null}
114     {"" : 32.0}
115     {"" : 1e5}
116   )";
117 
118     std::shared_ptr<StructArray> parse_array;
119     ASSERT_OK(ParseFromString(options, json_source, &parse_array));
120 
121     // call to convert
122     ASSERT_OK_AND_ASSIGN(auto converted,
123                          Convert(float_type, parse_array->GetFieldByName("")));
124 
125     // assert equality
126     auto expected = ArrayFromJSON(float_type, R"([
127           0, -0.0, null, 32.0, 1e5])");
128 
129     AssertArraysEqual(*expected, *converted);
130   }
131 }
132 
TEST(ConverterTest,StringAndLargeString)133 TEST(ConverterTest, StringAndLargeString) {
134   for (auto string_type : {utf8(), large_utf8()}) {
135     ParseOptions options;
136     options.explicit_schema = schema({field("", string_type)});
137 
138     std::string json_source = R"(
139     {"" : "a"}
140     {"" : "b c"}
141     {"" : null}
142     {"" : "d e f"}
143     {"" : "g"}
144   )";
145 
146     std::shared_ptr<StructArray> parse_array;
147     ASSERT_OK(ParseFromString(options, json_source, &parse_array));
148 
149     // call to convert
150     ASSERT_OK_AND_ASSIGN(auto converted,
151                          Convert(string_type, parse_array->GetFieldByName("")));
152 
153     // assert equality
154     auto expected = ArrayFromJSON(string_type, R"([
155           "a", "b c", null, "d e f", "g"])");
156 
157     AssertArraysEqual(*expected, *converted);
158   }
159 }
160 
TEST(ConverterTest,Timestamp)161 TEST(ConverterTest, Timestamp) {
162   auto timestamp_type = timestamp(TimeUnit::SECOND);
163 
164   ParseOptions options;
165   options.explicit_schema = schema({field("", timestamp_type)});
166 
167   std::string json_source = R"(
168     {"" : null}
169     {"" : "1970-01-01"}
170     {"" : "2018-11-13 17:11:10"}
171   )";
172 
173   std::shared_ptr<StructArray> parse_array;
174   ASSERT_OK(ParseFromString(options, json_source, &parse_array));
175 
176   // call to convert
177   ASSERT_OK_AND_ASSIGN(auto converted,
178                        Convert(timestamp_type, parse_array->GetFieldByName("")));
179 
180   // assert equality
181   auto expected = ArrayFromJSON(timestamp_type, R"([
182           null, "1970-01-01", "2018-11-13 17:11:10"])");
183 
184   AssertArraysEqual(*expected, *converted);
185 }
186 
TEST(ConverterTest,Decimal128And256)187 TEST(ConverterTest, Decimal128And256) {
188   for (auto decimal_type : {decimal128(38, 10), decimal256(38, 10)}) {
189     ParseOptions options;
190     options.explicit_schema = schema({field("", decimal_type)});
191 
192     std::string json_source = R"(
193     {"" : "02.0000000000"}
194     {"" : "30.0000000000"}
195   )";
196 
197     std::shared_ptr<StructArray> parse_array;
198     ASSERT_OK(ParseFromString(options, json_source, &parse_array));
199 
200     // call to convert
201     ASSERT_OK_AND_ASSIGN(auto converted,
202                          Convert(decimal_type, parse_array->GetFieldByName("")));
203 
204     // assert equality
205     auto expected = ArrayFromJSON(decimal_type, R"([
206           "02.0000000000",
207           "30.0000000000"])");
208 
209     AssertArraysEqual(*expected, *converted);
210   }
211 }
212 
213 }  // namespace json
214 }  // namespace arrow
215