xrpld
Toggle main menu visibility
Loading...
Searching...
No Matches
tests
libxrpl
basics
Units.cpp
1
#include <xrpl/protocol/Units.h>
2
3
#include <xrpl/beast/utility/Zero.h>
4
#include <xrpl/json/json_value.h>
5
#include <xrpl/protocol/SystemParameters.h>
6
#include <xrpl/protocol/XRPAmount.h>
7
8
#include <gtest/gtest.h>
9
10
#include <
cstdint
>
11
#include <
limits
>
12
#include <
type_traits
>
13
14
namespace
xrpl::test
{
15
16
TEST
(UnitsTest, types)
17
{
18
using
FeeLevel32 =
FeeLevel<std::uint32_t>
;
19
20
{
21
XRPAmount
const
x{100};
22
EXPECT_EQ(x.
drops
(), 100);
23
EXPECT_TRUE((
std::is_same_v
<
decltype
(x)::UnitType, unit::dropTag>));
24
auto
y = 4u * x;
25
EXPECT_EQ(y.value(), 400);
26
EXPECT_TRUE((
std::is_same_v
<
decltype
(y)::UnitType, unit::dropTag>));
27
28
auto
z = 4 * y;
29
EXPECT_EQ(z.value(), 1600);
30
EXPECT_TRUE((
std::is_same_v
<
decltype
(z)::UnitType, unit::dropTag>));
31
32
FeeLevel32
const
f{10};
33
FeeLevel32
const
baseFee{100};
34
35
auto
drops
=
mulDiv
(baseFee, x, f);
36
37
EXPECT_TRUE(
drops
);
38
EXPECT_EQ(
drops
.value(), 1000);
// NOLINT(bugprone-unchecked-optional-access)
39
EXPECT_TRUE(
40
(
std::is_same_v
<
std::remove_reference_t
<
decltype
(*
drops
)>::UnitType, unit::dropTag>));
41
42
EXPECT_TRUE((
std::is_same_v
<
std::remove_reference_t
<
decltype
(*
drops
)>,
XRPAmount
>));
43
}
44
{
45
XRPAmount
const
x{100};
46
EXPECT_EQ(x.
value
(), 100);
47
EXPECT_TRUE((
std::is_same_v
<
decltype
(x)::UnitType, unit::dropTag>));
48
auto
y = 4u * x;
49
EXPECT_EQ(y.value(), 400);
50
EXPECT_TRUE((
std::is_same_v
<
decltype
(y)::UnitType, unit::dropTag>));
51
52
FeeLevel64
const
f{10};
53
FeeLevel64
const
baseFee{100};
54
55
auto
drops
=
mulDiv
(baseFee, x, f);
56
57
EXPECT_TRUE(
drops
);
58
EXPECT_EQ(
drops
.value(), 1000);
// NOLINT(bugprone-unchecked-optional-access)
59
EXPECT_TRUE(
60
(
std::is_same_v
<
std::remove_reference_t
<
decltype
(*
drops
)>::UnitType, unit::dropTag>));
61
EXPECT_TRUE((
std::is_same_v
<
std::remove_reference_t
<
decltype
(*
drops
)>,
XRPAmount
>));
62
}
63
{
64
FeeLevel64
const
x{1024};
65
EXPECT_EQ(x.
value
(), 1024);
66
EXPECT_TRUE((
std::is_same_v
<
decltype
(x)::UnitType, unit::feelevelTag>));
67
std::uint64_t
const
m = 4;
68
auto
y = m * x;
69
EXPECT_EQ(y.value(), 4096);
70
EXPECT_TRUE((
std::is_same_v
<
decltype
(y)::UnitType, unit::feelevelTag>));
71
72
XRPAmount
const
basefee{10};
73
FeeLevel64
const
referencefee{256};
74
75
auto
drops
=
mulDiv
(x, basefee, referencefee);
76
77
EXPECT_TRUE(
drops
);
78
EXPECT_EQ(
drops
.value(), 40);
// NOLINT(bugprone-unchecked-optional-access)
79
EXPECT_TRUE(
80
(
std::is_same_v
<
std::remove_reference_t
<
decltype
(*
drops
)>::UnitType, unit::dropTag>));
81
EXPECT_TRUE((
std::is_same_v
<
std::remove_reference_t
<
decltype
(*
drops
)>,
XRPAmount
>));
82
}
83
}
84
85
TEST
(UnitsTest,
json
)
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
EXPECT_EQ(y.type(),
json::ValueType::UInt
);
94
EXPECT_EQ(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
EXPECT_EQ(y.type(),
json::ValueType::UInt
);
101
EXPECT_EQ(y,
json::Value
{x.fee()});
102
}
103
104
{
105
FeeLevel64
const
x{
std::numeric_limits<std::uint64_t>::max
()};
106
auto
y = x.
jsonClipped
();
107
EXPECT_EQ(y.type(),
json::ValueType::UInt
);
108
EXPECT_EQ(y,
json::Value
{
std::numeric_limits<std::uint32_t>::max
()});
109
}
110
111
{
112
FeeLevel64
const
x{
std::numeric_limits<std::uint64_t>::min
()};
113
auto
y = x.
jsonClipped
();
114
EXPECT_EQ(y.type(),
json::ValueType::UInt
);
115
EXPECT_EQ(y,
json::Value
{0});
116
}
117
118
{
119
FeeLevelDouble
const
x{
std::numeric_limits<double>::max
()};
120
auto
y = x.
jsonClipped
();
121
EXPECT_EQ(y.type(),
json::ValueType::Real
);
122
EXPECT_EQ(y,
json::Value
{
std::numeric_limits<double>::max
()});
123
}
124
125
{
126
FeeLevelDouble
const
x{
std::numeric_limits<double>::min
()};
127
auto
y = x.
jsonClipped
();
128
EXPECT_EQ(y.type(),
json::ValueType::Real
);
129
EXPECT_EQ(y,
json::Value
{
std::numeric_limits<double>::min
()});
130
}
131
132
{
133
XRPAmount
const
x{
std::numeric_limits<std::int64_t>::max
()};
134
auto
y = x.
jsonClipped
();
135
EXPECT_EQ(y.type(),
json::ValueType::Int
);
136
EXPECT_EQ(y,
json::Value
{
std::numeric_limits<std::int32_t>::max
()});
137
}
138
139
{
140
XRPAmount
const
x{
std::numeric_limits<std::int64_t>::min
()};
141
auto
y = x.
jsonClipped
();
142
EXPECT_EQ(y.type(),
json::ValueType::Int
);
143
EXPECT_EQ(y,
json::Value
{
std::numeric_limits<std::int32_t>::min
()});
144
}
145
}
146
147
TEST
(UnitsTest, functions)
148
{
149
// Explicitly test every defined function for the ValueUnit class
150
// since some of them are templated, but not used anywhere else.
151
using
FeeLevel32 =
FeeLevel<std::uint32_t>
;
152
153
{
154
auto
make = [&](
auto
x) ->
FeeLevel64
{
return
x; };
155
auto
explicitmake = [&](
auto
x) ->
FeeLevel64
{
return
FeeLevel64
{x}; };
156
157
[[maybe_unused]]
158
FeeLevel64
const
defaulted{};
159
FeeLevel64
test
{0};
160
EXPECT_EQ(
test
.fee(), 0);
161
162
test
= explicitmake(
beast::kZero
);
163
EXPECT_EQ(
test
.fee(), 0);
164
165
test
=
beast::kZero
;
166
EXPECT_EQ(
test
.fee(), 0);
167
168
test
= explicitmake(100u);
169
EXPECT_EQ(
test
.fee(), 100);
170
171
FeeLevel64
const
targetSame{200u};
172
FeeLevel32
const
targetOther{300u};
173
test
= make(targetSame);
174
EXPECT_EQ(
test
.fee(), 200);
175
EXPECT_EQ(
test
, targetSame);
176
EXPECT_TRUE(
test
<
FeeLevel64
{1000});
177
EXPECT_TRUE(
test
>
FeeLevel64
{100});
178
test
= make(targetOther);
179
EXPECT_EQ(
test
.fee(), 300);
180
EXPECT_EQ(
test
, targetOther);
181
182
test
=
std::uint64_t
(200);
183
EXPECT_EQ(
test
.fee(), 200);
184
test
=
std::uint32_t
(300);
185
EXPECT_EQ(
test
.fee(), 300);
186
187
test
= targetSame;
188
EXPECT_EQ(
test
.fee(), 200);
189
test
= targetOther.fee();
190
EXPECT_EQ(
test
.fee(), 300);
191
EXPECT_EQ(
test
, targetOther);
192
193
test
= targetSame * 2;
194
EXPECT_EQ(
test
.fee(), 400);
195
test
= 3 * targetSame;
196
EXPECT_EQ(
test
.fee(), 600);
197
test
= targetSame / 10;
198
EXPECT_EQ(
test
.fee(), 20);
199
200
test
+= targetSame;
201
EXPECT_EQ(
test
.fee(), 220);
202
203
test
-= targetSame;
204
EXPECT_EQ(
test
.fee(), 20);
205
206
test
++;
207
EXPECT_EQ(
test
.fee(), 21);
208
++
test
;
209
EXPECT_EQ(
test
.fee(), 22);
210
test
--;
211
EXPECT_EQ(
test
.fee(), 21);
212
--
test
;
213
EXPECT_EQ(
test
.fee(), 20);
214
215
test
*= 5;
216
EXPECT_EQ(
test
.fee(), 100);
217
test
/= 2;
218
EXPECT_EQ(
test
.fee(), 50);
219
test
%= 13;
220
EXPECT_EQ(
test
.fee(), 11);
221
222
/*
223
// illegal with unsigned
224
test = -test;
225
EXPECT_EQ(test.fee(), -11);
226
EXPECT_EQ(test.signum(), -1);
227
EXPECT_EQ(to_string(test), "-11");
228
*/
229
230
EXPECT_TRUE(
test
);
231
test
= 0;
232
EXPECT_FALSE(
test
);
233
EXPECT_EQ(
test
.signum(), 0);
234
test
= targetSame;
235
EXPECT_EQ(
test
.signum(), 1);
236
EXPECT_EQ(
to_string
(
test
),
"200"
);
237
}
238
{
239
auto
make = [&](
auto
x) ->
FeeLevelDouble
{
return
x; };
240
auto
explicitmake = [&](
auto
x) ->
FeeLevelDouble
{
return
FeeLevelDouble
{x}; };
241
242
[[maybe_unused]]
243
FeeLevelDouble
const
defaulted{};
244
FeeLevelDouble
test
{0};
245
EXPECT_EQ(
test
.fee(), 0);
246
247
test
= explicitmake(
beast::kZero
);
248
EXPECT_EQ(
test
.fee(), 0);
249
250
test
=
beast::kZero
;
251
EXPECT_EQ(
test
.fee(), 0);
252
253
test
= explicitmake(100.0);
254
EXPECT_EQ(
test
.fee(), 100);
255
256
FeeLevelDouble
const
targetSame{200.0};
257
FeeLevel64
const
targetOther{300};
258
test
= make(targetSame);
259
EXPECT_EQ(
test
.fee(), 200);
260
EXPECT_EQ(
test
, targetSame);
261
EXPECT_TRUE(
test
<
FeeLevelDouble
{1000.0});
262
EXPECT_TRUE(
test
>
FeeLevelDouble
{100.0});
263
test
= targetOther.
fee
();
264
EXPECT_EQ(
test
.fee(), 300);
265
EXPECT_EQ(
test
, targetOther);
266
267
test
= 200.0;
268
EXPECT_EQ(
test
.fee(), 200);
269
test
=
std::uint64_t
(300);
270
EXPECT_EQ(
test
.fee(), 300);
271
272
test
= targetSame;
273
EXPECT_EQ(
test
.fee(), 200);
274
275
test
= targetSame * 2;
276
EXPECT_EQ(
test
.fee(), 400);
277
test
= 3 * targetSame;
278
EXPECT_EQ(
test
.fee(), 600);
279
test
= targetSame / 10;
280
EXPECT_EQ(
test
.fee(), 20);
281
282
test
+= targetSame;
283
EXPECT_EQ(
test
.fee(), 220);
284
285
test
-= targetSame;
286
EXPECT_EQ(
test
.fee(), 20);
287
288
test
++;
289
EXPECT_EQ(
test
.fee(), 21);
290
++
test
;
291
EXPECT_EQ(
test
.fee(), 22);
292
test
--;
293
EXPECT_EQ(
test
.fee(), 21);
294
--
test
;
295
EXPECT_EQ(
test
.fee(), 20);
296
297
test
*= 5;
298
EXPECT_EQ(
test
.fee(), 100);
299
test
/= 2;
300
EXPECT_EQ(
test
.fee(), 50);
301
/* illegal with floating
302
test %= 13;
303
EXPECT_EQ(test.fee(), 11);
304
*/
305
306
// legal with signed
307
test
= -
test
;
308
EXPECT_EQ(
test
.fee(), -50);
309
EXPECT_EQ(
test
.signum(), -1);
310
EXPECT_EQ(
to_string
(
test
),
"-50.000000"
);
311
312
EXPECT_TRUE(
test
);
313
test
= 0;
314
EXPECT_FALSE(
test
);
315
EXPECT_EQ(
test
.signum(), 0);
316
test
= targetSame;
317
EXPECT_EQ(
test
.signum(), 1);
318
EXPECT_EQ(
to_string
(
test
),
"200.000000"
);
319
}
320
}
321
322
TEST
(UnitsTest, initial_xrp)
323
{
324
EXPECT_EQ(
kInitialXrp
.drops(), 100'000'000'000'000'000);
325
EXPECT_EQ(
kInitialXrp
,
XRPAmount
{100'000'000'000'000'000});
326
}
327
328
}
// namespace xrpl::test
json::Value
Represents a JSON value.
Definition
json_value.h:117
xrpl::XRPAmount::jsonClipped
json::Value jsonClipped() const
Definition
XRPAmount.h:210
xrpl::XRPAmount::value
constexpr value_type value() const
Returns the underlying value.
Definition
XRPAmount.h:232
xrpl::XRPAmount::drops
constexpr value_type drops() const
Returns the number of drops.
Definition
XRPAmount.h:170
xrpl::unit::ValueUnit::value
constexpr value_type value() const
Returns the underlying value.
Definition
Units.h:338
xrpl::unit::ValueUnit::jsonClipped
json::Value jsonClipped() const
Definition
Units.h:309
xrpl::unit::ValueUnit::fee
constexpr value_type fee() const
Returns the number of drops.
Definition
Units.h:292
cstdint
std::uint64_t
std::is_same_v
T is_same_v
limits
std::numeric_limits::max
T max(T... args)
std::numeric_limits::min
T min(T... args)
beast::kZero
constexpr Zero kZero
Definition
Zero.h:30
json
JSON (JavaScript Object Notation).
Definition
json_errors.h:5
json::ValueType::UInt
@ UInt
unsigned integer value
Definition
json_value.h:24
json::ValueType::Int
@ Int
signed integer value
Definition
json_value.h:23
json::ValueType::Real
@ Real
double value
Definition
json_value.h:25
xrpl::test::jtx::drops
PrettyAmount drops(Integer i)
Returns an XRP PrettyAmount, which is trivially convertible to STAmount.
Definition
src/test/jtx/amount.h:361
xrpl::test
Definition
STLedgerEntry.h:21
xrpl::test::TEST
TEST(UnitsTest, types)
Definition
Units.cpp:16
xrpl::test::XRPAmount
constexpr XRPAmount
Convert XRP to drops (integral types).
Definition
TxTest.h:54
xrpl::mulDiv
std::optional< std::uint64_t > mulDiv(std::uint64_t value, std::uint64_t mul, std::uint64_t div)
Return value*mul/div accurately.
Definition
libxrpl/basics/mulDiv.cpp:11
xrpl::to_string
std::string to_string(BaseUInt< Bits, Tag > const &a)
Definition
base_uint.h:657
xrpl::FeeLevel64
FeeLevel< std::uint64_t > FeeLevel64
Definition
Units.h:443
xrpl::FeeLevelDouble
FeeLevel< double > FeeLevelDouble
Definition
Units.h:444
xrpl::FeeLevel
unit::ValueUnit< unit::feelevelTag, T > FeeLevel
Definition
Units.h:442
xrpl::kInitialXrp
constexpr XRPAmount kInitialXrp
Configure the native currency.
Definition
SystemParameters.h:31
std::remove_reference_t
type_traits
Generated by
1.17.0