1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "utils_json_visitor_test.h"
17
18 #include "json_visitor.h"
19 #include "macros_updater.h"
20
21 namespace Updater {
22 DEFINE_STRUCT_TRAIT(D, "D",
23 (int, d1),
24 (std::string, d2),
25 (bool, d3)
26 );
27
28 DEFINE_STRUCT_TRAIT(Color, "Color",
29 (int, r),
30 (std::string, g),
31 (bool, b)
32 );
33
34 DEFINE_STRUCT_TRAIT(E, "E",
35 (int, d1),
36 (Color, d2)
37 );
38
39 DEFINE_STRUCT_TRAIT(F, "F",
40 (int, d1),
41 (std::string, d2)
42 );
43
44 DEFINE_STRUCT_TRAIT(G, "G",
45 (int, d1),
46 (bool, d2),
47 (F, d3)
48 );
49
50 DEFINE_STRUCT_TRAIT(H, "H",
51 (int, d1),
52 (bool, d2),
53 (G, d3)
54 );
55
56 DEFINE_STRUCT_TRAIT(I, "I",
57 (std::vector<std::string>, d1)
58 );
59
60 DEFINE_STRUCT_TRAIT(J, "J",
61 (std::vector<std::vector<std::string>>, d1)
62 );
63
64 DEFINE_STRUCT_TRAIT(K, "K",
65 (int, d1),
66 (std::string, d2)
67 );
68
69 DEFINE_STRUCT_TRAIT(L, "L",
70 (std::vector<int>, d1)
71 );
72
operator ==(const D & lhs,const D & rhs)73 bool operator==(const D &lhs, const D &rhs)
74 {
75 return lhs.d1 == rhs.d1 && lhs.d2 == rhs.d2 && lhs.d3 == rhs.d3;
76 }
77 }
78
79 using namespace Updater;
80 using namespace std;
81 using namespace testing::ext;
82
83 namespace {
84 using PairType = std::pair<std::string_view, std::string_view>;
85 template<typename T, std::size_t N>
TestInvalidCases(T & obj,const std::array<PairType,N> & replaceData,const std::string & jsonStr)86 void TestInvalidCases(T &obj, const std::array<PairType, N> &replaceData, const std::string &jsonStr)
87 {
88 for (auto data : replaceData) {
89 auto pos = jsonStr.find(data.first);
90 ASSERT_NE(pos, std::string::npos) << data.first;
91 {
92 // make type not matched
93 std::string newJsonStr = jsonStr;
94 newJsonStr.replace(pos, data.first.size(), data.second.data(), data.second.size());
95 JsonNode node {newJsonStr};
96 EXPECT_EQ(false, Visit<SETVAL>(node[Traits<T>::STRUCT_KEY], obj)) << data.first;
97 EXPECT_EQ(false, Visit<SETVAL>({}, node[Traits<T>::STRUCT_KEY], obj)) << data.first;
98 }
99 {
100 // make field not existed
101 std::string newJsonStr = jsonStr;
102 newJsonStr.replace(pos, data.first.size(), "");
103 JsonNode node {newJsonStr};
104 EXPECT_EQ(false, Visit<SETVAL>(node[Traits<T>::STRUCT_KEY], obj)) << data.first;
105 EXPECT_EQ(false, Visit<SETVAL>({}, node[Traits<T>::STRUCT_KEY], obj)) << data.first;
106 }
107 }
108 }
109 }
110
111 namespace UpdaterUt {
112 // do something at the each function begining
SetUp(void)113 void UtilsJsonVisitorUnitTest::SetUp(void)
114 {
115 cout << "Updater Unit UtilsJsonVisitorUnitTest Begin!" << endl;
116 }
117
118 // do something at the each function end
TearDown(void)119 void UtilsJsonVisitorUnitTest::TearDown(void)
120 {
121 cout << "Updater Unit UtilsJsonVisitorUnitTest End!" << endl;
122 }
123
124 // init
SetUpTestCase(void)125 void UtilsJsonVisitorUnitTest::SetUpTestCase(void)
126 {
127 cout << "SetUpTestCase" << endl;
128 }
129
130 // end
TearDownTestCase(void)131 void UtilsJsonVisitorUnitTest::TearDownTestCase(void)
132 {
133 cout << "TearDownTestCase" << endl;
134 }
135
136 HWTEST_F(UtilsJsonVisitorUnitTest, testD, TestSize.Level0)
137 {
138 std::string dJson = R"({
139 "D": {
140 "d1":1,
141 "d2":"true",
142 "d3":true
143 }
144 })";
145 JsonNode node {dJson};
146 D d {};
147 EXPECT_EQ(Visit<SETVAL>(node["D"], d), true);
148 EXPECT_EQ(d.d1, 1);
149 EXPECT_EQ(d.d2, "true");
150 EXPECT_EQ(d.d3, true);
151
152 constexpr std::array replaceData {
153 PairType { R"("d1":1)", R"("d1":"1")" }, PairType { R"("d2":"true")", R"("d2":true)" },
154 PairType { R"("d3":true)", R"("d3":"true")" }
155 };
156 TestInvalidCases(d, replaceData, dJson);
157 }
158
159 HWTEST_F(UtilsJsonVisitorUnitTest, testE, TestSize.Level0)
160 {
161 std::string eJson = R"({
162 "E": {
163 "d1":1,
164 "d2": {
165 "r":1,
166 "g":"foo",
167 "b":true
168 }
169 }
170 })";
171 E e {};
172 JsonNode node {eJson};
173 EXPECT_EQ(Visit<SETVAL>(node["E"], e), true);
174 EXPECT_EQ(e.d1, 1);
175 EXPECT_EQ(e.d2.r, 1);
176 EXPECT_EQ(e.d2.g, "foo");
177 EXPECT_EQ(e.d2.b, true);
178
179 constexpr std::array replaceData {
180 PairType { R"("d1":1)", R"("d1":"1")" }, PairType { R"("r":1)", R"("r":"1")" },
181 PairType { R"("g":"foo")", R"("g":1)" }, PairType { R"("b":true)", R"("b":"true")" },
182 PairType { R"("d2": {
183 "r":1,
184 "g":"foo",
185 "b":true
186 })", R"("d2":2)"},
187 };
188 TestInvalidCases(e, replaceData, eJson);
189 }
190
191 HWTEST_F(UtilsJsonVisitorUnitTest, testH, TestSize.Level0)
192 {
193 std::string hJson = R"({
194 "H": {
195 "d1":1,
196 "d2":true,
197 "d3": {
198 "d1":2,
199 "d2":false,
200 "d3": {
201 "d1":3,
202 "d2":"foo"
203 }
204 }
205 }
206 })";
207 H h {};
208 JsonNode node {hJson};
209 EXPECT_EQ(Visit<SETVAL>(node["H"], h), true);
210 EXPECT_EQ(h.d1, 1);
211 EXPECT_EQ(h.d2, true);
212 EXPECT_EQ(h.d3.d1, 2);
213 EXPECT_EQ(h.d3.d2, false);
214 EXPECT_EQ(h.d3.d3.d1, 3);
215 EXPECT_EQ(h.d3.d3.d2, "foo");
216
217 constexpr std::array replaceData {
218 PairType { R"("d1":1)", R"("d1":"1")" }, PairType { R"("d1":2)", R"("d1":"2")" },
219 PairType { R"("d1":3)", R"("d1":"3")" }, PairType { R"("d2":true)", R"("d2":"true")" },
220 PairType { R"("d2":false)", R"("d2":"false")" }, PairType { R"("d2":"foo")", R"("d2":1)" },
221 PairType { R"("d3": {
222 "d1":2,
223 "d2":false,
224 "d3": {
225 "d1":3,
226 "d2":"foo"
227 }
228 })", R"("d3":1)"},
229 PairType { R"("d3": {
230 "d1":3,
231 "d2":"foo"
232 })", R"("d3":2)"}
233 };
234 TestInvalidCases(h, replaceData, hJson);
235 }
236
237 HWTEST_F(UtilsJsonVisitorUnitTest, testI, TestSize.Level0)
238 {
239 std::string iJson = R"({ "I" : { "d1": [ "foo", "bar", "baz" ] } })";
240 I i {};
241 JsonNode node {iJson};
242 EXPECT_EQ(Visit<SETVAL>(node["I"], i), true);
243 EXPECT_EQ(i.d1, std::vector<std::string>({"foo", "bar", "baz"}));
244 i = {};
245 EXPECT_EQ(Visit<SETVAL>({}, node["I"], i), true);
246 EXPECT_EQ(i.d1, std::vector<std::string>({"foo", "bar", "baz"}));
247 EXPECT_EQ(Visit<SETVAL>(JsonNode {R"({"I" : { "d1" : 1 }})"s} ["I"], i), false);
248 EXPECT_EQ(Visit<SETVAL>({}, JsonNode {R"({"I" : { "d1" : 1 }})"s} ["I"], i), false);
249 EXPECT_EQ(Visit<SETVAL>(JsonNode {R"({ "I" : { "d1": "foo" } })"s} ["I"], i), false);
250 EXPECT_EQ(Visit<SETVAL>(JsonNode {R"({ "I" : { "d1": [ 1 ] } })"s} ["I"], i), false);
251 }
252
253 HWTEST_F(UtilsJsonVisitorUnitTest, testJ, TestSize.Level0)
254 {
255 J j {};
256 JsonNode node {R"({"J" : {"d1" : [["foo","bar","baz"],["foo1","bar1","baz1"]]}})"s};
257 EXPECT_EQ(Visit<SETVAL>(node["J"], j), true);
258 ASSERT_EQ(j.d1.size(), 2u);
259 EXPECT_EQ(j.d1[0], std::vector<std::string>({"foo", "bar", "baz"}));
260 EXPECT_EQ(j.d1[1], std::vector<std::string>({"foo1", "bar1", "baz1"}));
261
262 j = {};
263 EXPECT_EQ(Visit<SETVAL>({}, node["J"], j), true);
264 ASSERT_EQ(j.d1.size(), 2u);
265 EXPECT_EQ(j.d1[0], std::vector<std::string>({"foo", "bar", "baz"}));
266 EXPECT_EQ(j.d1[1], std::vector<std::string>({"foo1", "bar1", "baz1"}));
267
268 j = {};
269 EXPECT_EQ(Visit<SETVAL>(JsonNode {R"({"J" : { "d1" : 1 }})"s} ["J"], j), false);
270 EXPECT_EQ(Visit<SETVAL>(JsonNode {R"({"J" : { "d1" : [1] }})"s} ["J"], j), false);
271 EXPECT_EQ(Visit<SETVAL>(JsonNode {R"({"J" : { "d1" : [[1]] }})"s} ["J"], j), false);
272 EXPECT_EQ(Visit<SETVAL>({}, JsonNode {R"({"J" : { "d1" : 1 }})"s} ["J"], j), false);
273 EXPECT_EQ(Visit<SETVAL>({}, JsonNode {R"({"J" : { "d1" : [1] }})"s} ["J"], j), false);
274 EXPECT_EQ(Visit<SETVAL>({}, JsonNode {R"({"J" : { "d1" : [[1]] }})"s} ["J"], j), false);
275 }
276
277 HWTEST_F(UtilsJsonVisitorUnitTest, testInvalidK, TestSize.Level0)
278 {
279 K k {};
280 EXPECT_EQ(Visit<SETVAL>(JsonNode {R"({ "K" : { "d1" : 1 } })"s} ["K"], k), false);
281 EXPECT_EQ(Visit<SETVAL>(JsonNode {R"({ "K" : { "d1" : "1" } })"s} ["K"], k), false);
282 }
283
284 HWTEST_F(UtilsJsonVisitorUnitTest, testNoDefaultAndNonDefaultK, TestSize.Level0)
285 {
286 std::string kJson = R"({
287 "K" : { "d1" : 1 },
288 "KNonDefault0" : { "d1" : 2 },
289 "KNonDefault1" : { "d1" : 2, "d2" : "v2" }
290 })";
291 K k {};
292 JsonNode node {kJson};
293 EXPECT_EQ(Visit<SETVAL>(node["KNonDefault0"], node["K"], k), false);
294 EXPECT_EQ(Visit<SETVAL>(node["KNonDefault0"], JsonNode {"{"s}, k), false);
295 EXPECT_EQ(Visit<SETVAL>(JsonNode {"{"s}, node["KNonDefault0"], k), false);
296 EXPECT_EQ(Visit<SETVAL>(node["KNonDefault1"], node["K"], k), true);
297 EXPECT_EQ(k.d1, 2);
298 EXPECT_EQ(k.d2, "v2");
299 }
300
301 HWTEST_F(UtilsJsonVisitorUnitTest, testArrayL, TestSize.Level0)
302 {
303 std::string lJson = R"({
304 "L" : { "d1" : [1] },
305 "LNonDefault0" : { "d1" : [2] },
306 "LNonDefault1" : { "d1" : "2" },
307 "LNonDefault2" : { "d1" : ["2"] }
308 })";
309 L l {};
310 JsonNode node {lJson};
311 EXPECT_EQ(Visit<SETVAL>(node["LNonDefault0"], node["L"], l), true);
312 EXPECT_EQ(l.d1, std::vector<int>({2, 1}));
313
314 l = {};
315 EXPECT_EQ(Visit<SETVAL>(node["L"], node["LNonDefault0"], l), true);
316 EXPECT_EQ(l.d1, std::vector<int>({1, 2}));
317
318 EXPECT_EQ(Visit<SETVAL>(node["LNonDefault1"], node["L"], l), false);
319 EXPECT_EQ(Visit<SETVAL>(node["L"], node["LNonDefault1"], l), false);
320 EXPECT_EQ(Visit<SETVAL>(node["L"], node["LNonDefault2"], l), false);
321 EXPECT_EQ(Visit<SETVAL>(node["LNonDefault2"], node["L"], l), false);
322 }
323
324 HWTEST_F(UtilsJsonVisitorUnitTest, testVisitVector, TestSize.Level0)
325 {
326 std::string jsonStr = R"({
327 "dVector" : [
328 {"d1":1, "d2":"1", "d3":false},
329 {"d1":2, "d2":"2", "d3":true},
330 {"d1":3, "d2":"3", "d3":false}
331 ],
332 "dVector_empty" : [],
333 "dVector_invalid1" : [{"d1":1, "d2":"1"}],
334 "dVector_invalid2" : [{"d1":"1"}]
335 })";
336 std::vector<D> dVector {};
337 JsonNode node {jsonStr};
338 EXPECT_EQ(Visit<SETVAL>(node["dVector"], dVector), true);
339 EXPECT_EQ(dVector, (std::vector<D>{{1, "1", false}, {2, "2", true}, {3, "3", false}}));
340
341 dVector.clear();
342 EXPECT_EQ(Visit<SETVAL>(node["dVector_empty"], dVector), true);
343 EXPECT_EQ(dVector, std::vector<D>{});
344
345 dVector.clear();
346 EXPECT_EQ(Visit<SETVAL>(node["dVector_invalid1"], dVector), false);
347
348 dVector.clear();
349 EXPECT_EQ(Visit<SETVAL>(node["dVector_invalid2"], dVector), false);
350 }
351 } // namespace UpdaterUt
352