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.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 }
73
74 using namespace Updater;
75 using namespace std;
76 using namespace testing::ext;
77
78 namespace {
79 using PairType = std::pair<std::string_view, std::string_view>;
80 template<typename T, std::size_t N>
TestInvalidCases(T & obj,const std::array<PairType,N> & replaceData,const std::string & jsonStr)81 void TestInvalidCases(T &obj, const std::array<PairType, N> &replaceData, const std::string &jsonStr)
82 {
83 for (auto data : replaceData) {
84 auto pos = jsonStr.find(data.first);
85 ASSERT_NE(pos, std::string::npos) << data.first;
86 {
87 // make type not matched
88 std::string newJsonStr = jsonStr;
89 newJsonStr.replace(pos, data.first.size(), data.second.data(), data.second.size());
90 JsonNode node {newJsonStr};
91 EXPECT_EQ(false, Visit<SETVAL>(node[Traits<T>::STRUCT_KEY], obj)) << data.first;
92 EXPECT_EQ(false, Visit<SETVAL>({}, node[Traits<T>::STRUCT_KEY], obj)) << data.first;
93 }
94 {
95 // make field not existed
96 std::string newJsonStr = jsonStr;
97 newJsonStr.replace(pos, data.first.size(), "");
98 JsonNode node {newJsonStr};
99 EXPECT_EQ(false, Visit<SETVAL>(node[Traits<T>::STRUCT_KEY], obj)) << data.first;
100 EXPECT_EQ(false, Visit<SETVAL>({}, node[Traits<T>::STRUCT_KEY], obj)) << data.first;
101 }
102 }
103 }
104 }
105
106 namespace UpdaterUt {
107 // do something at the each function begining
SetUp(void)108 void UtilsJsonVisitorUnitTest::SetUp(void)
109 {
110 cout << "Updater Unit UtilsJsonVisitorUnitTest Begin!" << endl;
111 }
112
113 // do something at the each function end
TearDown(void)114 void UtilsJsonVisitorUnitTest::TearDown(void)
115 {
116 cout << "Updater Unit UtilsJsonVisitorUnitTest End!" << endl;
117 }
118
119 // init
SetUpTestCase(void)120 void UtilsJsonVisitorUnitTest::SetUpTestCase(void)
121 {
122 cout << "SetUpTestCase" << endl;
123 }
124
125 // end
TearDownTestCase(void)126 void UtilsJsonVisitorUnitTest::TearDownTestCase(void)
127 {
128 cout << "TearDownTestCase" << endl;
129 }
130
131 HWTEST_F(UtilsJsonVisitorUnitTest, testD, TestSize.Level0)
132 {
133 std::string dJson = R"({
134 "D": {
135 "d1":1,
136 "d2":"true",
137 "d3":true
138 }
139 })";
140 JsonNode node {dJson};
141 D d {};
142 EXPECT_EQ(Visit<SETVAL>(node["D"], d), true);
143 EXPECT_EQ(d.d1, 1);
144 EXPECT_EQ(d.d2, "true");
145 EXPECT_EQ(d.d3, true);
146
147 constexpr std::array replaceData {
148 PairType { R"("d1":1)", R"("d1":"1")" }, PairType { R"("d2":"true")", R"("d2":true)" },
149 PairType { R"("d3":true)", R"("d3":"true")" }
150 };
151 TestInvalidCases(d, replaceData, dJson);
152 }
153
154 HWTEST_F(UtilsJsonVisitorUnitTest, testE, TestSize.Level0)
155 {
156 std::string eJson = R"({
157 "E": {
158 "d1":1,
159 "d2": {
160 "r":1,
161 "g":"foo",
162 "b":true
163 }
164 }
165 })";
166 E e {};
167 JsonNode node {eJson};
168 EXPECT_EQ(Visit<SETVAL>(node["E"], e), true);
169 EXPECT_EQ(e.d1, 1);
170 EXPECT_EQ(e.d2.r, 1);
171 EXPECT_EQ(e.d2.g, "foo");
172 EXPECT_EQ(e.d2.b, true);
173
174 constexpr std::array replaceData {
175 PairType { R"("d1":1)", R"("d1":"1")" }, PairType { R"("r":1)", R"("r":"1")" },
176 PairType { R"("g":"foo")", R"("g":1)" }, PairType { R"("b":true)", R"("b":"true")" },
177 PairType { R"("d2": {
178 "r":1,
179 "g":"foo",
180 "b":true
181 })", R"("d2":2)"},
182 };
183 TestInvalidCases(e, replaceData, eJson);
184 }
185
186 HWTEST_F(UtilsJsonVisitorUnitTest, testH, TestSize.Level0)
187 {
188 std::string hJson = R"({
189 "H": {
190 "d1":1,
191 "d2":true,
192 "d3": {
193 "d1":2,
194 "d2":false,
195 "d3": {
196 "d1":3,
197 "d2":"foo"
198 }
199 }
200 }
201 })";
202 H h {};
203 JsonNode node {hJson};
204 EXPECT_EQ(Visit<SETVAL>(node["H"], h), true);
205 EXPECT_EQ(h.d1, 1);
206 EXPECT_EQ(h.d2, true);
207 EXPECT_EQ(h.d3.d1, 2);
208 EXPECT_EQ(h.d3.d2, false);
209 EXPECT_EQ(h.d3.d3.d1, 3);
210 EXPECT_EQ(h.d3.d3.d2, "foo");
211
212 constexpr std::array replaceData {
213 PairType { R"("d1":1)", R"("d1":"1")" }, PairType { R"("d1":2)", R"("d1":"2")" },
214 PairType { R"("d1":3)", R"("d1":"3")" }, PairType { R"("d2":true)", R"("d2":"true")" },
215 PairType { R"("d2":false)", R"("d2":"false")" }, PairType { R"("d2":"foo")", R"("d2":1)" },
216 PairType { R"("d3": {
217 "d1":2,
218 "d2":false,
219 "d3": {
220 "d1":3,
221 "d2":"foo"
222 }
223 })", R"("d3":1)"},
224 PairType { R"("d3": {
225 "d1":3,
226 "d2":"foo"
227 })", R"("d3":2)"}
228 };
229 TestInvalidCases(h, replaceData, hJson);
230 }
231
232 HWTEST_F(UtilsJsonVisitorUnitTest, testI, TestSize.Level0)
233 {
234 std::string iJson = R"({ "I" : { "d1": [ "foo", "bar", "baz" ] } })";
235 I i {};
236 JsonNode node {iJson};
237 EXPECT_EQ(Visit<SETVAL>(node["I"], i), true);
238 EXPECT_EQ(i.d1, std::vector<std::string>({"foo", "bar", "baz"}));
239 i = {};
240 EXPECT_EQ(Visit<SETVAL>({}, node["I"], i), true);
241 EXPECT_EQ(i.d1, std::vector<std::string>({"foo", "bar", "baz"}));
242 EXPECT_EQ(Visit<SETVAL>(JsonNode {R"({"I" : { "d1" : 1 }})"s} ["I"], i), false);
243 EXPECT_EQ(Visit<SETVAL>({}, JsonNode {R"({"I" : { "d1" : 1 }})"s} ["I"], i), false);
244 EXPECT_EQ(Visit<SETVAL>(JsonNode {R"({ "I" : { "d1": "foo" } })"s} ["I"], i), false);
245 EXPECT_EQ(Visit<SETVAL>(JsonNode {R"({ "I" : { "d1": [ 1 ] } })"s} ["I"], i), false);
246 }
247
248 HWTEST_F(UtilsJsonVisitorUnitTest, testJ, TestSize.Level0)
249 {
250 J j {};
251 JsonNode node {R"({"J" : {"d1" : [["foo","bar","baz"],["foo1","bar1","baz1"]]}})"s};
252 EXPECT_EQ(Visit<SETVAL>(node["J"], j), true);
253 ASSERT_EQ(j.d1.size(), 2);
254 EXPECT_EQ(j.d1[0], std::vector<std::string>({"foo", "bar", "baz"}));
255 EXPECT_EQ(j.d1[1], std::vector<std::string>({"foo1", "bar1", "baz1"}));
256
257 j = {};
258 EXPECT_EQ(Visit<SETVAL>({}, node["J"], j), true);
259 ASSERT_EQ(j.d1.size(), 2);
260 EXPECT_EQ(j.d1[0], std::vector<std::string>({"foo", "bar", "baz"}));
261 EXPECT_EQ(j.d1[1], std::vector<std::string>({"foo1", "bar1", "baz1"}));
262
263 j = {};
264 EXPECT_EQ(Visit<SETVAL>(JsonNode {R"({"J" : { "d1" : 1 }})"s} ["J"], j), false);
265 EXPECT_EQ(Visit<SETVAL>(JsonNode {R"({"J" : { "d1" : [1] }})"s} ["J"], j), false);
266 EXPECT_EQ(Visit<SETVAL>(JsonNode {R"({"J" : { "d1" : [[1]] }})"s} ["J"], j), false);
267 EXPECT_EQ(Visit<SETVAL>({}, JsonNode {R"({"J" : { "d1" : 1 }})"s} ["J"], j), false);
268 EXPECT_EQ(Visit<SETVAL>({}, JsonNode {R"({"J" : { "d1" : [1] }})"s} ["J"], j), false);
269 EXPECT_EQ(Visit<SETVAL>({}, JsonNode {R"({"J" : { "d1" : [[1]] }})"s} ["J"], j), false);
270 }
271
272 HWTEST_F(UtilsJsonVisitorUnitTest, testInvalidK, TestSize.Level0)
273 {
274 K k {};
275 EXPECT_EQ(Visit<SETVAL>(JsonNode {R"({ "K" : { "d1" : 1 } })"s} ["K"], k), false);
276 EXPECT_EQ(Visit<SETVAL>(JsonNode {R"({ "K" : { "d1" : "1" } })"s} ["K"], k), false);
277 }
278
279 HWTEST_F(UtilsJsonVisitorUnitTest, testNoDefaultAndNonDefaultK, TestSize.Level0)
280 {
281 std::string kJson = R"({
282 "K" : { "d1" : 1 },
283 "KNonDefault0" : { "d1" : 2 },
284 "KNonDefault1" : { "d1" : 2, "d2" : "v2" }
285 })";
286 K k {};
287 JsonNode node {kJson};
288 EXPECT_EQ(Visit<SETVAL>(node["KNonDefault0"], node["K"], k), false);
289 EXPECT_EQ(Visit<SETVAL>(node["KNonDefault0"], JsonNode {"{"s}, k), false);
290 EXPECT_EQ(Visit<SETVAL>(JsonNode {"{"s}, node["KNonDefault0"], k), false);
291 EXPECT_EQ(Visit<SETVAL>(node["KNonDefault1"], node["K"], k), true);
292 EXPECT_EQ(k.d1, 2);
293 EXPECT_EQ(k.d2, "v2");
294 }
295
296 HWTEST_F(UtilsJsonVisitorUnitTest, testArrayL, TestSize.Level0)
297 {
298 std::string lJson = R"({
299 "L" : { "d1" : [1] },
300 "LNonDefault0" : { "d1" : [2] },
301 "LNonDefault1" : { "d1" : "2" },
302 "LNonDefault2" : { "d1" : ["2"] }
303 })";
304 L l {};
305 JsonNode node {lJson};
306 EXPECT_EQ(Visit<SETVAL>(node["LNonDefault0"], node["L"], l), true);
307 EXPECT_EQ(l.d1, std::vector<int>({2, 1}));
308
309 l = {};
310 EXPECT_EQ(Visit<SETVAL>(node["L"], node["LNonDefault0"], l), true);
311 EXPECT_EQ(l.d1, std::vector<int>({1, 2}));
312
313 EXPECT_EQ(Visit<SETVAL>(node["LNonDefault1"], node["L"], l), false);
314 EXPECT_EQ(Visit<SETVAL>(node["L"], node["LNonDefault1"], l), false);
315 EXPECT_EQ(Visit<SETVAL>(node["L"], node["LNonDefault2"], l), false);
316 EXPECT_EQ(Visit<SETVAL>(node["LNonDefault2"], node["L"], l), false);
317 }
318 } // namespace UpdaterUt
319