rippled
Loading...
Searching...
No Matches
STNumber_test.cpp
1#include <xrpl/beast/unit_test.h>
2#include <xrpl/beast/unit_test/suite.h>
3#include <xrpl/json/json_forwards.h>
4#include <xrpl/protocol/Issue.h>
5#include <xrpl/protocol/SField.h>
6#include <xrpl/protocol/STAmount.h>
7#include <xrpl/protocol/STNumber.h>
8
9#include <limits>
10#include <ostream>
11#include <stdexcept>
12
13namespace ripple {
14
16{
17 void
19 {
20 STNumber const before{sfNumber, number};
21 BEAST_EXPECT(number == before);
22 Serializer s;
23 before.add(s);
24 BEAST_EXPECT(s.size() == 12);
25 SerialIter sit(s.slice());
26 STNumber const after{sit, sfNumber};
27 BEAST_EXPECT(after.isEquivalent(before));
28 BEAST_EXPECT(number == after);
29 }
30
31 void
32 run() override
33 {
35
36 {
37 STNumber const stnum{sfNumber};
38 BEAST_EXPECT(stnum.getSType() == STI_NUMBER);
39 BEAST_EXPECT(stnum.getText() == "0");
40 BEAST_EXPECT(stnum.isDefault() == true);
41 BEAST_EXPECT(stnum.value() == Number{0});
42 }
43
44 std::initializer_list<std::int64_t> const mantissas = {
46 -1,
47 0,
48 1,
50 for (std::int64_t mantissa : mantissas)
51 testCombo(Number{mantissa});
52
53 std::initializer_list<std::int32_t> const exponents = {
55 for (std::int32_t exponent : exponents)
56 testCombo(Number{123, exponent});
57
58 {
59 STAmount const strikePrice{noIssue(), 100};
60 STNumber const factor{sfNumber, 100};
61 auto const iouValue = strikePrice.iou();
62 IOUAmount totalValue{iouValue * factor};
63 STAmount const totalAmount{totalValue, strikePrice.issue()};
64 BEAST_EXPECT(totalAmount == Number{10'000});
65 }
66
67 {
68 BEAST_EXPECT(
69 numberFromJson(sfNumber, Json::Value(42)) ==
70 STNumber(sfNumber, 42));
71 BEAST_EXPECT(
72 numberFromJson(sfNumber, Json::Value(-42)) ==
73 STNumber(sfNumber, -42));
74
75 BEAST_EXPECT(
76 numberFromJson(sfNumber, Json::UInt(42)) ==
77 STNumber(sfNumber, 42));
78
79 BEAST_EXPECT(
80 numberFromJson(sfNumber, "-123") == STNumber(sfNumber, -123));
81
82 BEAST_EXPECT(
83 numberFromJson(sfNumber, "123") == STNumber(sfNumber, 123));
84 BEAST_EXPECT(
85 numberFromJson(sfNumber, "-123") == STNumber(sfNumber, -123));
86
87 BEAST_EXPECT(
88 numberFromJson(sfNumber, "3.14") ==
89 STNumber(sfNumber, Number(314, -2)));
90 BEAST_EXPECT(
91 numberFromJson(sfNumber, "-3.14") ==
92 STNumber(sfNumber, -Number(314, -2)));
93 BEAST_EXPECT(
94 numberFromJson(sfNumber, "3.14e2") == STNumber(sfNumber, 314));
95 BEAST_EXPECT(
96 numberFromJson(sfNumber, "-3.14e2") ==
97 STNumber(sfNumber, -314));
98
99 BEAST_EXPECT(
100 numberFromJson(sfNumber, "1000e-2") == STNumber(sfNumber, 10));
101 BEAST_EXPECT(
102 numberFromJson(sfNumber, "-1000e-2") ==
103 STNumber(sfNumber, -10));
104
105 BEAST_EXPECT(
106 numberFromJson(sfNumber, "0") == STNumber(sfNumber, 0));
107 BEAST_EXPECT(
108 numberFromJson(sfNumber, "0.0") == STNumber(sfNumber, 0));
109 BEAST_EXPECT(
110 numberFromJson(sfNumber, "0.000") == STNumber(sfNumber, 0));
111 BEAST_EXPECT(
112 numberFromJson(sfNumber, "-0") == STNumber(sfNumber, 0));
113 BEAST_EXPECT(
114 numberFromJson(sfNumber, "-0.0") == STNumber(sfNumber, 0));
115 BEAST_EXPECT(
116 numberFromJson(sfNumber, "-0.000") == STNumber(sfNumber, 0));
117 BEAST_EXPECT(
118 numberFromJson(sfNumber, "0e6") == STNumber(sfNumber, 0));
119 BEAST_EXPECT(
120 numberFromJson(sfNumber, "0.0e6") == STNumber(sfNumber, 0));
121 BEAST_EXPECT(
122 numberFromJson(sfNumber, "0.000e6") == STNumber(sfNumber, 0));
123 BEAST_EXPECT(
124 numberFromJson(sfNumber, "-0e6") == STNumber(sfNumber, 0));
125 BEAST_EXPECT(
126 numberFromJson(sfNumber, "-0.0e6") == STNumber(sfNumber, 0));
127 BEAST_EXPECT(
128 numberFromJson(sfNumber, "-0.000e6") == STNumber(sfNumber, 0));
129
130 constexpr auto imin = std::numeric_limits<int>::min();
131 BEAST_EXPECT(
132 numberFromJson(sfNumber, imin) ==
133 STNumber(sfNumber, Number(imin, 0)));
134 BEAST_EXPECT(
135 numberFromJson(sfNumber, std::to_string(imin)) ==
136 STNumber(sfNumber, Number(imin, 0)));
137
138 constexpr auto imax = std::numeric_limits<int>::max();
139 BEAST_EXPECT(
140 numberFromJson(sfNumber, imax) ==
141 STNumber(sfNumber, Number(imax, 0)));
142 BEAST_EXPECT(
143 numberFromJson(sfNumber, std::to_string(imax)) ==
144 STNumber(sfNumber, Number(imax, 0)));
145
146 constexpr auto umax = std::numeric_limits<unsigned int>::max();
147 BEAST_EXPECT(
148 numberFromJson(sfNumber, umax) ==
149 STNumber(sfNumber, Number(umax, 0)));
150 BEAST_EXPECT(
151 numberFromJson(sfNumber, std::to_string(umax)) ==
152 STNumber(sfNumber, Number(umax, 0)));
153
154 // Obvious non-numbers tested here
155 try
156 {
157 auto _ = numberFromJson(sfNumber, "");
158 BEAST_EXPECT(false);
159 }
160 catch (std::runtime_error const& e)
161 {
162 std::string const expected = "'' is not a number";
163 BEAST_EXPECT(e.what() == expected);
164 }
165
166 try
167 {
168 auto _ = numberFromJson(sfNumber, "e");
169 BEAST_EXPECT(false);
170 }
171 catch (std::runtime_error const& e)
172 {
173 std::string const expected = "'e' is not a number";
174 BEAST_EXPECT(e.what() == expected);
175 }
176
177 try
178 {
179 auto _ = numberFromJson(sfNumber, "1e");
180 BEAST_EXPECT(false);
181 }
182 catch (std::runtime_error const& e)
183 {
184 std::string const expected = "'1e' is not a number";
185 BEAST_EXPECT(e.what() == expected);
186 }
187
188 try
189 {
190 auto _ = numberFromJson(sfNumber, "e2");
191 BEAST_EXPECT(false);
192 }
193 catch (std::runtime_error const& e)
194 {
195 std::string const expected = "'e2' is not a number";
196 BEAST_EXPECT(e.what() == expected);
197 }
198
199 try
200 {
201 auto _ = numberFromJson(sfNumber, Json::Value());
202 BEAST_EXPECT(false);
203 }
204 catch (std::runtime_error const& e)
205 {
206 std::string const expected = "not a number";
207 BEAST_EXPECT(e.what() == expected);
208 }
209
210 try
211 {
212 auto _ = numberFromJson(
213 sfNumber,
214 "1234567890123456789012345678901234567890123456789012345678"
215 "9012345678901234567890123456789012345678901234567890123456"
216 "78901234567890123456789012345678901234567890");
217 BEAST_EXPECT(false);
218 }
219 catch (std::bad_cast const& e)
220 {
221 BEAST_EXPECT(true);
222 }
223
224 // We do not handle leading zeros
225 try
226 {
227 auto _ = numberFromJson(sfNumber, "001");
228 BEAST_EXPECT(false);
229 }
230 catch (std::runtime_error const& e)
231 {
232 std::string const expected = "'001' is not a number";
233 BEAST_EXPECT(e.what() == expected);
234 }
235
236 try
237 {
238 auto _ = numberFromJson(sfNumber, "000.0");
239 BEAST_EXPECT(false);
240 }
241 catch (std::runtime_error const& e)
242 {
243 std::string const expected = "'000.0' is not a number";
244 BEAST_EXPECT(e.what() == expected);
245 }
246
247 // We do not handle dangling dot
248 try
249 {
250 auto _ = numberFromJson(sfNumber, ".1");
251 BEAST_EXPECT(false);
252 }
253 catch (std::runtime_error const& e)
254 {
255 std::string const expected = "'.1' is not a number";
256 BEAST_EXPECT(e.what() == expected);
257 }
258
259 try
260 {
261 auto _ = numberFromJson(sfNumber, "1.");
262 BEAST_EXPECT(false);
263 }
264 catch (std::runtime_error const& e)
265 {
266 std::string const expected = "'1.' is not a number";
267 BEAST_EXPECT(e.what() == expected);
268 }
269
270 try
271 {
272 auto _ = numberFromJson(sfNumber, "1.e3");
273 BEAST_EXPECT(false);
274 }
275 catch (std::runtime_error const& e)
276 {
277 std::string const expected = "'1.e3' is not a number";
278 BEAST_EXPECT(e.what() == expected);
279 }
280 }
281 }
282};
283
284BEAST_DEFINE_TESTSUITE(STNumber, protocol, ripple);
285
286void
288{
289 STNumber number{sfNumber, 42};
290 out << number;
291}
292
293} // namespace ripple
Represents a JSON value.
Definition json_value.h:131
A testsuite class.
Definition suite.h:52
Floating point representation of amounts with high dynamic range.
Definition IOUAmount.h:27
static constexpr int maxExponent
Definition Number.h:29
static constexpr int minExponent
Definition Number.h:28
Issue const & issue() const
Definition STAmount.h:477
A serializable number.
Definition STNumber.h:24
std::size_t size() const noexcept
Definition Serializer.h:53
Slice slice() const noexcept
Definition Serializer.h:47
T is_same_v
T max(T... args)
T min(T... args)
unsigned int UInt
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6
void testCompile(std::ostream &out)
Issue const & noIssue()
Returns an asset specifier that represents no account and currency.
Definition Issue.h:104
STNumber numberFromJson(SField const &field, Json::Value const &value)
Definition STNumber.cpp:160
bool after(NetClock::time_point now, std::uint32_t mark)
Has the specified time passed?
Definition View.cpp:3247
void testCombo(Number number)
void run() override
Runs the suite.
T to_string(T... args)
T what(T... args)