Skip to content

Commit 1dfe464

Browse files
committed
Import UniValue class unit tests from bitcoin project.
1 parent 0d3e74d commit 1dfe464

File tree

3 files changed

+373
-1
lines changed

3 files changed

+373
-1
lines changed

Makefile.am

+6-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ libunivalue_la_LDFLAGS = \
2020
-no-undefined
2121
libunivalue_la_CXXFLAGS = -I$(top_srcdir)/include
2222

23-
TESTS = test/unitester test/no_nul
23+
TESTS = test/object test/unitester test/no_nul
2424

2525
GENBIN = gen/gen$(BUILD_EXEEXT)
2626
GEN_SRCS = gen/gen.cpp
@@ -52,6 +52,11 @@ test_no_nul_LDADD = libunivalue.la
5252
test_no_nul_CXXFLAGS = -I$(top_srcdir)/include
5353
test_no_nul_LDFLAGS = -static $(LIBTOOL_APP_LDFLAGS)
5454

55+
test_object_SOURCES = test/object.cpp
56+
test_object_LDADD = libunivalue.la
57+
test_object_CXXFLAGS = -I$(top_srcdir)/include
58+
test_object_LDFLAGS = -static $(LIBTOOL_APP_LDFLAGS)
59+
5560
TEST_FILES = \
5661
$(TEST_DATA_DIR)/fail10.json \
5762
$(TEST_DATA_DIR)/fail11.json \

test/.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
2+
object
13
unitester
24
test_json
35
no_nul

test/object.cpp

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

0 commit comments

Comments
 (0)