rippled
Loading...
Searching...
No Matches
Quality_test.cpp
1#include <xrpl/beast/unit_test.h>
2#include <xrpl/protocol/Quality.h>
3
4#include <type_traits>
5
6namespace xrpl {
7
9{
10public:
11 // Create a raw, non-integral amount from mantissa and exponent
12 STAmount static raw(std::uint64_t mantissa, int exponent)
13 {
14 return STAmount(Issue{Currency(3), AccountID(3)}, mantissa, exponent);
15 }
16
17 template <class Integer>
18 static STAmount
20 {
21 static_assert(std::is_integral<Integer>::value, "");
22 return STAmount(integer, false);
23 }
24
25 template <class Integer>
26 static STAmount
28 {
29 static_assert(std::is_integral<Integer>::value, "");
30 if (integer < 0)
31 return STAmount(-integer, true);
32 return STAmount(integer, false);
33 }
34
35 template <class In, class Out>
36 static Amounts
37 amounts(In in, Out out)
38 {
39 return Amounts(amount(in), amount(out));
40 }
41
42 template <class In1, class Out1, class Int, class In2, class Out2>
43 void
44 ceil_in(Quality const& q, In1 in, Out1 out, Int limit, In2 in_expected, Out2 out_expected)
45 {
46 auto expect_result(amounts(in_expected, out_expected));
47 auto actual_result(q.ceil_in(amounts(in, out), amount(limit)));
48
49 BEAST_EXPECT(actual_result == expect_result);
50 }
51
52 template <class In1, class Out1, class Int, class In2, class Out2>
53 void
54 ceil_out(Quality const& q, In1 in, Out1 out, Int limit, In2 in_expected, Out2 out_expected)
55 {
56 auto const expect_result(amounts(in_expected, out_expected));
57 auto const actual_result(q.ceil_out(amounts(in, out), amount(limit)));
58
59 BEAST_EXPECT(actual_result == expect_result);
60 }
61
62 void
64 {
65 testcase("ceil_in");
66
67 {
68 // 1 in, 1 out:
69 Quality q(Amounts(amount(1), amount(1)));
70
71 ceil_in(
72 q,
73 1,
74 1, // 1 in, 1 out
75 1, // limit: 1
76 1,
77 1); // 1 in, 1 out
78
79 ceil_in(
80 q,
81 10,
82 10, // 10 in, 10 out
83 5, // limit: 5
84 5,
85 5); // 5 in, 5 out
86
87 ceil_in(
88 q,
89 5,
90 5, // 5 in, 5 out
91 10, // limit: 10
92 5,
93 5); // 5 in, 5 out
94 }
95
96 {
97 // 1 in, 2 out:
98 Quality q(Amounts(amount(1), amount(2)));
99
100 ceil_in(
101 q,
102 40,
103 80, // 40 in, 80 out
104 40, // limit: 40
105 40,
106 80); // 40 in, 20 out
107
108 ceil_in(
109 q,
110 40,
111 80, // 40 in, 80 out
112 20, // limit: 20
113 20,
114 40); // 20 in, 40 out
115
116 ceil_in(
117 q,
118 40,
119 80, // 40 in, 80 out
120 60, // limit: 60
121 40,
122 80); // 40 in, 80 out
123 }
124
125 {
126 // 2 in, 1 out:
127 Quality q(Amounts(amount(2), amount(1)));
128
129 ceil_in(
130 q,
131 40,
132 20, // 40 in, 20 out
133 20, // limit: 20
134 20,
135 10); // 20 in, 10 out
136
137 ceil_in(
138 q,
139 40,
140 20, // 40 in, 20 out
141 40, // limit: 40
142 40,
143 20); // 40 in, 20 out
144
145 ceil_in(
146 q,
147 40,
148 20, // 40 in, 20 out
149 50, // limit: 40
150 40,
151 20); // 40 in, 20 out
152 }
153 }
154
155 void
157 {
158 testcase("ceil_out");
159
160 {
161 // 1 in, 1 out:
162 Quality q(Amounts(amount(1), amount(1)));
163
164 ceil_out(
165 q,
166 1,
167 1, // 1 in, 1 out
168 1, // limit 1
169 1,
170 1); // 1 in, 1 out
171
172 ceil_out(
173 q,
174 10,
175 10, // 10 in, 10 out
176 5, // limit 5
177 5,
178 5); // 5 in, 5 out
179
180 ceil_out(
181 q,
182 10,
183 10, // 10 in, 10 out
184 20, // limit 20
185 10,
186 10); // 10 in, 10 out
187 }
188
189 {
190 // 1 in, 2 out:
191 Quality q(Amounts(amount(1), amount(2)));
192
193 ceil_out(
194 q,
195 40,
196 80, // 40 in, 80 out
197 40, // limit 40
198 20,
199 40); // 20 in, 40 out
200
201 ceil_out(
202 q,
203 40,
204 80, // 40 in, 80 out
205 80, // limit 80
206 40,
207 80); // 40 in, 80 out
208
209 ceil_out(
210 q,
211 40,
212 80, // 40 in, 80 out
213 100, // limit 100
214 40,
215 80); // 40 in, 80 out
216 }
217
218 {
219 // 2 in, 1 out:
220 Quality q(Amounts(amount(2), amount(1)));
221
222 ceil_out(
223 q,
224 40,
225 20, // 40 in, 20 out
226 20, // limit 20
227 40,
228 20); // 40 in, 20 out
229
230 ceil_out(
231 q,
232 40,
233 20, // 40 in, 20 out
234 40, // limit 40
235 40,
236 20); // 40 in, 20 out
237
238 ceil_out(
239 q,
240 40,
241 20, // 40 in, 20 out
242 10, // limit 10
243 20,
244 10); // 20 in, 10 out
245 }
246 }
247
248 void
250 {
251 testcase("raw");
252
253 {
254 Quality q(0x5d048191fb9130daull); // 126836389.7680090
255 Amounts const value(
256 amount(349469768), // 349.469768 XRP
257 raw(2755280000000000ull, -15)); // 2.75528
258 STAmount const limit(raw(4131113916555555, -16)); // .4131113916555555
259 Amounts const result(q.ceil_out(value, limit));
260 BEAST_EXPECT(result.in != beast::zero);
261 }
262 }
263
264 void
266 {
267 testcase("round");
268
269 Quality q(0x59148191fb913522ull); // 57719.63525051682
270 BEAST_EXPECT(q.round(3).rate().getText() == "57800");
271 BEAST_EXPECT(q.round(4).rate().getText() == "57720");
272 BEAST_EXPECT(q.round(5).rate().getText() == "57720");
273 BEAST_EXPECT(q.round(6).rate().getText() == "57719.7");
274 BEAST_EXPECT(q.round(7).rate().getText() == "57719.64");
275 BEAST_EXPECT(q.round(8).rate().getText() == "57719.636");
276 BEAST_EXPECT(q.round(9).rate().getText() == "57719.6353");
277 BEAST_EXPECT(q.round(10).rate().getText() == "57719.63526");
278 BEAST_EXPECT(q.round(11).rate().getText() == "57719.635251");
279 BEAST_EXPECT(q.round(12).rate().getText() == "57719.6352506");
280 BEAST_EXPECT(q.round(13).rate().getText() == "57719.63525052");
281 BEAST_EXPECT(q.round(14).rate().getText() == "57719.635250517");
282 BEAST_EXPECT(q.round(15).rate().getText() == "57719.6352505169");
283 BEAST_EXPECT(q.round(16).rate().getText() == "57719.63525051682");
284 }
285
286 void
288 {
289 testcase("comparisons");
290
291 STAmount const amount1(noIssue(), 231);
292 STAmount const amount2(noIssue(), 462);
293 STAmount const amount3(noIssue(), 924);
294
295 Quality const q11(Amounts(amount1, amount1));
296 Quality const q12(Amounts(amount1, amount2));
297 Quality const q13(Amounts(amount1, amount3));
298 Quality const q21(Amounts(amount2, amount1));
299 Quality const q31(Amounts(amount3, amount1));
300
301 BEAST_EXPECT(q11 == q11);
302 BEAST_EXPECT(q11 < q12);
303 BEAST_EXPECT(q12 < q13);
304 BEAST_EXPECT(q31 < q21);
305 BEAST_EXPECT(q21 < q11);
306 BEAST_EXPECT(q11 >= q11);
307 BEAST_EXPECT(q12 >= q11);
308 BEAST_EXPECT(q13 >= q12);
309 BEAST_EXPECT(q21 >= q31);
310 BEAST_EXPECT(q11 >= q21);
311 BEAST_EXPECT(q12 > q11);
312 BEAST_EXPECT(q13 > q12);
313 BEAST_EXPECT(q21 > q31);
314 BEAST_EXPECT(q11 > q21);
315 BEAST_EXPECT(q11 <= q11);
316 BEAST_EXPECT(q11 <= q12);
317 BEAST_EXPECT(q12 <= q13);
318 BEAST_EXPECT(q31 <= q21);
319 BEAST_EXPECT(q21 <= q11);
320 BEAST_EXPECT(q31 != q21);
321 }
322
323 void
325 {
326 testcase("composition");
327
328 STAmount const amount1(noIssue(), 231);
329 STAmount const amount2(noIssue(), 462);
330 STAmount const amount3(noIssue(), 924);
331
332 Quality const q11(Amounts(amount1, amount1));
333 Quality const q12(Amounts(amount1, amount2));
334 Quality const q13(Amounts(amount1, amount3));
335 Quality const q21(Amounts(amount2, amount1));
336 Quality const q31(Amounts(amount3, amount1));
337
338 BEAST_EXPECT(composed_quality(q12, q21) == q11);
339
340 Quality const q13_31(composed_quality(q13, q31));
341 Quality const q31_13(composed_quality(q31, q13));
342
343 BEAST_EXPECT(q13_31 == q31_13);
344 BEAST_EXPECT(q13_31 == q11);
345 }
346
347 void
349 {
350 testcase("operations");
351
352 Quality const q11(Amounts(STAmount(noIssue(), 731), STAmount(noIssue(), 731)));
353
354 Quality qa(q11);
355 Quality qb(q11);
356
357 BEAST_EXPECT(qa == qb);
358 BEAST_EXPECT(++qa != q11);
359 BEAST_EXPECT(qa != qb);
360 BEAST_EXPECT(--qb != q11);
361 BEAST_EXPECT(qa != qb);
362 BEAST_EXPECT(qb < qa);
363 BEAST_EXPECT(qb++ < qa);
364 BEAST_EXPECT(qb++ < qa);
365 BEAST_EXPECT(qb++ == qa);
366 BEAST_EXPECT(qa < qb);
367 }
368 void
369 run() override
370 {
374 test_ceil_in();
376 test_raw();
377 test_round();
378 }
379};
380
381BEAST_DEFINE_TESTSUITE(Quality, protocol, xrpl);
382
383} // namespace xrpl
A testsuite class.
Definition suite.h:52
testcase_t testcase
Memberspace for declaring test cases.
Definition suite.h:148
A currency issued by an account.
Definition Issue.h:14
static STAmount raw(std::uint64_t mantissa, int exponent)
static STAmount amount(Integer integer, std::enable_if_t<!std::is_signed< Integer >::value > *=0)
void ceil_out(Quality const &q, In1 in, Out1 out, Int limit, In2 in_expected, Out2 out_expected)
void run() override
Runs the suite.
void ceil_in(Quality const &q, In1 in, Out1 out, Int limit, In2 in_expected, Out2 out_expected)
static STAmount amount(Integer integer, std::enable_if_t< std::is_signed< Integer >::value > *=0)
static Amounts amounts(In in, Out out)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6
base_uint< 160, detail::CurrencyTag > Currency
Currency is a hash representing a specific currency.
Definition UintTypes.h:37
Quality composed_quality(Quality const &lhs, Quality const &rhs)
Definition Quality.cpp:111
base_uint< 160, detail::AccountIDTag > AccountID
A 160-bit unsigned that uniquely identifies an account.
Definition AccountID.h:29
Issue const & noIssue()
Returns an asset specifier that represents no account and currency.
Definition Issue.h:106