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 "doctest_compatibility.h"
31 
32 #define private public
33 #include <nlohmann/json.hpp>
34 using nlohmann::json;
35 #undef private
36 
37 TEST_CASE("iterator class")
38 {
39     SECTION("construction")
40     {
41         SECTION("constructor")
42         {
43             SECTION("null")
44             {
45                 json j(json::value_t::null);
46                 json::iterator it(&j);
47             }
48 
49             SECTION("object")
50             {
51                 json j(json::value_t::object);
52                 json::iterator it(&j);
53             }
54 
55             SECTION("array")
56             {
57                 json j(json::value_t::array);
58                 json::iterator it(&j);
59             }
60         }
61 
62         SECTION("copy assignment")
63         {
64             json j(json::value_t::null);
65             json::iterator it(&j);
66             json::iterator it2(&j);
67             it2 = it;
68         }
69     }
70 
71     SECTION("initialization")
72     {
73         SECTION("set_begin")
74         {
75             SECTION("null")
76             {
77                 json j(json::value_t::null);
78                 json::iterator it(&j);
79                 it.set_begin();
80                 CHECK((it == j.begin()));
81             }
82 
83             SECTION("object")
84             {
85                 json j(json::value_t::object);
86                 json::iterator it(&j);
87                 it.set_begin();
88                 CHECK((it == j.begin()));
89             }
90 
91             SECTION("array")
92             {
93                 json j(json::value_t::array);
94                 json::iterator it(&j);
95                 it.set_begin();
96                 CHECK((it == j.begin()));
97             }
98         }
99 
100         SECTION("set_end")
101         {
102             SECTION("null")
103             {
104                 json j(json::value_t::null);
105                 json::iterator it(&j);
106                 it.set_end();
107                 CHECK((it == j.end()));
108             }
109 
110             SECTION("object")
111             {
112                 json j(json::value_t::object);
113                 json::iterator it(&j);
114                 it.set_end();
115                 CHECK((it == j.end()));
116             }
117 
118             SECTION("array")
119             {
120                 json j(json::value_t::array);
121                 json::iterator it(&j);
122                 it.set_end();
123                 CHECK((it == j.end()));
124             }
125         }
126     }
127 
128     SECTION("element access")
129     {
130         SECTION("operator*")
131         {
132             SECTION("null")
133             {
134                 json j(json::value_t::null);
135                 json::iterator it = j.begin();
136                 CHECK_THROWS_AS(*it, json::invalid_iterator&);
137                 CHECK_THROWS_WITH(*it, "[json.exception.invalid_iterator.214] cannot get value");
138             }
139 
140             SECTION("number")
141             {
142                 json j(17);
143                 json::iterator it = j.begin();
144                 CHECK(*it == json(17));
145                 it = j.end();
146                 CHECK_THROWS_AS(*it, json::invalid_iterator&);
147                 CHECK_THROWS_WITH(*it, "[json.exception.invalid_iterator.214] cannot get value");
148             }
149 
150             SECTION("object")
151             {
152                 json j({{"foo", "bar"}});
153                 json::iterator it = j.begin();
154                 CHECK(*it == json("bar"));
155             }
156 
157             SECTION("array")
158             {
159                 json j({1, 2, 3, 4});
160                 json::iterator it = j.begin();
161                 CHECK(*it == json(1));
162             }
163         }
164 
165         SECTION("operator->")
166         {
167             SECTION("null")
168             {
169                 json j(json::value_t::null);
170                 json::iterator it = j.begin();
171                 CHECK_THROWS_AS(std::string(it->type_name()), json::invalid_iterator&);
172                 CHECK_THROWS_WITH(std::string(it->type_name()), "[json.exception.invalid_iterator.214] cannot get value");
173             }
174 
175             SECTION("number")
176             {
177                 json j(17);
178                 json::iterator it = j.begin();
179                 CHECK(std::string(it->type_name()) == "number");
180                 it = j.end();
181                 CHECK_THROWS_AS(std::string(it->type_name()), json::invalid_iterator&);
182                 CHECK_THROWS_WITH(std::string(it->type_name()), "[json.exception.invalid_iterator.214] cannot get value");
183             }
184 
185             SECTION("object")
186             {
187                 json j({{"foo", "bar"}});
188                 json::iterator it = j.begin();
189                 CHECK(std::string(it->type_name()) == "string");
190             }
191 
192             SECTION("array")
193             {
194                 json j({1, 2, 3, 4});
195                 json::iterator it = j.begin();
196                 CHECK(std::string(it->type_name()) == "number");
197             }
198         }
199     }
200 
201     SECTION("increment/decrement")
202     {
203         SECTION("post-increment")
204         {
205             SECTION("null")
206             {
207                 json j(json::value_t::null);
208                 json::iterator it = j.begin();
209                 CHECK((it.m_it.primitive_iterator.m_it == 1));
210                 it++;
211                 CHECK((it.m_it.primitive_iterator.m_it != 0 && it.m_it.primitive_iterator.m_it != 1));
212             }
213 
214             SECTION("number")
215             {
216                 json j(17);
217                 json::iterator it = j.begin();
218                 CHECK((it.m_it.primitive_iterator.m_it == 0));
219                 it++;
220                 CHECK((it.m_it.primitive_iterator.m_it == 1));
221                 it++;
222                 CHECK((it.m_it.primitive_iterator.m_it != 0 && it.m_it.primitive_iterator.m_it != 1));
223             }
224 
225             SECTION("object")
226             {
227                 json j({{"foo", "bar"}});
228                 json::iterator it = j.begin();
229                 CHECK((it.m_it.object_iterator == it.m_object->m_value.object->begin()));
230                 it++;
231                 CHECK((it.m_it.object_iterator == it.m_object->m_value.object->end()));
232             }
233 
234             SECTION("array")
235             {
236                 json j({1, 2, 3, 4});
237                 json::iterator it = j.begin();
238                 CHECK((it.m_it.array_iterator == it.m_object->m_value.array->begin()));
239                 it++;
240                 CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));
241                 CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));
242                 it++;
243                 CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));
244                 CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));
245                 it++;
246                 CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));
247                 CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));
248                 it++;
249                 CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));
250                 CHECK((it.m_it.array_iterator == it.m_object->m_value.array->end()));
251             }
252         }
253 
254         SECTION("pre-increment")
255         {
256             SECTION("null")
257             {
258                 json j(json::value_t::null);
259                 json::iterator it = j.begin();
260                 CHECK((it.m_it.primitive_iterator.m_it == 1));
261                 ++it;
262                 CHECK((it.m_it.primitive_iterator.m_it != 0 && it.m_it.primitive_iterator.m_it != 1));
263             }
264 
265             SECTION("number")
266             {
267                 json j(17);
268                 json::iterator it = j.begin();
269                 CHECK((it.m_it.primitive_iterator.m_it == 0));
270                 ++it;
271                 CHECK((it.m_it.primitive_iterator.m_it == 1));
272                 ++it;
273                 CHECK((it.m_it.primitive_iterator.m_it != 0 && it.m_it.primitive_iterator.m_it != 1));
274             }
275 
276             SECTION("object")
277             {
278                 json j({{"foo", "bar"}});
279                 json::iterator it = j.begin();
280                 CHECK((it.m_it.object_iterator == it.m_object->m_value.object->begin()));
281                 ++it;
282                 CHECK((it.m_it.object_iterator == it.m_object->m_value.object->end()));
283             }
284 
285             SECTION("array")
286             {
287                 json j({1, 2, 3, 4});
288                 json::iterator it = j.begin();
289                 CHECK((it.m_it.array_iterator == it.m_object->m_value.array->begin()));
290                 ++it;
291                 CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));
292                 CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));
293                 ++it;
294                 CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));
295                 CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));
296                 ++it;
297                 CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));
298                 CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));
299                 ++it;
300                 CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));
301                 CHECK((it.m_it.array_iterator == it.m_object->m_value.array->end()));
302             }
303         }
304 
305         SECTION("post-decrement")
306         {
307             SECTION("null")
308             {
309                 json j(json::value_t::null);
310                 json::iterator it = j.end();
311                 CHECK((it.m_it.primitive_iterator.m_it == 1));
312             }
313 
314             SECTION("number")
315             {
316                 json j(17);
317                 json::iterator it = j.end();
318                 CHECK((it.m_it.primitive_iterator.m_it == 1));
319                 it--;
320                 CHECK((it.m_it.primitive_iterator.m_it == 0));
321                 it--;
322                 CHECK((it.m_it.primitive_iterator.m_it != 0 && it.m_it.primitive_iterator.m_it != 1));
323             }
324 
325             SECTION("object")
326             {
327                 json j({{"foo", "bar"}});
328                 json::iterator it = j.end();
329                 CHECK((it.m_it.object_iterator == it.m_object->m_value.object->end()));
330                 it--;
331                 CHECK((it.m_it.object_iterator == it.m_object->m_value.object->begin()));
332             }
333 
334             SECTION("array")
335             {
336                 json j({1, 2, 3, 4});
337                 json::iterator it = j.end();
338                 CHECK((it.m_it.array_iterator == it.m_object->m_value.array->end()));
339                 it--;
340                 CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));
341                 CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));
342                 it--;
343                 CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));
344                 CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));
345                 it--;
346                 CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));
347                 CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));
348                 it--;
349                 CHECK((it.m_it.array_iterator == it.m_object->m_value.array->begin()));
350                 CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));
351             }
352         }
353 
354         SECTION("pre-decrement")
355         {
356             SECTION("null")
357             {
358                 json j(json::value_t::null);
359                 json::iterator it = j.end();
360                 CHECK((it.m_it.primitive_iterator.m_it == 1));
361             }
362 
363             SECTION("number")
364             {
365                 json j(17);
366                 json::iterator it = j.end();
367                 CHECK((it.m_it.primitive_iterator.m_it == 1));
368                 --it;
369                 CHECK((it.m_it.primitive_iterator.m_it == 0));
370                 --it;
371                 CHECK((it.m_it.primitive_iterator.m_it != 0 && it.m_it.primitive_iterator.m_it != 1));
372             }
373 
374             SECTION("object")
375             {
376                 json j({{"foo", "bar"}});
377                 json::iterator it = j.end();
378                 CHECK((it.m_it.object_iterator == it.m_object->m_value.object->end()));
379                 --it;
380                 CHECK((it.m_it.object_iterator == it.m_object->m_value.object->begin()));
381             }
382 
383             SECTION("array")
384             {
385                 json j({1, 2, 3, 4});
386                 json::iterator it = j.end();
387                 CHECK((it.m_it.array_iterator == it.m_object->m_value.array->end()));
388                 --it;
389                 CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));
390                 CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));
391                 --it;
392                 CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));
393                 CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));
394                 --it;
395                 CHECK((it.m_it.array_iterator != it.m_object->m_value.array->begin()));
396                 CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));
397                 --it;
398                 CHECK((it.m_it.array_iterator == it.m_object->m_value.array->begin()));
399                 CHECK((it.m_it.array_iterator != it.m_object->m_value.array->end()));
400             }
401         }
402     }
403 }
404