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