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/STAmount.h>
6#include <xrpl/protocol/STNumber.h>
7
8#include <limits>
9#include <ostream>
10#include <stdexcept>
11
12namespace ripple {
13
15{
16 void
18 {
19 STNumber const before{sfNumber, number};
20 BEAST_EXPECT(number == before);
21 Serializer s;
22 before.add(s);
23 BEAST_EXPECT(s.size() == 12);
24 SerialIter sit(s.slice());
25 STNumber const after{sit, sfNumber};
26 BEAST_EXPECT(after.isEquivalent(before));
27 BEAST_EXPECT(number == after);
28 }
29
30 void
31 run() override
32 {
34
35 {
36 STNumber const stnum{sfNumber};
37 BEAST_EXPECT(stnum.getSType() == STI_NUMBER);
38 BEAST_EXPECT(stnum.getText() == "0");
39 BEAST_EXPECT(stnum.isDefault() == true);
40 BEAST_EXPECT(stnum.value() == Number{0});
41 }
42
43 std::initializer_list<std::int64_t> const mantissas = {
45 -1,
46 0,
47 1,
49 for (std::int64_t mantissa : mantissas)
50 testCombo(Number{mantissa});
51
52 std::initializer_list<std::int32_t> const exponents = {
54 for (std::int32_t exponent : exponents)
55 testCombo(Number{123, exponent});
56
57 {
58 STAmount const strikePrice{noIssue(), 100};
59 STNumber const factor{sfNumber, 100};
60 auto const iouValue = strikePrice.iou();
61 IOUAmount totalValue{iouValue * factor};
62 STAmount const totalAmount{totalValue, strikePrice.issue()};
63 BEAST_EXPECT(totalAmount == Number{10'000});
64 }
65
66 {
67 BEAST_EXPECT(
68 numberFromJson(sfNumber, Json::Value(42)) ==
69 STNumber(sfNumber, 42));
70 BEAST_EXPECT(
71 numberFromJson(sfNumber, Json::Value(-42)) ==
72 STNumber(sfNumber, -42));
73
74 BEAST_EXPECT(
75 numberFromJson(sfNumber, Json::UInt(42)) ==
76 STNumber(sfNumber, 42));
77
78 BEAST_EXPECT(
79 numberFromJson(sfNumber, "-123") == STNumber(sfNumber, -123));
80
81 BEAST_EXPECT(
82 numberFromJson(sfNumber, "123") == STNumber(sfNumber, 123));
83 BEAST_EXPECT(
84 numberFromJson(sfNumber, "-123") == STNumber(sfNumber, -123));
85
86 BEAST_EXPECT(
87 numberFromJson(sfNumber, "3.14") ==
88 STNumber(sfNumber, Number(314, -2)));
89 BEAST_EXPECT(
90 numberFromJson(sfNumber, "-3.14") ==
91 STNumber(sfNumber, -Number(314, -2)));
92 BEAST_EXPECT(
93 numberFromJson(sfNumber, "3.14e2") == STNumber(sfNumber, 314));
94 BEAST_EXPECT(
95 numberFromJson(sfNumber, "-3.14e2") ==
96 STNumber(sfNumber, -314));
97
98 BEAST_EXPECT(
99 numberFromJson(sfNumber, "1000e-2") == STNumber(sfNumber, 10));
100 BEAST_EXPECT(
101 numberFromJson(sfNumber, "-1000e-2") ==
102 STNumber(sfNumber, -10));
103
104 BEAST_EXPECT(
105 numberFromJson(sfNumber, "0") == STNumber(sfNumber, 0));
106 BEAST_EXPECT(
107 numberFromJson(sfNumber, "0.0") == STNumber(sfNumber, 0));
108 BEAST_EXPECT(
109 numberFromJson(sfNumber, "0.000") == STNumber(sfNumber, 0));
110 BEAST_EXPECT(
111 numberFromJson(sfNumber, "-0") == STNumber(sfNumber, 0));
112 BEAST_EXPECT(
113 numberFromJson(sfNumber, "-0.0") == STNumber(sfNumber, 0));
114 BEAST_EXPECT(
115 numberFromJson(sfNumber, "-0.000") == STNumber(sfNumber, 0));
116 BEAST_EXPECT(
117 numberFromJson(sfNumber, "0e6") == STNumber(sfNumber, 0));
118 BEAST_EXPECT(
119 numberFromJson(sfNumber, "0.0e6") == STNumber(sfNumber, 0));
120 BEAST_EXPECT(
121 numberFromJson(sfNumber, "0.000e6") == STNumber(sfNumber, 0));
122 BEAST_EXPECT(
123 numberFromJson(sfNumber, "-0e6") == STNumber(sfNumber, 0));
124 BEAST_EXPECT(
125 numberFromJson(sfNumber, "-0.0e6") == STNumber(sfNumber, 0));
126 BEAST_EXPECT(
127 numberFromJson(sfNumber, "-0.000e6") == STNumber(sfNumber, 0));
128
129 // Obvious non-numbers tested here
130 try
131 {
132 auto _ = numberFromJson(sfNumber, "");
133 BEAST_EXPECT(false);
134 }
135 catch (std::runtime_error const& e)
136 {
137 std::string const expected = "'' is not a number";
138 BEAST_EXPECT(e.what() == expected);
139 }
140
141 try
142 {
143 auto _ = numberFromJson(sfNumber, "e");
144 BEAST_EXPECT(false);
145 }
146 catch (std::runtime_error const& e)
147 {
148 std::string const expected = "'e' is not a number";
149 BEAST_EXPECT(e.what() == expected);
150 }
151
152 try
153 {
154 auto _ = numberFromJson(sfNumber, "1e");
155 BEAST_EXPECT(false);
156 }
157 catch (std::runtime_error const& e)
158 {
159 std::string const expected = "'1e' is not a number";
160 BEAST_EXPECT(e.what() == expected);
161 }
162
163 try
164 {
165 auto _ = numberFromJson(sfNumber, "e2");
166 BEAST_EXPECT(false);
167 }
168 catch (std::runtime_error const& e)
169 {
170 std::string const expected = "'e2' is not a number";
171 BEAST_EXPECT(e.what() == expected);
172 }
173
174 try
175 {
176 auto _ = numberFromJson(sfNumber, Json::Value());
177 BEAST_EXPECT(false);
178 }
179 catch (std::runtime_error const& e)
180 {
181 std::string const expected = "not a number";
182 BEAST_EXPECT(e.what() == expected);
183 }
184
185 try
186 {
187 auto _ = numberFromJson(
188 sfNumber,
189 "1234567890123456789012345678901234567890123456789012345678"
190 "9012345678901234567890123456789012345678901234567890123456"
191 "78901234567890123456789012345678901234567890");
192 BEAST_EXPECT(false);
193 }
194 catch (std::bad_cast const& e)
195 {
196 BEAST_EXPECT(true);
197 }
198
199 // We do not handle leading zeros
200 try
201 {
202 auto _ = numberFromJson(sfNumber, "001");
203 BEAST_EXPECT(false);
204 }
205 catch (std::runtime_error const& e)
206 {
207 std::string const expected = "'001' is not a number";
208 BEAST_EXPECT(e.what() == expected);
209 }
210
211 try
212 {
213 auto _ = numberFromJson(sfNumber, "000.0");
214 BEAST_EXPECT(false);
215 }
216 catch (std::runtime_error const& e)
217 {
218 std::string const expected = "'000.0' is not a number";
219 BEAST_EXPECT(e.what() == expected);
220 }
221
222 // We do not handle dangling dot
223 try
224 {
225 auto _ = numberFromJson(sfNumber, ".1");
226 BEAST_EXPECT(false);
227 }
228 catch (std::runtime_error const& e)
229 {
230 std::string const expected = "'.1' is not a number";
231 BEAST_EXPECT(e.what() == expected);
232 }
233
234 try
235 {
236 auto _ = numberFromJson(sfNumber, "1.");
237 BEAST_EXPECT(false);
238 }
239 catch (std::runtime_error const& e)
240 {
241 std::string const expected = "'1.' is not a number";
242 BEAST_EXPECT(e.what() == expected);
243 }
244
245 try
246 {
247 auto _ = numberFromJson(sfNumber, "1.e3");
248 BEAST_EXPECT(false);
249 }
250 catch (std::runtime_error const& e)
251 {
252 std::string const expected = "'1.e3' is not a number";
253 BEAST_EXPECT(e.what() == expected);
254 }
255 }
256 }
257};
258
259BEAST_DEFINE_TESTSUITE(STNumber, protocol, ripple);
260
261void
263{
264 STNumber number{sfNumber, 42};
265 out << number;
266}
267
268} // namespace ripple
Represents a JSON value.
Definition json_value.h:130
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 what(T... args)