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