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