diff --git a/src/ripple/test/jtx/amount.h b/src/ripple/test/jtx/amount.h index 460330178..71d464fcc 100644 --- a/src/ripple/test/jtx/amount.h +++ b/src/ripple/test/jtx/amount.h @@ -143,7 +143,21 @@ operator<< (std::ostream& os, //------------------------------------------------------------------------------ -namespace detail { +// Specifies an order book +struct BookSpec +{ + AccountID account; + ripple::Currency currency; + + BookSpec(AccountID const& account_, + ripple::Currency const& currency_) + : account(account_) + , currency(currency_) + { + } +}; + +//------------------------------------------------------------------------------ struct XRP_t { @@ -202,9 +216,15 @@ struct XRP_t { return { xrpIssue() }; } -}; -} // detail + friend + BookSpec + operator~ (XRP_t const&) + { + return BookSpec( xrpAccount(), + xrpCurrency() ); + } +}; /** Converts to XRP Issue or STAmount. @@ -212,7 +232,7 @@ struct XRP_t XRP Converts to the XRP Issue XRP(10) Returns STAmount of 10 XRP */ -extern detail::XRP_t const XRP; +extern XRP_t const XRP; /** Returns an XRP STAmount. @@ -264,28 +284,21 @@ static epsilon_t const epsilon; */ class IOU { -private: - Account account_; - ripple::Currency currency_; - public: - IOU(Account const& account, - ripple::Currency const& currency) - : account_(account) - , currency_(currency) - { - } + Account account; + ripple::Currency currency; - Account - account() const + IOU(Account const& account_, + ripple::Currency const& currency_) + : account(account_) + , currency(currency_) { - return account_; } Issue issue() const { - return { currency_, account_.id() }; + return { currency, account.id() }; } /** Implicit conversion to Issue. @@ -306,7 +319,7 @@ public: // VFALCO NOTE Should throw if the // representation of v is not exact. return { amountFromString(issue(), - std::to_string(v)), account_.name() }; + std::to_string(v)), account.name() }; } PrettyAmount operator()(epsilon_t) const; @@ -320,6 +333,13 @@ public: { return { issue() }; } + + friend + BookSpec + operator~ (IOU const& iou) + { + return BookSpec(iou.account.id(), iou.currency); + } }; std::ostream& diff --git a/src/ripple/test/jtx/impl/Env_test.cpp b/src/ripple/test/jtx/impl/Env_test.cpp index a40e904b6..fa6a42e62 100644 --- a/src/ripple/test/jtx/impl/Env_test.cpp +++ b/src/ripple/test/jtx/impl/Env_test.cpp @@ -542,6 +542,25 @@ public: env(noop("bob")); } + void + testPath() + { + using namespace jtx; + Env env(*this); + auto const gw = Account("gw"); + auto const USD = gw["USD"]; + env.fund(XRP(10000), "alice", "bob"); + env.json( + pay("alice", "bob", USD(10)), + path(Account("alice")), + path("bob"), + path(USD), + path(~XRP), + path(~USD), + path("bob", USD, ~XRP, ~USD) + ); + } + void run() { @@ -560,6 +579,7 @@ public: testMemo(); testAdvance(); testClose(); + testPath(); } }; diff --git a/src/ripple/test/jtx/impl/amount.cpp b/src/ripple/test/jtx/impl/amount.cpp index 4275a4e46..a18eb652f 100644 --- a/src/ripple/test/jtx/impl/amount.cpp +++ b/src/ripple/test/jtx/impl/amount.cpp @@ -107,13 +107,13 @@ operator<< (std::ostream& os, //------------------------------------------------------------------------------ -detail::XRP_t const XRP { }; +XRP_t const XRP {}; PrettyAmount IOU::operator()(epsilon_t) const { return { STAmount(issue(), 1, -81), - account_.name() }; + account.name() }; } PrettyAmount @@ -121,7 +121,7 @@ IOU::operator()(detail::epsilon_multiple m) const { return { STAmount(issue(), static_cast(m.n), -81), - account_.name() }; + account.name() }; } std::ostream& @@ -130,7 +130,7 @@ operator<<(std::ostream& os, { os << to_string(iou.issue().currency) << - "(" << iou.account().name() << ")"; + "(" << iou.account.name() << ")"; return os; } diff --git a/src/ripple/test/jtx/impl/paths.cpp b/src/ripple/test/jtx/impl/paths.cpp index 7a3ff397c..bad2a95e5 100644 --- a/src/ripple/test/jtx/impl/paths.cpp +++ b/src/ripple/test/jtx/impl/paths.cpp @@ -49,6 +49,43 @@ paths::operator()(Env const& env, JTx& jt) const jv[jss::Paths] = ps.getJson(0); } +//------------------------------------------------------------------------------ + +Json::Value& +path::create() +{ + return jv_.append(Json::objectValue); +} + +void +path::append_one(Account const& account) +{ + auto& jv = create(); + jv["account"] = toBase58(account.id()); +} + +void +path::append_one(IOU const& iou) +{ + auto& jv = create(); + jv["currency"] = to_string(iou.issue().currency); + jv["account"] = toBase58(iou.issue().account); +} + +void +path::append_one(BookSpec const& book) +{ + auto& jv = create(); + jv["currency"] = to_string(book.currency); + jv["issuer"] = toBase58(book.account); +} + +void +path::operator()(Env const& env, JTx& jt) const +{ + jt.jv["Paths"].append(jv_); +} + } // jtx } // test } // ripple diff --git a/src/ripple/test/jtx/paths.h b/src/ripple/test/jtx/paths.h index 43b57fd6e..ed80b0f83 100644 --- a/src/ripple/test/jtx/paths.h +++ b/src/ripple/test/jtx/paths.h @@ -22,6 +22,7 @@ #include #include +#include // namespace ripple { namespace test { @@ -45,9 +46,77 @@ public: } void - operator()(Env const&, JTx& jtx) const; + operator()(Env const&, JTx& jt) const; }; +//------------------------------------------------------------------------------ + +/** Add a path. + + If no paths are present, a new one is created. +*/ +class path +{ +private: + Json::Value jv_; + +public: + path(); + + template + explicit + path (T const& t, Args const&... args); + + void + operator()(Env const&, JTx& jt) const; + +private: + Json::Value& + create(); + + void + append_one(Account const& account); + + template + std::enable_if_t< + std::is_constructible::value> + append_one(T const& t) + { + append_one(Account{ t }); + } + + void + append_one(IOU const& iou); + + void + append_one(BookSpec const& book); + + inline + void + append() + { + } + + template + void + append (T const& t, Args const&... args); +}; + +template +path::path (T const& t, Args const&... args) + : jv_(Json::arrayValue) +{ + append(t, args...); +} + +template +void +path::append (T const& t, Args const&... args) +{ + append_one(t); + append(args...); +} + } // jtx } // test } // ripple