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