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 t = TER::fromInt(i);
17 auto inRange = isTelLocal(t) || isTemMalformed(t) || isTefFailure(t) || isTerRetry(t) || isTesSuccess(t) ||
18 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))>;
52 static_assert(
54 static_assert(
56
57 // Assignment or conversion from integer to type should never work.
58 static_assert(!std::is_convertible<int, To_t>::value, "Convert err");
59 static_assert(!std::is_constructible<To_t, int>::value, "Construct err");
60 static_assert(!std::is_assignable<To_t&, int const&>::value, "Assign err");
61 }
62 };
63
64 // Fast iteration over the tuple.
65 template <std::size_t I1, std::size_t I2, template <std::size_t, std::size_t> class Func, typename Tup>
68 {
69 Func<I1, I2> func;
70 func(tup, s);
71 testIterate<I1 - 1, I2, Func>(tup, s);
72 }
73
74 // Slow iteration over the tuple.
75 template <std::size_t I1, std::size_t I2, template <std::size_t, std::size_t> class Func, typename Tup>
78 {
79 Func<I1, I2> func;
80 func(tup, s);
81 testIterate<std::tuple_size<Tup>::value - 1, I2 - 1, Func>(tup, s);
82 }
83
84 // Finish iteration over the tuple.
85 template <std::size_t I1, std::size_t I2, template <std::size_t, std::size_t> class Func, typename Tup>
88 {
89 Func<I1, I2> func;
90 func(tup, s);
91 }
92
93 void
95 {
96 // Verify that valid conversions are valid and invalid conversions
97 // are not valid.
98
99 // Examples of each kind of enum.
100 static auto const terEnums =
102 static int const hiIndex{std::tuple_size<decltype(terEnums)>::value - 1};
103
104 // Verify that enums cannot be converted to other enum types.
105 testIterate<hiIndex, hiIndex, NotConvertible>(terEnums, *this);
106
107 // Lambda that verifies assignability and convertibility.
108 auto isConvertible = [](auto from, auto to) {
109 using From_t = std::decay_t<decltype(from)>;
110 using To_t = std::decay_t<decltype(to)>;
111 static_assert(std::is_convertible<From_t, To_t>::value, "Convert err");
112 static_assert(std::is_constructible<To_t, From_t>::value, "Construct err");
113 static_assert(std::is_assignable<To_t&, From_t const&>::value, "Assign err");
114 };
115
116 // Verify the right types convert to NotTEC.
117 NotTEC const notTec;
118 isConvertible(telLOCAL_ERROR, notTec);
119 isConvertible(temMALFORMED, notTec);
120 isConvertible(tefFAILURE, notTec);
121 isConvertible(terRETRY, notTec);
122 isConvertible(tesSUCCESS, notTec);
123 isConvertible(notTec, notTec);
124
125 // Lambda that verifies types and not assignable or convertible.
126 auto notConvertible = [](auto from, auto to) {
127 using To_t = std::decay_t<decltype(to)>;
128 using From_t = std::decay_t<decltype(from)>;
129 static_assert(!std::is_convertible<From_t, To_t>::value, "Convert err");
130 static_assert(!std::is_constructible<To_t, From_t>::value, "Construct err");
131 static_assert(!std::is_assignable<To_t&, From_t const&>::value, "Assign err");
132 };
133
134 // Verify types that shouldn't convert to NotTEC.
135 TER const ter;
136 notConvertible(tecCLAIM, notTec);
137 notConvertible(ter, notTec);
138 notConvertible(4, notTec);
139
140 // Verify the right types convert to TER.
141 isConvertible(telLOCAL_ERROR, ter);
142 isConvertible(temMALFORMED, ter);
143 isConvertible(tefFAILURE, ter);
144 isConvertible(terRETRY, ter);
145 isConvertible(tesSUCCESS, ter);
146 isConvertible(tecCLAIM, ter);
147 isConvertible(notTec, ter);
148 isConvertible(ter, ter);
149
150 // Verify that you can't convert from int to ter.
151 notConvertible(4, ter);
152 }
153
154 // Helper template that makes sure two types are comparable. Also
155 // verifies that one of the types does not compare to int.
156 // o I1 one tuple index.
157 // o I2 other tuple index.
158 // o Tup is expected to be a tuple.
159 // It's a functor, rather than a function template, since a class template
160 // can be a template argument without being full specified.
161 template <std::size_t I1, std::size_t I2>
163 {
164 public:
165 template <typename Tup>
166 void
167 operator()(Tup const& tup, beast::unit_test::suite& s) const
168 {
169 // All entries in the tuple should be comparable one to the other.
170 auto const lhs = std::get<I1>(tup);
171 auto const rhs = std::get<I2>(tup);
172
173 static_assert(std::is_same<decltype(operator==(lhs, rhs)), bool>::value, "== err");
174
175 static_assert(std::is_same<decltype(operator!=(lhs, rhs)), bool>::value, "!= err");
176
177 static_assert(std::is_same<decltype(operator<(lhs, rhs)), bool>::value, "< err");
178
179 static_assert(std::is_same<decltype(operator<=(lhs, rhs)), bool>::value, "<= err");
180
181 static_assert(std::is_same<decltype(operator>(lhs, rhs)), bool>::value, "> err");
182
183 static_assert(std::is_same<decltype(operator>=(lhs, rhs)), bool>::value, ">= err");
184
185 // Make sure a sampling of TER types exhibit the expected behavior
186 // for all comparison operators.
187 s.expect((lhs == rhs) == (TERtoInt(lhs) == TERtoInt(rhs)));
188 s.expect((lhs != rhs) == (TERtoInt(lhs) != TERtoInt(rhs)));
189 s.expect((lhs < rhs) == (TERtoInt(lhs) < TERtoInt(rhs)));
190 s.expect((lhs <= rhs) == (TERtoInt(lhs) <= TERtoInt(rhs)));
191 s.expect((lhs > rhs) == (TERtoInt(lhs) > TERtoInt(rhs)));
192 s.expect((lhs >= rhs) == (TERtoInt(lhs) >= TERtoInt(rhs)));
193 }
194 };
195
196 void
198 {
199 // All of the TER-related types should be comparable.
200
201 // Examples of all the types we expect to successfully compare.
202 static auto const ters = std::make_tuple(
206 terRETRY,
208 tecCLAIM,
210 TER{tecCLAIM});
211 static int const hiIndex{std::tuple_size<decltype(ters)>::value - 1};
212
213 // Verify that all types in the ters tuple can be compared with all
214 // the other types in ters.
215 testIterate<hiIndex, hiIndex, CheckComparable>(ters, *this);
216 }
217
218 void
219 run() override
220 {
224 }
225};
226
227BEAST_DEFINE_TESTSUITE(TER, protocol, xrpl);
228
229} // namespace xrpl
A testsuite class.
Definition suite.h:52
bool expect(Condition const &shouldBeTrue)
Evaluate a test condition.
Definition suite.h:222
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:167
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:6
@ telLOCAL_ERROR
Definition TER.h:33
bool operator<(Slice const &lhs, Slice const &rhs) noexcept
Definition Slice.h:199
@ terRETRY
Definition TER.h:195
bool isTerRetry(TER x) noexcept
Definition TER.h:644
bool operator>=(STAmount const &lhs, STAmount const &rhs)
Definition STAmount.h:602
@ tefFAILURE
Definition TER.h:147
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:553
bool isTefFailure(TER x) noexcept
Definition TER.h:638
bool operator!=(Buffer const &lhs, Buffer const &rhs) noexcept
Definition Buffer.h:210
bool operator<=(STAmount const &lhs, STAmount const &rhs)
Definition STAmount.h:596
bool isTelLocal(TER x) noexcept
Definition TER.h:626
constexpr TERUnderlyingType TERtoInt(TELcodes v)
Definition TER.h:356
@ temMALFORMED
Definition TER.h:68
bool isTesSuccess(TER x) noexcept
Definition TER.h:650
std::optional< TER > transCode(std::string const &token)
Definition TER.cpp:261
@ tecCLAIM
Definition TER.h:263
bool isTecClaim(TER x) noexcept
Definition TER.h:657
bool isTemMalformed(TER x) noexcept
Definition TER.h:632
@ tesSUCCESS
Definition TER.h:226
void testTransResultInfo()
Definition TER_test.cpp:12
void testComparison()
Definition TER_test.cpp:197
void testConversion()
Definition TER_test.cpp:94
void run() override
Runs the suite.
Definition TER_test.cpp:219
std::enable_if_t< I1 !=0 > testIterate(Tup const &tup, beast::unit_test::suite &s)
Definition TER_test.cpp:67
std::enable_if_t< I1==0 &&I2 !=0 > testIterate(Tup const &tup, beast::unit_test::suite &s)
Definition TER_test.cpp:77
std::enable_if_t< I1==0 &&I2==0 > testIterate(Tup const &tup, beast::unit_test::suite &s)
Definition TER_test.cpp:87