forked from dogecoin/dogecoin
-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Import UniValue class unit tests from bitcoin project.
- Loading branch information
Showing
3 changed files
with
373 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
|
||
object | ||
unitester | ||
test_json | ||
no_nul | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,365 @@ | ||
// Copyright (c) 2014 BitPay Inc. | ||
// Copyright (c) 2014-2016 The Bitcoin Core developers | ||
// Distributed under the MIT 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 <cassert> | ||
#include <stdexcept> | ||
#include <univalue.h> | ||
|
||
#define BOOST_FIXTURE_TEST_SUITE(a, b) | ||
#define BOOST_AUTO_TEST_CASE(funcName) void funcName() | ||
#define BOOST_AUTO_TEST_SUITE_END() | ||
#define BOOST_CHECK(expr) assert(expr) | ||
#define BOOST_CHECK_EQUAL(v1, v2) assert((v1) == (v2)) | ||
#define BOOST_CHECK_THROW(stmt, excMatch) { \ | ||
try { \ | ||
(stmt); \ | ||
} catch (excMatch & e) { \ | ||
} catch (...) { \ | ||
assert(0); \ | ||
} \ | ||
} | ||
#define BOOST_CHECK_NO_THROW(stmt) { \ | ||
try { \ | ||
(stmt); \ | ||
} catch (...) { \ | ||
assert(0); \ | ||
} \ | ||
} | ||
|
||
BOOST_FIXTURE_TEST_SUITE(univalue_tests, BasicTestingSetup) | ||
|
||
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"); | ||
|
||
std::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_typecheck) | ||
{ | ||
UniValue v1; | ||
BOOST_CHECK(v1.setNumStr("1")); | ||
BOOST_CHECK(v1.isNum()); | ||
BOOST_CHECK_THROW(v1.get_bool(), std::runtime_error); | ||
|
||
UniValue v2; | ||
BOOST_CHECK(v2.setBool(true)); | ||
BOOST_CHECK_EQUAL(v2.get_bool(), true); | ||
BOOST_CHECK_THROW(v2.get_int(), std::runtime_error); | ||
|
||
UniValue v3; | ||
BOOST_CHECK(v3.setNumStr("32482348723847471234")); | ||
BOOST_CHECK_THROW(v3.get_int64(), std::runtime_error); | ||
BOOST_CHECK(v3.setNumStr("1000")); | ||
BOOST_CHECK_EQUAL(v3.get_int64(), 1000); | ||
|
||
UniValue v4; | ||
BOOST_CHECK(v4.setNumStr("2147483648")); | ||
BOOST_CHECK_EQUAL(v4.get_int64(), 2147483648); | ||
BOOST_CHECK_THROW(v4.get_int(), std::runtime_error); | ||
BOOST_CHECK(v4.setNumStr("1000")); | ||
BOOST_CHECK_EQUAL(v4.get_int(), 1000); | ||
BOOST_CHECK_THROW(v4.get_str(), std::runtime_error); | ||
BOOST_CHECK_EQUAL(v4.get_real(), 1000); | ||
BOOST_CHECK_THROW(v4.get_array(), std::runtime_error); | ||
BOOST_CHECK_THROW(v4.getKeys(), std::runtime_error); | ||
BOOST_CHECK_THROW(v4.getValues(), std::runtime_error); | ||
BOOST_CHECK_THROW(v4.get_obj(), std::runtime_error); | ||
|
||
UniValue v5; | ||
BOOST_CHECK(v5.read("[true, 10]")); | ||
BOOST_CHECK_NO_THROW(v5.get_array()); | ||
std::vector<UniValue> vals = v5.getValues(); | ||
BOOST_CHECK_THROW(vals[0].get_int(), std::runtime_error); | ||
BOOST_CHECK_EQUAL(vals[0].get_bool(), true); | ||
|
||
BOOST_CHECK_EQUAL(vals[1].get_int(), 10); | ||
BOOST_CHECK_THROW(vals[1].get_bool(), std::runtime_error); | ||
} | ||
|
||
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.size(), 0); | ||
BOOST_CHECK_EQUAL(v.getType(), UniValue::VOBJ); | ||
BOOST_CHECK(v.empty()); | ||
|
||
BOOST_CHECK(v.setArray()); | ||
BOOST_CHECK(v.isArray()); | ||
BOOST_CHECK_EQUAL(v.size(), 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()); | ||
} | ||
|
||
BOOST_AUTO_TEST_CASE(univalue_array) | ||
{ | ||
UniValue arr(UniValue::VARR); | ||
|
||
UniValue v((int64_t)1023LL); | ||
BOOST_CHECK(arr.push_back(v)); | ||
|
||
std::string vStr("zippy"); | ||
BOOST_CHECK(arr.push_back(vStr)); | ||
|
||
const char *s = "pippy"; | ||
BOOST_CHECK(arr.push_back(s)); | ||
|
||
std::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.size(), 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.size(), 0); | ||
} | ||
|
||
BOOST_AUTO_TEST_CASE(univalue_object) | ||
{ | ||
UniValue obj(UniValue::VOBJ); | ||
std::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.size(), 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")); | ||
|
||
std::map<std::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.size(), 0); | ||
} | ||
|
||
static const char *json1 = | ||
"[1.10000000,{\"key1\":\"str\\u0000\",\"key2\":800,\"key3\":{\"name\":\"martian http://test.com\"}}]"; | ||
|
||
BOOST_AUTO_TEST_CASE(univalue_readwrite) | ||
{ | ||
UniValue v; | ||
BOOST_CHECK(v.read(json1)); | ||
|
||
std::string strJson1(json1); | ||
BOOST_CHECK(v.read(strJson1)); | ||
|
||
BOOST_CHECK(v.isArray()); | ||
BOOST_CHECK_EQUAL(v.size(), 2); | ||
|
||
BOOST_CHECK_EQUAL(v[0].getValStr(), "1.10000000"); | ||
|
||
UniValue obj = v[1]; | ||
BOOST_CHECK(obj.isObject()); | ||
BOOST_CHECK_EQUAL(obj.size(), 3); | ||
|
||
BOOST_CHECK(obj["key1"].isStr()); | ||
std::string correctValue("str"); | ||
correctValue.push_back('\0'); | ||
BOOST_CHECK_EQUAL(obj["key1"].getValStr(), correctValue); | ||
BOOST_CHECK(obj["key2"].isNum()); | ||
BOOST_CHECK_EQUAL(obj["key2"].getValStr(), "800"); | ||
BOOST_CHECK(obj["key3"].isObject()); | ||
|
||
BOOST_CHECK_EQUAL(strJson1, v.write()); | ||
|
||
/* Check for (correctly reporting) a parsing error if the initial | ||
JSON construct is followed by more stuff. Note that whitespace | ||
is, of course, exempt. */ | ||
|
||
BOOST_CHECK(v.read(" {}\n ")); | ||
BOOST_CHECK(v.isObject()); | ||
BOOST_CHECK(v.read(" []\n ")); | ||
BOOST_CHECK(v.isArray()); | ||
|
||
BOOST_CHECK(!v.read("@{}")); | ||
BOOST_CHECK(!v.read("{} garbage")); | ||
BOOST_CHECK(!v.read("[]{}")); | ||
BOOST_CHECK(!v.read("{}[]")); | ||
BOOST_CHECK(!v.read("{} 42")); | ||
} | ||
|
||
BOOST_AUTO_TEST_SUITE_END() | ||
|
||
int main (int argc, char *argv[]) | ||
{ | ||
univalue_constructor(); | ||
univalue_typecheck(); | ||
univalue_set(); | ||
univalue_array(); | ||
univalue_object(); | ||
univalue_readwrite(); | ||
return 0; | ||
} | ||
|