rippled
Loading...
Searching...
No Matches
Quality_test.cpp
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github.com/ripple/rippled
4 Copyright (c) 2012, 2013 Ripple Labs Inc.
5
6 Permission to use, copy, modify, and/or distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#include <xrpl/beast/unit_test.h>
21#include <xrpl/protocol/Quality.h>
22
23#include <type_traits>
24
25namespace ripple {
26
28{
29public:
30 // Create a raw, non-integral amount from mantissa and exponent
31 STAmount static raw(std::uint64_t mantissa, int exponent)
32 {
33 return STAmount(Issue{Currency(3), AccountID(3)}, mantissa, exponent);
34 }
35
36 template <class Integer>
37 static STAmount
39 Integer integer,
41 {
42 static_assert(std::is_integral<Integer>::value, "");
43 return STAmount(integer, false);
44 }
45
46 template <class Integer>
47 static STAmount
49 Integer integer,
51 {
52 static_assert(std::is_integral<Integer>::value, "");
53 if (integer < 0)
54 return STAmount(-integer, true);
55 return STAmount(integer, false);
56 }
57
58 template <class In, class Out>
59 static Amounts
60 amounts(In in, Out out)
61 {
62 return Amounts(amount(in), amount(out));
63 }
64
65 template <class In1, class Out1, class Int, class In2, class Out2>
66 void
68 Quality const& q,
69 In1 in,
70 Out1 out,
71 Int limit,
72 In2 in_expected,
73 Out2 out_expected)
74 {
75 auto expect_result(amounts(in_expected, out_expected));
76 auto actual_result(q.ceil_in(amounts(in, out), amount(limit)));
77
78 BEAST_EXPECT(actual_result == expect_result);
79 }
80
81 template <class In1, class Out1, class Int, class In2, class Out2>
82 void
84 Quality const& q,
85 In1 in,
86 Out1 out,
87 Int limit,
88 In2 in_expected,
89 Out2 out_expected)
90 {
91 auto const expect_result(amounts(in_expected, out_expected));
92 auto const actual_result(q.ceil_out(amounts(in, out), amount(limit)));
93
94 BEAST_EXPECT(actual_result == expect_result);
95 }
96
97 void
99 {
100 testcase("ceil_in");
101
102 {
103 // 1 in, 1 out:
104 Quality q(Amounts(amount(1), amount(1)));
105
106 ceil_in(
107 q,
108 1,
109 1, // 1 in, 1 out
110 1, // limit: 1
111 1,
112 1); // 1 in, 1 out
113
114 ceil_in(
115 q,
116 10,
117 10, // 10 in, 10 out
118 5, // limit: 5
119 5,
120 5); // 5 in, 5 out
121
122 ceil_in(
123 q,
124 5,
125 5, // 5 in, 5 out
126 10, // limit: 10
127 5,
128 5); // 5 in, 5 out
129 }
130
131 {
132 // 1 in, 2 out:
133 Quality q(Amounts(amount(1), amount(2)));
134
135 ceil_in(
136 q,
137 40,
138 80, // 40 in, 80 out
139 40, // limit: 40
140 40,
141 80); // 40 in, 20 out
142
143 ceil_in(
144 q,
145 40,
146 80, // 40 in, 80 out
147 20, // limit: 20
148 20,
149 40); // 20 in, 40 out
150
151 ceil_in(
152 q,
153 40,
154 80, // 40 in, 80 out
155 60, // limit: 60
156 40,
157 80); // 40 in, 80 out
158 }
159
160 {
161 // 2 in, 1 out:
162 Quality q(Amounts(amount(2), amount(1)));
163
164 ceil_in(
165 q,
166 40,
167 20, // 40 in, 20 out
168 20, // limit: 20
169 20,
170 10); // 20 in, 10 out
171
172 ceil_in(
173 q,
174 40,
175 20, // 40 in, 20 out
176 40, // limit: 40
177 40,
178 20); // 40 in, 20 out
179
180 ceil_in(
181 q,
182 40,
183 20, // 40 in, 20 out
184 50, // limit: 40
185 40,
186 20); // 40 in, 20 out
187 }
188 }
189
190 void
192 {
193 testcase("ceil_out");
194
195 {
196 // 1 in, 1 out:
197 Quality q(Amounts(amount(1), amount(1)));
198
199 ceil_out(
200 q,
201 1,
202 1, // 1 in, 1 out
203 1, // limit 1
204 1,
205 1); // 1 in, 1 out
206
207 ceil_out(
208 q,
209 10,
210 10, // 10 in, 10 out
211 5, // limit 5
212 5,
213 5); // 5 in, 5 out
214
215 ceil_out(
216 q,
217 10,
218 10, // 10 in, 10 out
219 20, // limit 20
220 10,
221 10); // 10 in, 10 out
222 }
223
224 {
225 // 1 in, 2 out:
226 Quality q(Amounts(amount(1), amount(2)));
227
228 ceil_out(
229 q,
230 40,
231 80, // 40 in, 80 out
232 40, // limit 40
233 20,
234 40); // 20 in, 40 out
235
236 ceil_out(
237 q,
238 40,
239 80, // 40 in, 80 out
240 80, // limit 80
241 40,
242 80); // 40 in, 80 out
243
244 ceil_out(
245 q,
246 40,
247 80, // 40 in, 80 out
248 100, // limit 100
249 40,
250 80); // 40 in, 80 out
251 }
252
253 {
254 // 2 in, 1 out:
255 Quality q(Amounts(amount(2), amount(1)));
256
257 ceil_out(
258 q,
259 40,
260 20, // 40 in, 20 out
261 20, // limit 20
262 40,
263 20); // 40 in, 20 out
264
265 ceil_out(
266 q,
267 40,
268 20, // 40 in, 20 out
269 40, // limit 40
270 40,
271 20); // 40 in, 20 out
272
273 ceil_out(
274 q,
275 40,
276 20, // 40 in, 20 out
277 10, // limit 10
278 20,
279 10); // 20 in, 10 out
280 }
281 }
282
283 void
285 {
286 testcase("raw");
287
288 {
289 Quality q(0x5d048191fb9130daull); // 126836389.7680090
290 Amounts const value(
291 amount(349469768), // 349.469768 XRP
292 raw(2755280000000000ull, -15)); // 2.75528
293 STAmount const limit(
294 raw(4131113916555555, -16)); // .4131113916555555
295 Amounts const result(q.ceil_out(value, limit));
296 BEAST_EXPECT(result.in != beast::zero);
297 }
298 }
299
300 void
302 {
303 testcase("round");
304
305 Quality q(0x59148191fb913522ull); // 57719.63525051682
306 BEAST_EXPECT(q.round(3).rate().getText() == "57800");
307 BEAST_EXPECT(q.round(4).rate().getText() == "57720");
308 BEAST_EXPECT(q.round(5).rate().getText() == "57720");
309 BEAST_EXPECT(q.round(6).rate().getText() == "57719.7");
310 BEAST_EXPECT(q.round(7).rate().getText() == "57719.64");
311 BEAST_EXPECT(q.round(8).rate().getText() == "57719.636");
312 BEAST_EXPECT(q.round(9).rate().getText() == "57719.6353");
313 BEAST_EXPECT(q.round(10).rate().getText() == "57719.63526");
314 BEAST_EXPECT(q.round(11).rate().getText() == "57719.635251");
315 BEAST_EXPECT(q.round(12).rate().getText() == "57719.6352506");
316 BEAST_EXPECT(q.round(13).rate().getText() == "57719.63525052");
317 BEAST_EXPECT(q.round(14).rate().getText() == "57719.635250517");
318 BEAST_EXPECT(q.round(15).rate().getText() == "57719.6352505169");
319 BEAST_EXPECT(q.round(16).rate().getText() == "57719.63525051682");
320 }
321
322 void
324 {
325 testcase("comparisons");
326
327 STAmount const amount1(noIssue(), 231);
328 STAmount const amount2(noIssue(), 462);
329 STAmount const amount3(noIssue(), 924);
330
331 Quality const q11(Amounts(amount1, amount1));
332 Quality const q12(Amounts(amount1, amount2));
333 Quality const q13(Amounts(amount1, amount3));
334 Quality const q21(Amounts(amount2, amount1));
335 Quality const q31(Amounts(amount3, amount1));
336
337 BEAST_EXPECT(q11 == q11);
338 BEAST_EXPECT(q11 < q12);
339 BEAST_EXPECT(q12 < q13);
340 BEAST_EXPECT(q31 < q21);
341 BEAST_EXPECT(q21 < q11);
342 BEAST_EXPECT(q11 >= q11);
343 BEAST_EXPECT(q12 >= q11);
344 BEAST_EXPECT(q13 >= q12);
345 BEAST_EXPECT(q21 >= q31);
346 BEAST_EXPECT(q11 >= q21);
347 BEAST_EXPECT(q12 > q11);
348 BEAST_EXPECT(q13 > q12);
349 BEAST_EXPECT(q21 > q31);
350 BEAST_EXPECT(q11 > q21);
351 BEAST_EXPECT(q11 <= q11);
352 BEAST_EXPECT(q11 <= q12);
353 BEAST_EXPECT(q12 <= q13);
354 BEAST_EXPECT(q31 <= q21);
355 BEAST_EXPECT(q21 <= q11);
356 BEAST_EXPECT(q31 != q21);
357 }
358
359 void
361 {
362 testcase("composition");
363
364 STAmount const amount1(noIssue(), 231);
365 STAmount const amount2(noIssue(), 462);
366 STAmount const amount3(noIssue(), 924);
367
368 Quality const q11(Amounts(amount1, amount1));
369 Quality const q12(Amounts(amount1, amount2));
370 Quality const q13(Amounts(amount1, amount3));
371 Quality const q21(Amounts(amount2, amount1));
372 Quality const q31(Amounts(amount3, amount1));
373
374 BEAST_EXPECT(composed_quality(q12, q21) == q11);
375
376 Quality const q13_31(composed_quality(q13, q31));
377 Quality const q31_13(composed_quality(q31, q13));
378
379 BEAST_EXPECT(q13_31 == q31_13);
380 BEAST_EXPECT(q13_31 == q11);
381 }
382
383 void
385 {
386 testcase("operations");
387
388 Quality const q11(
389 Amounts(STAmount(noIssue(), 731), STAmount(noIssue(), 731)));
390
391 Quality qa(q11);
392 Quality qb(q11);
393
394 BEAST_EXPECT(qa == qb);
395 BEAST_EXPECT(++qa != q11);
396 BEAST_EXPECT(qa != qb);
397 BEAST_EXPECT(--qb != q11);
398 BEAST_EXPECT(qa != qb);
399 BEAST_EXPECT(qb < qa);
400 BEAST_EXPECT(qb++ < qa);
401 BEAST_EXPECT(qb++ < qa);
402 BEAST_EXPECT(qb++ == qa);
403 BEAST_EXPECT(qa < qb);
404 }
405 void
406 run() override
407 {
411 test_ceil_in();
413 test_raw();
414 test_round();
415 }
416};
417
418BEAST_DEFINE_TESTSUITE(Quality, protocol, ripple);
419
420} // namespace ripple
A testsuite class.
Definition suite.h:55
testcase_t testcase
Memberspace for declaring test cases.
Definition suite.h:155
A currency issued by an account.
Definition Issue.h:33
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:25
base_uint< 160, detail::AccountIDTag > AccountID
A 160-bit unsigned that uniquely identifies an account.
Definition AccountID.h:48
Quality composed_quality(Quality const &lhs, Quality const &rhs)
Definition Quality.cpp:158
base_uint< 160, detail::CurrencyTag > Currency
Currency is a hash representing a specific currency.
Definition UintTypes.h:56
Issue const & noIssue()
Returns an asset specifier that represents no account and currency.
Definition Issue.h:123