rippled
Loading...
Searching...
No Matches
TER_test.cpp
1#include <xrpl/beast/unit_test.h>
2#include <xrpl/protocol/TER.h>
3
4#include <tuple>
5#include <type_traits>
6
7namespace xrpl {
8
10{
11 void
13 {
14 for (auto i = -400; i < 400; ++i)
15 {
16 TER const t = TER::fromInt(i);
17 auto inRange = isTelLocal(t) || isTemMalformed(t) || isTefFailure(t) || isTerRetry(t) ||
18 isTesSuccess(t) || isTecClaim(t);
19
20 std::string token, text;
21 auto good = transResultInfo(t, token, text);
22 BEAST_EXPECT(inRange || !good);
23 BEAST_EXPECT(transToken(t) == (good ? token : "-"));
24 BEAST_EXPECT(transHuman(t) == (good ? text : "-"));
25
26 auto code = transCode(token);
27 BEAST_EXPECT(good == !!code);
28 BEAST_EXPECT(!code || *code == t);
29 }
30 }
31
32 // Helper template that makes sure two types are not convertible or
33 // assignable if not the same.
34 // o I1 one tuple index.
35 // o I2 other tuple index.
36 // o Tup is expected to be a tuple.
37 // It's a functor, rather than a function template, since a class template
38 // can be a template argument without being full specified.
39 template <std::size_t I1, std::size_t I2>
41 {
42 public:
43 template <typename Tup>
44 void
45 operator()(Tup const& tup, beast::unit_test::suite&) const
46 {
47 // Entries in the tuple should not be convertible or assignable
48 // unless they are the same types.
49 using To_t = std::decay_t<decltype(std::get<I1>(tup))>;
50 using From_t = std::decay_t<decltype(std::get<I2>(tup))>;
51 static_assert(
53 "Convert err");
54 static_assert(
56 "Construct err");
57 static_assert(
60 "Assign err");
61
62 // Assignment or conversion from integer to type should never work.
63 static_assert(!std::is_convertible<int, To_t>::value, "Convert err");
64 static_assert(!std::is_constructible<To_t, int>::value, "Construct err");
65 static_assert(!std::is_assignable<To_t&, int const&>::value, "Assign err");
66 }
67 };
68
69 // Fast iteration over the tuple.
70 template <
71 std::size_t I1,
72 std::size_t I2,
73 template <std::size_t, std::size_t> class Func,
74 typename Tup>
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>
91 {
92 Func<I1, I2> const func;
93 func(tup, s);
94 testIterate<std::tuple_size<Tup>::value - 1, I2 - 1, Func>(tup, s);
95 }
96
97 // Finish iteration over the tuple.
98 template <
99 std::size_t I1,
100 std::size_t I2,
101 template <std::size_t, std::size_t> class Func,
102 typename Tup>
105 {
106 Func<I1, I2> const func;
107 func(tup, s);
108 }
109
110 void
112 {
113 // Verify that valid conversions are valid and invalid conversions
114 // are not valid.
115
116 // Examples of each kind of enum.
117 static auto const terEnums = std::make_tuple(
119 static int const hiIndex{std::tuple_size<decltype(terEnums)>::value - 1};
120
121 // Verify that enums cannot be converted to other enum types.
122 testIterate<hiIndex, hiIndex, NotConvertible>(terEnums, *this);
123
124 // Lambda that verifies assignability and convertibility.
125 auto isConvertible = [](auto from, auto to) {
126 using From_t = std::decay_t<decltype(from)>;
127 using To_t = std::decay_t<decltype(to)>;
128 static_assert(std::is_convertible<From_t, To_t>::value, "Convert err");
129 static_assert(std::is_constructible<To_t, From_t>::value, "Construct err");
130 static_assert(std::is_assignable<To_t&, From_t const&>::value, "Assign err");
131 };
132
133 // Verify the right types convert to NotTEC.
134 NotTEC const notTec;
135 isConvertible(telLOCAL_ERROR, notTec);
136 isConvertible(temMALFORMED, notTec);
137 isConvertible(tefFAILURE, notTec);
138 isConvertible(terRETRY, notTec);
139 isConvertible(tesSUCCESS, notTec);
140 isConvertible(notTec, notTec);
141
142 // Lambda that verifies types and not assignable or convertible.
143 auto notConvertible = [](auto from, auto to) {
144 using To_t = std::decay_t<decltype(to)>;
145 using From_t = std::decay_t<decltype(from)>;
146 static_assert(!std::is_convertible<From_t, To_t>::value, "Convert err");
147 static_assert(!std::is_constructible<To_t, From_t>::value, "Construct err");
148 static_assert(!std::is_assignable<To_t&, From_t const&>::value, "Assign err");
149 };
150
151 // Verify types that shouldn't convert to NotTEC.
152 TER const ter;
153 notConvertible(tecCLAIM, notTec);
154 notConvertible(ter, notTec);
155 notConvertible(4, notTec);
156
157 // Verify the right types convert to TER.
158 isConvertible(telLOCAL_ERROR, ter);
159 isConvertible(temMALFORMED, ter);
160 isConvertible(tefFAILURE, ter);
161 isConvertible(terRETRY, ter);
162 isConvertible(tesSUCCESS, ter);
163 isConvertible(tecCLAIM, ter);
164 isConvertible(notTec, ter);
165 isConvertible(ter, ter);
166
167 // Verify that you can't convert from int to ter.
168 notConvertible(4, ter);
169 }
170
171 // Helper template that makes sure two types are comparable. Also
172 // verifies that one of the types does not compare to int.
173 // o I1 one tuple index.
174 // o I2 other tuple index.
175 // o Tup is expected to be a tuple.
176 // It's a functor, rather than a function template, since a class template
177 // can be a template argument without being full specified.
178 template <std::size_t I1, std::size_t I2>
180 {
181 public:
182 template <typename Tup>
183 void
184 operator()(Tup const& tup, beast::unit_test::suite& s) const
185 {
186 // All entries in the tuple should be comparable one to the other.
187 auto const lhs = std::get<I1>(tup);
188 auto const rhs = std::get<I2>(tup);
189
190 static_assert(std::is_same<decltype(operator==(lhs, rhs)), bool>::value, "== err");
191
192 static_assert(std::is_same<decltype(operator!=(lhs, rhs)), bool>::value, "!= err");
193
194 static_assert(std::is_same<decltype(operator<(lhs, rhs)), bool>::value, "< err");
195
196 static_assert(std::is_same<decltype(operator<=(lhs, rhs)), bool>::value, "<= err");
197
198 static_assert(std::is_same<decltype(operator>(lhs, rhs)), bool>::value, "> err");
199
200 static_assert(std::is_same<decltype(operator>=(lhs, rhs)), bool>::value, ">= err");
201
202 // Make sure a sampling of TER types exhibit the expected behavior
203 // for all comparison operators.
204 s.expect((lhs == rhs) == (TERtoInt(lhs) == TERtoInt(rhs)));
205 s.expect((lhs != rhs) == (TERtoInt(lhs) != TERtoInt(rhs)));
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 }
211 };
212
213 void
215 {
216 // All of the TER-related types should be comparable.
217
218 // Examples of all the types we expect to successfully compare.
219 static auto const ters = std::make_tuple(
223 terRETRY,
225 tecCLAIM,
227 TER{tecCLAIM});
228 static int const hiIndex{std::tuple_size<decltype(ters)>::value - 1};
229
230 // Verify that all types in the ters tuple can be compared with all
231 // the other types in ters.
232 testIterate<hiIndex, hiIndex, CheckComparable>(ters, *this);
233 }
234
235 void
236 run() override
237 {
241 }
242};
243
244BEAST_DEFINE_TESTSUITE(TER, protocol, xrpl);
245
246} // namespace xrpl
A testsuite class.
Definition suite.h:51
bool expect(Condition const &shouldBeTrue)
Evaluate a test condition.
Definition suite.h:224
static constexpr TERSubset fromInt(int from)
Definition TER.h:413
void operator()(Tup const &tup, beast::unit_test::suite &s) const
Definition TER_test.cpp:184
void operator()(Tup const &tup, beast::unit_test::suite &) const
Definition TER_test.cpp:45
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:32
bool operator<(Slice const &lhs, Slice const &rhs) noexcept
Definition Slice.h:199
@ terRETRY
Definition TER.h:194
bool isTerRetry(TER x) noexcept
Definition TER.h:645
bool operator>=(STAmount const &lhs, STAmount const &rhs)
Definition STAmount.h:619
@ tefFAILURE
Definition TER.h:146
std::string transHuman(TER code)
Definition TER.cpp:252
bool transResultInfo(TER code, std::string &token, std::string &text)
Definition TER.cpp:228
std::string transToken(TER code)
Definition TER.cpp:243
constexpr bool operator==(base_uint< Bits, Tag > const &lhs, base_uint< Bits, Tag > const &rhs)
Definition base_uint.h:557
bool isTefFailure(TER x) noexcept
Definition TER.h:639
bool operator!=(Buffer const &lhs, Buffer const &rhs) noexcept
Definition Buffer.h:209
bool operator<=(STAmount const &lhs, STAmount const &rhs)
Definition STAmount.h:613
bool isTelLocal(TER x) noexcept
Definition TER.h:627
constexpr TERUnderlyingType TERtoInt(TELcodes v)
Definition TER.h:355
@ temMALFORMED
Definition TER.h:67
bool isTesSuccess(TER x) noexcept
Definition TER.h:651
std::optional< TER > transCode(std::string const &token)
Definition TER.cpp:261
@ tecCLAIM
Definition TER.h:262
bool isTecClaim(TER x) noexcept
Definition TER.h:658
bool isTemMalformed(TER x) noexcept
Definition TER.h:633
@ tesSUCCESS
Definition TER.h:225
void testTransResultInfo()
Definition TER_test.cpp:12
void testComparison()
Definition TER_test.cpp:214
void testConversion()
Definition TER_test.cpp:111
void run() override
Runs the suite.
Definition TER_test.cpp:236
std::enable_if_t< I1 !=0 > testIterate(Tup const &tup, beast::unit_test::suite &s)
Definition TER_test.cpp:76
std::enable_if_t< I1==0 &&I2 !=0 > testIterate(Tup const &tup, beast::unit_test::suite &s)
Definition TER_test.cpp:90
std::enable_if_t< I1==0 &&I2==0 > testIterate(Tup const &tup, beast::unit_test::suite &s)
Definition TER_test.cpp:104