Bitcoin Core  23.99.0
P2P Digital Currency
object.cpp
Go to the documentation of this file.
1 // Copyright (c) 2014 BitPay Inc.
2 // Copyright (c) 2014-2016 The Bitcoin Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or https://opensource.org/licenses/mit-license.php.
5 
6 #include <univalue.h>
7 
8 #include <cassert>
9 #include <cstdint>
10 #include <map>
11 #include <memory>
12 #include <stdexcept>
13 #include <string>
14 #include <vector>
15 
16 #define BOOST_FIXTURE_TEST_SUITE(a, b)
17 #define BOOST_AUTO_TEST_CASE(funcName) void funcName()
18 #define BOOST_AUTO_TEST_SUITE_END()
19 #define BOOST_CHECK(expr) assert(expr)
20 #define BOOST_CHECK_EQUAL(v1, v2) assert((v1) == (v2))
21 #define BOOST_CHECK_THROW(stmt, excMatch) { \
22  try { \
23  (stmt); \
24  assert(0 && "No exception caught"); \
25  } catch (excMatch & e) { \
26  } catch (...) { \
27  assert(0 && "Wrong exception caught"); \
28  } \
29  }
30 #define BOOST_CHECK_NO_THROW(stmt) { \
31  try { \
32  (stmt); \
33  } catch (...) { \
34  assert(0); \
35  } \
36  }
37 
39 
40 BOOST_AUTO_TEST_CASE(univalue_constructor)
41 {
42  UniValue v1;
43  BOOST_CHECK(v1.isNull());
44 
46  BOOST_CHECK(v2.isStr());
47 
48  UniValue v3(UniValue::VSTR, "foo");
49  BOOST_CHECK(v3.isStr());
50  BOOST_CHECK_EQUAL(v3.getValStr(), "foo");
51 
52  UniValue numTest;
53  BOOST_CHECK(numTest.setNumStr("82"));
54  BOOST_CHECK(numTest.isNum());
55  BOOST_CHECK_EQUAL(numTest.getValStr(), "82");
56 
57  uint64_t vu64 = 82;
58  UniValue v4(vu64);
59  BOOST_CHECK(v4.isNum());
60  BOOST_CHECK_EQUAL(v4.getValStr(), "82");
61 
62  int64_t vi64 = -82;
63  UniValue v5(vi64);
64  BOOST_CHECK(v5.isNum());
65  BOOST_CHECK_EQUAL(v5.getValStr(), "-82");
66 
67  int vi = -688;
68  UniValue v6(vi);
69  BOOST_CHECK(v6.isNum());
70  BOOST_CHECK_EQUAL(v6.getValStr(), "-688");
71 
72  double vd = -7.21;
73  UniValue v7(vd);
74  BOOST_CHECK(v7.isNum());
75  BOOST_CHECK_EQUAL(v7.getValStr(), "-7.21");
76 
77  std::string vs("yawn");
78  UniValue v8(vs);
79  BOOST_CHECK(v8.isStr());
80  BOOST_CHECK_EQUAL(v8.getValStr(), "yawn");
81 
82  const char *vcs = "zappa";
83  UniValue v9(vcs);
84  BOOST_CHECK(v9.isStr());
85  BOOST_CHECK_EQUAL(v9.getValStr(), "zappa");
86 }
87 
88 BOOST_AUTO_TEST_CASE(univalue_typecheck)
89 {
90  UniValue v1;
91  BOOST_CHECK(v1.setNumStr("1"));
92  BOOST_CHECK(v1.isNum());
93  BOOST_CHECK_THROW(v1.get_bool(), std::runtime_error);
94 
95  UniValue v2;
96  BOOST_CHECK(v2.setBool(true));
97  BOOST_CHECK_EQUAL(v2.get_bool(), true);
98  BOOST_CHECK_THROW(v2.get_int(), std::runtime_error);
99 
100  UniValue v3;
101  BOOST_CHECK(v3.setNumStr("32482348723847471234"));
102  BOOST_CHECK_THROW(v3.get_int64(), std::runtime_error);
103  BOOST_CHECK(v3.setNumStr("1000"));
104  BOOST_CHECK_EQUAL(v3.get_int64(), 1000);
105 
106  UniValue v4;
107  BOOST_CHECK(v4.setNumStr("2147483648"));
108  BOOST_CHECK_EQUAL(v4.get_int64(), 2147483648);
109  BOOST_CHECK_THROW(v4.get_int(), std::runtime_error);
110  BOOST_CHECK(v4.setNumStr("1000"));
111  BOOST_CHECK_EQUAL(v4.get_int(), 1000);
112  BOOST_CHECK_THROW(v4.get_str(), std::runtime_error);
113  BOOST_CHECK_EQUAL(v4.get_real(), 1000);
114  BOOST_CHECK_THROW(v4.get_array(), std::runtime_error);
115  BOOST_CHECK_THROW(v4.getKeys(), std::runtime_error);
116  BOOST_CHECK_THROW(v4.getValues(), std::runtime_error);
117  BOOST_CHECK_THROW(v4.get_obj(), std::runtime_error);
118 
119  UniValue v5;
120  BOOST_CHECK(v5.read("[true, 10]"));
122  std::vector<UniValue> vals = v5.getValues();
123  BOOST_CHECK_THROW(vals[0].get_int(), std::runtime_error);
124  BOOST_CHECK_EQUAL(vals[0].get_bool(), true);
125 
126  BOOST_CHECK_EQUAL(vals[1].get_int(), 10);
127  BOOST_CHECK_THROW(vals[1].get_bool(), std::runtime_error);
128 }
129 
130 BOOST_AUTO_TEST_CASE(univalue_set)
131 {
132  UniValue v(UniValue::VSTR, "foo");
133  v.clear();
134  BOOST_CHECK(v.isNull());
135  BOOST_CHECK_EQUAL(v.getValStr(), "");
136 
137  BOOST_CHECK(v.setObject());
138  BOOST_CHECK(v.isObject());
139  BOOST_CHECK_EQUAL(v.size(), 0);
141  BOOST_CHECK(v.empty());
142 
143  BOOST_CHECK(v.setArray());
144  BOOST_CHECK(v.isArray());
145  BOOST_CHECK_EQUAL(v.size(), 0);
146 
147  BOOST_CHECK(v.setStr("zum"));
148  BOOST_CHECK(v.isStr());
149  BOOST_CHECK_EQUAL(v.getValStr(), "zum");
150 
151  BOOST_CHECK(v.setFloat(-1.01));
152  BOOST_CHECK(v.isNum());
153  BOOST_CHECK_EQUAL(v.getValStr(), "-1.01");
154 
155  BOOST_CHECK(v.setInt((int)1023));
156  BOOST_CHECK(v.isNum());
157  BOOST_CHECK_EQUAL(v.getValStr(), "1023");
158 
159  BOOST_CHECK(v.setInt((int64_t)-1023LL));
160  BOOST_CHECK(v.isNum());
161  BOOST_CHECK_EQUAL(v.getValStr(), "-1023");
162 
163  BOOST_CHECK(v.setInt((uint64_t)1023ULL));
164  BOOST_CHECK(v.isNum());
165  BOOST_CHECK_EQUAL(v.getValStr(), "1023");
166 
167  BOOST_CHECK(v.setNumStr("-688"));
168  BOOST_CHECK(v.isNum());
169  BOOST_CHECK_EQUAL(v.getValStr(), "-688");
170 
171  BOOST_CHECK(v.setBool(false));
172  BOOST_CHECK_EQUAL(v.isBool(), true);
173  BOOST_CHECK_EQUAL(v.isTrue(), false);
174  BOOST_CHECK_EQUAL(v.isFalse(), true);
175  BOOST_CHECK_EQUAL(v.getBool(), false);
176 
177  BOOST_CHECK(v.setBool(true));
178  BOOST_CHECK_EQUAL(v.isBool(), true);
179  BOOST_CHECK_EQUAL(v.isTrue(), true);
180  BOOST_CHECK_EQUAL(v.isFalse(), false);
181  BOOST_CHECK_EQUAL(v.getBool(), true);
182 
183  BOOST_CHECK(!v.setNumStr("zombocom"));
184 
185  BOOST_CHECK(v.setNull());
186  BOOST_CHECK(v.isNull());
187 }
188 
189 BOOST_AUTO_TEST_CASE(univalue_array)
190 {
192 
193  UniValue v((int64_t)1023LL);
194  BOOST_CHECK(arr.push_back(v));
195 
196  std::string vStr("zippy");
197  BOOST_CHECK(arr.push_back(vStr));
198 
199  const char *s = "pippy";
200  BOOST_CHECK(arr.push_back(s));
201 
202  std::vector<UniValue> vec;
203  v.setStr("boing");
204  vec.push_back(v);
205 
206  v.setStr("going");
207  vec.push_back(v);
208 
209  BOOST_CHECK(arr.push_backV(vec));
210 
211  BOOST_CHECK(arr.push_back((uint64_t) 400ULL));
212  BOOST_CHECK(arr.push_back((int64_t) -400LL));
213  BOOST_CHECK(arr.push_back((int) -401));
214  BOOST_CHECK(arr.push_back(-40.1));
215  BOOST_CHECK(arr.push_back(true));
216 
217  BOOST_CHECK_EQUAL(arr.empty(), false);
218  BOOST_CHECK_EQUAL(arr.size(), 10);
219 
220  BOOST_CHECK_EQUAL(arr[0].getValStr(), "1023");
221  BOOST_CHECK_EQUAL(arr[0].getType(), UniValue::VNUM);
222  BOOST_CHECK_EQUAL(arr[1].getValStr(), "zippy");
223  BOOST_CHECK_EQUAL(arr[1].getType(), UniValue::VSTR);
224  BOOST_CHECK_EQUAL(arr[2].getValStr(), "pippy");
225  BOOST_CHECK_EQUAL(arr[2].getType(), UniValue::VSTR);
226  BOOST_CHECK_EQUAL(arr[3].getValStr(), "boing");
227  BOOST_CHECK_EQUAL(arr[3].getType(), UniValue::VSTR);
228  BOOST_CHECK_EQUAL(arr[4].getValStr(), "going");
229  BOOST_CHECK_EQUAL(arr[4].getType(), UniValue::VSTR);
230  BOOST_CHECK_EQUAL(arr[5].getValStr(), "400");
231  BOOST_CHECK_EQUAL(arr[5].getType(), UniValue::VNUM);
232  BOOST_CHECK_EQUAL(arr[6].getValStr(), "-400");
233  BOOST_CHECK_EQUAL(arr[6].getType(), UniValue::VNUM);
234  BOOST_CHECK_EQUAL(arr[7].getValStr(), "-401");
235  BOOST_CHECK_EQUAL(arr[7].getType(), UniValue::VNUM);
236  BOOST_CHECK_EQUAL(arr[8].getValStr(), "-40.1");
237  BOOST_CHECK_EQUAL(arr[8].getType(), UniValue::VNUM);
238  BOOST_CHECK_EQUAL(arr[9].getValStr(), "1");
239  BOOST_CHECK_EQUAL(arr[9].getType(), UniValue::VBOOL);
240 
241  BOOST_CHECK_EQUAL(arr[999].getValStr(), "");
242 
243  arr.clear();
244  BOOST_CHECK(arr.empty());
245  BOOST_CHECK_EQUAL(arr.size(), 0);
246 }
247 
248 BOOST_AUTO_TEST_CASE(univalue_object)
249 {
251  std::string strKey, strVal;
252  UniValue v;
253 
254  strKey = "age";
255  v.setInt(100);
256  BOOST_CHECK(obj.pushKV(strKey, v));
257 
258  strKey = "first";
259  strVal = "John";
260  BOOST_CHECK(obj.pushKV(strKey, strVal));
261 
262  strKey = "last";
263  const char *cVal = "Smith";
264  BOOST_CHECK(obj.pushKV(strKey, cVal));
265 
266  strKey = "distance";
267  BOOST_CHECK(obj.pushKV(strKey, (int64_t) 25));
268 
269  strKey = "time";
270  BOOST_CHECK(obj.pushKV(strKey, (uint64_t) 3600));
271 
272  strKey = "calories";
273  BOOST_CHECK(obj.pushKV(strKey, (int) 12));
274 
275  strKey = "temperature";
276  BOOST_CHECK(obj.pushKV(strKey, (double) 90.012));
277 
278  strKey = "moon";
279  BOOST_CHECK(obj.pushKV(strKey, true));
280 
281  strKey = "spoon";
282  BOOST_CHECK(obj.pushKV(strKey, false));
283 
284  UniValue obj2(UniValue::VOBJ);
285  BOOST_CHECK(obj2.pushKV("cat1", 9000));
286  BOOST_CHECK(obj2.pushKV("cat2", 12345));
287 
288  BOOST_CHECK(obj.pushKVs(obj2));
289 
290  BOOST_CHECK_EQUAL(obj.empty(), false);
291  BOOST_CHECK_EQUAL(obj.size(), 11);
292 
293  BOOST_CHECK_EQUAL(obj["age"].getValStr(), "100");
294  BOOST_CHECK_EQUAL(obj["first"].getValStr(), "John");
295  BOOST_CHECK_EQUAL(obj["last"].getValStr(), "Smith");
296  BOOST_CHECK_EQUAL(obj["distance"].getValStr(), "25");
297  BOOST_CHECK_EQUAL(obj["time"].getValStr(), "3600");
298  BOOST_CHECK_EQUAL(obj["calories"].getValStr(), "12");
299  BOOST_CHECK_EQUAL(obj["temperature"].getValStr(), "90.012");
300  BOOST_CHECK_EQUAL(obj["moon"].getValStr(), "1");
301  BOOST_CHECK_EQUAL(obj["spoon"].getValStr(), "");
302  BOOST_CHECK_EQUAL(obj["cat1"].getValStr(), "9000");
303  BOOST_CHECK_EQUAL(obj["cat2"].getValStr(), "12345");
304 
305  BOOST_CHECK_EQUAL(obj["nyuknyuknyuk"].getValStr(), "");
306 
307  BOOST_CHECK(obj.exists("age"));
308  BOOST_CHECK(obj.exists("first"));
309  BOOST_CHECK(obj.exists("last"));
310  BOOST_CHECK(obj.exists("distance"));
311  BOOST_CHECK(obj.exists("time"));
312  BOOST_CHECK(obj.exists("calories"));
313  BOOST_CHECK(obj.exists("temperature"));
314  BOOST_CHECK(obj.exists("moon"));
315  BOOST_CHECK(obj.exists("spoon"));
316  BOOST_CHECK(obj.exists("cat1"));
317  BOOST_CHECK(obj.exists("cat2"));
318 
319  BOOST_CHECK(!obj.exists("nyuknyuknyuk"));
320 
321  std::map<std::string, UniValue::VType> objTypes;
322  objTypes["age"] = UniValue::VNUM;
323  objTypes["first"] = UniValue::VSTR;
324  objTypes["last"] = UniValue::VSTR;
325  objTypes["distance"] = UniValue::VNUM;
326  objTypes["time"] = UniValue::VNUM;
327  objTypes["calories"] = UniValue::VNUM;
328  objTypes["temperature"] = UniValue::VNUM;
329  objTypes["moon"] = UniValue::VBOOL;
330  objTypes["spoon"] = UniValue::VBOOL;
331  objTypes["cat1"] = UniValue::VNUM;
332  objTypes["cat2"] = UniValue::VNUM;
333  BOOST_CHECK(obj.checkObject(objTypes));
334 
335  objTypes["cat2"] = UniValue::VSTR;
336  BOOST_CHECK(!obj.checkObject(objTypes));
337 
338  obj.clear();
339  BOOST_CHECK(obj.empty());
340  BOOST_CHECK_EQUAL(obj.size(), 0);
342 
343  BOOST_CHECK_EQUAL(obj.setObject(), true);
344  UniValue uv;
345  uv.setInt(42);
346  obj.__pushKV("age", uv);
347  BOOST_CHECK_EQUAL(obj.size(), 1);
348  BOOST_CHECK_EQUAL(obj["age"].getValStr(), "42");
349 
350  uv.setInt(43);
351  obj.pushKV("age", uv);
352  BOOST_CHECK_EQUAL(obj.size(), 1);
353  BOOST_CHECK_EQUAL(obj["age"].getValStr(), "43");
354 
355  obj.pushKV("name", "foo bar");
356 
357  std::map<std::string,UniValue> kv;
358  obj.getObjMap(kv);
359  BOOST_CHECK_EQUAL(kv["age"].getValStr(), "43");
360  BOOST_CHECK_EQUAL(kv["name"].getValStr(), "foo bar");
361 
362 }
363 
364 static const char *json1 =
365 "[1.10000000,{\"key1\":\"str\\u0000\",\"key2\":800,\"key3\":{\"name\":\"martian http://test.com\"}}]";
366 
367 BOOST_AUTO_TEST_CASE(univalue_readwrite)
368 {
369  UniValue v;
370  BOOST_CHECK(v.read(json1));
371 
372  std::string strJson1(json1);
373  BOOST_CHECK(v.read(strJson1));
374 
375  BOOST_CHECK(v.isArray());
376  BOOST_CHECK_EQUAL(v.size(), 2);
377 
378  BOOST_CHECK_EQUAL(v[0].getValStr(), "1.10000000");
379 
380  UniValue obj = v[1];
381  BOOST_CHECK(obj.isObject());
382  BOOST_CHECK_EQUAL(obj.size(), 3);
383 
384  BOOST_CHECK(obj["key1"].isStr());
385  std::string correctValue("str");
386  correctValue.push_back('\0');
387  BOOST_CHECK_EQUAL(obj["key1"].getValStr(), correctValue);
388  BOOST_CHECK(obj["key2"].isNum());
389  BOOST_CHECK_EQUAL(obj["key2"].getValStr(), "800");
390  BOOST_CHECK(obj["key3"].isObject());
391 
392  BOOST_CHECK_EQUAL(strJson1, v.write());
393 
394  /* Check for (correctly reporting) a parsing error if the initial
395  JSON construct is followed by more stuff. Note that whitespace
396  is, of course, exempt. */
397 
398  BOOST_CHECK(v.read(" {}\n "));
399  BOOST_CHECK(v.isObject());
400  BOOST_CHECK(v.read(" []\n "));
401  BOOST_CHECK(v.isArray());
402 
403  BOOST_CHECK(!v.read("@{}"));
404  BOOST_CHECK(!v.read("{} garbage"));
405  BOOST_CHECK(!v.read("[]{}"));
406  BOOST_CHECK(!v.read("{}[]"));
407  BOOST_CHECK(!v.read("{} 42"));
408 }
409 
411 
412 int main (int argc, char *argv[])
413 {
414  univalue_constructor();
415  univalue_typecheck();
416  univalue_set();
417  univalue_array();
418  univalue_object();
419  univalue_readwrite();
420  return 0;
421 }
422 
UniValue::isBool
bool isBool() const
Definition: univalue.h:79
UniValue::VOBJ
@ VOBJ
Definition: univalue.h:20
UniValue::get_bool
bool get_bool() const
Definition: univalue_get.cpp:61
UniValue::clear
void clear()
Definition: univalue.cpp:18
UniValue::read
bool read(const char *raw, size_t len)
Definition: univalue_read.cpp:262
UniValue::isNull
bool isNull() const
Definition: univalue.h:76
UniValue::write
std::string write(unsigned int prettyIndent=0, unsigned int indentLevel=0) const
Definition: univalue_write.cpp:30
UniValue::isNum
bool isNum() const
Definition: univalue.h:81
UniValue::getType
enum VType getType() const
Definition: univalue.h:63
BOOST_FIXTURE_TEST_SUITE
#define BOOST_FIXTURE_TEST_SUITE(a, b)
Definition: object.cpp:16
UniValue::getBool
bool getBool() const
Definition: univalue.h:69
UniValue::pushKV
bool pushKV(const std::string &key, const UniValue &val)
Definition: univalue.cpp:136
UniValue::checkObject
bool checkObject(const std::map< std::string, UniValue::VType > &memberTypes) const
Definition: univalue.cpp:182
UniValue
Definition: univalue.h:18
UniValue::setNull
bool setNull()
Definition: univalue.cpp:26
UniValue::isFalse
bool isFalse() const
Definition: univalue.h:78
UniValue::get_str
const std::string & get_str() const
Definition: univalue_get.cpp:68
UniValue::isStr
bool isStr() const
Definition: univalue.h:80
UniValue::get_obj
const UniValue & get_obj() const
Definition: univalue_get.cpp:85
UniValue::pushKVs
bool pushKVs(const UniValue &obj)
Definition: univalue.cpp:149
UniValue::setInt
bool setInt(uint64_t val)
Definition: univalue.cpp:60
json1
static const char * json1
Definition: object.cpp:364
UniValue::exists
bool exists(const std::string &key) const
Definition: univalue.h:74
UniValue::VBOOL
@ VBOOL
Definition: univalue.h:20
univalue.h
UniValue::push_backV
bool push_backV(const std::vector< UniValue > &vec)
Definition: univalue.cpp:120
BOOST_CHECK_NO_THROW
#define BOOST_CHECK_NO_THROW(stmt)
Definition: object.cpp:30
BOOST_AUTO_TEST_CASE
#define BOOST_AUTO_TEST_CASE(funcName)
Definition: object.cpp:17
UniValue::__pushKV
void __pushKV(const std::string &key, const UniValue &val)
Definition: univalue.cpp:130
BasicTestingSetup
Basic testing setup.
Definition: setup_common.h:83
UniValue::getKeys
const std::vector< std::string > & getKeys() const
Definition: univalue_get.cpp:47
UniValue::VNUM
@ VNUM
Definition: univalue.h:20
UniValue::get_int
auto get_int() const
Definition: univalue.h:188
UniValue::isArray
bool isArray() const
Definition: univalue.h:82
UniValue::getObjMap
void getObjMap(std::map< std::string, UniValue > &kv) const
Definition: univalue.cpp:160
UniValue::getValStr
const std::string & getValStr() const
Definition: univalue.h:64
UniValue::setNumStr
bool setNumStr(const std::string &val)
Definition: univalue.cpp:49
UniValue::isTrue
bool isTrue() const
Definition: univalue.h:77
UniValue::push_back
bool push_back(const UniValue &val)
Definition: univalue.cpp:111
UniValue::get_int64
auto get_int64() const
Definition: univalue.h:189
UniValue::empty
bool empty() const
Definition: univalue.h:65
UniValue::getValues
const std::vector< UniValue > & getValues() const
Definition: univalue_get.cpp:54
UniValue::get_real
double get_real() const
Definition: univalue_get.cpp:75
UniValue::setBool
bool setBool(bool val)
Definition: univalue.cpp:32
BOOST_CHECK_THROW
#define BOOST_CHECK_THROW(stmt, excMatch)
Definition: object.cpp:21
UniValue::size
size_t size() const
Definition: univalue.h:67
main
int main(int argc, char *argv[])
Definition: object.cpp:412
UniValue::get_array
const UniValue & get_array() const
Definition: univalue_get.cpp:92
UniValue::VARR
@ VARR
Definition: univalue.h:20
UniValue::VNULL
@ VNULL
Definition: univalue.h:20
UniValue::VSTR
@ VSTR
Definition: univalue.h:20
UniValue::setObject
bool setObject()
Definition: univalue.cpp:104
UniValue::setFloat
bool setFloat(double val)
Definition: univalue.cpp:78
UniValue::setStr
bool setStr(const std::string &val)
Definition: univalue.cpp:89
BOOST_CHECK
#define BOOST_CHECK(expr)
Definition: object.cpp:19
BOOST_AUTO_TEST_SUITE_END
#define BOOST_AUTO_TEST_SUITE_END()
Definition: object.cpp:18
BOOST_CHECK_EQUAL
#define BOOST_CHECK_EQUAL(v1, v2)
Definition: object.cpp:20
UniValue::setArray
bool setArray()
Definition: univalue.cpp:97
UniValue::isObject
bool isObject() const
Definition: univalue.h:83