rippled
Loading...
Searching...
No Matches
Units_test.cpp
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github.com/ripple/rippled
4 Copyright (c) 2019 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#include <xrpl/beast/unit_test.h>
20#include <xrpl/protocol/SystemParameters.h>
21#include <xrpl/protocol/Units.h>
22
23namespace ripple {
24namespace test {
25
27{
28private:
29 void
31 {
32 using FeeLevel32 = FeeLevel<std::uint32_t>;
33
34 {
35 XRPAmount x{100};
36 BEAST_EXPECT(x.drops() == 100);
37 BEAST_EXPECT(
38 (std::is_same_v<decltype(x)::unit_type, unit::dropTag>));
39 auto y = 4u * x;
40 BEAST_EXPECT(y.value() == 400);
41 BEAST_EXPECT(
42 (std::is_same_v<decltype(y)::unit_type, unit::dropTag>));
43
44 auto z = 4 * y;
45 BEAST_EXPECT(z.value() == 1600);
46 BEAST_EXPECT(
47 (std::is_same_v<decltype(z)::unit_type, unit::dropTag>));
48
49 FeeLevel32 f{10};
50 FeeLevel32 baseFee{100};
51
52 auto drops = mulDiv(baseFee, x, f);
53
54 BEAST_EXPECT(drops);
55 BEAST_EXPECT(drops.value() == 1000);
56 BEAST_EXPECT((std::is_same_v<
57 std::remove_reference_t<decltype(*drops)>::unit_type,
58 unit::dropTag>));
59
60 BEAST_EXPECT((std::is_same_v<
62 XRPAmount>));
63 }
64 {
65 XRPAmount x{100};
66 BEAST_EXPECT(x.value() == 100);
67 BEAST_EXPECT(
68 (std::is_same_v<decltype(x)::unit_type, unit::dropTag>));
69 auto y = 4u * x;
70 BEAST_EXPECT(y.value() == 400);
71 BEAST_EXPECT(
72 (std::is_same_v<decltype(y)::unit_type, unit::dropTag>));
73
74 FeeLevel64 f{10};
75 FeeLevel64 baseFee{100};
76
77 auto drops = mulDiv(baseFee, x, f);
78
79 BEAST_EXPECT(drops);
80 BEAST_EXPECT(drops.value() == 1000);
81 BEAST_EXPECT((std::is_same_v<
82 std::remove_reference_t<decltype(*drops)>::unit_type,
83 unit::dropTag>));
84 BEAST_EXPECT((std::is_same_v<
86 XRPAmount>));
87 }
88 {
89 FeeLevel64 x{1024};
90 BEAST_EXPECT(x.value() == 1024);
91 BEAST_EXPECT(
92 (std::is_same_v<decltype(x)::unit_type, unit::feelevelTag>));
93 std::uint64_t m = 4;
94 auto y = m * x;
95 BEAST_EXPECT(y.value() == 4096);
96 BEAST_EXPECT(
97 (std::is_same_v<decltype(y)::unit_type, unit::feelevelTag>));
98
99 XRPAmount basefee{10};
100 FeeLevel64 referencefee{256};
101
102 auto drops = mulDiv(x, basefee, referencefee);
103
104 BEAST_EXPECT(drops);
105 BEAST_EXPECT(drops.value() == 40);
106 BEAST_EXPECT((std::is_same_v<
107 std::remove_reference_t<decltype(*drops)>::unit_type,
108 unit::dropTag>));
109 BEAST_EXPECT((std::is_same_v<
110 std::remove_reference_t<decltype(*drops)>,
111 XRPAmount>));
112 }
113 }
114
115 void
117 {
118 // Json value functionality
119 using FeeLevel32 = FeeLevel<std::uint32_t>;
120
121 {
123 auto y = x.jsonClipped();
124 BEAST_EXPECT(y.type() == Json::uintValue);
125 BEAST_EXPECT(y == Json::Value{x.fee()});
126 }
127
128 {
130 auto y = x.jsonClipped();
131 BEAST_EXPECT(y.type() == Json::uintValue);
132 BEAST_EXPECT(y == Json::Value{x.fee()});
133 }
134
135 {
137 auto y = x.jsonClipped();
138 BEAST_EXPECT(y.type() == Json::uintValue);
139 BEAST_EXPECT(
141 }
142
143 {
145 auto y = x.jsonClipped();
146 BEAST_EXPECT(y.type() == Json::uintValue);
147 BEAST_EXPECT(y == Json::Value{0});
148 }
149
150 {
152 auto y = x.jsonClipped();
153 BEAST_EXPECT(y.type() == Json::realValue);
154 BEAST_EXPECT(y == Json::Value{std::numeric_limits<double>::max()});
155 }
156
157 {
159 auto y = x.jsonClipped();
160 BEAST_EXPECT(y.type() == Json::realValue);
161 BEAST_EXPECT(y == Json::Value{std::numeric_limits<double>::min()});
162 }
163
164 {
166 auto y = x.jsonClipped();
167 BEAST_EXPECT(y.type() == Json::intValue);
168 BEAST_EXPECT(
170 }
171
172 {
174 auto y = x.jsonClipped();
175 BEAST_EXPECT(y.type() == Json::intValue);
176 BEAST_EXPECT(
178 }
179 }
180
181 void
183 {
184 // Explicitly test every defined function for the ValueUnit class
185 // since some of them are templated, but not used anywhere else.
186 using FeeLevel32 = FeeLevel<std::uint32_t>;
187
188 {
189 auto make = [&](auto x) -> FeeLevel64 { return x; };
190 auto explicitmake = [&](auto x) -> FeeLevel64 {
191 return FeeLevel64{x};
192 };
193
194 [[maybe_unused]]
195 FeeLevel64 defaulted;
196 FeeLevel64 test{0};
197 BEAST_EXPECT(test.fee() == 0);
198
199 test = explicitmake(beast::zero);
200 BEAST_EXPECT(test.fee() == 0);
201
202 test = beast::zero;
203 BEAST_EXPECT(test.fee() == 0);
204
205 test = explicitmake(100u);
206 BEAST_EXPECT(test.fee() == 100);
207
208 FeeLevel64 const targetSame{200u};
209 FeeLevel32 const targetOther{300u};
210 test = make(targetSame);
211 BEAST_EXPECT(test.fee() == 200);
212 BEAST_EXPECT(test == targetSame);
213 BEAST_EXPECT(test < FeeLevel64{1000});
214 BEAST_EXPECT(test > FeeLevel64{100});
215 test = make(targetOther);
216 BEAST_EXPECT(test.fee() == 300);
217 BEAST_EXPECT(test == targetOther);
218
219 test = std::uint64_t(200);
220 BEAST_EXPECT(test.fee() == 200);
221 test = std::uint32_t(300);
222 BEAST_EXPECT(test.fee() == 300);
223
224 test = targetSame;
225 BEAST_EXPECT(test.fee() == 200);
226 test = targetOther.fee();
227 BEAST_EXPECT(test.fee() == 300);
228 BEAST_EXPECT(test == targetOther);
229
230 test = targetSame * 2;
231 BEAST_EXPECT(test.fee() == 400);
232 test = 3 * targetSame;
233 BEAST_EXPECT(test.fee() == 600);
234 test = targetSame / 10;
235 BEAST_EXPECT(test.fee() == 20);
236
237 test += targetSame;
238 BEAST_EXPECT(test.fee() == 220);
239
240 test -= targetSame;
241 BEAST_EXPECT(test.fee() == 20);
242
243 test++;
244 BEAST_EXPECT(test.fee() == 21);
245 ++test;
246 BEAST_EXPECT(test.fee() == 22);
247 test--;
248 BEAST_EXPECT(test.fee() == 21);
249 --test;
250 BEAST_EXPECT(test.fee() == 20);
251
252 test *= 5;
253 BEAST_EXPECT(test.fee() == 100);
254 test /= 2;
255 BEAST_EXPECT(test.fee() == 50);
256 test %= 13;
257 BEAST_EXPECT(test.fee() == 11);
258
259 /*
260 // illegal with unsigned
261 test = -test;
262 BEAST_EXPECT(test.fee() == -11);
263 BEAST_EXPECT(test.signum() == -1);
264 BEAST_EXPECT(to_string(test) == "-11");
265 */
266
267 BEAST_EXPECT(test);
268 test = 0;
269 BEAST_EXPECT(!test);
270 BEAST_EXPECT(test.signum() == 0);
271 test = targetSame;
272 BEAST_EXPECT(test.signum() == 1);
273 BEAST_EXPECT(to_string(test) == "200");
274 }
275 {
276 auto make = [&](auto x) -> FeeLevelDouble { return x; };
277 auto explicitmake = [&](auto x) -> FeeLevelDouble {
278 return FeeLevelDouble{x};
279 };
280
281 [[maybe_unused]]
282 FeeLevelDouble defaulted;
283 FeeLevelDouble test{0};
284 BEAST_EXPECT(test.fee() == 0);
285
286 test = explicitmake(beast::zero);
287 BEAST_EXPECT(test.fee() == 0);
288
289 test = beast::zero;
290 BEAST_EXPECT(test.fee() == 0);
291
292 test = explicitmake(100.0);
293 BEAST_EXPECT(test.fee() == 100);
294
295 FeeLevelDouble const targetSame{200.0};
296 FeeLevel64 const targetOther{300};
297 test = make(targetSame);
298 BEAST_EXPECT(test.fee() == 200);
299 BEAST_EXPECT(test == targetSame);
300 BEAST_EXPECT(test < FeeLevelDouble{1000.0});
301 BEAST_EXPECT(test > FeeLevelDouble{100.0});
302 test = targetOther.fee();
303 BEAST_EXPECT(test.fee() == 300);
304 BEAST_EXPECT(test == targetOther);
305
306 test = 200.0;
307 BEAST_EXPECT(test.fee() == 200);
308 test = std::uint64_t(300);
309 BEAST_EXPECT(test.fee() == 300);
310
311 test = targetSame;
312 BEAST_EXPECT(test.fee() == 200);
313
314 test = targetSame * 2;
315 BEAST_EXPECT(test.fee() == 400);
316 test = 3 * targetSame;
317 BEAST_EXPECT(test.fee() == 600);
318 test = targetSame / 10;
319 BEAST_EXPECT(test.fee() == 20);
320
321 test += targetSame;
322 BEAST_EXPECT(test.fee() == 220);
323
324 test -= targetSame;
325 BEAST_EXPECT(test.fee() == 20);
326
327 test++;
328 BEAST_EXPECT(test.fee() == 21);
329 ++test;
330 BEAST_EXPECT(test.fee() == 22);
331 test--;
332 BEAST_EXPECT(test.fee() == 21);
333 --test;
334 BEAST_EXPECT(test.fee() == 20);
335
336 test *= 5;
337 BEAST_EXPECT(test.fee() == 100);
338 test /= 2;
339 BEAST_EXPECT(test.fee() == 50);
340 /* illegal with floating
341 test %= 13;
342 BEAST_EXPECT(test.fee() == 11);
343 */
344
345 // legal with signed
346 test = -test;
347 BEAST_EXPECT(test.fee() == -50);
348 BEAST_EXPECT(test.signum() == -1);
349 BEAST_EXPECT(to_string(test) == "-50.000000");
350
351 BEAST_EXPECT(test);
352 test = 0;
353 BEAST_EXPECT(!test);
354 BEAST_EXPECT(test.signum() == 0);
355 test = targetSame;
356 BEAST_EXPECT(test.signum() == 1);
357 BEAST_EXPECT(to_string(test) == "200.000000");
358 }
359 }
360
361public:
362 void
363 run() override
364 {
365 BEAST_EXPECT(INITIAL_XRP.drops() == 100'000'000'000'000'000);
366 BEAST_EXPECT(INITIAL_XRP == XRPAmount{100'000'000'000'000'000});
367
368 testTypes();
369 testJson();
371 }
372};
373
374BEAST_DEFINE_TESTSUITE(units, basics, ripple);
375
376} // namespace test
377} // namespace ripple
Represents a JSON value.
Definition json_value.h:149
A testsuite class.
Definition suite.h:55
constexpr value_type drops() const
Returns the number of drops.
Definition XRPAmount.h:177
Json::Value jsonClipped() const
Definition XRPAmount.h:218
void run() override
Runs the suite.
Json::Value jsonClipped() const
Definition Units.h:313
T is_same_v
T max(T... args)
T min(T... args)
@ realValue
double value
Definition json_value.h:41
@ intValue
signed integer value
Definition json_value.h:39
@ uintValue
unsigned integer value
Definition json_value.h:40
PrettyAmount drops(Integer i)
Returns an XRP PrettyAmount, which is trivially convertible to STAmount.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:25
constexpr XRPAmount INITIAL_XRP
Configure the native currency.
std::string to_string(base_uint< Bits, Tag > const &a)
Definition base_uint.h:630
std::optional< std::uint64_t > mulDiv(std::uint64_t value, std::uint64_t mul, std::uint64_t div)
Return value*mul/div accurately.