xrpld
Loading...
Searching...
No Matches
TER_test.cpp
1#include <xrpl/beast/unit_test/suite.h>
2#include <xrpl/protocol/TER.h>
3
4#include <cstddef>
5#include <string>
6#include <tuple>
7#include <type_traits>
8
9namespace xrpl {
10
12{
13 void
15 {
16 for (auto i = -400; i < 400; ++i)
17 {
18 TER const t = TER::fromInt(i);
19 auto inRange = isTelLocal(t) || isTemMalformed(t) || isTefFailure(t) || isTerRetry(t) ||
20 isTesSuccess(t) || isTecClaim(t);
21
22 std::string token, text;
23 auto good = transResultInfo(t, token, text);
24 BEAST_EXPECT(inRange || !good);
25 BEAST_EXPECT(transToken(t) == (good ? token : "-"));
26 BEAST_EXPECT(transHuman(t) == (good ? text : "-"));
27
28 auto code = transCode(token);
29 BEAST_EXPECT(good == !!code);
30 BEAST_EXPECT(!code || *code == t);
31 }
32 }
33
34 // Helper template that makes sure two types are not convertible or
35 // assignable if not the same.
36 // o I1 one tuple index.
37 // o I2 other tuple index.
38 // o Tup is expected to be a tuple.
39 // It's a functor, rather than a function template, since a class template
40 // can be a template argument without being full specified.
41 template <std::size_t I1, std::size_t I2>
43 {
44 public:
45 template <typename Tup>
46 void
47 operator()(Tup const& tup, beast::unit_test::Suite&) const
48 {
49 // Entries in the tuple should not be convertible or assignable
50 // unless they are the same types.
51 using ToT = std::decay_t<decltype(std::get<I1>(tup))>;
52 using FromT = std::decay_t<decltype(std::get<I2>(tup))>;
53 static_assert(
55 static_assert(
57 static_assert(
59 "Assign err");
60
61 // Assignment or conversion from integer to type should never work.
62 static_assert(!std::is_convertible_v<int, ToT>, "Convert err");
63 static_assert(!std::is_constructible_v<ToT, int>, "Construct err");
64 static_assert(!std::is_assignable_v<ToT&, int const&>, "Assign err");
65 }
66 };
67
68 // Fast iteration over the tuple.
69 template <
70 std::size_t I1,
71 std::size_t I2,
72 template <std::size_t, std::size_t> class Func,
73 typename Tup>
74 void
76 requires(I1 != 0)
77 {
78 Func<I1, I2> const func;
79 func(tup, s);
80 testIterate<I1 - 1, I2, Func>(tup, s);
81 }
82
83 // Slow iteration over the tuple.
84 template <
85 std::size_t I1,
86 std::size_t I2,
87 template <std::size_t, std::size_t> class Func,
88 typename Tup>
89 void
91 requires(I1 == 0 && I2 != 0)
92 {
93 Func<I1, I2> const func;
94 func(tup, s);
95 testIterate<std::tuple_size_v<Tup> - 1, I2 - 1, Func>(tup, s);
96 }
97
98 // Finish iteration over the tuple.
99 template <
100 std::size_t I1,
101 std::size_t I2,
102 template <std::size_t, std::size_t> class Func,
103 typename Tup>
104 void
106 requires(I1 == 0 && I2 == 0)
107 {
108 Func<I1, I2> const func;
109 func(tup, s);
110 }
111
112 void
114 {
115 // Verify that valid conversions are valid and invalid conversions
116 // are not valid.
117
118 // Examples of each kind of enum.
119 static auto const kTerEnums = std::make_tuple(
121 static int const kHiIndex{std::tuple_size_v<decltype(kTerEnums)> - 1};
122
123 // Verify that enums cannot be converted to other enum types.
125
126 // Lambda that verifies assignability and convertibility.
127 auto isConvertible = [](auto from, auto to) {
128 using FromT = std::decay_t<decltype(from)>;
129 using ToT = std::decay_t<decltype(to)>;
130 static_assert(std::is_convertible_v<FromT, ToT>, "Convert err");
131 static_assert(std::is_constructible_v<ToT, FromT>, "Construct err");
132 static_assert(std::is_assignable_v<ToT&, FromT const&>, "Assign err");
133 };
134
135 // Verify the right types convert to NotTEC.
136 NotTEC const notTec;
137 isConvertible(telLOCAL_ERROR, notTec);
138 isConvertible(temMALFORMED, notTec);
139 isConvertible(tefFAILURE, notTec);
140 isConvertible(terRETRY, notTec);
141 isConvertible(tesSUCCESS, notTec);
142 isConvertible(notTec, notTec);
143
144 // Lambda that verifies types and not assignable or convertible.
145 auto notConvertible = [](auto from, auto to) {
146 using ToT = std::decay_t<decltype(to)>;
147 using FromT = std::decay_t<decltype(from)>;
148 static_assert(!std::is_convertible_v<FromT, ToT>, "Convert err");
149 static_assert(!std::is_constructible_v<ToT, FromT>, "Construct err");
150 static_assert(!std::is_assignable_v<ToT&, FromT const&>, "Assign err");
151 };
152
153 // Verify types that shouldn't convert to NotTEC.
154 TER const ter;
155 notConvertible(tecCLAIM, notTec);
156 notConvertible(ter, notTec);
157 notConvertible(4, notTec);
158
159 // Verify the right types convert to TER.
160 isConvertible(telLOCAL_ERROR, ter);
161 isConvertible(temMALFORMED, ter);
162 isConvertible(tefFAILURE, ter);
163 isConvertible(terRETRY, ter);
164 isConvertible(tesSUCCESS, ter);
165 isConvertible(tecCLAIM, ter);
166 isConvertible(notTec, ter);
167 isConvertible(ter, ter);
168
169 // Verify that you can't convert from int to ter.
170 notConvertible(4, ter);
171 }
172
173 // Helper template that makes sure two types are comparable. Also
174 // verifies that one of the types does not compare to int.
175 // o I1 one tuple index.
176 // o I2 other tuple index.
177 // o Tup is expected to be a tuple.
178 // It's a functor, rather than a function template, since a class template
179 // can be a template argument without being full specified.
180 template <std::size_t I1, std::size_t I2>
182 {
183 public:
184 template <typename Tup>
185 void
186 operator()(Tup const& tup, beast::unit_test::Suite& s) const
187 {
188 // All entries in the tuple should be comparable one to the other.
189 auto const lhs = std::get<I1>(tup);
190 auto const rhs = std::get<I2>(tup);
191
192 static_assert(std::is_same_v<decltype(operator==(lhs, rhs)), bool>, "== err");
193
194 static_assert(std::is_same_v<decltype(operator!=(lhs, rhs)), bool>, "!= err");
195
196 static_assert(std::is_same_v<decltype(operator<(lhs, rhs)), bool>, "< err");
197
198 static_assert(std::is_same_v<decltype(operator<=(lhs, rhs)), bool>, "<= err");
199
200 static_assert(std::is_same_v<decltype(operator>(lhs, rhs)), bool>, "> err");
201
202 static_assert(std::is_same_v<decltype(operator>=(lhs, rhs)), bool>, ">= err");
203
204 // Make sure a sampling of TER types exhibit the expected behavior
205 // for all comparison operators.
206 s.expect((lhs == rhs) == (TERtoInt(lhs) == TERtoInt(rhs)));
207 s.expect((lhs != rhs) == (TERtoInt(lhs) != TERtoInt(rhs)));
208 s.expect((lhs < rhs) == (TERtoInt(lhs) < TERtoInt(rhs)));
209 s.expect((lhs <= rhs) == (TERtoInt(lhs) <= TERtoInt(rhs)));
210 s.expect((lhs > rhs) == (TERtoInt(lhs) > TERtoInt(rhs)));
211 s.expect((lhs >= rhs) == (TERtoInt(lhs) >= TERtoInt(rhs)));
212 }
213 };
214
215 void
217 {
218 // All of the TER-related types should be comparable.
219
220 // Examples of all the types we expect to successfully compare.
221 static auto const kTers = std::make_tuple(
225 terRETRY,
227 tecCLAIM,
229 TER{tecCLAIM});
230 static int const kHiIndex{std::tuple_size_v<decltype(kTers)> - 1};
231
232 // Verify that all types in the ters tuple can be compared with all
233 // the other types in ters.
235 }
236
237 void
238 run() override
239 {
243 }
244};
245
247
248} // namespace xrpl
A testsuite class.
Definition suite.h:52
bool expect(Condition const &shouldBeTrue)
Evaluate a test condition.
Definition suite.h:235
static constexpr TERSubset fromInt(int from)
Definition TER.h:444
void operator()(Tup const &tup, beast::unit_test::Suite &s) const
Definition TER_test.cpp:186
void operator()(Tup const &tup, beast::unit_test::Suite &) const
Definition TER_test.cpp:47
T is_assignable_v
T is_constructible_v
T is_convertible_v
T is_same_v
T make_tuple(T... args)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
@ telLOCAL_ERROR
Definition TER.h:38
bool operator<(Slice const &lhs, Slice const &rhs) noexcept
Definition Slice.h:212
@ terRETRY
Definition TER.h:215
bool isTerRetry(TER x) noexcept
Definition TER.h:677
constexpr bool operator==(BaseUInt< Bits, Tag > const &lhs, BaseUInt< Bits, Tag > const &rhs)
Definition base_uint.h:612
bool operator>=(STAmount const &lhs, STAmount const &rhs)
Definition STAmount.h:658
@ tefFAILURE
Definition TER.h:161
std::string transHuman(TER code)
Definition TER.cpp:266
bool transResultInfo(TER code, std::string &token, std::string &text)
Definition TER.cpp:242
std::string transToken(TER code)
Definition TER.cpp:257
bool operator!=(SecretKey const &lhs, SecretKey const &rhs)=delete
TERSubset< CanCvtToNotTEC > NotTEC
Definition TER.h:614
bool isTefFailure(TER x) noexcept
Definition TER.h:671
bool operator<=(STAmount const &lhs, STAmount const &rhs)
Definition STAmount.h:652
bool isTelLocal(TER x) noexcept
Definition TER.h:659
constexpr TERUnderlyingType TERtoInt(TELcodes v)
Definition TER.h:386
@ temMALFORMED
Definition TER.h:75
bool isTesSuccess(TER x) noexcept
Definition TER.h:683
TERSubset< CanCvtToTER > TER
Definition TER.h:654
std::optional< TER > transCode(std::string const &token)
Definition TER.cpp:275
@ tecCLAIM
Definition TER.h:289
bool isTecClaim(TER x) noexcept
Definition TER.h:690
BEAST_DEFINE_TESTSUITE(AccountTxPaging, app, xrpl)
bool isTemMalformed(TER x) noexcept
Definition TER.h:665
@ tesSUCCESS
Definition TER.h:250
void testIterate(Tup const &tup, beast::unit_test::Suite &s)
Definition TER_test.cpp:90
void testTransResultInfo()
Definition TER_test.cpp:14
void testComparison()
Definition TER_test.cpp:216
void testConversion()
Definition TER_test.cpp:113
void testIterate(Tup const &tup, beast::unit_test::Suite &s)
Definition TER_test.cpp:105
void testIterate(Tup const &tup, beast::unit_test::Suite &s)
Definition TER_test.cpp:75
void run() override
Runs the suite.
Definition TER_test.cpp:238
T tuple_size_v