-
Notifications
You must be signed in to change notification settings - Fork 35.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
UniValue: fix major bug, add unit tests #4730
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,275 @@ | ||
// Copyright 2014 BitPay, Inc. | ||
// Distributed under the MIT/X11 software license, see the accompanying | ||
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||
|
||
#include <stdint.h> | ||
#include <vector> | ||
#include <string> | ||
#include <map> | ||
#include "univalue/univalue.h" | ||
|
||
#include <boost/test/unit_test.hpp> | ||
|
||
using namespace std; | ||
|
||
BOOST_AUTO_TEST_SUITE(univalue_tests) | ||
|
||
BOOST_AUTO_TEST_CASE(univalue_constructor) | ||
{ | ||
UniValue v1; | ||
BOOST_CHECK(v1.isNull()); | ||
|
||
UniValue v2(UniValue::VSTR); | ||
BOOST_CHECK(v2.isStr()); | ||
|
||
UniValue v3(UniValue::VSTR, "foo"); | ||
BOOST_CHECK(v3.isStr()); | ||
BOOST_CHECK_EQUAL(v3.getValStr(), "foo"); | ||
|
||
UniValue numTest; | ||
BOOST_CHECK(numTest.setNumStr("82")); | ||
BOOST_CHECK(numTest.isNum()); | ||
BOOST_CHECK_EQUAL(numTest.getValStr(), "82"); | ||
|
||
uint64_t vu64 = 82; | ||
UniValue v4(vu64); | ||
BOOST_CHECK(v4.isNum()); | ||
BOOST_CHECK_EQUAL(v4.getValStr(), "82"); | ||
|
||
int64_t vi64 = -82; | ||
UniValue v5(vi64); | ||
BOOST_CHECK(v5.isNum()); | ||
BOOST_CHECK_EQUAL(v5.getValStr(), "-82"); | ||
|
||
int vi = -688; | ||
UniValue v6(vi); | ||
BOOST_CHECK(v6.isNum()); | ||
BOOST_CHECK_EQUAL(v6.getValStr(), "-688"); | ||
|
||
double vd = -7.21; | ||
UniValue v7(vd); | ||
BOOST_CHECK(v7.isNum()); | ||
BOOST_CHECK_EQUAL(v7.getValStr(), "-7.21"); | ||
|
||
string vs("yawn"); | ||
UniValue v8(vs); | ||
BOOST_CHECK(v8.isStr()); | ||
BOOST_CHECK_EQUAL(v8.getValStr(), "yawn"); | ||
|
||
const char *vcs = "zappa"; | ||
UniValue v9(vcs); | ||
BOOST_CHECK(v9.isStr()); | ||
BOOST_CHECK_EQUAL(v9.getValStr(), "zappa"); | ||
} | ||
|
||
BOOST_AUTO_TEST_CASE(univalue_set) | ||
{ | ||
UniValue v(UniValue::VSTR, "foo"); | ||
v.clear(); | ||
BOOST_CHECK(v.isNull()); | ||
BOOST_CHECK_EQUAL(v.getValStr(), ""); | ||
|
||
BOOST_CHECK(v.setObject()); | ||
BOOST_CHECK(v.isObject()); | ||
BOOST_CHECK_EQUAL(v.count(), 0); | ||
BOOST_CHECK_EQUAL(v.getType(), UniValue::VOBJ); | ||
BOOST_CHECK(v.empty()); | ||
|
||
BOOST_CHECK(v.setArray()); | ||
BOOST_CHECK(v.isArray()); | ||
BOOST_CHECK_EQUAL(v.count(), 0); | ||
|
||
BOOST_CHECK(v.setStr("zum")); | ||
BOOST_CHECK(v.isStr()); | ||
BOOST_CHECK_EQUAL(v.getValStr(), "zum"); | ||
|
||
BOOST_CHECK(v.setFloat(-1.01)); | ||
BOOST_CHECK(v.isNum()); | ||
BOOST_CHECK_EQUAL(v.getValStr(), "-1.01"); | ||
|
||
BOOST_CHECK(v.setInt((int)1023)); | ||
BOOST_CHECK(v.isNum()); | ||
BOOST_CHECK_EQUAL(v.getValStr(), "1023"); | ||
|
||
BOOST_CHECK(v.setInt((int64_t)-1023LL)); | ||
BOOST_CHECK(v.isNum()); | ||
BOOST_CHECK_EQUAL(v.getValStr(), "-1023"); | ||
|
||
BOOST_CHECK(v.setInt((uint64_t)1023ULL)); | ||
BOOST_CHECK(v.isNum()); | ||
BOOST_CHECK_EQUAL(v.getValStr(), "1023"); | ||
|
||
BOOST_CHECK(v.setNumStr("-688")); | ||
BOOST_CHECK(v.isNum()); | ||
BOOST_CHECK_EQUAL(v.getValStr(), "-688"); | ||
|
||
BOOST_CHECK(v.setBool(false)); | ||
BOOST_CHECK_EQUAL(v.isBool(), true); | ||
BOOST_CHECK_EQUAL(v.isTrue(), false); | ||
BOOST_CHECK_EQUAL(v.isFalse(), true); | ||
BOOST_CHECK_EQUAL(v.getBool(), false); | ||
|
||
BOOST_CHECK(v.setBool(true)); | ||
BOOST_CHECK_EQUAL(v.isBool(), true); | ||
BOOST_CHECK_EQUAL(v.isTrue(), true); | ||
BOOST_CHECK_EQUAL(v.isFalse(), false); | ||
BOOST_CHECK_EQUAL(v.getBool(), true); | ||
|
||
BOOST_CHECK(!v.setNumStr("zombocom")); | ||
|
||
BOOST_CHECK(v.setNull()); | ||
BOOST_CHECK(v.isNull()); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seems most of these checks assume pretty sane input. It'd be nice to see some exotic and/or blatantly wrong set's here, in order to test that they work or fail as anticipated. For those, I really don't know what the expected results would be, so I suppose it'd serve as some poor-man's documentation as well. |
||
|
||
BOOST_AUTO_TEST_CASE(univalue_array) | ||
{ | ||
UniValue arr(UniValue::VARR); | ||
|
||
UniValue v((int64_t)1023LL); | ||
BOOST_CHECK(arr.push_back(v)); | ||
|
||
string vStr("zippy"); | ||
BOOST_CHECK(arr.push_back(vStr)); | ||
|
||
const char *s = "pippy"; | ||
BOOST_CHECK(arr.push_back(s)); | ||
|
||
vector<UniValue> vec; | ||
v.setStr("boing"); | ||
vec.push_back(v); | ||
|
||
v.setStr("going"); | ||
vec.push_back(v); | ||
|
||
BOOST_CHECK(arr.push_backV(vec)); | ||
|
||
BOOST_CHECK_EQUAL(arr.empty(), false); | ||
BOOST_CHECK_EQUAL(arr.count(), 5); | ||
|
||
BOOST_CHECK_EQUAL(arr[0].getValStr(), "1023"); | ||
BOOST_CHECK_EQUAL(arr[1].getValStr(), "zippy"); | ||
BOOST_CHECK_EQUAL(arr[2].getValStr(), "pippy"); | ||
BOOST_CHECK_EQUAL(arr[3].getValStr(), "boing"); | ||
BOOST_CHECK_EQUAL(arr[4].getValStr(), "going"); | ||
|
||
BOOST_CHECK_EQUAL(arr[999].getValStr(), ""); | ||
|
||
arr.clear(); | ||
BOOST_CHECK(arr.empty()); | ||
BOOST_CHECK_EQUAL(arr.count(), 0); | ||
} | ||
|
||
BOOST_AUTO_TEST_CASE(univalue_object) | ||
{ | ||
UniValue obj(UniValue::VOBJ); | ||
string strKey, strVal; | ||
UniValue v; | ||
|
||
strKey = "age"; | ||
v.setInt(100); | ||
BOOST_CHECK(obj.pushKV(strKey, v)); | ||
|
||
strKey = "first"; | ||
strVal = "John"; | ||
BOOST_CHECK(obj.pushKV(strKey, strVal)); | ||
|
||
strKey = "last"; | ||
const char *cVal = "Smith"; | ||
BOOST_CHECK(obj.pushKV(strKey, cVal)); | ||
|
||
strKey = "distance"; | ||
BOOST_CHECK(obj.pushKV(strKey, (int64_t) 25)); | ||
|
||
strKey = "time"; | ||
BOOST_CHECK(obj.pushKV(strKey, (uint64_t) 3600)); | ||
|
||
strKey = "calories"; | ||
BOOST_CHECK(obj.pushKV(strKey, (int) 12)); | ||
|
||
strKey = "temperature"; | ||
BOOST_CHECK(obj.pushKV(strKey, (double) 90.012)); | ||
|
||
UniValue obj2(UniValue::VOBJ); | ||
BOOST_CHECK(obj2.pushKV("cat1", 9000)); | ||
BOOST_CHECK(obj2.pushKV("cat2", 12345)); | ||
|
||
BOOST_CHECK(obj.pushKVs(obj2)); | ||
|
||
BOOST_CHECK_EQUAL(obj.empty(), false); | ||
BOOST_CHECK_EQUAL(obj.count(), 9); | ||
|
||
BOOST_CHECK_EQUAL(obj["age"].getValStr(), "100"); | ||
BOOST_CHECK_EQUAL(obj["first"].getValStr(), "John"); | ||
BOOST_CHECK_EQUAL(obj["last"].getValStr(), "Smith"); | ||
BOOST_CHECK_EQUAL(obj["distance"].getValStr(), "25"); | ||
BOOST_CHECK_EQUAL(obj["time"].getValStr(), "3600"); | ||
BOOST_CHECK_EQUAL(obj["calories"].getValStr(), "12"); | ||
BOOST_CHECK_EQUAL(obj["temperature"].getValStr(), "90.012"); | ||
BOOST_CHECK_EQUAL(obj["cat1"].getValStr(), "9000"); | ||
BOOST_CHECK_EQUAL(obj["cat2"].getValStr(), "12345"); | ||
|
||
BOOST_CHECK_EQUAL(obj["nyuknyuknyuk"].getValStr(), ""); | ||
|
||
BOOST_CHECK(obj.exists("age")); | ||
BOOST_CHECK(obj.exists("first")); | ||
BOOST_CHECK(obj.exists("last")); | ||
BOOST_CHECK(obj.exists("distance")); | ||
BOOST_CHECK(obj.exists("time")); | ||
BOOST_CHECK(obj.exists("calories")); | ||
BOOST_CHECK(obj.exists("temperature")); | ||
BOOST_CHECK(obj.exists("cat1")); | ||
BOOST_CHECK(obj.exists("cat2")); | ||
|
||
BOOST_CHECK(!obj.exists("nyuknyuknyuk")); | ||
|
||
map<string, UniValue::VType> objTypes; | ||
objTypes["age"] = UniValue::VNUM; | ||
objTypes["first"] = UniValue::VSTR; | ||
objTypes["last"] = UniValue::VSTR; | ||
objTypes["distance"] = UniValue::VNUM; | ||
objTypes["time"] = UniValue::VNUM; | ||
objTypes["calories"] = UniValue::VNUM; | ||
objTypes["temperature"] = UniValue::VNUM; | ||
objTypes["cat1"] = UniValue::VNUM; | ||
objTypes["cat2"] = UniValue::VNUM; | ||
BOOST_CHECK(obj.checkObject(objTypes)); | ||
|
||
objTypes["cat2"] = UniValue::VSTR; | ||
BOOST_CHECK(!obj.checkObject(objTypes)); | ||
|
||
obj.clear(); | ||
BOOST_CHECK(obj.empty()); | ||
BOOST_CHECK_EQUAL(obj.count(), 0); | ||
} | ||
|
||
static const char *json1 = | ||
"[1.1,{\"key1\":\"str\",\"key2\":800,\"key3\":{\"name\":\"martian\"}}]"; | ||
|
||
BOOST_AUTO_TEST_CASE(univalue_readwrite) | ||
{ | ||
UniValue v; | ||
BOOST_CHECK(v.read(json1)); | ||
|
||
string strJson1(json1); | ||
BOOST_CHECK(v.read(strJson1)); | ||
|
||
BOOST_CHECK(v.isArray()); | ||
BOOST_CHECK_EQUAL(v.count(), 2); | ||
|
||
BOOST_CHECK_EQUAL(v[0].getValStr(), "1.1"); | ||
|
||
UniValue obj = v[1]; | ||
BOOST_CHECK(obj.isObject()); | ||
BOOST_CHECK_EQUAL(obj.count(), 3); | ||
|
||
BOOST_CHECK(obj["key1"].isStr()); | ||
BOOST_CHECK_EQUAL(obj["key1"].getValStr(), "str"); | ||
BOOST_CHECK(obj["key2"].isNum()); | ||
BOOST_CHECK_EQUAL(obj["key2"].getValStr(), "800"); | ||
BOOST_CHECK(obj["key3"].isObject()); | ||
|
||
BOOST_CHECK_EQUAL(strJson1, v.write()); | ||
} | ||
|
||
BOOST_AUTO_TEST_SUITE_END() | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
welcome to zombocom!