VirtualBox

source: vbox/trunk/src/VBox/Runtime/testcase/tstRTCRest-1.cpp@ 74195

Last change on this file since 74195 was 74195, checked in by vboxsync, 6 years ago

IPRT/rest: Build fix for array tests. Started testing the string map. Added isEmpty method to the string map. bugref:9167

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 77.1 KB
Line 
1/* $Id: tstRTCRest-1.cpp 74195 2018-09-11 11:45:35Z vboxsync $ */
2/** @file
3 * IPRT Testcase - REST C++ classes.
4 */
5
6/*
7 * Copyright (C) 2018 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*********************************************************************************************************************************
29* Header Files *
30*********************************************************************************************************************************/
31#include <iprt/cpp/restbase.h>
32#include <iprt/cpp/restarray.h>
33#include <iprt/cpp/reststringmap.h>
34
35#include <iprt/err.h>
36#include <iprt/message.h>
37#include <iprt/string.h>
38#include <iprt/test.h>
39
40#include <float.h> /* DBL_MIN, DBL_MAX */
41
42
43/*********************************************************************************************************************************
44* Global Variables *
45*********************************************************************************************************************************/
46static RTTEST g_hTest;
47
48
49static char *toJson(RTCRestObjectBase const *pObj)
50{
51 RTCString str;
52 RTCRestOutputToString Dst(&str, false);
53 pObj->serializeAsJson(Dst);
54
55 static char s_szReturnBuffer[4096];
56 RTStrCopy(s_szReturnBuffer, sizeof(s_szReturnBuffer), str.c_str());
57 return s_szReturnBuffer;
58}
59
60
61static int deserializeFromJson(RTCRestObjectBase *pObj, const char *pszJson, PRTERRINFOSTATIC pErrInfo, const char *pszName)
62{
63 RTJSONVAL hValue;
64 RTTESTI_CHECK_RC_OK_RET(RTJsonParseFromString(&hValue, pszJson, pErrInfo ? RTErrInfoInitStatic(pErrInfo) : NULL), rcCheck);
65 RTCRestJsonPrimaryCursor Cursor(hValue, pszName, pErrInfo ? RTErrInfoInitStatic(pErrInfo) : NULL);
66 return pObj->deserializeFromJson(Cursor.m_Cursor);
67}
68
69
70static int fromString(RTCRestObjectBase *pObj, const char *pszString, PRTERRINFOSTATIC pErrInfo, const char *pszName)
71{
72 RTCString strValue(pszString);
73 return pObj->fromString(strValue, pszName, pErrInfo ? RTErrInfoInitStatic(pErrInfo) : NULL);
74}
75
76
77static void testBool(void)
78{
79 RTTestSub(g_hTest, "RTCRestBool");
80
81 {
82 RTCRestBool obj1;
83 RTTESTI_CHECK(obj1.m_fValue == false);
84 RTTESTI_CHECK(obj1.isNull() == false);
85 RTTESTI_CHECK(strcmp(obj1.typeName(), "bool") == 0);
86 RTTESTI_CHECK(obj1.typeClass() == RTCRestObjectBase::kTypeClass_Bool);
87 }
88
89 {
90 RTCRestBool obj2(true);
91 RTTESTI_CHECK(obj2.m_fValue == true);
92 RTTESTI_CHECK(obj2.isNull() == false);
93 }
94
95 {
96 RTCRestBool obj2(false);
97 RTTESTI_CHECK(obj2.m_fValue == false);
98 RTTESTI_CHECK(obj2.isNull() == false);
99 }
100
101 {
102 /* Value assignments: */
103 RTCRestBool obj3;
104 RTTESTI_CHECK_RC(obj3.setNull(), VINF_SUCCESS);
105 RTTESTI_CHECK(obj3.isNull() == true);
106 obj3.assignValue(true);
107 RTTESTI_CHECK(obj3.m_fValue == true);
108 RTTESTI_CHECK(obj3.isNull() == false);
109
110 RTTESTI_CHECK_RC(obj3.setNull(), VINF_SUCCESS);
111 RTTESTI_CHECK(obj3.isNull() == true);
112 obj3.assignValue(false);
113 RTTESTI_CHECK(obj3.m_fValue == false);
114 RTTESTI_CHECK(obj3.isNull() == false);
115
116 obj3.assignValue(true);
117 RTTESTI_CHECK(obj3.m_fValue == true);
118 RTTESTI_CHECK(obj3.isNull() == false);
119
120 RTTESTI_CHECK_RC(obj3.resetToDefault(), VINF_SUCCESS);
121 RTTESTI_CHECK(obj3.m_fValue == false);
122 RTTESTI_CHECK(obj3.isNull() == false);
123
124 obj3.assignValue(true);
125 RTTESTI_CHECK_RC(obj3.setNull(), VINF_SUCCESS);
126 RTTESTI_CHECK_RC(obj3.resetToDefault(), VINF_SUCCESS);
127 RTTESTI_CHECK(obj3.m_fValue == false);
128 RTTESTI_CHECK(obj3.isNull() == false);
129
130 /* Copy assignments: */
131 RTCRestBool obj3True(true);
132 RTTESTI_CHECK(obj3True.m_fValue == true);
133 RTTESTI_CHECK(obj3True.isNull() == false);
134 RTCRestBool obj3False(false);
135 RTTESTI_CHECK(obj3False.m_fValue == false);
136 RTTESTI_CHECK(obj3False.isNull() == false);
137 RTCRestBool obj3Null;
138 obj3Null.setNull();
139 RTTESTI_CHECK(obj3Null.m_fValue == false);
140 RTTESTI_CHECK(obj3Null.isNull() == true);
141
142 RTTESTI_CHECK_RC(obj3.setNull(), VINF_SUCCESS);
143 RTTESTI_CHECK_RC(obj3.assignCopy(obj3True), VINF_SUCCESS);
144 RTTESTI_CHECK(obj3.m_fValue == true);
145 RTTESTI_CHECK(obj3.isNull() == false);
146
147 RTTESTI_CHECK_RC(obj3.assignCopy(obj3Null), VINF_SUCCESS);
148 RTTESTI_CHECK(obj3.m_fValue == false);
149 RTTESTI_CHECK(obj3.isNull() == true);
150
151 RTTESTI_CHECK_RC(obj3.assignCopy(obj3False), VINF_SUCCESS);
152 RTTESTI_CHECK(obj3.m_fValue == false);
153 RTTESTI_CHECK(obj3.isNull() == false);
154
155 obj3 = obj3Null;
156 RTTESTI_CHECK(obj3.m_fValue == false);
157 RTTESTI_CHECK(obj3.isNull() == true);
158
159 obj3 = obj3True;
160 RTTESTI_CHECK(obj3.m_fValue == true);
161 RTTESTI_CHECK(obj3.isNull() == false);
162
163 obj3 = obj3Null;
164 RTTESTI_CHECK(obj3.m_fValue == false);
165 RTTESTI_CHECK(obj3.isNull() == true);
166
167 obj3 = obj3False;
168 RTTESTI_CHECK(obj3.m_fValue == false);
169 RTTESTI_CHECK(obj3.isNull() == false);
170
171 /* setNull implies resetToDefault: */
172 obj3 = obj3True;
173 RTTESTI_CHECK(obj3.m_fValue == true);
174 RTTESTI_CHECK(obj3.isNull() == false);
175 RTTESTI_CHECK_RC(obj3.setNull(), VINF_SUCCESS);
176 RTTESTI_CHECK(obj3.isNull() == true);
177 RTTESTI_CHECK(obj3.m_fValue == false);
178
179 /* Copy constructors: */
180 {
181 RTCRestBool obj3a(obj3True);
182 RTTESTI_CHECK(obj3a.m_fValue == true);
183 RTTESTI_CHECK(obj3a.isNull() == false);
184 }
185 {
186 RTCRestBool obj3b(obj3False);
187 RTTESTI_CHECK(obj3b.m_fValue == false);
188 RTTESTI_CHECK(obj3b.isNull() == false);
189 }
190 {
191 RTCRestBool obj3c(obj3Null);
192 RTTESTI_CHECK(obj3c.m_fValue == false);
193 RTTESTI_CHECK(obj3c.isNull() == true);
194 }
195
196 /* Serialization to json: */
197 const char *pszJson = toJson(&obj3True);
198 RTTESTI_CHECK_MSG(strcmp(pszJson, "true") == 0, ("pszJson=%s\n", pszJson));
199 pszJson = toJson(&obj3False);
200 RTTESTI_CHECK_MSG(strcmp(pszJson, "false") == 0, ("pszJson=%s\n", pszJson));
201 pszJson = toJson(&obj3Null);
202 RTTESTI_CHECK_MSG(strcmp(pszJson, "null") == 0, ("pszJson=%s\n", pszJson));
203
204 /* Serialization to string. */
205 RTCString str;
206 str = "lead-in:";
207 RTTESTI_CHECK_RC(obj3True.toString(&str, RTCRestObjectBase::kToString_Append), VINF_SUCCESS);
208 RTTESTI_CHECK_MSG(str.equals("lead-in:true"), ("str=%s\n", str.c_str()));
209 RTTESTI_CHECK_RC(obj3True.toString(&str), VINF_SUCCESS);
210 RTTESTI_CHECK_MSG(str.equals("true"), ("str=%s\n", str.c_str()));
211
212 str = "lead-in:";
213 RTTESTI_CHECK_RC(obj3False.toString(&str, RTCRestObjectBase::kToString_Append), VINF_SUCCESS);
214 RTTESTI_CHECK_MSG(str.equals("lead-in:false"), ("str=%s\n", str.c_str()));
215 RTTESTI_CHECK_RC(obj3False.toString(&str), VINF_SUCCESS);
216 RTTESTI_CHECK_MSG(str.equals("false"), ("str=%s\n", str.c_str()));
217
218 str = "lead-in:";
219 RTTESTI_CHECK_RC(obj3Null.toString(&str, RTCRestObjectBase::kToString_Append), VINF_SUCCESS);
220 RTTESTI_CHECK_MSG(str.equals("lead-in:null"), ("str=%s\n", str.c_str()));
221 RTTESTI_CHECK_RC(obj3Null.toString(&str), VINF_SUCCESS);
222 RTTESTI_CHECK_MSG(str.equals("null"), ("str=%s\n", str.c_str()));
223 }
224
225 /* deserialize: */
226 RTERRINFOSTATIC ErrInfo;
227 {
228 RTCRestBool obj4;
229 obj4.setNull();
230 RTTESTI_CHECK_RC(deserializeFromJson(&obj4, "false", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
231 RTTESTI_CHECK(obj4.m_fValue == false);
232 RTTESTI_CHECK(obj4.isNull() == false);
233
234 obj4.setNull();
235 RTTESTI_CHECK_RC(deserializeFromJson(&obj4, "true", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
236 RTTESTI_CHECK(obj4.m_fValue == true);
237 RTTESTI_CHECK(obj4.isNull() == false);
238
239 RTTESTI_CHECK_RC(deserializeFromJson(&obj4, "null", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
240 RTTESTI_CHECK(obj4.m_fValue == false);
241 RTTESTI_CHECK(obj4.isNull() == true);
242
243 /* object goes to default state on failure: */
244 RTTESTI_CHECK_RC(deserializeFromJson(&obj4, "0", &ErrInfo, RT_XSTR(__LINE__)), VERR_REST_WRONG_JSON_TYPE_FOR_BOOL);
245 RTTESTI_CHECK(obj4.m_fValue == false);
246 RTTESTI_CHECK(obj4.isNull() == false);
247 RTTESTI_CHECK(RTErrInfoIsSet(&ErrInfo.Core));
248
249 obj4.assignValue(true);
250 RTTESTI_CHECK_RC(deserializeFromJson(&obj4, "\"false\"", &ErrInfo, RT_XSTR(__LINE__)), VERR_REST_WRONG_JSON_TYPE_FOR_BOOL);
251 RTTESTI_CHECK(obj4.m_fValue == false);
252 RTTESTI_CHECK(obj4.isNull() == false);
253 RTTESTI_CHECK(RTErrInfoIsSet(&ErrInfo.Core));
254
255 obj4.setNull();
256 RTTESTI_CHECK_RC(deserializeFromJson(&obj4, "[ null ]", NULL, RT_XSTR(__LINE__)), VERR_REST_WRONG_JSON_TYPE_FOR_BOOL);
257 RTTESTI_CHECK(obj4.m_fValue == false);
258 RTTESTI_CHECK(obj4.isNull() == false);
259
260 obj4.setNull();
261 RTTESTI_CHECK_RC(fromString(&obj4, "true", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
262 RTTESTI_CHECK(obj4.m_fValue == true);
263 RTTESTI_CHECK(obj4.isNull() == false);
264
265 RTTESTI_CHECK_RC(fromString(&obj4, "false", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
266 RTTESTI_CHECK(obj4.m_fValue == false);
267 RTTESTI_CHECK(obj4.isNull() == false);
268
269 obj4.m_fValue = true;
270 RTTESTI_CHECK_RC(fromString(&obj4, "null", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
271 RTTESTI_CHECK(obj4.m_fValue == false);
272 RTTESTI_CHECK(obj4.isNull() == true);
273
274 obj4.setNull();
275 RTTESTI_CHECK_RC(fromString(&obj4, " TrUe ", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
276 RTTESTI_CHECK(obj4.m_fValue == true);
277 RTTESTI_CHECK(obj4.isNull() == false);
278
279 RTTESTI_CHECK_RC(fromString(&obj4, "\tfAlSe;", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
280 RTTESTI_CHECK(obj4.m_fValue == false);
281 RTTESTI_CHECK(obj4.isNull() == false);
282
283 RTTESTI_CHECK_RC(fromString(&obj4, "\r\nfAlSe\n;", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
284 RTTESTI_CHECK(obj4.m_fValue == false);
285 RTTESTI_CHECK(obj4.isNull() == false);
286
287 RTTESTI_CHECK_RC(fromString(&obj4, "\r\tNuLl\n;", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
288 RTTESTI_CHECK(obj4.m_fValue == false);
289 RTTESTI_CHECK(obj4.isNull() == true);
290
291 RTTESTI_CHECK_RC(fromString(&obj4, "1", &ErrInfo, RT_XSTR(__LINE__)), VERR_REST_UNABLE_TO_PARSE_STRING_AS_BOOL);
292 RTTESTI_CHECK(RTErrInfoIsSet(&ErrInfo.Core));
293
294 RTTESTI_CHECK_RC(fromString(&obj4, "0", NULL, RT_XSTR(__LINE__)), VERR_REST_UNABLE_TO_PARSE_STRING_AS_BOOL);
295 }
296}
297
298class Int64Constants
299{
300public:
301 Int64Constants() {}
302 const char *getSubName() const { return "RTCRestInt64"; }
303 int64_t getMin() const { return INT64_MIN; }
304 const char *getMinStr() const { return "-9223372036854775808"; }
305 int64_t getMax() const { return INT64_MAX; }
306 const char *getMaxStr() const { return "9223372036854775807"; }
307 const char *getTypeName() const { return "int64_t"; }
308 RTCRestObjectBase::kTypeClass getTypeClass() const { return RTCRestObjectBase::kTypeClass_Int64; }
309};
310
311class Int32Constants
312{
313public:
314 Int32Constants() { }
315 const char *getSubName() const { return "RTCRestInt32"; }
316 int32_t getMin() const { return INT32_MIN; }
317 const char *getMinStr() const { return "-2147483648"; }
318 int32_t getMax() const { return INT32_MAX; }
319 const char *getMaxStr() const { return "2147483647"; }
320 const char *getTypeName() const { return "int32_t"; }
321 RTCRestObjectBase::kTypeClass getTypeClass() const { return RTCRestObjectBase::kTypeClass_Int32; }
322};
323
324class Int16Constants
325{
326public:
327 Int16Constants() { }
328 const char *getSubName() const { return "RTCRestInt16"; }
329 int16_t getMin() const { return INT16_MIN; }
330 const char *getMinStr() const { return "-32768"; }
331 int16_t getMax() const { return INT16_MAX; }
332 const char *getMaxStr() const { return "32767"; }
333 const char *getTypeName() const { return "int16_t"; }
334 RTCRestObjectBase::kTypeClass getTypeClass() const { return RTCRestObjectBase::kTypeClass_Int16; }
335};
336
337template<typename RestType, typename IntType, typename ConstantClass>
338void testInteger(void)
339{
340 ConstantClass const Consts;
341 RTTestSub(g_hTest, Consts.getSubName());
342
343 {
344 RestType obj1;
345 RTTESTI_CHECK(obj1.m_iValue == 0);
346 RTTESTI_CHECK(obj1.isNull() == false);
347 RTTESTI_CHECK(strcmp(obj1.typeName(), Consts.getTypeName()) == 0);
348 RTTESTI_CHECK(obj1.typeClass() == Consts.getTypeClass());
349 }
350
351 {
352 RestType obj2(2398);
353 RTTESTI_CHECK(obj2.m_iValue == 2398);
354 RTTESTI_CHECK(obj2.isNull() == false);
355 }
356
357 {
358 RestType obj2(-7345);
359 RTTESTI_CHECK(obj2.m_iValue == -7345);
360 RTTESTI_CHECK(obj2.isNull() == false);
361 }
362
363 {
364 /* Value assignments: */
365 RestType obj3;
366 RTTESTI_CHECK_RC(obj3.setNull(), VINF_SUCCESS);
367 RTTESTI_CHECK(obj3.isNull() == true);
368 RTTESTI_CHECK(obj3.m_iValue == 0);
369 obj3.assignValue(-1);
370 RTTESTI_CHECK(obj3.m_iValue == -1);
371 RTTESTI_CHECK(obj3.isNull() == false);
372
373 RTTESTI_CHECK_RC(obj3.setNull(), VINF_SUCCESS);
374 RTTESTI_CHECK(obj3.isNull() == true);
375 obj3.assignValue(42);
376 RTTESTI_CHECK(obj3.m_iValue == 42);
377 RTTESTI_CHECK(obj3.isNull() == false);
378
379 obj3.assignValue(Consts.getMax());
380 RTTESTI_CHECK(obj3.m_iValue == Consts.getMax());
381 RTTESTI_CHECK(obj3.isNull() == false);
382
383 obj3.assignValue(Consts.getMin());
384 RTTESTI_CHECK(obj3.m_iValue == Consts.getMin());
385 RTTESTI_CHECK(obj3.isNull() == false);
386
387 /* Reset to default: */
388 RTTESTI_CHECK_RC(obj3.resetToDefault(), VINF_SUCCESS);
389 RTTESTI_CHECK(obj3.m_iValue == 0);
390 RTTESTI_CHECK(obj3.isNull() == false);
391
392 obj3.assignValue(42);
393 RTTESTI_CHECK_RC(obj3.setNull(), VINF_SUCCESS);
394 RTTESTI_CHECK_RC(obj3.resetToDefault(), VINF_SUCCESS);
395 RTTESTI_CHECK(obj3.m_iValue == 0);
396 RTTESTI_CHECK(obj3.isNull() == false);
397
398 /* Copy assignments: */
399 RestType obj3Max(Consts.getMax());
400 RTTESTI_CHECK(obj3Max.m_iValue == Consts.getMax());
401 RTTESTI_CHECK(obj3Max.isNull() == false);
402 RestType obj3Min(Consts.getMin());
403 RTTESTI_CHECK(obj3Min.m_iValue == Consts.getMin());
404 RTTESTI_CHECK(obj3Min.isNull() == false);
405 RestType obj3Null;
406 obj3Null.setNull();
407 RTTESTI_CHECK(obj3Null.m_iValue == 0);
408 RTTESTI_CHECK(obj3Null.isNull() == true);
409
410 RTTESTI_CHECK_RC(obj3.setNull(), VINF_SUCCESS);
411 RTTESTI_CHECK_RC(obj3.assignCopy(obj3Max), VINF_SUCCESS);
412 RTTESTI_CHECK(obj3.m_iValue == Consts.getMax());
413 RTTESTI_CHECK(obj3.isNull() == false);
414
415 RTTESTI_CHECK_RC(obj3.assignCopy(obj3Null), VINF_SUCCESS);
416 RTTESTI_CHECK(obj3.m_iValue == 0);
417 RTTESTI_CHECK(obj3.isNull() == true);
418
419 RTTESTI_CHECK_RC(obj3.assignCopy(obj3Min), VINF_SUCCESS);
420 RTTESTI_CHECK(obj3.m_iValue == Consts.getMin());
421 RTTESTI_CHECK(obj3.isNull() == false);
422
423 obj3 = obj3Null;
424 RTTESTI_CHECK(obj3.m_iValue == 0);
425 RTTESTI_CHECK(obj3.isNull() == true);
426
427 obj3 = obj3Max;
428 RTTESTI_CHECK(obj3.m_iValue == Consts.getMax());
429 RTTESTI_CHECK(obj3.isNull() == false);
430
431 obj3 = obj3Null;
432 RTTESTI_CHECK(obj3.m_iValue == 0);
433 RTTESTI_CHECK(obj3.isNull() == true);
434
435 obj3 = obj3Min;
436 RTTESTI_CHECK(obj3.m_iValue == Consts.getMin());
437 RTTESTI_CHECK(obj3.isNull() == false);
438
439 /* setNull implies resetToDefault: */
440 obj3 = obj3Max;
441 RTTESTI_CHECK(obj3.m_iValue == Consts.getMax());
442 RTTESTI_CHECK(obj3.isNull() == false);
443 RTTESTI_CHECK_RC(obj3.setNull(), VINF_SUCCESS);
444 RTTESTI_CHECK(obj3.isNull() == true);
445 RTTESTI_CHECK(obj3.m_iValue == 0);
446
447 /* Copy constructors: */
448 {
449 RestType obj3a(obj3Max);
450 RTTESTI_CHECK(obj3a.m_iValue == Consts.getMax());
451 RTTESTI_CHECK(obj3a.isNull() == false);
452 }
453 {
454 RestType obj3b(obj3Min);
455 RTTESTI_CHECK(obj3b.m_iValue == Consts.getMin());
456 RTTESTI_CHECK(obj3b.isNull() == false);
457 }
458 {
459 RestType obj3c(obj3Null);
460 RTTESTI_CHECK(obj3c.m_iValue == 0);
461 RTTESTI_CHECK(obj3c.isNull() == true);
462 }
463
464 /* Serialization to json: */
465 const char *pszJson = toJson(&obj3Max);
466 RTTESTI_CHECK_MSG(strcmp(pszJson, Consts.getMaxStr()) == 0, ("pszJson=%s\n", pszJson));
467 pszJson = toJson(&obj3Min);
468 RTTESTI_CHECK_MSG(strcmp(pszJson, Consts.getMinStr()) == 0, ("pszJson=%s\n", pszJson));
469 pszJson = toJson(&obj3Null);
470 RTTESTI_CHECK_MSG(strcmp(pszJson, "null") == 0, ("pszJson=%s\n", pszJson));
471
472 /* Serialization to string. */
473 RTCString str;
474 RTCString strExpect;
475 str = "lead-in:";
476 RTTESTI_CHECK_RC(obj3Max.toString(&str, RTCRestObjectBase::kToString_Append), VINF_SUCCESS);
477 strExpect.printf("lead-in:%s", Consts.getMaxStr());
478 RTTESTI_CHECK_MSG(str.equals(strExpect), ("str=%s strExpect=%s\n", str.c_str(), strExpect.c_str()));
479 RTTESTI_CHECK_RC(obj3Max.toString(&str), VINF_SUCCESS);
480 RTTESTI_CHECK_MSG(str.equals(Consts.getMaxStr()), ("str=%s\n", str.c_str()));
481
482 str = "lead-in:";
483 RTTESTI_CHECK_RC(obj3Min.toString(&str, RTCRestObjectBase::kToString_Append), VINF_SUCCESS);
484 strExpect.printf("lead-in:%s", Consts.getMinStr());
485 RTTESTI_CHECK_MSG(str.equals(strExpect), ("str=%s strExpect=%s\n", str.c_str(), strExpect.c_str()));
486 RTTESTI_CHECK_RC(obj3Min.toString(&str), VINF_SUCCESS);
487 RTTESTI_CHECK_MSG(str.equals(Consts.getMinStr()), ("str=%s\n", str.c_str()));
488
489 str = "lead-in:";
490 RTTESTI_CHECK_RC(obj3Null.toString(&str, RTCRestObjectBase::kToString_Append), VINF_SUCCESS);
491 RTTESTI_CHECK_MSG(str.equals("lead-in:null"), ("str=%s\n", str.c_str()));
492 RTTESTI_CHECK_RC(obj3Null.toString(&str), VINF_SUCCESS);
493 RTTESTI_CHECK_MSG(str.equals("null"), ("str=%s\n", str.c_str()));
494 }
495
496 /* deserialize: */
497 RTERRINFOSTATIC ErrInfo;
498 {
499 /* from json: */
500 RestType obj4;
501 obj4.setNull();
502 RTTESTI_CHECK_RC(deserializeFromJson(&obj4, "42", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
503 RTTESTI_CHECK(obj4.m_iValue == 42);
504 RTTESTI_CHECK(obj4.isNull() == false);
505
506 obj4.setNull();
507 RTTESTI_CHECK_RC(deserializeFromJson(&obj4, "-22", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
508 RTTESTI_CHECK(obj4.m_iValue == -22);
509 RTTESTI_CHECK(obj4.isNull() == false);
510
511 obj4.setNull();
512 RTTESTI_CHECK_RC(deserializeFromJson(&obj4, Consts.getMaxStr(), &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
513 RTTESTI_CHECK(obj4.m_iValue == Consts.getMax());
514 RTTESTI_CHECK(obj4.isNull() == false);
515
516 obj4.setNull();
517 RTTESTI_CHECK_RC(deserializeFromJson(&obj4, Consts.getMinStr(), &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
518 RTTESTI_CHECK(obj4.m_iValue == Consts.getMin());
519 RTTESTI_CHECK(obj4.isNull() == false);
520
521 RTTESTI_CHECK_RC(deserializeFromJson(&obj4, "null", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
522 RTTESTI_CHECK(obj4.m_iValue == 0);
523 RTTESTI_CHECK(obj4.isNull() == true);
524
525 /* object goes to default state on failure: */
526 obj4.assignValue(Consts.getMin());
527 RTTESTI_CHECK_RC(deserializeFromJson(&obj4, "0.0", &ErrInfo, RT_XSTR(__LINE__)), VERR_REST_WRONG_JSON_TYPE_FOR_INTEGER);
528 RTTESTI_CHECK(obj4.m_iValue == 0);
529 RTTESTI_CHECK(obj4.isNull() == false);
530 RTTESTI_CHECK(RTErrInfoIsSet(&ErrInfo.Core));
531
532 obj4.assignValue(Consts.getMax());
533 RTTESTI_CHECK_RC(deserializeFromJson(&obj4, "\"false\"", &ErrInfo, RT_XSTR(__LINE__)), VERR_REST_WRONG_JSON_TYPE_FOR_INTEGER);
534 RTTESTI_CHECK(obj4.m_iValue == 0);
535 RTTESTI_CHECK(obj4.isNull() == false);
536 RTTESTI_CHECK(RTErrInfoIsSet(&ErrInfo.Core));
537
538 obj4.setNull();
539 RTTESTI_CHECK_RC(deserializeFromJson(&obj4, "[ null ]", NULL, RT_XSTR(__LINE__)), VERR_REST_WRONG_JSON_TYPE_FOR_INTEGER);
540 RTTESTI_CHECK(obj4.m_iValue == 0);
541 RTTESTI_CHECK(obj4.isNull() == false);
542
543 /* from string: */
544 obj4.setNull();
545 RTTESTI_CHECK_RC(fromString(&obj4, "22", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
546 RTTESTI_CHECK(obj4.m_iValue == 22);
547 RTTESTI_CHECK(obj4.isNull() == false);
548
549 RTTESTI_CHECK_RC(fromString(&obj4, "-42", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
550 RTTESTI_CHECK(obj4.m_iValue == -42);
551 RTTESTI_CHECK(obj4.isNull() == false);
552
553 RTTESTI_CHECK_RC(fromString(&obj4, Consts.getMaxStr(), &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
554 RTTESTI_CHECK(obj4.m_iValue == Consts.getMax());
555 RTTESTI_CHECK(obj4.isNull() == false);
556
557 RTTESTI_CHECK_RC(fromString(&obj4, Consts.getMinStr(), &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
558 RTTESTI_CHECK(obj4.m_iValue == Consts.getMin());
559 RTTESTI_CHECK(obj4.isNull() == false);
560
561 obj4.m_iValue = 33;
562 RTTESTI_CHECK_RC(fromString(&obj4, "null", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
563 RTTESTI_CHECK(obj4.m_iValue == 0);
564 RTTESTI_CHECK(obj4.isNull() == true);
565
566 obj4.m_iValue = 33;
567 RTTESTI_CHECK_RC(fromString(&obj4, " nULl;", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
568 RTTESTI_CHECK(obj4.m_iValue == 0);
569 RTTESTI_CHECK(obj4.isNull() == true);
570
571 obj4.setNull();
572 RTTESTI_CHECK_RC(fromString(&obj4, " 0x42 ", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
573 RTTESTI_CHECK(obj4.m_iValue == 0x42);
574 RTTESTI_CHECK(obj4.isNull() == false);
575
576 RTTESTI_CHECK_RC(fromString(&obj4, "\t010\t", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
577 RTTESTI_CHECK(obj4.m_iValue == 8);
578 RTTESTI_CHECK(obj4.isNull() == false);
579
580 RTTESTI_CHECK_RC(fromString(&obj4, "\r\t0X4FDB\t", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
581 RTTESTI_CHECK(obj4.m_iValue == 0x4fdb);
582 RTTESTI_CHECK(obj4.isNull() == false);
583
584 RTTESTI_CHECK_RC(fromString(&obj4, "1.1", &ErrInfo, RT_XSTR(__LINE__)), VERR_TRAILING_CHARS);
585 RTTESTI_CHECK(RTErrInfoIsSet(&ErrInfo.Core));
586
587 RTTESTI_CHECK_RC(fromString(&obj4, "false", NULL, RT_XSTR(__LINE__)), VERR_NO_DIGITS);
588 }
589}
590
591
592void testDouble(void)
593{
594 RTTestSub(g_hTest, "RTCRestDouble");
595#define DBL_MAX_STRING "1.7976931348623157e+308"
596#define DBL_MIN_STRING "2.2250738585072014e-308"
597
598 {
599 RTCRestDouble obj1;
600 RTTESTI_CHECK(obj1.m_rdValue == 0.0);
601 RTTESTI_CHECK(obj1.isNull() == false);
602 RTTESTI_CHECK(strcmp(obj1.typeName(), "double") == 0);
603 RTTESTI_CHECK(obj1.typeClass() == RTCRestObjectBase::kTypeClass_Double);
604 }
605
606 {
607 RTCRestDouble obj2(2398.1);
608 RTTESTI_CHECK(obj2.m_rdValue == 2398.1);
609 RTTESTI_CHECK(obj2.isNull() == false);
610 }
611
612 {
613 RTCRestDouble obj2(-7345.2);
614 RTTESTI_CHECK(obj2.m_rdValue == -7345.2);
615 RTTESTI_CHECK(obj2.isNull() == false);
616 }
617
618 {
619 /* Value assignments: */
620 RTCRestDouble obj3;
621 RTTESTI_CHECK_RC(obj3.setNull(), VINF_SUCCESS);
622 RTTESTI_CHECK(obj3.isNull() == true);
623 RTTESTI_CHECK(obj3.m_rdValue == 0.0);
624 obj3.assignValue(-1.0);
625 RTTESTI_CHECK(obj3.m_rdValue == -1.0);
626 RTTESTI_CHECK(obj3.isNull() == false);
627
628 RTTESTI_CHECK_RC(obj3.setNull(), VINF_SUCCESS);
629 RTTESTI_CHECK(obj3.isNull() == true);
630 obj3.assignValue(42.42);
631 RTTESTI_CHECK(obj3.m_rdValue == 42.42);
632 RTTESTI_CHECK(obj3.isNull() == false);
633
634 obj3.assignValue(DBL_MAX);
635 RTTESTI_CHECK(obj3.m_rdValue == DBL_MAX);
636 RTTESTI_CHECK(obj3.isNull() == false);
637
638 obj3.assignValue(DBL_MIN);
639 RTTESTI_CHECK(obj3.m_rdValue == DBL_MIN);
640 RTTESTI_CHECK(obj3.isNull() == false);
641
642 /* Reset to default: */
643 RTTESTI_CHECK_RC(obj3.resetToDefault(), VINF_SUCCESS);
644 RTTESTI_CHECK(obj3.m_rdValue == 0.0);
645 RTTESTI_CHECK(obj3.isNull() == false);
646
647 obj3.assignValue(42);
648 RTTESTI_CHECK_RC(obj3.setNull(), VINF_SUCCESS);
649 RTTESTI_CHECK_RC(obj3.resetToDefault(), VINF_SUCCESS);
650 RTTESTI_CHECK(obj3.m_rdValue == 0.0);
651 RTTESTI_CHECK(obj3.isNull() == false);
652
653 /* Copy assignments: */
654 RTCRestDouble obj3Max(DBL_MAX);
655 RTTESTI_CHECK(obj3Max.m_rdValue == DBL_MAX);
656 RTTESTI_CHECK(obj3Max.isNull() == false);
657 RTCRestDouble obj3Min(DBL_MIN);
658 RTTESTI_CHECK(obj3Min.m_rdValue == DBL_MIN);
659 RTTESTI_CHECK(obj3Min.isNull() == false);
660 RTCRestDouble obj3Null;
661 obj3Null.setNull();
662 RTTESTI_CHECK(obj3Null.m_rdValue == 0.0);
663 RTTESTI_CHECK(obj3Null.isNull() == true);
664
665 RTTESTI_CHECK_RC(obj3.setNull(), VINF_SUCCESS);
666 RTTESTI_CHECK_RC(obj3.assignCopy(obj3Max), VINF_SUCCESS);
667 RTTESTI_CHECK(obj3.m_rdValue == DBL_MAX);
668 RTTESTI_CHECK(obj3.isNull() == false);
669
670 RTTESTI_CHECK_RC(obj3.assignCopy(obj3Null), VINF_SUCCESS);
671 RTTESTI_CHECK(obj3.m_rdValue == 0.0);
672 RTTESTI_CHECK(obj3.isNull() == true);
673
674 RTTESTI_CHECK_RC(obj3.assignCopy(obj3Min), VINF_SUCCESS);
675 RTTESTI_CHECK(obj3.m_rdValue == DBL_MIN);
676 RTTESTI_CHECK(obj3.isNull() == false);
677
678 obj3 = obj3Null;
679 RTTESTI_CHECK(obj3.m_rdValue == 0.0);
680 RTTESTI_CHECK(obj3.isNull() == true);
681
682 obj3 = obj3Max;
683 RTTESTI_CHECK(obj3.m_rdValue == DBL_MAX);
684 RTTESTI_CHECK(obj3.isNull() == false);
685
686 obj3 = obj3Null;
687 RTTESTI_CHECK(obj3.m_rdValue == 0.0);
688 RTTESTI_CHECK(obj3.isNull() == true);
689
690 obj3 = obj3Min;
691 RTTESTI_CHECK(obj3.m_rdValue == DBL_MIN);
692 RTTESTI_CHECK(obj3.isNull() == false);
693
694 /* setNull implies resetToDefault: */
695 obj3 = obj3Max;
696 RTTESTI_CHECK(obj3.m_rdValue == DBL_MAX);
697 RTTESTI_CHECK(obj3.isNull() == false);
698 RTTESTI_CHECK_RC(obj3.setNull(), VINF_SUCCESS);
699 RTTESTI_CHECK(obj3.isNull() == true);
700 RTTESTI_CHECK(obj3.m_rdValue == 0.0);
701
702 /* Copy constructors: */
703 {
704 RTCRestDouble obj3a(obj3Max);
705 RTTESTI_CHECK(obj3a.m_rdValue == DBL_MAX);
706 RTTESTI_CHECK(obj3a.isNull() == false);
707 }
708 {
709 RTCRestDouble obj3b(obj3Min);
710 RTTESTI_CHECK(obj3b.m_rdValue == DBL_MIN);
711 RTTESTI_CHECK(obj3b.isNull() == false);
712 }
713 {
714 RTCRestDouble obj3c(obj3Null);
715 RTTESTI_CHECK(obj3c.m_rdValue == 0.0);
716 RTTESTI_CHECK(obj3c.isNull() == true);
717 }
718
719 /* Serialization to json: */
720 const char *pszJson = toJson(&obj3Max);
721 RTTESTI_CHECK_MSG(strcmp(pszJson, DBL_MAX_STRING) == 0, ("pszJson=%s\n", pszJson));
722 pszJson = toJson(&obj3Min);
723 RTTESTI_CHECK_MSG(strcmp(pszJson, DBL_MIN_STRING) == 0, ("pszJson=%s\n", pszJson));
724 pszJson = toJson(&obj3Null);
725 RTTESTI_CHECK_MSG(strcmp(pszJson, "null") == 0, ("pszJson=%s\n", pszJson));
726
727 /* Serialization to string. */
728 RTCString str;
729 RTCString strExpect;
730 str = "lead-in:";
731 RTTESTI_CHECK_RC(obj3Max.toString(&str, RTCRestObjectBase::kToString_Append), VINF_SUCCESS);
732 strExpect.printf("lead-in:%s", DBL_MAX_STRING);
733 RTTESTI_CHECK_MSG(str.equals(strExpect), ("str=%s strExpect=%s\n", str.c_str(), strExpect.c_str()));
734 RTTESTI_CHECK_RC(obj3Max.toString(&str), VINF_SUCCESS);
735 RTTESTI_CHECK_MSG(str.equals(DBL_MAX_STRING), ("str=%s\n", str.c_str()));
736
737 str = "lead-in:";
738 RTTESTI_CHECK_RC(obj3Min.toString(&str, RTCRestObjectBase::kToString_Append), VINF_SUCCESS);
739 strExpect.printf("lead-in:%s", DBL_MIN_STRING);
740 RTTESTI_CHECK_MSG(str.equals(strExpect), ("str=%s strExpect=%s\n", str.c_str(), strExpect.c_str()));
741 RTTESTI_CHECK_RC(obj3Min.toString(&str), VINF_SUCCESS);
742 RTTESTI_CHECK_MSG(str.equals(DBL_MIN_STRING), ("str=%s\n", str.c_str()));
743
744 str = "lead-in:";
745 RTTESTI_CHECK_RC(obj3Null.toString(&str, RTCRestObjectBase::kToString_Append), VINF_SUCCESS);
746 RTTESTI_CHECK_MSG(str.equals("lead-in:null"), ("str=%s\n", str.c_str()));
747 RTTESTI_CHECK_RC(obj3Null.toString(&str), VINF_SUCCESS);
748 RTTESTI_CHECK_MSG(str.equals("null"), ("str=%s\n", str.c_str()));
749 }
750
751 /* deserialize: */
752 RTERRINFOSTATIC ErrInfo;
753 {
754 /* from json: */
755 RTCRestDouble obj4;
756 obj4.setNull();
757 RTTESTI_CHECK_RC(deserializeFromJson(&obj4, "42.42", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
758 RTTESTI_CHECK(obj4.m_rdValue == 42.42);
759 RTTESTI_CHECK(obj4.isNull() == false);
760
761 obj4.setNull();
762 RTTESTI_CHECK_RC(deserializeFromJson(&obj4, "-22.22", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
763 RTTESTI_CHECK(obj4.m_rdValue == -22.22);
764 RTTESTI_CHECK(obj4.isNull() == false);
765
766 obj4.setNull();
767 RTTESTI_CHECK_RC(deserializeFromJson(&obj4, DBL_MAX_STRING, &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
768 RTTESTI_CHECK(obj4.m_rdValue == DBL_MAX);
769 RTTESTI_CHECK(obj4.isNull() == false);
770
771 obj4.setNull();
772 RTTESTI_CHECK_RC(deserializeFromJson(&obj4, DBL_MIN_STRING, &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
773 RTTESTI_CHECK(obj4.m_rdValue == DBL_MIN);
774 RTTESTI_CHECK(obj4.isNull() == false);
775
776 RTTESTI_CHECK_RC(deserializeFromJson(&obj4, "null", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
777 RTTESTI_CHECK(obj4.m_rdValue == 0.0);
778 RTTESTI_CHECK(obj4.isNull() == true);
779
780 obj4.setNull();
781 RTTESTI_CHECK_RC(deserializeFromJson(&obj4, "14323", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
782 RTTESTI_CHECK(obj4.m_rdValue == 14323.0);
783 RTTESTI_CHECK(obj4.isNull() == false);
784
785 obj4.setNull();
786 RTTESTI_CHECK_RC(deserializeFromJson(&obj4, "-234875", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
787 RTTESTI_CHECK(obj4.m_rdValue == -234875.0);
788 RTTESTI_CHECK(obj4.isNull() == false);
789
790 /* object goes to default state on failure: */
791 obj4.assignValue(DBL_MIN);
792 RTTESTI_CHECK_RC(deserializeFromJson(&obj4, "false", &ErrInfo, RT_XSTR(__LINE__)), VERR_REST_WRONG_JSON_TYPE_FOR_DOUBLE);
793 RTTESTI_CHECK(obj4.m_rdValue == 0.0);
794 RTTESTI_CHECK(obj4.isNull() == false);
795 RTTESTI_CHECK(RTErrInfoIsSet(&ErrInfo.Core));
796
797 obj4.assignValue(DBL_MAX);
798 RTTESTI_CHECK_RC(deserializeFromJson(&obj4, "\"false\"", &ErrInfo, RT_XSTR(__LINE__)), VERR_REST_WRONG_JSON_TYPE_FOR_DOUBLE);
799 RTTESTI_CHECK(obj4.m_rdValue == 0.0);
800 RTTESTI_CHECK(obj4.isNull() == false);
801 RTTESTI_CHECK(RTErrInfoIsSet(&ErrInfo.Core));
802
803 obj4.setNull();
804 RTTESTI_CHECK_RC(deserializeFromJson(&obj4, "[ null ]", NULL, RT_XSTR(__LINE__)), VERR_REST_WRONG_JSON_TYPE_FOR_DOUBLE);
805 RTTESTI_CHECK(obj4.m_rdValue == 0.0);
806 RTTESTI_CHECK(obj4.isNull() == false);
807
808 /* from string: */
809 obj4.setNull();
810 RTTESTI_CHECK_RC(fromString(&obj4, "22.42", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
811 RTTESTI_CHECK(obj4.m_rdValue == 22.42);
812 RTTESTI_CHECK(obj4.isNull() == false);
813
814 RTTESTI_CHECK_RC(fromString(&obj4, "-42.22", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
815 RTTESTI_CHECK(obj4.m_rdValue == -42.22);
816 RTTESTI_CHECK(obj4.isNull() == false);
817
818 RTTESTI_CHECK_RC(fromString(&obj4, DBL_MAX_STRING, &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
819 RTTESTI_CHECK(obj4.m_rdValue == DBL_MAX);
820 RTTESTI_CHECK(obj4.isNull() == false);
821
822 RTTESTI_CHECK_RC(fromString(&obj4, DBL_MIN_STRING, &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
823 RTTESTI_CHECK(obj4.m_rdValue == DBL_MIN);
824 RTTESTI_CHECK(obj4.isNull() == false);
825
826 obj4.m_rdValue = 33.33;
827 RTTESTI_CHECK_RC(fromString(&obj4, "null", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
828 RTTESTI_CHECK(obj4.m_rdValue == 0.0);
829 RTTESTI_CHECK(obj4.isNull() == true);
830
831 obj4.m_rdValue = 33.33;
832 RTTESTI_CHECK_RC(fromString(&obj4, " nULl;", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
833 RTTESTI_CHECK(obj4.m_rdValue == 0.0);
834 RTTESTI_CHECK(obj4.isNull() == true);
835
836 obj4.setNull();
837 RTTESTI_CHECK_RC(fromString(&obj4, " 42.22 ", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
838 RTTESTI_CHECK(obj4.m_rdValue == 42.22);
839 RTTESTI_CHECK(obj4.isNull() == false);
840
841 RTTESTI_CHECK_RC(fromString(&obj4, "\t010\t", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
842 RTTESTI_CHECK(obj4.m_rdValue ==10.0);
843 RTTESTI_CHECK(obj4.isNull() == false);
844
845 RTTESTI_CHECK_RC(fromString(&obj4, "\r\t03495.344\t\r\n", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
846 RTTESTI_CHECK(obj4.m_rdValue == 3495.344);
847 RTTESTI_CHECK(obj4.isNull() == false);
848
849 RTTESTI_CHECK_RC(fromString(&obj4, "1.1;", &ErrInfo, RT_XSTR(__LINE__)), VERR_TRAILING_CHARS);
850 RTTESTI_CHECK(RTErrInfoIsSet(&ErrInfo.Core));
851
852 RTTESTI_CHECK_RC(fromString(&obj4, "false", NULL, RT_XSTR(__LINE__)), VERR_NO_DIGITS);
853
854 RTTESTI_CHECK_RC(fromString(&obj4, " 0x42 ", &ErrInfo, RT_XSTR(__LINE__)), VERR_TRAILING_CHARS);
855 RTTESTI_CHECK(obj4.m_rdValue == 0.0);
856 RTTESTI_CHECK(obj4.isNull() == false);
857 }
858}
859
860
861void testString(const char *pszDummy, ...)
862{
863 RTTestSub(g_hTest, "RTCRestString");
864
865 {
866 RTCRestString obj1;
867 RTTESTI_CHECK(obj1.isEmpty());
868 RTTESTI_CHECK(obj1.isNull() == false);
869 RTTESTI_CHECK(strcmp(obj1.typeName(), "RTCString") == 0);
870 RTTESTI_CHECK(obj1.typeClass() == RTCRestObjectBase::kTypeClass_String);
871 }
872
873 {
874 RTCRestString obj2(RTCString("2398.1"));
875 RTTESTI_CHECK(obj2 == "2398.1");
876 RTTESTI_CHECK(obj2.isNull() == false);
877 }
878
879 {
880 RTCRestString obj2("-7345.2");
881 RTTESTI_CHECK(obj2 == "-7345.2");
882 RTTESTI_CHECK(obj2.isNull() == false);
883 }
884
885 {
886 /* Value assignments: */
887 RTCRestString obj3;
888 RTTESTI_CHECK_RC(obj3.setNull(), VINF_SUCCESS);
889 RTTESTI_CHECK(obj3.isNull() == true);
890 RTTESTI_CHECK(obj3.isEmpty());
891 obj3 = "-1.0";
892 RTTESTI_CHECK(obj3 == "-1.0");
893 RTTESTI_CHECK(obj3.isNull() == false);
894
895 RTTESTI_CHECK_RC(obj3.setNull(), VINF_SUCCESS);
896 RTTESTI_CHECK(obj3.isNull() == true && obj3.isEmpty());
897 obj3 = RTCString("-2.0");
898 RTTESTI_CHECK(obj3 == "-2.0");
899 RTTESTI_CHECK(obj3.isNull() == false);
900
901 RTTESTI_CHECK_RC(obj3.setNull(), VINF_SUCCESS);
902 RTTESTI_CHECK(obj3.isNull() == true && obj3.isEmpty());
903 obj3 = RTCRestString("-3.0");
904 RTTESTI_CHECK(obj3 == "-3.0");
905 RTTESTI_CHECK(obj3.isNull() == false);
906
907 RTTESTI_CHECK_RC(obj3.setNull(), VINF_SUCCESS);
908 RTTESTI_CHECK(obj3.isNull() == true && obj3.isEmpty());
909 RTTESTI_CHECK_RC(obj3.assignNoThrow(RTCRestString("4.0")), VINF_SUCCESS);
910 RTTESTI_CHECK(obj3 == "4.0");
911 RTTESTI_CHECK(obj3.isNull() == false);
912
913 RTTESTI_CHECK_RC(obj3.setNull(), VINF_SUCCESS);
914 RTTESTI_CHECK(obj3.isNull() == true && obj3.isEmpty());
915 RTTESTI_CHECK_RC(obj3.assignNoThrow("-4.0"), VINF_SUCCESS);
916 RTTESTI_CHECK(obj3 == "-4.0");
917 RTTESTI_CHECK(obj3.isNull() == false);
918
919 RTTESTI_CHECK_RC(obj3.setNull(), VINF_SUCCESS);
920 RTTESTI_CHECK(obj3.isNull() == true && obj3.isEmpty());
921 RTTESTI_CHECK_RC(obj3.assignNoThrow(RTCRestString("0123456789"), 3, 5), VINF_SUCCESS);
922 RTTESTI_CHECK(obj3 == "34567");
923 RTTESTI_CHECK(obj3.isNull() == false);
924
925 RTTESTI_CHECK_RC(obj3.setNull(), VINF_SUCCESS);
926 RTTESTI_CHECK(obj3.isNull() == true && obj3.isEmpty());
927 RTTESTI_CHECK_RC(obj3.assignNoThrow("0123456789", 4), VINF_SUCCESS);
928 RTTESTI_CHECK(obj3 == "0123");
929 RTTESTI_CHECK(obj3.isNull() == false);
930
931 RTTESTI_CHECK_RC(obj3.setNull(), VINF_SUCCESS);
932 RTTESTI_CHECK(obj3.isNull() == true && obj3.isEmpty());
933 RTTESTI_CHECK_RC(obj3.assignNoThrow(8, 'x'), VINF_SUCCESS);
934 RTTESTI_CHECK(obj3 == "xxxxxxxx");
935 RTTESTI_CHECK(obj3.isNull() == false);
936
937 RTTESTI_CHECK_RC(obj3.setNull(), VINF_SUCCESS);
938 RTTESTI_CHECK(obj3.isNull() == true && obj3.isEmpty());
939 RTTESTI_CHECK_RC(obj3.printfNoThrow("%d%s%d", 42, "asdf", 22), VINF_SUCCESS);
940 RTTESTI_CHECK(obj3 == "42asdf22");
941 RTTESTI_CHECK(obj3.isNull() == false);
942
943 RTTESTI_CHECK_RC(obj3.setNull(), VINF_SUCCESS);
944 RTTESTI_CHECK(obj3.isNull() == true && obj3.isEmpty());
945 va_list va;
946 va_start(va, pszDummy);
947 RTTESTI_CHECK_RC(obj3.printfVNoThrow("asdf", va), VINF_SUCCESS);
948 va_end(va);
949 RTTESTI_CHECK(obj3 == "asdf");
950 RTTESTI_CHECK(obj3.isNull() == false);
951
952 RTTESTI_CHECK_RC(obj3.setNull(), VINF_SUCCESS);
953 RTTESTI_CHECK(obj3.isNull() == true && obj3.isEmpty());
954 obj3.assign(RTCRestString("4.0"));
955 RTTESTI_CHECK(obj3 == "4.0");
956 RTTESTI_CHECK(obj3.isNull() == false);
957
958 RTTESTI_CHECK_RC(obj3.setNull(), VINF_SUCCESS);
959 RTTESTI_CHECK(obj3.isNull() == true && obj3.isEmpty());
960 obj3.assign("-4.0");
961 RTTESTI_CHECK(obj3 == "-4.0");
962 RTTESTI_CHECK(obj3.isNull() == false);
963
964 RTTESTI_CHECK_RC(obj3.setNull(), VINF_SUCCESS);
965 RTTESTI_CHECK(obj3.isNull() == true && obj3.isEmpty());
966 obj3.assign(RTCRestString("0123456789"), 3, 5);
967 RTTESTI_CHECK(obj3 == "34567");
968 RTTESTI_CHECK(obj3.isNull() == false);
969
970 RTTESTI_CHECK_RC(obj3.setNull(), VINF_SUCCESS);
971 RTTESTI_CHECK(obj3.isNull() == true && obj3.isEmpty());
972 obj3.assign("0123456789", 4);
973 RTTESTI_CHECK(obj3 == "0123");
974 RTTESTI_CHECK(obj3.isNull() == false);
975
976 RTTESTI_CHECK_RC(obj3.setNull(), VINF_SUCCESS);
977 RTTESTI_CHECK(obj3.isNull() == true && obj3.isEmpty());
978 obj3.assign(8, 'x');
979 RTTESTI_CHECK(obj3 == "xxxxxxxx");
980 RTTESTI_CHECK(obj3.isNull() == false);
981
982 RTTESTI_CHECK_RC(obj3.setNull(), VINF_SUCCESS);
983 RTTESTI_CHECK(obj3.isNull() == true && obj3.isEmpty());
984 obj3.printf("%d%s%d", 42, "asdf", 22);
985 RTTESTI_CHECK(obj3 == "42asdf22");
986 RTTESTI_CHECK(obj3.isNull() == false);
987
988 RTTESTI_CHECK_RC(obj3.setNull(), VINF_SUCCESS);
989 RTTESTI_CHECK(obj3.isNull() == true && obj3.isEmpty());
990 va_start(va, pszDummy);
991 obj3.printfV("asdf", va);
992 va_end(va);
993 RTTESTI_CHECK(obj3 == "asdf");
994 RTTESTI_CHECK(obj3.isNull() == false);
995
996 /* Reset to default: */
997 RTTESTI_CHECK_RC(obj3.resetToDefault(), VINF_SUCCESS);
998 RTTESTI_CHECK(obj3.isEmpty());
999 RTTESTI_CHECK(obj3.isNull() == false);
1000
1001 obj3 = "1";
1002 RTTESTI_CHECK_RC(obj3.setNull(), VINF_SUCCESS);
1003 RTTESTI_CHECK_RC(obj3.resetToDefault(), VINF_SUCCESS);
1004 RTTESTI_CHECK(obj3.isEmpty());
1005 RTTESTI_CHECK(obj3.isNull() == false);
1006
1007 /* Copy assignments: */
1008 RTCRestString const obj3Max("max");
1009 RTTESTI_CHECK(obj3Max == "max");
1010 RTTESTI_CHECK(obj3Max.isNull() == false);
1011 RTCRestString obj3Null;
1012 obj3Null.setNull();
1013 RTTESTI_CHECK(obj3Null.isEmpty());
1014 RTTESTI_CHECK(obj3Null.isNull() == true);
1015 RTCRestString obj3Empty;
1016 RTTESTI_CHECK(obj3Empty.isEmpty());
1017 RTTESTI_CHECK(obj3Empty.isNull() == false);
1018
1019 RTTESTI_CHECK_RC(obj3.setNull(), VINF_SUCCESS);
1020 RTTESTI_CHECK(obj3.isNull() == true && obj3.isEmpty());
1021 RTTESTI_CHECK_RC(obj3.assignCopy(obj3Max), VINF_SUCCESS);
1022 RTTESTI_CHECK(obj3 == "max");
1023 RTTESTI_CHECK(obj3.isNull() == false);
1024
1025 RTTESTI_CHECK_RC(obj3.setNull(), VINF_SUCCESS);
1026 RTTESTI_CHECK(obj3.isNull() == true && obj3.isEmpty());
1027 RTTESTI_CHECK_RC(obj3.assignCopy(obj3Null), VINF_SUCCESS);
1028 RTTESTI_CHECK(obj3.isEmpty());
1029 RTTESTI_CHECK(obj3.isNull() == true);
1030
1031 RTTESTI_CHECK_RC(obj3.setNull(), VINF_SUCCESS);
1032 RTTESTI_CHECK(obj3.isNull() == true && obj3.isEmpty());
1033 RTTESTI_CHECK_RC(obj3.assignCopy(obj3Empty), VINF_SUCCESS);
1034 RTTESTI_CHECK(obj3 == "");
1035 RTTESTI_CHECK(obj3.isEmpty());
1036 RTTESTI_CHECK(obj3.isNull() == false);
1037
1038 RTTESTI_CHECK_RC(obj3.setNull(), VINF_SUCCESS);
1039 RTTESTI_CHECK(obj3.isNull() == true && obj3.isEmpty());
1040 RTTESTI_CHECK_RC(obj3.assignCopy(RTCString("11.0")), VINF_SUCCESS);
1041 RTTESTI_CHECK(obj3 == "11.0");
1042 RTTESTI_CHECK(obj3.isNull() == false);
1043
1044 RTTESTI_CHECK_RC(obj3.setNull(), VINF_SUCCESS);
1045 RTTESTI_CHECK(obj3.isNull() == true && obj3.isEmpty());
1046 RTTESTI_CHECK_RC(obj3.assignCopy("12.0"), VINF_SUCCESS);
1047 RTTESTI_CHECK(obj3 == "12.0");
1048 RTTESTI_CHECK(obj3.isNull() == false);
1049
1050 /* setNull implies resetToDefault: */
1051 obj3 = obj3Max;
1052 RTTESTI_CHECK(obj3 == "max");
1053 RTTESTI_CHECK(obj3.isNull() == false);
1054 RTTESTI_CHECK_RC(obj3.setNull(), VINF_SUCCESS);
1055 RTTESTI_CHECK(obj3.isNull() == true);
1056 RTTESTI_CHECK(obj3.isEmpty());
1057
1058 /* Copy constructors: */
1059 {
1060 RTCRestString obj3a(obj3Max);
1061 RTTESTI_CHECK(obj3a == "max");
1062 RTTESTI_CHECK(obj3a.isNull() == false);
1063 }
1064 {
1065 RTCRestString const obj3c(obj3Null);
1066 RTTESTI_CHECK(obj3c.isEmpty());
1067 RTTESTI_CHECK(obj3c.isNull() == true);
1068 }
1069
1070 /* Serialization to json: */
1071 const char *pszJson = toJson(&obj3Max);
1072 RTTESTI_CHECK_MSG(strcmp(pszJson, "\"max\"") == 0, ("pszJson=%s\n", pszJson));
1073 pszJson = toJson(&obj3Null);
1074 RTTESTI_CHECK_MSG(strcmp(pszJson, "null") == 0, ("pszJson=%s\n", pszJson));
1075 pszJson = toJson(&obj3Empty);
1076 RTTESTI_CHECK_MSG(strcmp(pszJson, "\"\"") == 0, ("pszJson=%s\n", pszJson));
1077
1078 /* Serialization to string. */
1079 RTCString str;
1080 RTCString strExpect;
1081 str = "lead-in:";
1082 RTTESTI_CHECK_RC(obj3Max.toString(&str, RTCRestObjectBase::kToString_Append), VINF_SUCCESS);
1083 RTTESTI_CHECK_MSG(str.equals("lead-in:max"), ("str=%s\n", str.c_str()));
1084 RTTESTI_CHECK_RC(obj3Max.toString(&str), VINF_SUCCESS);
1085 RTTESTI_CHECK_MSG(str.equals("max"), ("str=%s\n", str.c_str()));
1086
1087 str = "lead-in:";
1088 RTTESTI_CHECK_RC(obj3Empty.toString(&str, RTCRestObjectBase::kToString_Append), VINF_SUCCESS);
1089 RTTESTI_CHECK_MSG(str.equals("lead-in:"), ("str=%s\n", str.c_str()));
1090 RTTESTI_CHECK_RC(obj3Empty.toString(&str), VINF_SUCCESS);
1091 RTTESTI_CHECK_MSG(str.equals(""), ("str=%s\n", str.c_str()));
1092
1093 str = "lead-in:";
1094 RTTESTI_CHECK_RC(obj3Null.toString(&str, RTCRestObjectBase::kToString_Append), VINF_SUCCESS);
1095 RTTESTI_CHECK_MSG(str.equals("lead-in:"), ("str=%s\n", str.c_str()));
1096 RTTESTI_CHECK_RC(obj3Null.toString(&str), VINF_SUCCESS);
1097 RTTESTI_CHECK_MSG(str.equals(""), ("str=%s\n", str.c_str()));
1098 }
1099
1100 /* deserialize: */
1101 RTERRINFOSTATIC ErrInfo;
1102 {
1103 /* from json: */
1104 RTCRestString obj4;
1105 obj4.setNull();
1106 RTTESTI_CHECK_RC(deserializeFromJson(&obj4, "\"42.42\"", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
1107 RTTESTI_CHECK(obj4 == "42.42");
1108 RTTESTI_CHECK(obj4.isNull() == false);
1109
1110 obj4.setNull();
1111 RTTESTI_CHECK_RC(deserializeFromJson(&obj4, "\"-22.22\"", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
1112 RTTESTI_CHECK(obj4 == "-22.22");
1113 RTTESTI_CHECK(obj4.isNull() == false);
1114
1115 obj4.setNull();
1116 RTTESTI_CHECK_RC(deserializeFromJson(&obj4, "\"maximum\"", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
1117 RTTESTI_CHECK(obj4 == "maximum");
1118 RTTESTI_CHECK(obj4.isNull() == false);
1119
1120 RTTESTI_CHECK_RC(deserializeFromJson(&obj4, "null", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
1121 RTTESTI_CHECK(obj4.isEmpty());
1122 RTTESTI_CHECK(obj4.isNull() == true);
1123
1124 obj4.setNull();
1125 RTTESTI_CHECK_RC(deserializeFromJson(&obj4, "\"\\u0020\"", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
1126 RTTESTI_CHECK(obj4 == " ");
1127 RTTESTI_CHECK(obj4.isNull() == false);
1128
1129 obj4.setNull();
1130 RTTESTI_CHECK_RC(deserializeFromJson(&obj4, "\"\\u004f\\u004D\\u0047\\u0021 :-)\"",
1131 &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
1132 RTTESTI_CHECK(obj4 == "OMG! :-)");
1133 RTTESTI_CHECK(obj4.isNull() == false);
1134
1135 obj4.setNull();
1136 RTTESTI_CHECK_RC(deserializeFromJson(&obj4, "\"42:\\uD801\\udC37\\ud852\\uDf62:42\"", /* U+10437 U+24B62 */
1137 &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
1138 RTTESTI_CHECK(obj4 == "42:" "\xf0\x90\x90\xb7" "\xf0\xa4\xad\xa2" ":42");
1139 RTTESTI_CHECK(obj4.isNull() == false);
1140
1141 /* object goes to default state on failure: */
1142 obj4 = "asdf";
1143 RTTESTI_CHECK_RC(deserializeFromJson(&obj4, "false", &ErrInfo, RT_XSTR(__LINE__)), VERR_REST_WRONG_JSON_TYPE_FOR_STRING);
1144 RTTESTI_CHECK(obj4.isEmpty());
1145 RTTESTI_CHECK(obj4.isNull() == false);
1146 RTTESTI_CHECK(RTErrInfoIsSet(&ErrInfo.Core));
1147
1148 obj4 = "asdf";
1149 RTTESTI_CHECK_RC(deserializeFromJson(&obj4, "1", &ErrInfo, RT_XSTR(__LINE__)), VERR_REST_WRONG_JSON_TYPE_FOR_STRING);
1150 RTTESTI_CHECK(obj4.isEmpty());
1151 RTTESTI_CHECK(obj4.isNull() == false);
1152 RTTESTI_CHECK(RTErrInfoIsSet(&ErrInfo.Core));
1153
1154 obj4.setNull();
1155 RTTESTI_CHECK_RC(deserializeFromJson(&obj4, "[ null ]", NULL, RT_XSTR(__LINE__)), VERR_REST_WRONG_JSON_TYPE_FOR_STRING);
1156 RTTESTI_CHECK(obj4.isEmpty());
1157 RTTESTI_CHECK(obj4.isNull() == false);
1158
1159 /* from string: */
1160 obj4.setNull();
1161 RTTESTI_CHECK_RC(fromString(&obj4, "22.42", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
1162 RTTESTI_CHECK(obj4 == "22.42");
1163 RTTESTI_CHECK(obj4.isNull() == false);
1164
1165 RTTESTI_CHECK_RC(fromString(&obj4, "-42.22", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
1166 RTTESTI_CHECK(obj4 == "-42.22");
1167 RTTESTI_CHECK(obj4.isNull() == false);
1168
1169 obj4.setNull();
1170 RTTESTI_CHECK_RC(fromString(&obj4, "null", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
1171 RTTESTI_CHECK(obj4 == "null");
1172 RTTESTI_CHECK(obj4.isNull() == false);
1173 }
1174}
1175
1176
1177void testDate()
1178{
1179 RTTestSub(g_hTest, "RTCRestDate");
1180 int64_t const iRecent = INT64_C(1536580687739632500);
1181 int64_t const iRecentSec = INT64_C(1536580687000000000);
1182 RTTIMESPEC TimeSpec;
1183
1184#define CHECK_DATE(a_obj, a_fNull, a_fOkay, a_i64Nano, a_sz, a_fUtc) \
1185 do { \
1186 RTTESTI_CHECK((a_obj).isOkay() == (a_fOkay)); \
1187 if ((a_obj).getEpochNano() != (a_i64Nano)) \
1188 RTTestIFailed("line " RT_XSTR(__LINE__) ": getEpochNano=%RI64, expected %RI64", (a_obj).getEpochNano(), (int64_t)(a_i64Nano)); \
1189 if (!(a_obj).getString().equals(a_sz)) \
1190 RTTestIFailed("line " RT_XSTR(__LINE__) ": getString=%s, expected %s", (a_obj).getString().c_str(), a_sz); \
1191 RTTESTI_CHECK((a_obj).isUtc() == (a_fUtc)); \
1192 RTTESTI_CHECK((a_obj).isNull() == (a_fNull)); \
1193 } while (0)
1194#define CHECK_DATE_FMT(a_obj, a_fNull, a_fOkay, a_i64Nano, a_sz, a_fUtc, a_enmFormat) \
1195 do { \
1196 CHECK_DATE(a_obj, a_fNull, a_fOkay, a_i64Nano, a_sz, a_fUtc); \
1197 if ((a_obj).getFormat() != (a_enmFormat)) \
1198 RTTestIFailed("line " RT_XSTR(__LINE__) ": getFormat=%d, expected %d (%s)", (a_obj).getFormat(), (a_enmFormat), #a_enmFormat); \
1199 } while (0)
1200
1201 {
1202 RTCRestDate obj1;
1203 CHECK_DATE(obj1, true, false, 0, "", true);
1204 RTTESTI_CHECK(strcmp(obj1.typeName(), "RTCRestDate") == 0);
1205 RTTESTI_CHECK(obj1.typeClass() == RTCRestObjectBase::kTypeClass_Date);
1206 }
1207
1208 {
1209 /* Value assignments: */
1210 RTCRestDate obj3;
1211 RTTESTI_CHECK_RC(obj3.assignValue(RTTimeSpecSetNano(&TimeSpec, 0), RTCRestDate::kFormat_Rfc3339), VINF_SUCCESS);
1212 CHECK_DATE(obj3, false, true, 0, "1970-01-01T00:00:00Z", true);
1213
1214 RTTESTI_CHECK_RC(obj3.setNull(), VINF_SUCCESS);
1215 CHECK_DATE(obj3, true, false, 0, "", true);
1216 RTTESTI_CHECK_RC(obj3.assignValueRfc3339(RTTimeSpecSetNano(&TimeSpec, 0)), VINF_SUCCESS);
1217 CHECK_DATE(obj3, false, true, 0, "1970-01-01T00:00:00Z", true);
1218
1219 RTTESTI_CHECK_RC(obj3.setNull(), VINF_SUCCESS);
1220 CHECK_DATE(obj3, true, false, 0, "", true);
1221 RTTESTI_CHECK_RC(obj3.assignValueRfc2822(RTTimeSpecSetNano(&TimeSpec, 0)), VINF_SUCCESS);
1222 CHECK_DATE(obj3, false, true, 0, "Thu, 1 Jan 1970 00:00:00 -0000", true);
1223
1224 RTTESTI_CHECK_RC(obj3.setNull(), VINF_SUCCESS);
1225 RTTESTI_CHECK_RC(obj3.assignValueRfc7131(RTTimeSpecSetNano(&TimeSpec, 0)), VINF_SUCCESS);
1226 CHECK_DATE(obj3, false, true, 0, "Thu, 1 Jan 1970 00:00:00 GMT", true);
1227
1228 RTTESTI_CHECK_RC(obj3.setNull(), VINF_SUCCESS);
1229 RTTESTI_CHECK_RC(obj3.assignValue(RTTimeSpecSetNano(&TimeSpec, 0), RTCRestDate::kFormat_Rfc2822), VINF_SUCCESS);
1230 CHECK_DATE(obj3, false, true, 0, "Thu, 1 Jan 1970 00:00:00 -0000", true);
1231
1232 RTTESTI_CHECK_RC(obj3.setNull(), VINF_SUCCESS);
1233 RTTESTI_CHECK_RC(obj3.assignValue(RTTimeSpecSetNano(&TimeSpec, 0), RTCRestDate::kFormat_Rfc7131), VINF_SUCCESS);
1234 CHECK_DATE(obj3, false, true, 0, "Thu, 1 Jan 1970 00:00:00 GMT", true);
1235
1236 RTTESTI_CHECK_RC(obj3.setNull(), VINF_SUCCESS);
1237 RTTESTI_CHECK_RC(obj3.assignValue(RTTimeSpecSetNano(&TimeSpec, 0), RTCRestDate::kFormat_Rfc3339_Fraction_9), VINF_SUCCESS);
1238 CHECK_DATE(obj3, false, true, 0, "1970-01-01T00:00:00.000000000Z", true);
1239
1240 RTTESTI_CHECK_RC(obj3.setNull(), VINF_SUCCESS);
1241 RTTESTI_CHECK_RC(obj3.assignValue(RTTimeSpecSetNano(&TimeSpec, 0), RTCRestDate::kFormat_Rfc3339_Fraction_6), VINF_SUCCESS);
1242 CHECK_DATE(obj3, false, true, 0, "1970-01-01T00:00:00.000000Z", true);
1243
1244 RTTESTI_CHECK_RC(obj3.setNull(), VINF_SUCCESS);
1245 RTTESTI_CHECK_RC(obj3.assignValue(RTTimeSpecSetNano(&TimeSpec, 0), RTCRestDate::kFormat_Rfc3339_Fraction_3), VINF_SUCCESS);
1246 CHECK_DATE(obj3, false, true, 0, "1970-01-01T00:00:00.000Z", true);
1247
1248 RTTESTI_CHECK_RC(obj3.setNull(), VINF_SUCCESS);
1249 RTTESTI_CHECK_RC(obj3.assignValue(RTTimeSpecSetNano(&TimeSpec, 0), RTCRestDate::kFormat_Rfc3339_Fraction_2), VINF_SUCCESS);
1250 CHECK_DATE(obj3, false, true, 0, "1970-01-01T00:00:00.00Z", true);
1251
1252 /* Format changes: */
1253 RTTESTI_CHECK_RC(obj3.assignValue(RTTimeSpecSetNano(&TimeSpec, 59123456789), RTCRestDate::kFormat_Rfc3339_Fraction_9), VINF_SUCCESS);
1254 CHECK_DATE(obj3, false, true, 59123456789, "1970-01-01T00:00:59.123456789Z", true);
1255 RTTESTI_CHECK_RC(obj3.setFormat(RTCRestDate::kFormat_Rfc2822), VINF_SUCCESS);
1256 CHECK_DATE(obj3, false, true, 59123456789, "Thu, 1 Jan 1970 00:00:59 -0000", true);
1257 RTTESTI_CHECK_RC(obj3.setFormat(RTCRestDate::kFormat_Rfc7131), VINF_SUCCESS);
1258 CHECK_DATE(obj3, false, true, 59123456789, "Thu, 1 Jan 1970 00:00:59 GMT", true);
1259 RTTESTI_CHECK_RC(obj3.setFormat(RTCRestDate::kFormat_Rfc3339), VINF_SUCCESS);
1260 CHECK_DATE(obj3, false, true, 59123456789, "1970-01-01T00:00:59Z", true);
1261 RTTESTI_CHECK_RC(obj3.setFormat(RTCRestDate::kFormat_Rfc3339_Fraction_2), VINF_SUCCESS);
1262 CHECK_DATE(obj3, false, true, 59123456789, "1970-01-01T00:00:59.12Z", true);
1263 RTTESTI_CHECK_RC(obj3.setFormat(RTCRestDate::kFormat_Rfc3339_Fraction_3), VINF_SUCCESS);
1264 CHECK_DATE(obj3, false, true, 59123456789, "1970-01-01T00:00:59.123Z", true);
1265 RTTESTI_CHECK_RC(obj3.setFormat(RTCRestDate::kFormat_Rfc3339_Fraction_6), VINF_SUCCESS);
1266 CHECK_DATE(obj3, false, true, 59123456789, "1970-01-01T00:00:59.123456Z", true);
1267 RTTESTI_CHECK_RC(obj3.setFormat(RTCRestDate::kFormat_Rfc3339_Fraction_9), VINF_SUCCESS);
1268 CHECK_DATE(obj3, false, true, 59123456789, "1970-01-01T00:00:59.123456789Z", true);
1269
1270 /* Reset to default and setNull works identically: */
1271 RTTESTI_CHECK_RC(obj3.resetToDefault(), VINF_SUCCESS);
1272 CHECK_DATE(obj3, true, false, 0, "", true);
1273
1274 RTTESTI_CHECK_RC(obj3.assignValue(RTTimeSpecSetNano(&TimeSpec, 0), RTCRestDate::kFormat_Rfc3339_Fraction_2), VINF_SUCCESS);
1275 CHECK_DATE(obj3, false, true, 0, "1970-01-01T00:00:00.00Z", true);
1276 RTTESTI_CHECK_RC(obj3.setNull(), VINF_SUCCESS);
1277 CHECK_DATE(obj3, true, false, 0, "", true);
1278
1279 /* Copy assignments: */
1280 RTCRestDate obj3Epoch_3339_9;
1281 RTTESTI_CHECK_RC(obj3Epoch_3339_9.assignValue(RTTimeSpecSetNano(&TimeSpec, 0), RTCRestDate::kFormat_Rfc3339_Fraction_9), VINF_SUCCESS);
1282 CHECK_DATE(obj3Epoch_3339_9, false, true, 0, "1970-01-01T00:00:00.000000000Z", true);
1283
1284 RTCRestDate obj3Epoch_7131;
1285 RTTESTI_CHECK_RC(obj3Epoch_7131.assignValue(RTTimeSpecSetNano(&TimeSpec, 0), RTCRestDate::kFormat_Rfc7131), VINF_SUCCESS);
1286 CHECK_DATE(obj3Epoch_7131, false, true, 0, "Thu, 1 Jan 1970 00:00:00 GMT", true);
1287
1288 RTCRestDate obj3Recent_3339;
1289 RTTESTI_CHECK_RC(obj3Recent_3339.assignValue(RTTimeSpecSetNano(&TimeSpec, iRecent), RTCRestDate::kFormat_Rfc3339), VINF_SUCCESS);
1290 CHECK_DATE(obj3Recent_3339, false, true, iRecent, "2018-09-10T11:58:07Z", true);
1291
1292 RTCRestDate obj3Recent_2822;
1293 RTTESTI_CHECK_RC(obj3Recent_2822.assignValue(RTTimeSpecSetNano(&TimeSpec, iRecent), RTCRestDate::kFormat_Rfc2822), VINF_SUCCESS);
1294 CHECK_DATE(obj3Recent_2822, false, true, iRecent, "Mon, 10 Sep 2018 11:58:07 -0000", true);
1295
1296 RTCRestDate const obj3Null;
1297 CHECK_DATE(obj3Null, true, false, 0, "", true);
1298
1299 RTTESTI_CHECK_RC(obj3.setNull(), VINF_SUCCESS);
1300 RTTESTI_CHECK_RC(obj3.assignCopy(obj3Epoch_3339_9), VINF_SUCCESS);
1301 CHECK_DATE(obj3, false, true, 0, "1970-01-01T00:00:00.000000000Z", true);
1302
1303 RTTESTI_CHECK_RC(obj3.setNull(), VINF_SUCCESS);
1304 RTTESTI_CHECK_RC(obj3.assignCopy(obj3Epoch_7131), VINF_SUCCESS);
1305 CHECK_DATE(obj3, false, true, 0, "Thu, 1 Jan 1970 00:00:00 GMT", true);
1306
1307 RTTESTI_CHECK_RC(obj3.assignCopy(obj3Recent_3339), VINF_SUCCESS);
1308 CHECK_DATE(obj3Recent_2822, false, true, iRecent, "Mon, 10 Sep 2018 11:58:07 -0000", true);
1309
1310 RTTESTI_CHECK_RC(obj3.assignCopy(obj3Null), VINF_SUCCESS);
1311 CHECK_DATE(obj3, true, false, 0, "", true);
1312
1313 obj3 = obj3Recent_2822;
1314 CHECK_DATE(obj3Recent_2822, false, true, iRecent, "Mon, 10 Sep 2018 11:58:07 -0000", true);
1315
1316 obj3 = obj3Epoch_3339_9;
1317 CHECK_DATE(obj3, false, true, 0, "1970-01-01T00:00:00.000000000Z", true);
1318
1319 obj3 = obj3Null;
1320 CHECK_DATE(obj3, true, false, 0, "", true);
1321
1322 /* Copy constructors: */
1323 {
1324 RTCRestDate obj3a(obj3Epoch_3339_9);
1325 CHECK_DATE(obj3a, false, true, 0, "1970-01-01T00:00:00.000000000Z", true);
1326 }
1327 {
1328 RTCRestDate obj3b(obj3Epoch_7131);
1329 CHECK_DATE(obj3b, false, true, 0, "Thu, 1 Jan 1970 00:00:00 GMT", true);
1330 }
1331 {
1332 RTCRestDate obj3c(obj3Recent_3339);
1333 CHECK_DATE(obj3Recent_3339, false, true, iRecent, "2018-09-10T11:58:07Z", true);
1334 }
1335 {
1336 RTCRestDate obj3d(obj3Recent_2822);
1337 CHECK_DATE(obj3d, false, true, iRecent, "Mon, 10 Sep 2018 11:58:07 -0000", true);
1338 }
1339 {
1340 RTCRestDate obj3e(obj3Null);
1341 CHECK_DATE(obj3e, true, false, 0, "", true);
1342 }
1343
1344 /* Serialization to json: */
1345 const char *pszJson = toJson(&obj3Epoch_3339_9);
1346 RTTESTI_CHECK_MSG(strcmp(pszJson, "\"1970-01-01T00:00:00.000000000Z\"") == 0, ("pszJson=%s\n", pszJson));
1347 pszJson = toJson(&obj3Epoch_7131);
1348 RTTESTI_CHECK_MSG(strcmp(pszJson, "\"Thu, 1 Jan 1970 00:00:00 GMT\"") == 0, ("pszJson=%s\n", pszJson));
1349 pszJson = toJson(&obj3Recent_3339);
1350 RTTESTI_CHECK_MSG(strcmp(pszJson, "\"2018-09-10T11:58:07Z\"") == 0, ("pszJson=%s\n", pszJson));
1351 pszJson = toJson(&obj3Recent_2822);
1352 RTTESTI_CHECK_MSG(strcmp(pszJson, "\"Mon, 10 Sep 2018 11:58:07 -0000\"") == 0, ("pszJson=%s\n", pszJson));
1353 pszJson = toJson(&obj3Null);
1354 RTTESTI_CHECK_MSG(strcmp(pszJson, "null") == 0, ("pszJson=%s\n", pszJson));
1355
1356 /* Serialization to string. */
1357 RTCString str;
1358 str = "lead-in:";
1359 RTTESTI_CHECK_RC(obj3Epoch_7131.toString(&str, RTCRestObjectBase::kToString_Append), VINF_SUCCESS);
1360 RTTESTI_CHECK_MSG(str.equals("lead-in:Thu, 1 Jan 1970 00:00:00 GMT"), ("str=%s\n", str.c_str()));
1361 RTTESTI_CHECK_RC(obj3Epoch_7131.toString(&str), VINF_SUCCESS);
1362 RTTESTI_CHECK_MSG(str.equals("Thu, 1 Jan 1970 00:00:00 GMT"), ("str=%s\n", str.c_str()));
1363
1364 str = "lead-in:";
1365 RTTESTI_CHECK_RC(obj3Recent_3339.toString(&str, RTCRestObjectBase::kToString_Append), VINF_SUCCESS);
1366 RTTESTI_CHECK_MSG(str.equals("lead-in:2018-09-10T11:58:07Z"), ("str=%s\n", str.c_str()));
1367 RTTESTI_CHECK_RC(obj3Recent_3339.toString(&str), VINF_SUCCESS);
1368 RTTESTI_CHECK_MSG(str.equals("2018-09-10T11:58:07Z"), ("str=%s\n", str.c_str()));
1369
1370 str = "lead-in:";
1371 RTTESTI_CHECK_RC(obj3Null.toString(&str, RTCRestObjectBase::kToString_Append), VINF_SUCCESS);
1372 RTTESTI_CHECK_MSG(str.equals("lead-in:null"), ("str=%s\n", str.c_str()));
1373 RTTESTI_CHECK_RC(obj3Null.toString(&str), VINF_SUCCESS);
1374 RTTESTI_CHECK_MSG(str.equals("null"), ("str=%s\n", str.c_str()));
1375 }
1376
1377 /* deserialize: */
1378 RTERRINFOSTATIC ErrInfo;
1379 {
1380 RTCRestDate obj4;
1381 RTTESTI_CHECK_RC(deserializeFromJson(&obj4, "\"Thu, 1 Jan 1970 00:00:00 GMT\"", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
1382 CHECK_DATE_FMT(obj4, false, true, 0, "Thu, 1 Jan 1970 00:00:00 GMT", true, RTCRestDate::kFormat_Rfc7131);
1383
1384 obj4.setNull();
1385 RTTESTI_CHECK_RC(deserializeFromJson(&obj4, "\"Thu, 1 Jan 1970 00:00:00.0000 GMT\"", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
1386 CHECK_DATE_FMT(obj4, false, true, 0, "Thu, 1 Jan 1970 00:00:00.0000 GMT", true, RTCRestDate::kFormat_Rfc7131);
1387
1388 RTTESTI_CHECK_RC(deserializeFromJson(&obj4, "\"1 Jan 1970 00:00:00 GMT\"", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
1389 CHECK_DATE_FMT(obj4, false, true, 0, "1 Jan 1970 00:00:00 GMT", true, RTCRestDate::kFormat_Rfc7131);
1390
1391 RTTESTI_CHECK_RC(deserializeFromJson(&obj4, "\"1 Jan 1970 00:00:00\"", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
1392 CHECK_DATE_FMT(obj4, false, true, 0, "1 Jan 1970 00:00:00", false, RTCRestDate::kFormat_Rfc2822);
1393
1394 RTTESTI_CHECK_RC(deserializeFromJson(&obj4, "\"1 Jan 070 00:00:00\"", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
1395 CHECK_DATE_FMT(obj4, false, true, 0, "1 Jan 070 00:00:00", false, RTCRestDate::kFormat_Rfc2822);
1396
1397 RTTESTI_CHECK_RC(deserializeFromJson(&obj4, "\"2018-09-10T11:58:07Z\"", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
1398 CHECK_DATE_FMT(obj4, false, true, iRecentSec , "2018-09-10T11:58:07Z", true, RTCRestDate::kFormat_Rfc3339);
1399
1400 RTTESTI_CHECK_RC(deserializeFromJson(&obj4, "\"1 Jan 70 00:00:00\"", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
1401 CHECK_DATE_FMT(obj4, false, true, 0, "1 Jan 70 00:00:00", false, RTCRestDate::kFormat_Rfc2822);
1402
1403 RTTESTI_CHECK_RC(deserializeFromJson(&obj4, "\"2018-09-10T11:58:07.739632500Z\"", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
1404 CHECK_DATE_FMT(obj4, false, true, iRecent, "2018-09-10T11:58:07.739632500Z", true, RTCRestDate::kFormat_Rfc3339_Fraction_9);
1405
1406 RTTESTI_CHECK_RC(deserializeFromJson(&obj4, "null", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
1407 CHECK_DATE_FMT(obj4, true, false, 0, "", true, RTCRestDate::kFormat_Rfc3339_Fraction_9);
1408
1409 /* object goes to default state if not string and to non-okay if string: */
1410 RTTESTI_CHECK_RC(obj4.assignValue(RTTimeSpecSetNano(&TimeSpec, iRecent), RTCRestDate::kFormat_Rfc2822), VINF_SUCCESS);
1411 RTTESTI_CHECK_RC(deserializeFromJson(&obj4, "true", &ErrInfo, RT_XSTR(__LINE__)), VERR_REST_WRONG_JSON_TYPE_FOR_DATE);
1412 CHECK_DATE_FMT(obj4, true, false, 0, "", true, RTCRestDate::kFormat_Rfc2822);
1413
1414 RTTESTI_CHECK_RC(obj4.assignValue(RTTimeSpecSetNano(&TimeSpec, iRecent), RTCRestDate::kFormat_Rfc2822), VINF_SUCCESS);
1415 RTTESTI_CHECK_RC(deserializeFromJson(&obj4, "\"string\"", &ErrInfo, RT_XSTR(__LINE__)), VWRN_REST_UNABLE_TO_DECODE_DATE);
1416 CHECK_DATE_FMT(obj4, false, false, 0, "string", false, RTCRestDate::kFormat_Rfc2822);
1417
1418 RTTESTI_CHECK_RC(obj4.assignValue(RTTimeSpecSetNano(&TimeSpec, iRecent), RTCRestDate::kFormat_Rfc2822), VINF_SUCCESS);
1419 RTTESTI_CHECK_RC(deserializeFromJson(&obj4, "\"0x199 string\"", &ErrInfo, RT_XSTR(__LINE__)), VWRN_REST_UNABLE_TO_DECODE_DATE);
1420 CHECK_DATE_FMT(obj4, false, false, 0, "0x199 string", false, RTCRestDate::kFormat_Rfc2822);
1421
1422 RTTESTI_CHECK_RC(obj4.assignValue(RTTimeSpecSetNano(&TimeSpec, iRecent), RTCRestDate::kFormat_Rfc2822), VINF_SUCCESS);
1423 RTTESTI_CHECK_RC(deserializeFromJson(&obj4, "[ null ]", &ErrInfo, RT_XSTR(__LINE__)), VERR_REST_WRONG_JSON_TYPE_FOR_DATE);
1424 CHECK_DATE_FMT(obj4, true, false, 0, "", true, RTCRestDate::kFormat_Rfc2822);
1425
1426 RTTESTI_CHECK_RC(obj4.assignValue(RTTimeSpecSetNano(&TimeSpec, iRecent), RTCRestDate::kFormat_Rfc2822), VINF_SUCCESS);
1427 RTTESTI_CHECK_RC(deserializeFromJson(&obj4, "{ \"foo\": 1 }", &ErrInfo, RT_XSTR(__LINE__)), VERR_REST_WRONG_JSON_TYPE_FOR_DATE);
1428 CHECK_DATE_FMT(obj4, true, false, 0, "", true, RTCRestDate::kFormat_Rfc2822);
1429
1430 /* From string: */
1431 obj4.setNull();
1432 RTTESTI_CHECK_RC(fromString(&obj4, "Thu, 1 Jan 1970 00:00:00 GMT", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
1433 CHECK_DATE_FMT(obj4, false, true, 0, "Thu, 1 Jan 1970 00:00:00 GMT", true, RTCRestDate::kFormat_Rfc7131);
1434
1435 RTTESTI_CHECK_RC(fromString(&obj4, "Mon, 10 Sep 2018 11:58:07 -0000", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
1436 CHECK_DATE_FMT(obj4, false, true, iRecentSec, "Mon, 10 Sep 2018 11:58:07 -0000", true, RTCRestDate::kFormat_Rfc2822);
1437
1438 RTTESTI_CHECK_RC(fromString(&obj4, "\t\n\rnull;\r\n\t", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
1439 CHECK_DATE_FMT(obj4, true, false, 0, "", true, RTCRestDate::kFormat_Rfc2822);
1440
1441 RTTESTI_CHECK_RC(fromString(&obj4, "Mon, 10 Sep 2018 11:58:07 +0000", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
1442 CHECK_DATE_FMT(obj4, false, true, iRecentSec, "Mon, 10 Sep 2018 11:58:07 +0000", false, RTCRestDate::kFormat_Rfc2822);
1443
1444 RTTESTI_CHECK_RC(fromString(&obj4, "1970-01-01T00:00:00.000000000Z", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
1445 CHECK_DATE_FMT(obj4, false, true, 0, "1970-01-01T00:00:00.000000000Z", true, RTCRestDate::kFormat_Rfc3339_Fraction_9);
1446
1447 RTTESTI_CHECK_RC(fromString(&obj4, "10 Sep 2018 11:58:07 -0000", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
1448 CHECK_DATE_FMT(obj4, false, true, iRecentSec, "10 Sep 2018 11:58:07 -0000", true, RTCRestDate::kFormat_Rfc2822);
1449
1450 RTTESTI_CHECK_RC(fromString(&obj4, "null", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
1451 CHECK_DATE_FMT(obj4, true, false, 0, "", true, RTCRestDate::kFormat_Rfc2822);
1452
1453 RTTESTI_CHECK_RC(fromString(&obj4, "Mon, 10 Sep 18 11:58:07 -0000", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
1454 CHECK_DATE_FMT(obj4, false, true, iRecentSec, "Mon, 10 Sep 18 11:58:07 -0000", true, RTCRestDate::kFormat_Rfc2822);
1455
1456 RTTESTI_CHECK_RC(fromString(&obj4, "fa;se", &ErrInfo, RT_XSTR(__LINE__)), VERR_REST_UNABLE_TO_DECODE_DATE);
1457 CHECK_DATE_FMT(obj4, false, false, 0, "fa;se", false, RTCRestDate::kFormat_Rfc2822);
1458
1459 RTTESTI_CHECK_RC(fromString(&obj4, "10 Sep 18 11:58:07", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
1460 CHECK_DATE_FMT(obj4, false, true, iRecentSec, "10 Sep 18 11:58:07", false, RTCRestDate::kFormat_Rfc2822);
1461
1462 obj4.setNull();
1463 RTTESTI_CHECK_RC(fromString(&obj4, "10 Sep 118 11:58:07", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
1464 CHECK_DATE_FMT(obj4, false, true, iRecentSec, "10 Sep 118 11:58:07", false, RTCRestDate::kFormat_Rfc2822);
1465 }
1466}
1467
1468
1469/** Wraps RTCRestInt16 to check for leaks. */
1470class MyRestInt16 : public RTCRestInt16
1471{
1472public:
1473 static size_t s_cInstances;
1474 MyRestInt16() : RTCRestInt16() { s_cInstances++; }
1475 MyRestInt16(MyRestInt16 const &a_rThat) : RTCRestInt16(a_rThat) { s_cInstances++; }
1476 MyRestInt16(int16_t a_iValue) : RTCRestInt16(a_iValue) { s_cInstances++; }
1477 ~MyRestInt16() { s_cInstances--; }
1478};
1479
1480size_t MyRestInt16::s_cInstances = 0;
1481
1482
1483static void verifyArray(RTCRestArray<MyRestInt16> const &rArray, int iLine, unsigned cElements, ...)
1484{
1485 if (rArray.size() != cElements)
1486 RTTestIFailed("line %u: size() -> %zu, expected %u", iLine, rArray.size(), cElements);
1487 va_list va;
1488 va_start(va, cElements);
1489 for (unsigned i = 0; i < cElements; i++)
1490 {
1491 int iExpected = va_arg(va, int);
1492 if (rArray.at(i)->m_iValue != iExpected)
1493 RTTestIFailed("line %u: element #%u: %d, expected %d", iLine, i, rArray.at(i)->m_iValue, iExpected);
1494 }
1495 va_end(va);
1496}
1497
1498
1499static void testArray()
1500{
1501 RTTestSub(g_hTest, "RTCRestArray");
1502
1503 {
1504 RTCRestArray<RTCRestBool> obj1;
1505 RTTESTI_CHECK(obj1.size() == 0);
1506 RTTESTI_CHECK(obj1.isEmpty() == true);
1507 RTTESTI_CHECK(obj1.isNull() == false);
1508 RTTESTI_CHECK(strcmp(obj1.typeName(), "RTCRestArray<ElementType>") == 0);
1509 RTTESTI_CHECK(obj1.typeClass() == RTCRestObjectBase::kTypeClass_Array);
1510 }
1511
1512 /* Some random order insertion and manipulations: */
1513 {
1514 RTCRestArray<MyRestInt16> Arr2;
1515 RTCRestArray<MyRestInt16> const *pConstArr2 = &Arr2;
1516
1517 RTTESTI_CHECK_RC(Arr2.insert(0, new MyRestInt16(3)), VINF_SUCCESS);
1518 verifyArray(Arr2, __LINE__, 1, 3);
1519 RTTESTI_CHECK_RC(Arr2.append( new MyRestInt16(7)), VINF_SUCCESS);
1520 verifyArray(Arr2, __LINE__, 2, 3, 7);
1521 RTTESTI_CHECK_RC(Arr2.insert(1, new MyRestInt16(5)), VINF_SUCCESS);
1522 verifyArray(Arr2, __LINE__, 3, 3, 5, 7);
1523 RTTESTI_CHECK_RC(Arr2.insert(2, new MyRestInt16(6)), VINF_SUCCESS);
1524 verifyArray(Arr2, __LINE__, 4, 3, 5, 6, 7);
1525 RTTESTI_CHECK_RC(Arr2.prepend( new MyRestInt16(0)), VINF_SUCCESS);
1526 verifyArray(Arr2, __LINE__, 5, 0, 3, 5, 6, 7);
1527 RTTESTI_CHECK_RC(Arr2.append( new MyRestInt16(9)), VINF_SUCCESS);
1528 verifyArray(Arr2, __LINE__, 6, 0, 3, 5, 6, 7, 9);
1529 RTTESTI_CHECK_RC(Arr2.insert(5, new MyRestInt16(8)), VINF_SUCCESS);
1530 verifyArray(Arr2, __LINE__, 7, 0, 3, 5, 6, 7, 8, 9);
1531 RTTESTI_CHECK_RC(Arr2.insert(1, new MyRestInt16(1)), VINF_SUCCESS);
1532 verifyArray(Arr2, __LINE__, 8, 0, 1, 3, 5, 6, 7, 8, 9);
1533 RTTESTI_CHECK_RC(Arr2.insert(3, new MyRestInt16(4)), VINF_SUCCESS);
1534 verifyArray(Arr2, __LINE__, 9, 0, 1, 3, 4, 5, 6, 7, 8, 9);
1535 RTTESTI_CHECK_RC(Arr2.insert(2, new MyRestInt16(2)), VINF_SUCCESS);
1536 verifyArray(Arr2, __LINE__, 10, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
1537 RTTESTI_CHECK_MSG(MyRestInt16::s_cInstances == Arr2.size(), ("%zu vs %zu\n", MyRestInt16::s_cInstances, Arr2.size()));
1538
1539 RTTESTI_CHECK(Arr2.size() == 10);
1540
1541 for (size_t i = 0; i < Arr2.size(); i++)
1542 {
1543 MyRestInt16 *pCur = Arr2.at(i);
1544 RTTESTI_CHECK(pCur->m_iValue == (int16_t)i);
1545
1546 MyRestInt16 const *pCur2 = pConstArr2->at(i);
1547 RTTESTI_CHECK(pCur2->m_iValue == (int16_t)i);
1548 }
1549
1550 RTTESTI_CHECK_RC(Arr2.replace(2, new MyRestInt16(22)), VWRN_ALREADY_EXISTS);
1551 verifyArray(Arr2, __LINE__, 10, 0, 1, 22, 3, 4, 5, 6, 7, 8, 9);
1552
1553 RTTESTI_CHECK_RC(Arr2.replace(7, new MyRestInt16(77)), VWRN_ALREADY_EXISTS);
1554 verifyArray(Arr2, __LINE__, 10, 0, 1, 22, 3, 4, 5, 6, 77, 8, 9);
1555
1556 RTTESTI_CHECK_RC(Arr2.replace(10, new MyRestInt16(10)), VINF_SUCCESS);
1557 verifyArray(Arr2, __LINE__, 11, 0, 1, 22, 3, 4, 5, 6, 77, 8, 9, 10);
1558
1559 RTTESTI_CHECK_RC(Arr2.replaceCopy(2, MyRestInt16(2)), VWRN_ALREADY_EXISTS);
1560 verifyArray(Arr2, __LINE__, 11, 0, 1, 2, 3, 4, 5, 6, 77, 8, 9, 10);
1561 RTTESTI_CHECK_MSG(MyRestInt16::s_cInstances == Arr2.size(), ("%zu vs %zu\n", MyRestInt16::s_cInstances, Arr2.size()));
1562
1563 /* copy constructor: */
1564 {
1565 RTCRestArray<MyRestInt16> const Arr2Copy(Arr2);
1566 verifyArray(Arr2Copy, __LINE__, 11, 0, 1, 2, 3, 4, 5, 6, 77, 8, 9, 10);
1567 }
1568 verifyArray(Arr2, __LINE__, 11, 0, 1, 2, 3, 4, 5, 6, 77, 8, 9, 10);
1569 RTTESTI_CHECK_MSG(MyRestInt16::s_cInstances == Arr2.size(), ("%zu vs %zu\n", MyRestInt16::s_cInstances, Arr2.size()));
1570
1571 {
1572 RTCRestArray<MyRestInt16> Arr2Copy2(Arr2);
1573 verifyArray(Arr2Copy2, __LINE__, 11, 0, 1, 2, 3, 4, 5, 6, 77, 8, 9, 10);
1574 RTTESTI_CHECK_RC(Arr2Copy2.removeAt(7), VINF_SUCCESS);
1575 verifyArray(Arr2Copy2, __LINE__, 10, 0, 1, 2, 3, 4, 5, 6, 8, 9, 10);
1576 }
1577 verifyArray(Arr2, __LINE__, 11, 0, 1, 2, 3, 4, 5, 6, 77, 8, 9, 10);
1578 RTTESTI_CHECK_MSG(MyRestInt16::s_cInstances == Arr2.size(), ("%zu vs %zu\n", MyRestInt16::s_cInstances, Arr2.size()));
1579
1580 /* copy method + clear: */
1581 {
1582 RTCRestArray<MyRestInt16> Arr2Copy3;
1583 RTTESTI_CHECK_RC(Arr2Copy3.assignCopy(Arr2), VINF_SUCCESS);
1584 verifyArray(Arr2Copy3, __LINE__, 11, 0, 1, 2, 3, 4, 5, 6, 77, 8, 9, 10);
1585 Arr2Copy3.at(3)->m_iValue = 33;
1586 verifyArray(Arr2Copy3, __LINE__, 11, 0, 1, 2, 33, 4, 5, 6, 77, 8, 9, 10);
1587 Arr2Copy3.clear();
1588 verifyArray(Arr2Copy3, __LINE__, 0);
1589 RTTESTI_CHECK_MSG(MyRestInt16::s_cInstances == Arr2.size(), ("%zu vs %zu\n", MyRestInt16::s_cInstances, Arr2.size()));
1590 }
1591 verifyArray(Arr2, __LINE__, 11, 0, 1, 2, 3, 4, 5, 6, 77, 8, 9, 10);
1592 RTTESTI_CHECK_MSG(MyRestInt16::s_cInstances == Arr2.size(), ("%zu vs %zu\n", MyRestInt16::s_cInstances, Arr2.size()));
1593
1594 /* Check setNull and resetToDefaults with copies: */
1595 {
1596 RTCRestArray<MyRestInt16> Arr2Copy4(Arr2);
1597 verifyArray(Arr2Copy4, __LINE__, 11, 0, 1, 2, 3, 4, 5, 6, 77, 8, 9, 10);
1598
1599 RTTESTI_CHECK_RC(Arr2Copy4.setNull(), VINF_SUCCESS);
1600 verifyArray(Arr2Copy4, __LINE__, 0);
1601 RTTESTI_CHECK_MSG(MyRestInt16::s_cInstances == Arr2.size(), ("%zu vs %zu\n", MyRestInt16::s_cInstances, Arr2.size()));
1602 RTTESTI_CHECK(Arr2Copy4.isNull() == true);
1603
1604 RTTESTI_CHECK_RC(Arr2Copy4.resetToDefault(), VINF_SUCCESS);
1605 RTTESTI_CHECK(Arr2Copy4.isNull() == false);
1606 verifyArray(Arr2Copy4, __LINE__, 0);
1607 }
1608 verifyArray(Arr2, __LINE__, 11, 0, 1, 2, 3, 4, 5, 6, 77, 8, 9, 10);
1609 {
1610 RTCRestArray<MyRestInt16> Arr2Copy5(Arr2);
1611 verifyArray(Arr2Copy5, __LINE__, 11, 0, 1, 2, 3, 4, 5, 6, 77, 8, 9, 10);
1612
1613 RTTESTI_CHECK_RC(Arr2Copy5.resetToDefault(), VINF_SUCCESS);
1614 verifyArray(Arr2Copy5, __LINE__, 0);
1615 RTTESTI_CHECK_MSG(MyRestInt16::s_cInstances == Arr2.size(), ("%zu vs %zu\n", MyRestInt16::s_cInstances, Arr2.size()));
1616 RTTESTI_CHECK(Arr2Copy5.isNull() == false);
1617
1618 RTTESTI_CHECK_RC(Arr2Copy5.setNull(), VINF_SUCCESS);
1619 RTTESTI_CHECK(Arr2Copy5.isNull() == true);
1620
1621 RTTESTI_CHECK_RC(Arr2Copy5.append(new MyRestInt16(100)), VINF_SUCCESS);
1622 RTTESTI_CHECK(Arr2Copy5.isNull() == false);
1623 verifyArray(Arr2Copy5, __LINE__, 1, 100);
1624 RTTESTI_CHECK_MSG(MyRestInt16::s_cInstances == Arr2.size() + 1, ("%zu vs %zu\n", MyRestInt16::s_cInstances, Arr2.size() + 1));
1625 }
1626 verifyArray(Arr2, __LINE__, 11, 0, 1, 2, 3, 4, 5, 6, 77, 8, 9, 10);
1627
1628 RTTESTI_CHECK_MSG(MyRestInt16::s_cInstances == Arr2.size(), ("%zu vs %zu\n", MyRestInt16::s_cInstances, Arr2.size()));
1629 }
1630 RTTESTI_CHECK_MSG(MyRestInt16::s_cInstances == 0, ("%zu\n", MyRestInt16::s_cInstances));
1631
1632 {
1633 RTCRestArray<RTCRestInt64> Arr3;
1634 RTCRestArray<RTCRestInt64> const *pConstArr3 = &Arr3;
1635
1636 /* Insert a range of numbers into a int64 array. */
1637 for (int64_t i = 0; i < _64K; i++)
1638 {
1639 if (i & 1)
1640 {
1641 RTCRestInt64 toCopy(i);
1642 if (i & 2)
1643 RTTESTI_CHECK_RC(Arr3.insertCopy(i, toCopy), VINF_SUCCESS);
1644 else
1645 RTTESTI_CHECK_RC(Arr3.appendCopy(toCopy), VINF_SUCCESS);
1646 }
1647 else
1648 {
1649 RTCRestInt64 *pDirect = new RTCRestInt64(i);
1650 if (i & 2)
1651 RTTESTI_CHECK_RC(Arr3.insert(i, pDirect), VINF_SUCCESS);
1652 else
1653 RTTESTI_CHECK_RC(Arr3.append(pDirect), VINF_SUCCESS);
1654 }
1655 RTTESTI_CHECK(Arr3.size() == (size_t)i + 1);
1656 RTTESTI_CHECK(Arr3.isEmpty() == false);
1657 }
1658
1659 /* Verify insertions: */
1660 size_t cElements = _64K;
1661 RTTESTI_CHECK(Arr3.size() == cElements);
1662
1663 for (int64_t i = 0; i < _64K; i++)
1664 {
1665 RTCRestInt64 *pCur = Arr3.at(i);
1666 RTTESTI_CHECK(pCur->m_iValue == i);
1667
1668 RTCRestInt64 const *pCur2 = pConstArr3->at(i);
1669 RTTESTI_CHECK(pCur2->m_iValue == i);
1670 }
1671 RTTESTI_CHECK(Arr3.first()->m_iValue == 0);
1672 RTTESTI_CHECK(Arr3.last()->m_iValue == _64K - 1);
1673 RTTESTI_CHECK(pConstArr3->first()->m_iValue == 0);
1674 RTTESTI_CHECK(pConstArr3->last()->m_iValue == _64K - 1);
1675
1676 /* Remove every 3rd element: */
1677 RTTESTI_CHECK(Arr3.size() == cElements);
1678 for (int64_t i = _64K - 1; i >= 0; i -= 3)
1679 {
1680 RTTESTI_CHECK_RC(Arr3.removeAt(i), VINF_SUCCESS);
1681 cElements--;
1682 RTTESTI_CHECK(Arr3.size() == cElements);
1683 }
1684
1685 /* Verify after removal: */
1686 for (int64_t i = 0, iValue = 0; i < (ssize_t)Arr3.size(); i++, iValue++)
1687 {
1688 if ((iValue % 3) == 0)
1689 iValue++;
1690 RTTESTI_CHECK_MSG(Arr3.at(i)->m_iValue == iValue, ("%RI64: %RI64 vs %RI64\n", i, Arr3.at(i)->m_iValue, iValue));
1691 }
1692
1693 /* Clear it and we're done: */
1694 Arr3.clear();
1695 RTTESTI_CHECK(Arr3.size() == 0);
1696 RTTESTI_CHECK(Arr3.isEmpty() == true);
1697 }
1698
1699 {
1700 RTCRestArray<RTCRestInt32> Arr4;
1701
1702 /* Insert a range of numbers into a int32 array, in reverse order. */
1703 for (int32_t i = 0; i < 2048; i++)
1704 {
1705 if (i & 1)
1706 {
1707 RTCRestInt32 toCopy(i);
1708 if (i & 2)
1709 RTTESTI_CHECK_RC(Arr4.insertCopy(0, toCopy), VINF_SUCCESS);
1710 else
1711 RTTESTI_CHECK_RC(Arr4.prependCopy(toCopy), VINF_SUCCESS);
1712 }
1713 else
1714 {
1715 RTCRestInt32 *pDirect = new RTCRestInt32(i);
1716 if (i & 2)
1717 RTTESTI_CHECK_RC(Arr4.insert(0, pDirect), VINF_SUCCESS);
1718 else
1719 RTTESTI_CHECK_RC(Arr4.prepend(pDirect), VINF_SUCCESS);
1720 }
1721 RTTESTI_CHECK(Arr4.size() == i + 1);
1722 RTTESTI_CHECK(Arr4.isEmpty() == false);
1723 }
1724
1725 for (int32_t i = 0, iValue = (int32_t)Arr4.size() - 1; i < (ssize_t)Arr4.size(); i++, iValue--)
1726 RTTESTI_CHECK_MSG(Arr4.at(i)->m_iValue == iValue, ("%RI32: %RI32 vs %RI32\n", i, Arr4.at(i)->m_iValue, iValue));
1727
1728 for (int32_t i = 0; i < 512; i++)
1729 RTTESTI_CHECK_RC(Arr4.removeAt(0), VINF_SUCCESS);
1730 RTTESTI_CHECK(Arr4.size() == 1536);
1731
1732 for (int32_t i = 0; i < 512; i++)
1733 RTTESTI_CHECK_RC(Arr4.removeAt(~(size_t)0), VINF_SUCCESS);
1734 RTTESTI_CHECK(Arr4.size() == 1024);
1735
1736 for (int32_t i = 0, iValue = 1535; i < (ssize_t)Arr4.size(); i++, iValue--)
1737 RTTESTI_CHECK_MSG(Arr4.at(i)->m_iValue == iValue, ("%RI32: %RI32 vs %RI32\n", i, Arr4.at(i)->m_iValue, iValue));
1738 }
1739}
1740
1741
1742void testStringMap(void)
1743{
1744 RTTestSub(g_hTest, "RTCRestMap");
1745
1746 {
1747 RTCRestStringMap<RTCRestString> obj1;
1748 RTTESTI_CHECK(obj1.size() == 0);
1749 RTTESTI_CHECK(obj1.isEmpty() == true);
1750 RTTESTI_CHECK(obj1.isNull() == false);
1751 RTTESTI_CHECK(strcmp(obj1.typeName(), "RTCRestStringMap<ValueType>") == 0);
1752 RTTESTI_CHECK(obj1.typeClass() == RTCRestObjectBase::kTypeClass_StringMap);
1753 }
1754
1755}
1756
1757
1758int main()
1759{
1760 RTEXITCODE rcExit = RTTestInitAndCreate("tstRTRest-1", &g_hTest);
1761 if (rcExit == RTEXITCODE_SUCCESS )
1762 {
1763 testBool();
1764 testInteger<RTCRestInt64, int64_t, Int64Constants>();
1765 testInteger<RTCRestInt32, int32_t, Int32Constants>();
1766 testInteger<RTCRestInt16, int16_t, Int16Constants>();
1767 testDouble();
1768 testString("dummy", 1, 2);
1769 testDate();
1770 testArray();
1771 testStringMap();
1772
1773 rcExit = RTTestSummaryAndDestroy(g_hTest);
1774 }
1775 return rcExit;
1776}
1777
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette