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 ripple {
8
10{
11 void
13 {
14 for (auto i = -400; i < 400; ++i)
15 {
16 TER t = TER::fromInt(i);
17 auto inRange = isTelLocal(t) || isTemMalformed(t) ||
18 isTefFailure(t) || isTerRetry(t) || isTesSuccess(t) ||
19 isTecClaim(t);
20
21 std::string token, text;
22 auto good = transResultInfo(t, token, text);
23 BEAST_EXPECT(inRange || !good);
24 BEAST_EXPECT(transToken(t) == (good ? token : "-"));
25 BEAST_EXPECT(transHuman(t) == (good ? text : "-"));
26
27 auto code = transCode(token);
28 BEAST_EXPECT(good == !!code);
29 BEAST_EXPECT(!code || *code == t);
30 }
31 }
32
33 // Helper template that makes sure two types are not convertible or
34 // assignable if not the same.
35 // o I1 one tuple index.
36 // o I2 other tuple index.
37 // o Tup is expected to be a tuple.
38 // It's a functor, rather than a function template, since a class template
39 // can be a template argument without being full specified.
40 template <std::size_t I1, std::size_t I2>
42 {
43 public:
44 template <typename Tup>
45 void
46 operator()(Tup const& tup, beast::unit_test::suite&) const
47 {
48 // Entries in the tuple should not be convertible or assignable
49 // unless they are the same types.
50 using To_t = std::decay_t<decltype(std::get<I1>(tup))>;
51 using From_t = std::decay_t<decltype(std::get<I2>(tup))>;
52 static_assert(
55 "Convert err");
56 static_assert(
59 "Construct err");
60 static_assert(
63 "Assign err");
64
65 // Assignment or conversion from integer to type should never work.
66 static_assert(
68 static_assert(
70 static_assert(
72 }
73 };
74
75 // Fast iteration over the tuple.
76 template <
77 std::size_t I1,
78 std::size_t I2,
79 template <std::size_t, std::size_t>
80 class Func,
81 typename Tup>
84 {
85 Func<I1, I2> func;
86 func(tup, s);
87 testIterate<I1 - 1, I2, Func>(tup, s);
88 }
89
90 // Slow iteration over the tuple.
91 template <
92 std::size_t I1,
93 std::size_t I2,
94 template <std::size_t, std::size_t>
95 class Func,
96 typename Tup>
99 {
100 Func<I1, I2> func;
101 func(tup, s);
102 testIterate<std::tuple_size<Tup>::value - 1, I2 - 1, Func>(tup, s);
103 }
104
105 // Finish iteration over the tuple.
106 template <
107 std::size_t I1,
108 std::size_t I2,
109 template <std::size_t, std::size_t>
110 class Func,
111 typename Tup>
114 {
115 Func<I1, I2> func;
116 func(tup, s);
117 }
118
119 void
121 {
122 // Verify that valid conversions are valid and invalid conversions
123 // are not valid.
124
125 // Examples of each kind of enum.
126 static auto const terEnums = std::make_tuple(
130 terRETRY,
132 tecCLAIM);
133 static int const hiIndex{
134 std::tuple_size<decltype(terEnums)>::value - 1};
135
136 // Verify that enums cannot be converted to other enum types.
137 testIterate<hiIndex, hiIndex, NotConvertible>(terEnums, *this);
138
139 // Lambda that verifies assignability and convertibility.
140 auto isConvertable = [](auto from, auto to) {
141 using From_t = std::decay_t<decltype(from)>;
142 using To_t = std::decay_t<decltype(to)>;
143 static_assert(
145 static_assert(
147 static_assert(
149 };
150
151 // Verify the right types convert to NotTEC.
152 NotTEC const notTec;
153 isConvertable(telLOCAL_ERROR, notTec);
154 isConvertable(temMALFORMED, notTec);
155 isConvertable(tefFAILURE, notTec);
156 isConvertable(terRETRY, notTec);
157 isConvertable(tesSUCCESS, notTec);
158 isConvertable(notTec, notTec);
159
160 // Lambda that verifies types and not assignable or convertible.
161 auto notConvertible = [](auto from, auto to) {
162 using To_t = std::decay_t<decltype(to)>;
163 using From_t = std::decay_t<decltype(from)>;
164 static_assert(
166 static_assert(
168 static_assert(
170 };
171
172 // Verify types that shouldn't convert to NotTEC.
173 TER const ter;
174 notConvertible(tecCLAIM, notTec);
175 notConvertible(ter, notTec);
176 notConvertible(4, notTec);
177
178 // Verify the right types convert to TER.
179 isConvertable(telLOCAL_ERROR, ter);
180 isConvertable(temMALFORMED, ter);
181 isConvertable(tefFAILURE, ter);
182 isConvertable(terRETRY, ter);
183 isConvertable(tesSUCCESS, ter);
184 isConvertable(tecCLAIM, ter);
185 isConvertable(notTec, ter);
186 isConvertable(ter, ter);
187
188 // Verify that you can't convert from int to ter.
189 notConvertible(4, ter);
190 }
191
192 // Helper template that makes sure two types are comparable. Also
193 // verifies that one of the types does not compare to int.
194 // o I1 one tuple index.
195 // o I2 other tuple index.
196 // o Tup is expected to be a tuple.
197 // It's a functor, rather than a function template, since a class template
198 // can be a template argument without being full specified.
199 template <std::size_t I1, std::size_t I2>
201 {
202 public:
203 template <typename Tup>
204 void
205 operator()(Tup const& tup, beast::unit_test::suite& s) const
206 {
207 // All entries in the tuple should be comparable one to the other.
208 auto const lhs = std::get<I1>(tup);
209 auto const rhs = std::get<I2>(tup);
210
211 static_assert(
212 std::is_same<decltype(operator==(lhs, rhs)), bool>::value,
213 "== err");
214
215 static_assert(
216 std::is_same<decltype(operator!=(lhs, rhs)), bool>::value,
217 "!= err");
218
219 static_assert(
220 std::is_same<decltype(operator<(lhs, rhs)), bool>::value,
221 "< err");
222
223 static_assert(
224 std::is_same<decltype(operator<=(lhs, rhs)), bool>::value,
225 "<= err");
226
227 static_assert(
228 std::is_same<decltype(operator>(lhs, rhs)), bool>::value,
229 "> err");
230
231 static_assert(
232 std::is_same<decltype(operator>=(lhs, rhs)), bool>::value,
233 ">= err");
234
235 // Make sure a sampling of TER types exhibit the expected behavior
236 // for all comparison operators.
237 s.expect((lhs == rhs) == (TERtoInt(lhs) == TERtoInt(rhs)));
238 s.expect((lhs != rhs) == (TERtoInt(lhs) != TERtoInt(rhs)));
239 s.expect((lhs < rhs) == (TERtoInt(lhs) < TERtoInt(rhs)));
240 s.expect((lhs <= rhs) == (TERtoInt(lhs) <= TERtoInt(rhs)));
241 s.expect((lhs > rhs) == (TERtoInt(lhs) > TERtoInt(rhs)));
242 s.expect((lhs >= rhs) == (TERtoInt(lhs) >= TERtoInt(rhs)));
243 }
244 };
245
246 void
248 {
249 // All of the TER-related types should be comparable.
250
251 // Examples of all the types we expect to successfully compare.
252 static auto const ters = std::make_tuple(
256 terRETRY,
258 tecCLAIM,
260 TER{tecCLAIM});
261 static int const hiIndex{std::tuple_size<decltype(ters)>::value - 1};
262
263 // Verify that all types in the ters tuple can be compared with all
264 // the other types in ters.
265 testIterate<hiIndex, hiIndex, CheckComparable>(ters, *this);
266 }
267
268 void
269 run() override
270 {
274 }
275};
276
277BEAST_DEFINE_TESTSUITE(TER, protocol, ripple);
278
279} // namespace ripple
A testsuite class.
Definition suite.h:52
bool expect(Condition const &shouldBeTrue)
Evaluate a test condition.
Definition suite.h:226
static constexpr TERSubset fromInt(int from)
Definition TER.h:414
void operator()(Tup const &tup, beast::unit_test::suite &s) const
Definition TER_test.cpp:205
void operator()(Tup const &tup, beast::unit_test::suite &) const
Definition TER_test.cpp:46
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:6
bool operator<=(STAmount const &lhs, STAmount const &rhs)
Definition STAmount.h:610
std::string transHuman(TER code)
Definition TER.cpp:254
bool operator!=(Buffer const &lhs, Buffer const &rhs) noexcept
Definition Buffer.h:213
@ telLOCAL_ERROR
Definition TER.h:33
@ tefFAILURE
Definition TER.h:147
bool isTefFailure(TER x) noexcept
Definition TER.h:647
std::string transToken(TER code)
Definition TER.cpp:245
@ tecCLAIM
Definition TER.h:263
bool isTerRetry(TER x) noexcept
Definition TER.h:653
@ tesSUCCESS
Definition TER.h:226
bool operator<(Slice const &lhs, Slice const &rhs) noexcept
Definition Slice.h:204
bool isTesSuccess(TER x) noexcept
Definition TER.h:659
constexpr TERUnderlyingType TERtoInt(TELcodes v)
Definition TER.h:356
bool isTemMalformed(TER x) noexcept
Definition TER.h:641
constexpr bool operator==(base_uint< Bits, Tag > const &lhs, base_uint< Bits, Tag > const &rhs)
Definition base_uint.h:566
@ terRETRY
Definition TER.h:195
bool transResultInfo(TER code, std::string &token, std::string &text)
Definition TER.cpp:230
bool operator>=(STAmount const &lhs, STAmount const &rhs)
Definition STAmount.h:616
bool isTecClaim(TER x) noexcept
Definition TER.h:666
bool isTelLocal(TER x) noexcept
Definition TER.h:635
std::optional< TER > transCode(std::string const &token)
Definition TER.cpp:263
@ temMALFORMED
Definition TER.h:68
void testTransResultInfo()
Definition TER_test.cpp:12
void testComparison()
Definition TER_test.cpp:247
std::enable_if_t< I1==0 &&I2 !=0 > testIterate(Tup const &tup, beast::unit_test::suite &s)
Definition TER_test.cpp:98
void testConversion()
Definition TER_test.cpp:120
std::enable_if_t< I1 !=0 > testIterate(Tup const &tup, beast::unit_test::suite &s)
Definition TER_test.cpp:83
void run() override
Runs the suite.
Definition TER_test.cpp:269
std::enable_if_t< I1==0 &&I2==0 > testIterate(Tup const &tup, beast::unit_test::suite &s)
Definition TER_test.cpp:113