mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Normalize files containing unit test code:
Source files are split to place all unit test code into translation
units ending in .test.cpp with no other business logic in the same file,
and in directories named "test".
A new target is added to the SConstruct, invoked by:
scons count
This prints the total number of source code lines occupied by unit tests,
in rippled specific code and excluding library subtrees.
This commit is contained in:
@@ -18,7 +18,7 @@
|
||||
//==============================================================================
|
||||
|
||||
#include <ripple/rpc/Coroutine.h>
|
||||
#include <ripple/rpc/impl/TestOutputSuite.h>
|
||||
#include <ripple/rpc/tests/TestOutputSuite.test.h>
|
||||
|
||||
namespace ripple {
|
||||
namespace RPC {
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <ripple/rpc/Coroutine.h>
|
||||
#include <ripple/rpc/Yield.h>
|
||||
#include <ripple/rpc/impl/TestOutputSuite.h>
|
||||
|
||||
namespace ripple {
|
||||
namespace RPC {
|
||||
|
||||
class Coroutine_test : public TestOutputSuite
|
||||
{
|
||||
public:
|
||||
using Strings = std::vector <std::string>;
|
||||
|
||||
void test (std::string const& name, int chunkSize, Strings const& expected)
|
||||
{
|
||||
setup (name);
|
||||
|
||||
std::string buffer;
|
||||
Output output = stringOutput (buffer);
|
||||
|
||||
auto coroutine = Coroutine ([=] (Yield yield)
|
||||
{
|
||||
auto out = chunkedYieldingOutput (output, yield, chunkSize);
|
||||
out ("hello ");
|
||||
out ("there ");
|
||||
out ("world.");
|
||||
});
|
||||
|
||||
Strings result;
|
||||
while (coroutine)
|
||||
{
|
||||
coroutine();
|
||||
result.push_back (buffer);
|
||||
}
|
||||
|
||||
expectCollectionEquals (result, expected);
|
||||
}
|
||||
|
||||
void run() override
|
||||
{
|
||||
test ("zero", 0, {"hello ", "hello there ", "hello there world."});
|
||||
test ("three", 3, {"hello ", "hello there ", "hello there world."});
|
||||
test ("five", 5, {"hello ", "hello there ", "hello there world."});
|
||||
test ("seven", 7, {"hello there ", "hello there world."});
|
||||
test ("ten", 10, {"hello there ", "hello there world."});
|
||||
test ("thirteen", 13, {"hello there world."});
|
||||
test ("fifteen", 15, {"hello there world."});
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(Coroutine, RPC, ripple);
|
||||
|
||||
} // RPC
|
||||
} // ripple
|
||||
@@ -1,249 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <ripple/rpc/impl/JsonObject.h>
|
||||
#include <ripple/rpc/impl/TestOutputSuite.h>
|
||||
#include <beast/unit_test/suite.h>
|
||||
|
||||
namespace ripple {
|
||||
namespace RPC {
|
||||
|
||||
class JsonObject_test : public TestOutputSuite
|
||||
{
|
||||
void setup (std::string const& testName)
|
||||
{
|
||||
testcase (testName);
|
||||
output_.clear ();
|
||||
}
|
||||
|
||||
std::unique_ptr<WriterObject> writerObject_;
|
||||
|
||||
Object& makeRoot()
|
||||
{
|
||||
writerObject_ = std::make_unique<WriterObject> (
|
||||
stringWriterObject (output_));
|
||||
return **writerObject_;
|
||||
}
|
||||
|
||||
void expectResult (std::string const& expected)
|
||||
{
|
||||
writerObject_.reset();
|
||||
TestOutputSuite::expectResult (expected);
|
||||
}
|
||||
|
||||
public:
|
||||
void testTrivial ()
|
||||
{
|
||||
setup ("trivial");
|
||||
|
||||
{
|
||||
auto& root = makeRoot();
|
||||
(void) root;
|
||||
}
|
||||
expectResult ("{}");
|
||||
}
|
||||
|
||||
void testSimple ()
|
||||
{
|
||||
setup ("simple");
|
||||
{
|
||||
auto& root = makeRoot();
|
||||
root["hello"] = "world";
|
||||
root["skidoo"] = 23;
|
||||
root["awake"] = false;
|
||||
root["temperature"] = 98.6;
|
||||
}
|
||||
|
||||
expectResult (
|
||||
"{\"hello\":\"world\","
|
||||
"\"skidoo\":23,"
|
||||
"\"awake\":false,"
|
||||
"\"temperature\":98.6}");
|
||||
}
|
||||
|
||||
void testSimpleShort ()
|
||||
{
|
||||
setup ("simpleShort");
|
||||
makeRoot()
|
||||
.set ("hello", "world")
|
||||
.set ("skidoo", 23)
|
||||
.set ("awake", false)
|
||||
.set ("temperature", 98.6);
|
||||
|
||||
expectResult (
|
||||
"{\"hello\":\"world\","
|
||||
"\"skidoo\":23,"
|
||||
"\"awake\":false,"
|
||||
"\"temperature\":98.6}");
|
||||
}
|
||||
|
||||
void testOneSub ()
|
||||
{
|
||||
setup ("oneSub");
|
||||
{
|
||||
auto& root = makeRoot();
|
||||
root.makeArray ("ar");
|
||||
}
|
||||
expectResult ("{\"ar\":[]}");
|
||||
}
|
||||
|
||||
void testSubs ()
|
||||
{
|
||||
setup ("subs");
|
||||
{
|
||||
auto& root = makeRoot();
|
||||
|
||||
{
|
||||
// Add an array with three entries.
|
||||
auto array = root.makeArray ("ar");
|
||||
array.append (23);
|
||||
array.append (false);
|
||||
array.append (23.5);
|
||||
}
|
||||
|
||||
{
|
||||
// Add an object with one entry.
|
||||
auto obj = root.makeObject ("obj");
|
||||
obj["hello"] = "world";
|
||||
}
|
||||
|
||||
{
|
||||
// Add another object with two entries.
|
||||
auto obj = root.makeObject ("obj2");
|
||||
obj["h"] = "w";
|
||||
obj["f"] = false;
|
||||
}
|
||||
}
|
||||
|
||||
expectResult (
|
||||
"{\"ar\":[23,false,23.5],"
|
||||
"\"obj\":{\"hello\":\"world\"},"
|
||||
"\"obj2\":{\"h\":\"w\",\"f\":false}}");
|
||||
}
|
||||
|
||||
void testSubsShort ()
|
||||
{
|
||||
setup ("subsShort");
|
||||
|
||||
{
|
||||
auto& root = makeRoot();
|
||||
|
||||
// Add an array with three entries.
|
||||
root.makeArray ("ar")
|
||||
.append (23)
|
||||
.append (false)
|
||||
.append (23.5);
|
||||
|
||||
// Add an object with one entry.
|
||||
root.makeObject ("obj")["hello"] = "world";
|
||||
|
||||
// Add another object with two entries.
|
||||
root.makeObject ("obj2")
|
||||
.set("h", "w")
|
||||
.set("f", false);
|
||||
}
|
||||
|
||||
expectResult (
|
||||
"{\"ar\":[23,false,23.5],"
|
||||
"\"obj\":{\"hello\":\"world\"},"
|
||||
"\"obj2\":{\"h\":\"w\",\"f\":false}}");
|
||||
}
|
||||
|
||||
void testFailureObject()
|
||||
{
|
||||
{
|
||||
setup ("object failure assign");
|
||||
auto& root = makeRoot();
|
||||
auto obj = root.makeObject ("o1");
|
||||
expectException ([&]() { root["fail"] = "complete"; });
|
||||
}
|
||||
{
|
||||
setup ("object failure object");
|
||||
auto& root = makeRoot();
|
||||
auto obj = root.makeObject ("o1");
|
||||
expectException ([&] () { root.makeObject ("o2"); });
|
||||
}
|
||||
{
|
||||
setup ("object failure Array");
|
||||
auto& root = makeRoot();
|
||||
auto obj = root.makeArray ("o1");
|
||||
expectException ([&] () { root.makeArray ("o2"); });
|
||||
}
|
||||
}
|
||||
|
||||
void testFailureArray()
|
||||
{
|
||||
{
|
||||
setup ("array failure append");
|
||||
auto& root = makeRoot();
|
||||
auto array = root.makeArray ("array");
|
||||
auto subarray = array.makeArray ();
|
||||
auto fail = [&]() { array.append ("fail"); };
|
||||
expectException (fail);
|
||||
}
|
||||
{
|
||||
setup ("array failure makeArray");
|
||||
auto& root = makeRoot();
|
||||
auto array = root.makeArray ("array");
|
||||
auto subarray = array.makeArray ();
|
||||
auto fail = [&]() { array.makeArray (); };
|
||||
expectException (fail);
|
||||
}
|
||||
{
|
||||
setup ("array failure makeObject");
|
||||
auto& root = makeRoot();
|
||||
auto array = root.makeArray ("array");
|
||||
auto subarray = array.makeArray ();
|
||||
auto fail = [&]() { array.makeObject (); };
|
||||
expectException (fail);
|
||||
}
|
||||
}
|
||||
|
||||
void testKeyFailure ()
|
||||
{
|
||||
#ifdef DEBUG
|
||||
setup ("repeating keys");
|
||||
auto& root = makeRoot();
|
||||
root.set ("foo", "bar")
|
||||
.set ("baz", 0);
|
||||
auto fail = [&]() { root.set ("foo", "bar"); };
|
||||
expectException (fail);
|
||||
#endif
|
||||
}
|
||||
|
||||
void run () override
|
||||
{
|
||||
testTrivial ();
|
||||
testSimple ();
|
||||
testSimpleShort ();
|
||||
|
||||
testOneSub ();
|
||||
testSubs ();
|
||||
testSubsShort ();
|
||||
|
||||
testFailureObject ();
|
||||
testFailureArray ();
|
||||
testKeyFailure ();
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(JsonObject, ripple_basics, ripple);
|
||||
|
||||
} // RPC
|
||||
} // ripple
|
||||
@@ -1,207 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <ripple/json/json_writer.h>
|
||||
|
||||
#include <ripple/rpc/impl/JsonWriter.h>
|
||||
#include <ripple/rpc/impl/TestOutputSuite.h>
|
||||
#include <beast/unit_test/suite.h>
|
||||
|
||||
namespace ripple {
|
||||
namespace RPC {
|
||||
|
||||
class JsonWriter_test : public TestOutputSuite
|
||||
{
|
||||
public:
|
||||
void testTrivial ()
|
||||
{
|
||||
setup ("trivial");
|
||||
expect (output_.empty ());
|
||||
expectResult("");
|
||||
}
|
||||
|
||||
void testNearTrivial ()
|
||||
{
|
||||
setup ("near trivial");
|
||||
expect (output_.empty ());
|
||||
writer_->output (0);
|
||||
expectResult("0");
|
||||
}
|
||||
|
||||
void testPrimitives ()
|
||||
{
|
||||
setup ("true");
|
||||
writer_->output (true);
|
||||
expectResult ("true");
|
||||
|
||||
setup ("false");
|
||||
writer_->output (false);
|
||||
expectResult ("false");
|
||||
|
||||
setup ("23");
|
||||
writer_->output (23);
|
||||
expectResult ("23");
|
||||
|
||||
setup ("23.0");
|
||||
writer_->output (23.0);
|
||||
expectResult ("23.0");
|
||||
|
||||
setup ("23.5");
|
||||
writer_->output (23.5);
|
||||
expectResult ("23.5");
|
||||
|
||||
setup ("a string");
|
||||
writer_->output ("a string");
|
||||
expectResult ("\"a string\"");
|
||||
|
||||
setup ("nullptr");
|
||||
writer_->output (nullptr);
|
||||
expectResult ("null");
|
||||
}
|
||||
|
||||
void testEmpty ()
|
||||
{
|
||||
setup ("empty array");
|
||||
writer_->startRoot (Writer::array);
|
||||
writer_->finish ();
|
||||
expectResult ("[]");
|
||||
|
||||
setup ("empty object");
|
||||
writer_->startRoot (Writer::object);
|
||||
writer_->finish ();
|
||||
expectResult ("{}");
|
||||
}
|
||||
|
||||
void testEscaping ()
|
||||
{
|
||||
setup ("backslash");
|
||||
writer_->output ("\\");
|
||||
expectResult ("\"\\\\\"");
|
||||
|
||||
setup ("quote");
|
||||
writer_->output ("\"");
|
||||
expectResult ("\"\\\"\"");
|
||||
|
||||
setup ("backslash and quote");
|
||||
writer_->output ("\\\"");
|
||||
expectResult ("\"\\\\\\\"\"");
|
||||
|
||||
setup ("escape embedded");
|
||||
writer_->output ("this contains a \\ in the middle of it.");
|
||||
expectResult ("\"this contains a \\\\ in the middle of it.\"");
|
||||
|
||||
setup ("remaining escapes");
|
||||
writer_->output ("\b\f\n\r\t");
|
||||
expectResult ("\"\\b\\f\\n\\r\\t\"");
|
||||
}
|
||||
|
||||
void testArray ()
|
||||
{
|
||||
setup ("empty array");
|
||||
writer_->startRoot (Writer::array);
|
||||
writer_->append (12);
|
||||
writer_->finish ();
|
||||
expectResult ("[12]");
|
||||
}
|
||||
|
||||
void testLongArray ()
|
||||
{
|
||||
setup ("long array");
|
||||
writer_->startRoot (Writer::array);
|
||||
writer_->append (12);
|
||||
writer_->append (true);
|
||||
writer_->append ("hello");
|
||||
writer_->finish ();
|
||||
expectResult ("[12,true,\"hello\"]");
|
||||
}
|
||||
|
||||
void testEmbeddedArraySimple ()
|
||||
{
|
||||
setup ("embedded array simple");
|
||||
writer_->startRoot (Writer::array);
|
||||
writer_->startAppend (Writer::array);
|
||||
writer_->finish ();
|
||||
writer_->finish ();
|
||||
expectResult ("[[]]");
|
||||
}
|
||||
|
||||
void testObject ()
|
||||
{
|
||||
setup ("object");
|
||||
writer_->startRoot (Writer::object);
|
||||
writer_->set ("hello", "world");
|
||||
writer_->finish ();
|
||||
|
||||
expectResult ("{\"hello\":\"world\"}");
|
||||
}
|
||||
|
||||
void testComplexObject ()
|
||||
{
|
||||
setup ("complex object");
|
||||
writer_->startRoot (Writer::object);
|
||||
|
||||
writer_->set ("hello", "world");
|
||||
writer_->startSet (Writer::array, "array");
|
||||
|
||||
writer_->append (true);
|
||||
writer_->append (12);
|
||||
writer_->startAppend (Writer::array);
|
||||
writer_->startAppend (Writer::object);
|
||||
writer_->set ("goodbye", "cruel world.");
|
||||
writer_->startSet (Writer::array, "subarray");
|
||||
writer_->append (23.5);
|
||||
writer_->finishAll ();
|
||||
|
||||
expectResult ("{\"hello\":\"world\",\"array\":[true,12,"
|
||||
"[{\"goodbye\":\"cruel world.\","
|
||||
"\"subarray\":[23.5]}]]}");
|
||||
}
|
||||
|
||||
void testJson ()
|
||||
{
|
||||
setup ("object");
|
||||
Json::Value value (Json::objectValue);
|
||||
value["foo"] = 23;
|
||||
writer_->startRoot (Writer::object);
|
||||
writer_->set ("hello", value);
|
||||
writer_->finish ();
|
||||
|
||||
expectResult ("{\"hello\":{\"foo\":23}}");
|
||||
}
|
||||
|
||||
void run () override
|
||||
{
|
||||
testTrivial ();
|
||||
testNearTrivial ();
|
||||
testPrimitives ();
|
||||
testEmpty ();
|
||||
testEscaping ();
|
||||
testArray ();
|
||||
testLongArray ();
|
||||
testEmbeddedArraySimple ();
|
||||
testObject ();
|
||||
testComplexObject ();
|
||||
testJson();
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(JsonWriter, ripple_basics, ripple);
|
||||
|
||||
} // RPC
|
||||
} // ripple
|
||||
@@ -1,212 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <ripple/rpc/Status.h>
|
||||
#include <beast/unit_test/suite.h>
|
||||
|
||||
namespace ripple {
|
||||
namespace RPC {
|
||||
|
||||
class codeString_test : public beast::unit_test::suite
|
||||
{
|
||||
private:
|
||||
template <typename Type>
|
||||
std::string codeString (Type t)
|
||||
{
|
||||
return Status (t).codeString();
|
||||
}
|
||||
|
||||
void test_OK ()
|
||||
{
|
||||
testcase ("OK");
|
||||
{
|
||||
auto s = codeString (Status ());
|
||||
expect (s.empty(), "String for OK status");
|
||||
}
|
||||
|
||||
{
|
||||
auto s = codeString (Status::OK);
|
||||
expect (s.empty(), "String for OK status");
|
||||
}
|
||||
|
||||
{
|
||||
auto s = codeString (0);
|
||||
expect (s.empty(), "String for 0 status");
|
||||
}
|
||||
|
||||
{
|
||||
auto s = codeString (tesSUCCESS);
|
||||
expect (s.empty(), "String for tesSUCCESS");
|
||||
}
|
||||
|
||||
{
|
||||
auto s = codeString (rpcSUCCESS);
|
||||
expect (s.empty(), "String for rpcSUCCESS");
|
||||
}
|
||||
}
|
||||
|
||||
void test_error ()
|
||||
{
|
||||
testcase ("error");
|
||||
{
|
||||
auto s = codeString (23);
|
||||
expect (s == "23", s);
|
||||
}
|
||||
|
||||
{
|
||||
auto s = codeString (temBAD_AMOUNT);
|
||||
expect (s == "temBAD_AMOUNT: Can only send positive amounts.", s);
|
||||
}
|
||||
|
||||
{
|
||||
auto s = codeString (rpcBAD_SYNTAX);
|
||||
expect (s == "badSyntax: Syntax error.", s);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
void run()
|
||||
{
|
||||
test_OK ();
|
||||
test_error ();
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE (codeString, Status, RPC);
|
||||
|
||||
class fillJson_test : public beast::unit_test::suite
|
||||
{
|
||||
private:
|
||||
Json::Value value_;
|
||||
|
||||
template <typename Type>
|
||||
void fillJson (Type t)
|
||||
{
|
||||
value_.clear ();
|
||||
Status (t).fillJson (value_);
|
||||
}
|
||||
|
||||
void test_OK ()
|
||||
{
|
||||
testcase ("OK");
|
||||
fillJson (Status ());
|
||||
expect (value_.empty(), "Value for empty status");
|
||||
|
||||
fillJson (0);
|
||||
expect (value_.empty(), "Value for 0 status");
|
||||
|
||||
fillJson (Status::OK);
|
||||
expect (value_.empty(), "Value for OK status");
|
||||
|
||||
fillJson (tesSUCCESS);
|
||||
expect (value_.empty(), "Value for tesSUCCESS");
|
||||
|
||||
fillJson (rpcSUCCESS);
|
||||
expect (value_.empty(), "Value for rpcSUCCESS");
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
void expectFill (
|
||||
std::string const& label,
|
||||
Type status,
|
||||
Status::Strings messages,
|
||||
std::string const& message)
|
||||
{
|
||||
value_.clear ();
|
||||
fillJson (Status (status, messages));
|
||||
|
||||
auto prefix = label + ": ";
|
||||
expect (!value_.empty(), prefix + "No value");
|
||||
|
||||
auto error = value_[jss::error];
|
||||
expect (!error.empty(), prefix + "No error.");
|
||||
|
||||
auto code = error[jss::code].asInt();
|
||||
expect (status == code, prefix + "Wrong status " +
|
||||
std::to_string (code) + " != " + std::to_string (status));
|
||||
|
||||
auto m = error[jss::message].asString ();
|
||||
expect (m == message, m + " != " + message);
|
||||
|
||||
auto d = error[jss::data];
|
||||
size_t s1 = d.size(), s2 = messages.size();
|
||||
expect (s1 == s2, prefix + "Data sizes differ " +
|
||||
std::to_string (s1) + " != " + std::to_string (s2));
|
||||
for (auto i = 0; i < std::min (s1, s2); ++i)
|
||||
{
|
||||
auto ds = d[i].asString();
|
||||
expect (ds == messages[i], prefix + ds + " != " + messages[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void test_error ()
|
||||
{
|
||||
testcase ("error");
|
||||
expectFill (
|
||||
"temBAD_AMOUNT",
|
||||
temBAD_AMOUNT,
|
||||
{},
|
||||
"temBAD_AMOUNT: Can only send positive amounts.");
|
||||
|
||||
expectFill (
|
||||
"rpcBAD_SYNTAX",
|
||||
rpcBAD_SYNTAX,
|
||||
{"An error.", "Another error."},
|
||||
"badSyntax: Syntax error.");
|
||||
|
||||
expectFill (
|
||||
"integer message",
|
||||
23,
|
||||
{"Stuff."},
|
||||
"23");
|
||||
}
|
||||
|
||||
void test_throw ()
|
||||
{
|
||||
testcase ("throw");
|
||||
try
|
||||
{
|
||||
throw Status (temBAD_PATH, {"path=sdcdfd"});
|
||||
}
|
||||
catch (Status const& s)
|
||||
{
|
||||
expect (s.toTER () == temBAD_PATH, "temBAD_PATH wasn't thrown");
|
||||
auto msgs = s.messages ();
|
||||
expect (msgs.size () == 1, "Wrong number of messages");
|
||||
expect (msgs[0] == "path=sdcdfd", msgs[0]);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
expect (false, "Didn't catch a Status");
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
void run()
|
||||
{
|
||||
test_OK ();
|
||||
test_error ();
|
||||
test_throw ();
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE (fillJson, Status, RPC);
|
||||
|
||||
} // namespace RPC
|
||||
} // ripple
|
||||
@@ -1,56 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLED_RIPPLE_RPC_IMPL_TESTOUTPUT_H
|
||||
#define RIPPLED_RIPPLE_RPC_IMPL_TESTOUTPUT_H
|
||||
|
||||
#include <ripple/rpc/Output.h>
|
||||
#include <ripple/rpc/impl/JsonWriter.h>
|
||||
#include <ripple/basics/TestSuite.h>
|
||||
|
||||
namespace ripple {
|
||||
namespace RPC {
|
||||
|
||||
class TestOutputSuite : public TestSuite
|
||||
{
|
||||
protected:
|
||||
std::string output_;
|
||||
std::unique_ptr <Writer> writer_;
|
||||
|
||||
void setup (std::string const& testName)
|
||||
{
|
||||
testcase (testName);
|
||||
output_.clear ();
|
||||
writer_ = std::make_unique <Writer> (stringOutput (output_));
|
||||
}
|
||||
|
||||
// Test the result and report values.
|
||||
void expectResult (std::string const& expected,
|
||||
std::string const& message = "")
|
||||
{
|
||||
writer_.reset ();
|
||||
|
||||
expectEquals (output_, expected, message);
|
||||
}
|
||||
};
|
||||
|
||||
} // RPC
|
||||
} // ripple
|
||||
|
||||
#endif
|
||||
@@ -550,551 +550,5 @@ transactionSign (
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Struct used to test calls to transactionSign and transactionSubmit.
|
||||
struct TxnTestData
|
||||
{
|
||||
// Gah, without constexpr I can't make this an enum and initialize
|
||||
// OR operators at compile time. Punting with integer constants.
|
||||
static unsigned int const allGood = 0x0;
|
||||
static unsigned int const signFail = 0x1;
|
||||
static unsigned int const submitFail = 0x2;
|
||||
|
||||
char const* const json;
|
||||
unsigned int result;
|
||||
|
||||
TxnTestData () = delete;
|
||||
TxnTestData (TxnTestData const&) = delete;
|
||||
TxnTestData& operator= (TxnTestData const&) = delete;
|
||||
TxnTestData (char const* jsonIn, unsigned int resultIn)
|
||||
: json (jsonIn)
|
||||
, result (resultIn)
|
||||
{ }
|
||||
};
|
||||
|
||||
// Declare storage for statics to avoid link errors.
|
||||
unsigned int const TxnTestData::allGood;
|
||||
unsigned int const TxnTestData::signFail;
|
||||
unsigned int const TxnTestData::submitFail;
|
||||
|
||||
|
||||
static TxnTestData const txnTestArray [] =
|
||||
{
|
||||
|
||||
// Minimal payment.
|
||||
{R"({
|
||||
"command": "submit",
|
||||
"secret": "masterpassphrase",
|
||||
"tx_json": {
|
||||
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||
"Amount": "1000000000",
|
||||
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
|
||||
"TransactionType": "Payment"
|
||||
}
|
||||
})", TxnTestData::allGood},
|
||||
|
||||
// Pass in Fee with minimal payment.
|
||||
{R"({
|
||||
"command": "submit",
|
||||
"secret": "masterpassphrase",
|
||||
"tx_json": {
|
||||
"Fee": 10,
|
||||
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||
"Amount": "1000000000",
|
||||
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
|
||||
"TransactionType": "Payment"
|
||||
}
|
||||
})", TxnTestData::allGood},
|
||||
|
||||
// Pass in Sequence.
|
||||
{R"({
|
||||
"command": "submit",
|
||||
"secret": "masterpassphrase",
|
||||
"tx_json": {
|
||||
"Sequence": 0,
|
||||
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||
"Amount": "1000000000",
|
||||
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
|
||||
"TransactionType": "Payment"
|
||||
}
|
||||
})", TxnTestData::allGood},
|
||||
|
||||
// Pass in Sequence and Fee with minimal payment.
|
||||
{R"({
|
||||
"command": "submit",
|
||||
"secret": "masterpassphrase",
|
||||
"tx_json": {
|
||||
"Sequence": 0,
|
||||
"Fee": 10,
|
||||
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||
"Amount": "1000000000",
|
||||
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
|
||||
"TransactionType": "Payment"
|
||||
}
|
||||
})", TxnTestData::allGood},
|
||||
|
||||
// Add "fee_mult_max" field.
|
||||
{R"({
|
||||
"command": "submit",
|
||||
"secret": "masterpassphrase",
|
||||
"fee_mult_max": 7,
|
||||
"tx_json": {
|
||||
"Sequence": 0,
|
||||
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||
"Amount": "1000000000",
|
||||
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
|
||||
"TransactionType": "Payment"
|
||||
}
|
||||
})", TxnTestData::allGood},
|
||||
|
||||
// "fee_mult_max is ignored if "Fee" is present.
|
||||
{R"({
|
||||
"command": "submit",
|
||||
"secret": "masterpassphrase",
|
||||
"fee_mult_max": 0,
|
||||
"tx_json": {
|
||||
"Sequence": 0,
|
||||
"Fee": 10,
|
||||
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||
"Amount": "1000000000",
|
||||
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
|
||||
"TransactionType": "Payment"
|
||||
}
|
||||
})", TxnTestData::allGood},
|
||||
|
||||
// Invalid "fee_mult_max" field.
|
||||
{R"({
|
||||
"command": "submit",
|
||||
"secret": "masterpassphrase",
|
||||
"fee_mult_max": "NotAFeeMultiplier",
|
||||
"tx_json": {
|
||||
"Sequence": 0,
|
||||
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||
"Amount": "1000000000",
|
||||
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
|
||||
"TransactionType": "Payment"
|
||||
}
|
||||
})", TxnTestData::signFail | TxnTestData::submitFail},
|
||||
|
||||
// Invalid value for "fee_mult_max" field.
|
||||
{R"({
|
||||
"command": "submit",
|
||||
"secret": "masterpassphrase",
|
||||
"fee_mult_max": 0,
|
||||
"tx_json": {
|
||||
"Sequence": 0,
|
||||
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||
"Amount": "1000000000",
|
||||
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
|
||||
"TransactionType": "Payment"
|
||||
}
|
||||
})", TxnTestData::signFail | TxnTestData::submitFail},
|
||||
|
||||
// Missing "Amount".
|
||||
{R"({
|
||||
"command": "submit",
|
||||
"secret": "masterpassphrase",
|
||||
"tx_json": {
|
||||
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
|
||||
"TransactionType": "Payment"
|
||||
}
|
||||
})", TxnTestData::signFail | TxnTestData::submitFail},
|
||||
|
||||
// Invalid "Amount".
|
||||
{R"({
|
||||
"command": "submit",
|
||||
"secret": "masterpassphrase",
|
||||
"tx_json": {
|
||||
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||
"Amount": "NotAnAmount",
|
||||
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
|
||||
"TransactionType": "Payment"
|
||||
}
|
||||
})", TxnTestData::signFail | TxnTestData::submitFail},
|
||||
|
||||
// Missing "Destination".
|
||||
{R"({
|
||||
"command": "submit",
|
||||
"secret": "masterpassphrase",
|
||||
"tx_json": {
|
||||
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||
"Amount": "1000000000",
|
||||
"TransactionType": "Payment"
|
||||
}
|
||||
})", TxnTestData::signFail | TxnTestData::submitFail},
|
||||
|
||||
// Invalid "Destination".
|
||||
{R"({
|
||||
"command": "submit",
|
||||
"secret": "masterpassphrase",
|
||||
"tx_json": {
|
||||
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||
"Amount": "1000000000",
|
||||
"Destination": "NotADestination",
|
||||
"TransactionType": "Payment"
|
||||
}
|
||||
})", TxnTestData::signFail | TxnTestData::submitFail},
|
||||
|
||||
// Cannot create XRP to XRP paths.
|
||||
{R"({
|
||||
"command": "submit",
|
||||
"secret": "masterpassphrase",
|
||||
"build_path": 1,
|
||||
"tx_json": {
|
||||
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||
"Amount": "1000000000",
|
||||
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
|
||||
"TransactionType": "Payment"
|
||||
}
|
||||
})", TxnTestData::signFail | TxnTestData::submitFail},
|
||||
|
||||
// Successful "build_path".
|
||||
{R"({
|
||||
"command": "submit",
|
||||
"secret": "masterpassphrase",
|
||||
"build_path": 1,
|
||||
"tx_json": {
|
||||
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||
"Amount": {
|
||||
"value": "10",
|
||||
"currency": "USD",
|
||||
"issuer": "0123456789012345678901234567890123456789"
|
||||
},
|
||||
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
|
||||
"TransactionType": "Payment"
|
||||
}
|
||||
})", TxnTestData::allGood},
|
||||
|
||||
// Not valid to include both "Paths" and "build_path".
|
||||
{R"({
|
||||
"command": "submit",
|
||||
"secret": "masterpassphrase",
|
||||
"build_path": 1,
|
||||
"tx_json": {
|
||||
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||
"Amount": {
|
||||
"value": "10",
|
||||
"currency": "USD",
|
||||
"issuer": "0123456789012345678901234567890123456789"
|
||||
},
|
||||
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
|
||||
"Paths": "",
|
||||
"TransactionType": "Payment"
|
||||
}
|
||||
})", TxnTestData::signFail | TxnTestData::submitFail},
|
||||
|
||||
// Successful "SendMax".
|
||||
{R"({
|
||||
"command": "submit",
|
||||
"secret": "masterpassphrase",
|
||||
"build_path": 1,
|
||||
"tx_json": {
|
||||
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||
"Amount": {
|
||||
"value": "10",
|
||||
"currency": "USD",
|
||||
"issuer": "0123456789012345678901234567890123456789"
|
||||
},
|
||||
"SendMax": {
|
||||
"value": "5",
|
||||
"currency": "USD",
|
||||
"issuer": "0123456789012345678901234567890123456789"
|
||||
},
|
||||
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
|
||||
"TransactionType": "Payment"
|
||||
}
|
||||
})", TxnTestData::allGood},
|
||||
|
||||
// Even though "Amount" may not be XRP for pathfinding, "SendMax" may be XRP.
|
||||
{R"({
|
||||
"command": "submit",
|
||||
"secret": "masterpassphrase",
|
||||
"build_path": 1,
|
||||
"tx_json": {
|
||||
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||
"Amount": {
|
||||
"value": "10",
|
||||
"currency": "USD",
|
||||
"issuer": "0123456789012345678901234567890123456789"
|
||||
},
|
||||
"SendMax": 10000,
|
||||
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
|
||||
"TransactionType": "Payment"
|
||||
}
|
||||
})", TxnTestData::allGood},
|
||||
|
||||
// "secret" must be present.
|
||||
{R"({
|
||||
"command": "submit",
|
||||
"tx_json": {
|
||||
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||
"Amount": "1000000000",
|
||||
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
|
||||
"TransactionType": "Payment"
|
||||
}
|
||||
})", TxnTestData::signFail | TxnTestData::submitFail},
|
||||
|
||||
// "secret" must be non-empty.
|
||||
{R"({
|
||||
"command": "submit",
|
||||
"secret": "",
|
||||
"tx_json": {
|
||||
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||
"Amount": "1000000000",
|
||||
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
|
||||
"TransactionType": "Payment"
|
||||
}
|
||||
})", TxnTestData::signFail | TxnTestData::submitFail},
|
||||
|
||||
// "tx_json" must be present.
|
||||
{R"({
|
||||
"command": "submit",
|
||||
"secret": "masterpassphrase",
|
||||
"rx_json": {
|
||||
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||
"Amount": "1000000000",
|
||||
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
|
||||
"TransactionType": "Payment"
|
||||
}
|
||||
})", TxnTestData::signFail | TxnTestData::submitFail},
|
||||
|
||||
// "TransactionType" must be present.
|
||||
{R"({
|
||||
"command": "submit",
|
||||
"secret": "masterpassphrase",
|
||||
"tx_json": {
|
||||
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||
"Amount": "1000000000",
|
||||
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
|
||||
}
|
||||
})", TxnTestData::signFail | TxnTestData::submitFail},
|
||||
|
||||
// The "TransactionType" must be one of the pre-established transaction types.
|
||||
{R"({
|
||||
"command": "submit",
|
||||
"secret": "masterpassphrase",
|
||||
"tx_json": {
|
||||
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||
"Amount": "1000000000",
|
||||
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
|
||||
"TransactionType": "tt"
|
||||
}
|
||||
})", TxnTestData::signFail | TxnTestData::submitFail},
|
||||
|
||||
// The "TransactionType", however, may be represented with an integer.
|
||||
{R"({
|
||||
"command": "submit",
|
||||
"secret": "masterpassphrase",
|
||||
"tx_json": {
|
||||
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||
"Amount": "1000000000",
|
||||
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
|
||||
"TransactionType": 0
|
||||
}
|
||||
})", TxnTestData::allGood},
|
||||
|
||||
// "Account" must be present.
|
||||
{R"({
|
||||
"command": "submit",
|
||||
"secret": "masterpassphrase",
|
||||
"tx_json": {
|
||||
"Amount": "1000000000",
|
||||
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
|
||||
"TransactionType": "Payment"
|
||||
}
|
||||
})", TxnTestData::signFail | TxnTestData::submitFail},
|
||||
|
||||
// "Account" must be well formed.
|
||||
{R"({
|
||||
"command": "submit",
|
||||
"secret": "masterpassphrase",
|
||||
"tx_json": {
|
||||
"Account": "NotAnAccount",
|
||||
"Amount": "1000000000",
|
||||
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
|
||||
"TransactionType": "Payment"
|
||||
}
|
||||
})", TxnTestData::signFail | TxnTestData::submitFail},
|
||||
|
||||
// The "offline" tag may be added to the transaction.
|
||||
{R"({
|
||||
"command": "submit",
|
||||
"secret": "masterpassphrase",
|
||||
"offline": 0,
|
||||
"tx_json": {
|
||||
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||
"Amount": "1000000000",
|
||||
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
|
||||
"TransactionType": "Payment"
|
||||
}
|
||||
})", TxnTestData::allGood},
|
||||
|
||||
// If "offline" is true then a "Sequence" field must be supplied.
|
||||
{R"({
|
||||
"command": "submit",
|
||||
"secret": "masterpassphrase",
|
||||
"offline": 1,
|
||||
"tx_json": {
|
||||
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||
"Amount": "1000000000",
|
||||
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
|
||||
"TransactionType": "Payment"
|
||||
}
|
||||
})", TxnTestData::signFail | TxnTestData::submitFail},
|
||||
|
||||
// Valid transaction if "offline" is true.
|
||||
{R"({
|
||||
"command": "submit",
|
||||
"secret": "masterpassphrase",
|
||||
"offline": 1,
|
||||
"tx_json": {
|
||||
"Sequence": 0,
|
||||
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||
"Amount": "1000000000",
|
||||
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
|
||||
"TransactionType": "Payment"
|
||||
}
|
||||
})", TxnTestData::allGood},
|
||||
|
||||
// A "Flags' field may be specified.
|
||||
{R"({
|
||||
"command": "submit",
|
||||
"secret": "masterpassphrase",
|
||||
"tx_json": {
|
||||
"Flags": 0,
|
||||
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||
"Amount": "1000000000",
|
||||
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
|
||||
"TransactionType": "Payment"
|
||||
}
|
||||
})", TxnTestData::allGood},
|
||||
|
||||
// The "Flags" field must be numeric.
|
||||
{R"({
|
||||
"command": "submit",
|
||||
"secret": "masterpassphrase",
|
||||
"tx_json": {
|
||||
"Flags": "NotGoodFlags",
|
||||
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||
"Amount": "1000000000",
|
||||
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
|
||||
"TransactionType": "Payment"
|
||||
}
|
||||
})", TxnTestData::signFail | TxnTestData::submitFail},
|
||||
|
||||
// It's okay to add a "debug_signing" field.
|
||||
{R"({
|
||||
"command": "submit",
|
||||
"secret": "masterpassphrase",
|
||||
"debug_signing": 0,
|
||||
"tx_json": {
|
||||
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||
"Amount": "1000000000",
|
||||
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
|
||||
"TransactionType": "Payment"
|
||||
}
|
||||
})", TxnTestData::allGood},
|
||||
|
||||
};
|
||||
|
||||
class JSONRPC_test : public beast::unit_test::suite
|
||||
{
|
||||
public:
|
||||
void testAutoFillFees ()
|
||||
{
|
||||
RippleAddress rootSeedMaster
|
||||
= RippleAddress::createSeedGeneric ("masterpassphrase");
|
||||
RippleAddress rootGeneratorMaster
|
||||
= RippleAddress::createGeneratorPublic (rootSeedMaster);
|
||||
RippleAddress rootAddress
|
||||
= RippleAddress::createAccountPublic (rootGeneratorMaster, 0);
|
||||
std::uint64_t startAmount (100000);
|
||||
Ledger::pointer ledger (std::make_shared <Ledger> (
|
||||
rootAddress, startAmount));
|
||||
|
||||
using namespace RPCDetail;
|
||||
LedgerFacade facade (LedgerFacade::noNetOPs, ledger);
|
||||
|
||||
{
|
||||
Json::Value req;
|
||||
Json::Value result;
|
||||
Json::Reader ().parse (
|
||||
R"({ "fee_mult_max" : 1, "tx_json" : { } } )"
|
||||
, req);
|
||||
autofill_fee (req, facade, result, true);
|
||||
|
||||
expect (! contains_error (result));
|
||||
}
|
||||
|
||||
{
|
||||
Json::Value req;
|
||||
Json::Value result;
|
||||
Json::Reader ().parse (
|
||||
R"({ "fee_mult_max" : 0, "tx_json" : { } } )"
|
||||
, req);
|
||||
autofill_fee (req, facade, result, true);
|
||||
|
||||
expect (contains_error (result));
|
||||
}
|
||||
}
|
||||
|
||||
void testTransactionRPC ()
|
||||
{
|
||||
// This loop is forward-looking for when there are separate
|
||||
// transactionSign () and transcationSubmit () functions. For now
|
||||
// they just have a bool (false = sign, true = submit) and a flag
|
||||
// to help classify failure types.
|
||||
using TestStuff = std::pair <bool, unsigned int>;
|
||||
static TestStuff const testFuncs [] =
|
||||
{
|
||||
TestStuff {false, TxnTestData::signFail},
|
||||
TestStuff {true, TxnTestData::submitFail},
|
||||
};
|
||||
|
||||
for (auto testFunc : testFuncs)
|
||||
{
|
||||
// For each JSON test.
|
||||
for (auto const& txnTest : txnTestArray)
|
||||
{
|
||||
Json::Value req;
|
||||
Json::Reader ().parse (txnTest.json, req);
|
||||
if (contains_error (req))
|
||||
throw std::runtime_error (
|
||||
"Internal JSONRPC_test error. Bad test JSON.");
|
||||
|
||||
static Role const testedRoles[] =
|
||||
{Role::GUEST, Role::USER, Role::ADMIN, Role::FORBID};
|
||||
|
||||
for (Role testRole : testedRoles)
|
||||
{
|
||||
// Mock so we can run without a ledger.
|
||||
RPCDetail::LedgerFacade fakeNetOPs (
|
||||
RPCDetail::LedgerFacade::noNetOPs);
|
||||
|
||||
Json::Value result = transactionSign (
|
||||
req,
|
||||
testFunc.first,
|
||||
true,
|
||||
fakeNetOPs,
|
||||
testRole);
|
||||
|
||||
expect (contains_error (result) ==
|
||||
static_cast <bool> (txnTest.result & testFunc.second));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void run ()
|
||||
{
|
||||
testAutoFillFees ();
|
||||
testTransactionRPC ();
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(JSONRPC,ripple_app,ripple);
|
||||
|
||||
} // RPC
|
||||
} // ripple
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <ripple/rpc/impl/WriteJson.h>
|
||||
#include <ripple/rpc/impl/TestOutputSuite.h>
|
||||
|
||||
namespace ripple {
|
||||
namespace RPC {
|
||||
|
||||
struct WriteJson_test : TestOutputSuite
|
||||
{
|
||||
void runTest (std::string const& name, std::string const& valueDesc)
|
||||
{
|
||||
setup (name);
|
||||
Json::Value value;
|
||||
expect (Json::Reader().parse (valueDesc, value));
|
||||
auto out = stringOutput (output_);
|
||||
writeJson (value, out);
|
||||
|
||||
// Compare with the original version.
|
||||
auto expected = Json::FastWriter().write (value);
|
||||
expected.resize (expected.size() - 1);
|
||||
// For some reason, the FastWriter puts a carriage return on the end of
|
||||
// every piece of Json it outputs.
|
||||
|
||||
expectResult (expected);
|
||||
expectResult (valueDesc);
|
||||
expectResult (jsonAsString (value));
|
||||
}
|
||||
|
||||
void runTest (std::string const& name)
|
||||
{
|
||||
runTest (name, name);
|
||||
}
|
||||
|
||||
void run () override
|
||||
{
|
||||
runTest ("null");
|
||||
runTest ("true");
|
||||
runTest ("0");
|
||||
runTest ("23.5");
|
||||
runTest ("string", "\"a string\"");
|
||||
runTest ("empty dict", "{}");
|
||||
runTest ("empty array", "[]");
|
||||
runTest ("array", "[23,4.25,true,null,\"string\"]");
|
||||
runTest ("dict", "{\"hello\":\"world\"}");
|
||||
runTest ("array dict", "[{}]");
|
||||
runTest ("array array", "[[]]");
|
||||
runTest ("more complex",
|
||||
"{\"array\":[{\"12\":23},{},null,false,0.5]}");
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(WriteJson, ripple_basics, ripple);
|
||||
|
||||
} // RPC
|
||||
} // ripple
|
||||
@@ -18,7 +18,7 @@
|
||||
//==============================================================================
|
||||
|
||||
#include <ripple/rpc/Yield.h>
|
||||
#include <ripple/rpc/impl/TestOutputSuite.h>
|
||||
#include <ripple/rpc/tests/TestOutputSuite.test.h>
|
||||
|
||||
namespace ripple {
|
||||
namespace RPC {
|
||||
|
||||
@@ -1,105 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <ripple/rpc/Yield.h>
|
||||
#include <ripple/rpc/impl/TestOutputSuite.h>
|
||||
|
||||
namespace ripple {
|
||||
namespace RPC {
|
||||
|
||||
struct Yield_test : TestOutputSuite
|
||||
{
|
||||
void chunkedYieldingTest ()
|
||||
{
|
||||
setup ("chunkedYieldingTest");
|
||||
std::string lastYield;
|
||||
|
||||
auto yield = [&]() { lastYield = output_; };
|
||||
auto output = chunkedYieldingOutput (stringOutput (output_), yield, 5);
|
||||
output ("hello");
|
||||
expectResult ("hello");
|
||||
expectEquals (lastYield, "");
|
||||
|
||||
output (", th"); // Goes over the boundary.
|
||||
expectResult ("hello, th");
|
||||
expectEquals (lastYield, "");
|
||||
|
||||
output ("ere!"); // Forces a yield.
|
||||
expectResult ("hello, there!");
|
||||
expectEquals (lastYield, "hello, th");
|
||||
|
||||
output ("!!");
|
||||
expectResult ("hello, there!!!");
|
||||
expectEquals (lastYield, "hello, th");
|
||||
|
||||
output (""); // Forces a yield.
|
||||
expectResult ("hello, there!!!");
|
||||
expectEquals (lastYield, "hello, there!!!");
|
||||
}
|
||||
|
||||
void trivialCountedYieldTest()
|
||||
{
|
||||
setup ("trivialCountedYield");
|
||||
|
||||
auto didYield = false;
|
||||
auto yield = [&]() { didYield = true; };
|
||||
|
||||
CountedYield cy (0, yield);
|
||||
|
||||
for (auto i = 0; i < 4; ++i)
|
||||
{
|
||||
cy.yield();
|
||||
expect (!didYield, "We yielded when we shouldn't have.");
|
||||
}
|
||||
}
|
||||
|
||||
void countedYieldTest()
|
||||
{
|
||||
setup ("countedYield");
|
||||
|
||||
auto didYield = false;
|
||||
auto yield = [&]() { didYield = true; };
|
||||
|
||||
CountedYield cy (5, yield);
|
||||
|
||||
for (auto j = 0; j < 3; ++j)
|
||||
{
|
||||
for (auto i = 0; i < 4; ++i)
|
||||
{
|
||||
cy.yield();
|
||||
expect (!didYield, "We yielded when we shouldn't have.");
|
||||
}
|
||||
cy.yield();
|
||||
expect (didYield, "We didn't yield");
|
||||
didYield = false;
|
||||
}
|
||||
}
|
||||
|
||||
void run () override
|
||||
{
|
||||
chunkedYieldingTest();
|
||||
trivialCountedYieldTest();
|
||||
countedYieldTest();
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(Yield, ripple_basics, ripple);
|
||||
|
||||
} // RPC
|
||||
} // ripple
|
||||
Reference in New Issue
Block a user