• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2     __ _____ _____ _____
3  __|  |   __|     |   | |  JSON for Modern C++ (test suite)
4 |  |  |__   |  |  | | | |  version 3.9.1
5 |_____|_____|_____|_|___|  https://github.com/nlohmann/json
6 
7 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
8 SPDX-License-Identifier: MIT
9 Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
10 
11 Permission is hereby  granted, free of charge, to any  person obtaining a copy
12 of this software and associated  documentation files (the "Software"), to deal
13 in the Software  without restriction, including without  limitation the rights
14 to  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell
15 copies  of  the Software,  and  to  permit persons  to  whom  the Software  is
16 furnished to do so, subject to the following conditions:
17 
18 The above copyright notice and this permission notice shall be included in all
19 copies or substantial portions of the Software.
20 
21 THE SOFTWARE  IS PROVIDED "AS  IS", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR
22 IMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,
23 FITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE
24 AUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER
25 LIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 OUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE
27 SOFTWARE.
28 */
29 
30 #include <string>
31 #include <vector>
32 #include "doctest_compatibility.h"
33 
34 #include <nlohmann/json.hpp>
35 using nlohmann::json;
36 
37 namespace persons
38 {
39 class person_with_private_data
40 {
41   private:
42     std::string name = "";
43     int age = 0;
44     json metadata = nullptr;
45 
46   public:
operator ==(const person_with_private_data & rhs) const47     bool operator==(const person_with_private_data& rhs) const
48     {
49         return name == rhs.name && age == rhs.age && metadata == rhs.metadata;
50     }
51 
52     person_with_private_data() = default;
person_with_private_data(std::string name_,int age_,json metadata_)53     person_with_private_data(std::string name_, int age_, json metadata_)
54         : name(std::move(name_))
55         , age(age_)
56         , metadata(std::move(metadata_))
57     {}
58 
59     NLOHMANN_DEFINE_TYPE_INTRUSIVE(person_with_private_data, age, name, metadata)
60 };
61 
62 class person_without_private_data_1
63 {
64   public:
65     std::string name = "";
66     int age = 0;
67     json metadata = nullptr;
68 
operator ==(const person_without_private_data_1 & rhs) const69     bool operator==(const person_without_private_data_1& rhs) const
70     {
71         return name == rhs.name && age == rhs.age && metadata == rhs.metadata;
72     }
73 
74     person_without_private_data_1() = default;
person_without_private_data_1(std::string name_,int age_,json metadata_)75     person_without_private_data_1(std::string name_, int age_, json metadata_)
76         : name(std::move(name_))
77         , age(age_)
78         , metadata(std::move(metadata_))
79     {}
80 
81     NLOHMANN_DEFINE_TYPE_INTRUSIVE(person_without_private_data_1, age, name, metadata)
82 };
83 
84 class person_without_private_data_2
85 {
86   public:
87     std::string name = "";
88     int age = 0;
89     json metadata = nullptr;
90 
operator ==(const person_without_private_data_2 & rhs) const91     bool operator==(const person_without_private_data_2& rhs) const
92     {
93         return name == rhs.name && age == rhs.age && metadata == rhs.metadata;
94     }
95 
96     person_without_private_data_2() = default;
person_without_private_data_2(std::string name_,int age_,json metadata_)97     person_without_private_data_2(std::string name_, int age_, json metadata_)
98         : name(std::move(name_))
99         , age(age_)
100         , metadata(std::move(metadata_))
101     {}
102 };
103 
104 NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(person_without_private_data_2, age, name, metadata)
105 
106 class person_with_private_alphabet
107 {
108   public:
operator ==(const person_with_private_alphabet & other)109     bool operator==(const person_with_private_alphabet& other)
110     {
111         return  a == other.a &&
112                 b == other.b &&
113                 c == other.c &&
114                 d == other.d &&
115                 e == other.e &&
116                 f == other.f &&
117                 g == other.g &&
118                 h == other.h &&
119                 i == other.i &&
120                 j == other.j &&
121                 k == other.k &&
122                 l == other.l &&
123                 m == other.m &&
124                 n == other.n &&
125                 o == other.o &&
126                 p == other.p &&
127                 q == other.q &&
128                 r == other.r &&
129                 s == other.s &&
130                 t == other.t &&
131                 u == other.u &&
132                 v == other.v &&
133                 w == other.w &&
134                 x == other.x &&
135                 y == other.y &&
136                 z == other.z;
137     }
138 
139   private:
140     int a = 0;
141     int b = 0;
142     int c = 0;
143     int d = 0;
144     int e = 0;
145     int f = 0;
146     int g = 0;
147     int h = 0;
148     int i = 0;
149     int j = 0;
150     int k = 0;
151     int l = 0;
152     int m = 0;
153     int n = 0;
154     int o = 0;
155     int p = 0;
156     int q = 0;
157     int r = 0;
158     int s = 0;
159     int t = 0;
160     int u = 0;
161     int v = 0;
162     int w = 0;
163     int x = 0;
164     int y = 0;
165     int z = 0;
166     NLOHMANN_DEFINE_TYPE_INTRUSIVE(person_with_private_alphabet, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z)
167 };
168 
169 class person_with_public_alphabet
170 {
171   public:
operator ==(const person_with_public_alphabet & other)172     bool operator==(const person_with_public_alphabet& other)
173     {
174         return  a == other.a &&
175                 b == other.b &&
176                 c == other.c &&
177                 d == other.d &&
178                 e == other.e &&
179                 f == other.f &&
180                 g == other.g &&
181                 h == other.h &&
182                 i == other.i &&
183                 j == other.j &&
184                 k == other.k &&
185                 l == other.l &&
186                 m == other.m &&
187                 n == other.n &&
188                 o == other.o &&
189                 p == other.p &&
190                 q == other.q &&
191                 r == other.r &&
192                 s == other.s &&
193                 t == other.t &&
194                 u == other.u &&
195                 v == other.v &&
196                 w == other.w &&
197                 x == other.x &&
198                 y == other.y &&
199                 z == other.z;
200     }
201 
202     int a = 0;
203     int b = 0;
204     int c = 0;
205     int d = 0;
206     int e = 0;
207     int f = 0;
208     int g = 0;
209     int h = 0;
210     int i = 0;
211     int j = 0;
212     int k = 0;
213     int l = 0;
214     int m = 0;
215     int n = 0;
216     int o = 0;
217     int p = 0;
218     int q = 0;
219     int r = 0;
220     int s = 0;
221     int t = 0;
222     int u = 0;
223     int v = 0;
224     int w = 0;
225     int x = 0;
226     int y = 0;
227     int z = 0;
228 };
229 
230 NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(person_with_public_alphabet, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z)
231 
232 } // namespace persons
233 
234 TEST_CASE_TEMPLATE("Serialization/deserialization via NLOHMANN_DEFINE_TYPE_INTRUSIVE", T,
235                    persons::person_with_private_data,
236                    persons::person_without_private_data_1,
237                    persons::person_without_private_data_2)
238 {
239     SECTION("person")
240     {
241         // serialization
242         T p1("Erik", 1, {{"haircuts", 2}});
243         CHECK(json(p1).dump() == "{\"age\":1,\"metadata\":{\"haircuts\":2},\"name\":\"Erik\"}");
244 
245         // deserialization
246         auto p2 = json(p1).get<T>();
247         CHECK(p2 == p1);
248 
249         // roundtrip
250         CHECK(T(json(p1)) == p1);
251         CHECK(json(T(json(p1))) == json(p1));
252 
253         // check exception in case of missing field
254         json j = json(p1);
255         j.erase("age");
256         CHECK_THROWS_WITH_AS(j.get<T>(), "[json.exception.out_of_range.403] key 'age' not found", json::out_of_range);
257     }
258 }
259 
260 TEST_CASE_TEMPLATE("Serialization/deserialization of classes with 26 public/private member variables via NLOHMANN_DEFINE_TYPE_INTRUSIVE and NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE", T,
261                    persons::person_with_private_alphabet,
262                    persons::person_with_public_alphabet)
263 {
264     SECTION("alphabet")
265     {
266         {
267             T obj1;
268             nlohmann::json j = obj1; //via json object
269             T obj2;
270             j.get_to(obj2);
271             bool ok = (obj1 == obj2);
272             CHECK(ok);
273         }
274 
275         {
276             T obj1;
277             nlohmann::json j1 = obj1; //via json string
278             std::string s = j1.dump();
279             nlohmann::json j2 = nlohmann::json::parse(s);
280             T obj2;
281             j2.get_to(obj2);
282             bool ok = (obj1 == obj2);
283             CHECK(ok);
284         }
285 
286         {
287             T obj1;
288             nlohmann::json j1 = obj1; //via msgpack
289             std::vector<uint8_t> buf = nlohmann::json::to_msgpack(j1);
290             nlohmann::json j2 = nlohmann::json::from_msgpack(buf);
291             T obj2;
292             j2.get_to(obj2);
293             bool ok = (obj1 == obj2);
294             CHECK(ok);
295         }
296 
297         {
298             T obj1;
299             nlohmann::json j1 = obj1; //via bson
300             std::vector<uint8_t> buf = nlohmann::json::to_bson(j1);
301             nlohmann::json j2 = nlohmann::json::from_bson(buf);
302             T obj2;
303             j2.get_to(obj2);
304             bool ok = (obj1 == obj2);
305             CHECK(ok);
306         }
307 
308         {
309             T obj1;
310             nlohmann::json j1 = obj1; //via cbor
311             std::vector<uint8_t> buf = nlohmann::json::to_cbor(j1);
312             nlohmann::json j2 = nlohmann::json::from_cbor(buf);
313             T obj2;
314             j2.get_to(obj2);
315             bool ok = (obj1 == obj2);
316             CHECK(ok);
317         }
318 
319         {
320             T obj1;
321             nlohmann::json j1 = obj1; //via ubjson
322             std::vector<uint8_t> buf = nlohmann::json::to_ubjson(j1);
323             nlohmann::json j2 = nlohmann::json::from_ubjson(buf);
324             T obj2;
325             j2.get_to(obj2);
326             bool ok = (obj1 == obj2);
327             CHECK(ok);
328         }
329     }
330 }
331