rippled
Loading...
Searching...
No Matches
OfferTests.cpp
1// Auto-generated unit tests for ledger entry Offer
2
3
4#include <gtest/gtest.h>
5
6#include <protocol_autogen/TestHelpers.h>
7
8#include <xrpl/protocol/STLedgerEntry.h>
9#include <xrpl/protocol_autogen/ledger_entries/Offer.h>
10#include <xrpl/protocol_autogen/ledger_entries/Ticket.h>
11
12#include <string>
13
14namespace xrpl::ledger_entries {
15
16// 1 & 4) Set fields via builder setters, build, then read them back via
17// wrapper getters. After build(), validate() should succeed for both the
18// builder's STObject and the wrapper's SLE.
19TEST(OfferTests, BuilderSettersRoundTrip)
20{
21 uint256 const index{1u};
22
23 auto const accountValue = canonical_ACCOUNT();
24 auto const sequenceValue = canonical_UINT32();
25 auto const takerPaysValue = canonical_AMOUNT();
26 auto const takerGetsValue = canonical_AMOUNT();
27 auto const bookDirectoryValue = canonical_UINT256();
28 auto const bookNodeValue = canonical_UINT64();
29 auto const ownerNodeValue = canonical_UINT64();
30 auto const previousTxnIDValue = canonical_UINT256();
31 auto const previousTxnLgrSeqValue = canonical_UINT32();
32 auto const expirationValue = canonical_UINT32();
33 auto const domainIDValue = canonical_UINT256();
34 auto const additionalBooksValue = canonical_ARRAY();
35
36 OfferBuilder builder{
37 accountValue,
38 sequenceValue,
39 takerPaysValue,
40 takerGetsValue,
41 bookDirectoryValue,
42 bookNodeValue,
43 ownerNodeValue,
44 previousTxnIDValue,
45 previousTxnLgrSeqValue
46 };
47
48 builder.setExpiration(expirationValue);
49 builder.setDomainID(domainIDValue);
50 builder.setAdditionalBooks(additionalBooksValue);
51
52 builder.setLedgerIndex(index);
53 builder.setFlags(0x1u);
54
55 EXPECT_TRUE(builder.validate());
56
57 auto const entry = builder.build(index);
58
59 EXPECT_TRUE(entry.validate());
60
61 {
62 auto const& expected = accountValue;
63 auto const actual = entry.getAccount();
64 expectEqualField(expected, actual, "sfAccount");
65 }
66
67 {
68 auto const& expected = sequenceValue;
69 auto const actual = entry.getSequence();
70 expectEqualField(expected, actual, "sfSequence");
71 }
72
73 {
74 auto const& expected = takerPaysValue;
75 auto const actual = entry.getTakerPays();
76 expectEqualField(expected, actual, "sfTakerPays");
77 }
78
79 {
80 auto const& expected = takerGetsValue;
81 auto const actual = entry.getTakerGets();
82 expectEqualField(expected, actual, "sfTakerGets");
83 }
84
85 {
86 auto const& expected = bookDirectoryValue;
87 auto const actual = entry.getBookDirectory();
88 expectEqualField(expected, actual, "sfBookDirectory");
89 }
90
91 {
92 auto const& expected = bookNodeValue;
93 auto const actual = entry.getBookNode();
94 expectEqualField(expected, actual, "sfBookNode");
95 }
96
97 {
98 auto const& expected = ownerNodeValue;
99 auto const actual = entry.getOwnerNode();
100 expectEqualField(expected, actual, "sfOwnerNode");
101 }
102
103 {
104 auto const& expected = previousTxnIDValue;
105 auto const actual = entry.getPreviousTxnID();
106 expectEqualField(expected, actual, "sfPreviousTxnID");
107 }
108
109 {
110 auto const& expected = previousTxnLgrSeqValue;
111 auto const actual = entry.getPreviousTxnLgrSeq();
112 expectEqualField(expected, actual, "sfPreviousTxnLgrSeq");
113 }
114
115 {
116 auto const& expected = expirationValue;
117 auto const actualOpt = entry.getExpiration();
118 ASSERT_TRUE(actualOpt.has_value());
119 expectEqualField(expected, *actualOpt, "sfExpiration");
120 EXPECT_TRUE(entry.hasExpiration());
121 }
122
123 {
124 auto const& expected = domainIDValue;
125 auto const actualOpt = entry.getDomainID();
126 ASSERT_TRUE(actualOpt.has_value());
127 expectEqualField(expected, *actualOpt, "sfDomainID");
128 EXPECT_TRUE(entry.hasDomainID());
129 }
130
131 {
132 auto const& expected = additionalBooksValue;
133 auto const actualOpt = entry.getAdditionalBooks();
134 ASSERT_TRUE(actualOpt.has_value());
135 expectEqualField(expected, *actualOpt, "sfAdditionalBooks");
136 EXPECT_TRUE(entry.hasAdditionalBooks());
137 }
138
139 EXPECT_TRUE(entry.hasLedgerIndex());
140 auto const ledgerIndex = entry.getLedgerIndex();
141 ASSERT_TRUE(ledgerIndex.has_value());
142 EXPECT_EQ(*ledgerIndex, index);
143 EXPECT_EQ(entry.getKey(), index);
144}
145
146// 2 & 4) Start from an SLE, set fields directly on it, construct a builder
147// from that SLE, build a new wrapper, and verify all fields (and validate()).
148TEST(OfferTests, BuilderFromSleRoundTrip)
149{
150 uint256 const index{2u};
151
152 auto const accountValue = canonical_ACCOUNT();
153 auto const sequenceValue = canonical_UINT32();
154 auto const takerPaysValue = canonical_AMOUNT();
155 auto const takerGetsValue = canonical_AMOUNT();
156 auto const bookDirectoryValue = canonical_UINT256();
157 auto const bookNodeValue = canonical_UINT64();
158 auto const ownerNodeValue = canonical_UINT64();
159 auto const previousTxnIDValue = canonical_UINT256();
160 auto const previousTxnLgrSeqValue = canonical_UINT32();
161 auto const expirationValue = canonical_UINT32();
162 auto const domainIDValue = canonical_UINT256();
163 auto const additionalBooksValue = canonical_ARRAY();
164
165 auto sle = std::make_shared<SLE>(Offer::entryType, index);
166
167 sle->at(sfAccount) = accountValue;
168 sle->at(sfSequence) = sequenceValue;
169 sle->at(sfTakerPays) = takerPaysValue;
170 sle->at(sfTakerGets) = takerGetsValue;
171 sle->at(sfBookDirectory) = bookDirectoryValue;
172 sle->at(sfBookNode) = bookNodeValue;
173 sle->at(sfOwnerNode) = ownerNodeValue;
174 sle->at(sfPreviousTxnID) = previousTxnIDValue;
175 sle->at(sfPreviousTxnLgrSeq) = previousTxnLgrSeqValue;
176 sle->at(sfExpiration) = expirationValue;
177 sle->at(sfDomainID) = domainIDValue;
178 sle->setFieldArray(sfAdditionalBooks, additionalBooksValue);
179
180 OfferBuilder builderFromSle{sle};
181 EXPECT_TRUE(builderFromSle.validate());
182
183 auto const entryFromBuilder = builderFromSle.build(index);
184
185 Offer entryFromSle{sle};
186 EXPECT_TRUE(entryFromBuilder.validate());
187 EXPECT_TRUE(entryFromSle.validate());
188
189 {
190 auto const& expected = accountValue;
191
192 auto const fromSle = entryFromSle.getAccount();
193 auto const fromBuilder = entryFromBuilder.getAccount();
194
195 expectEqualField(expected, fromSle, "sfAccount");
196 expectEqualField(expected, fromBuilder, "sfAccount");
197 }
198
199 {
200 auto const& expected = sequenceValue;
201
202 auto const fromSle = entryFromSle.getSequence();
203 auto const fromBuilder = entryFromBuilder.getSequence();
204
205 expectEqualField(expected, fromSle, "sfSequence");
206 expectEqualField(expected, fromBuilder, "sfSequence");
207 }
208
209 {
210 auto const& expected = takerPaysValue;
211
212 auto const fromSle = entryFromSle.getTakerPays();
213 auto const fromBuilder = entryFromBuilder.getTakerPays();
214
215 expectEqualField(expected, fromSle, "sfTakerPays");
216 expectEqualField(expected, fromBuilder, "sfTakerPays");
217 }
218
219 {
220 auto const& expected = takerGetsValue;
221
222 auto const fromSle = entryFromSle.getTakerGets();
223 auto const fromBuilder = entryFromBuilder.getTakerGets();
224
225 expectEqualField(expected, fromSle, "sfTakerGets");
226 expectEqualField(expected, fromBuilder, "sfTakerGets");
227 }
228
229 {
230 auto const& expected = bookDirectoryValue;
231
232 auto const fromSle = entryFromSle.getBookDirectory();
233 auto const fromBuilder = entryFromBuilder.getBookDirectory();
234
235 expectEqualField(expected, fromSle, "sfBookDirectory");
236 expectEqualField(expected, fromBuilder, "sfBookDirectory");
237 }
238
239 {
240 auto const& expected = bookNodeValue;
241
242 auto const fromSle = entryFromSle.getBookNode();
243 auto const fromBuilder = entryFromBuilder.getBookNode();
244
245 expectEqualField(expected, fromSle, "sfBookNode");
246 expectEqualField(expected, fromBuilder, "sfBookNode");
247 }
248
249 {
250 auto const& expected = ownerNodeValue;
251
252 auto const fromSle = entryFromSle.getOwnerNode();
253 auto const fromBuilder = entryFromBuilder.getOwnerNode();
254
255 expectEqualField(expected, fromSle, "sfOwnerNode");
256 expectEqualField(expected, fromBuilder, "sfOwnerNode");
257 }
258
259 {
260 auto const& expected = previousTxnIDValue;
261
262 auto const fromSle = entryFromSle.getPreviousTxnID();
263 auto const fromBuilder = entryFromBuilder.getPreviousTxnID();
264
265 expectEqualField(expected, fromSle, "sfPreviousTxnID");
266 expectEqualField(expected, fromBuilder, "sfPreviousTxnID");
267 }
268
269 {
270 auto const& expected = previousTxnLgrSeqValue;
271
272 auto const fromSle = entryFromSle.getPreviousTxnLgrSeq();
273 auto const fromBuilder = entryFromBuilder.getPreviousTxnLgrSeq();
274
275 expectEqualField(expected, fromSle, "sfPreviousTxnLgrSeq");
276 expectEqualField(expected, fromBuilder, "sfPreviousTxnLgrSeq");
277 }
278
279 {
280 auto const& expected = expirationValue;
281
282 auto const fromSleOpt = entryFromSle.getExpiration();
283 auto const fromBuilderOpt = entryFromBuilder.getExpiration();
284
285 ASSERT_TRUE(fromSleOpt.has_value());
286 ASSERT_TRUE(fromBuilderOpt.has_value());
287
288 expectEqualField(expected, *fromSleOpt, "sfExpiration");
289 expectEqualField(expected, *fromBuilderOpt, "sfExpiration");
290 }
291
292 {
293 auto const& expected = domainIDValue;
294
295 auto const fromSleOpt = entryFromSle.getDomainID();
296 auto const fromBuilderOpt = entryFromBuilder.getDomainID();
297
298 ASSERT_TRUE(fromSleOpt.has_value());
299 ASSERT_TRUE(fromBuilderOpt.has_value());
300
301 expectEqualField(expected, *fromSleOpt, "sfDomainID");
302 expectEqualField(expected, *fromBuilderOpt, "sfDomainID");
303 }
304
305 {
306 auto const& expected = additionalBooksValue;
307
308 auto const fromSleOpt = entryFromSle.getAdditionalBooks();
309 auto const fromBuilderOpt = entryFromBuilder.getAdditionalBooks();
310
311 ASSERT_TRUE(fromSleOpt.has_value());
312 ASSERT_TRUE(fromBuilderOpt.has_value());
313
314 expectEqualField(expected, *fromSleOpt, "sfAdditionalBooks");
315 expectEqualField(expected, *fromBuilderOpt, "sfAdditionalBooks");
316 }
317
318 EXPECT_EQ(entryFromSle.getKey(), index);
319 EXPECT_EQ(entryFromBuilder.getKey(), index);
320}
321
322// 3) Verify wrapper throws when constructed from wrong ledger entry type.
323TEST(OfferTests, WrapperThrowsOnWrongEntryType)
324{
325 uint256 const index{3u};
326
327 // Build a valid ledger entry of a different type
328 // Ticket requires: Account, OwnerNode, TicketSequence, PreviousTxnID, PreviousTxnLgrSeq
329 // Check requires: Account, Destination, SendMax, Sequence, OwnerNode, DestinationNode, PreviousTxnID, PreviousTxnLgrSeq
330 TicketBuilder wrongBuilder{
336 auto wrongEntry = wrongBuilder.build(index);
337
338 EXPECT_THROW(Offer{wrongEntry.getSle()}, std::runtime_error);
339}
340
341// 4) Verify builder throws when constructed from wrong ledger entry type.
342TEST(OfferTests, BuilderThrowsOnWrongEntryType)
343{
344 uint256 const index{4u};
345
346 // Build a valid ledger entry of a different type
347 TicketBuilder wrongBuilder{
353 auto wrongEntry = wrongBuilder.build(index);
354
355 EXPECT_THROW(OfferBuilder{wrongEntry.getSle()}, std::runtime_error);
356}
357
358// 5) Build with only required fields and verify optional fields return nullopt.
359TEST(OfferTests, OptionalFieldsReturnNullopt)
360{
361 uint256 const index{3u};
362
363 auto const accountValue = canonical_ACCOUNT();
364 auto const sequenceValue = canonical_UINT32();
365 auto const takerPaysValue = canonical_AMOUNT();
366 auto const takerGetsValue = canonical_AMOUNT();
367 auto const bookDirectoryValue = canonical_UINT256();
368 auto const bookNodeValue = canonical_UINT64();
369 auto const ownerNodeValue = canonical_UINT64();
370 auto const previousTxnIDValue = canonical_UINT256();
371 auto const previousTxnLgrSeqValue = canonical_UINT32();
372
373 OfferBuilder builder{
374 accountValue,
375 sequenceValue,
376 takerPaysValue,
377 takerGetsValue,
378 bookDirectoryValue,
379 bookNodeValue,
380 ownerNodeValue,
381 previousTxnIDValue,
382 previousTxnLgrSeqValue
383 };
384
385 auto const entry = builder.build(index);
386
387 // Verify optional fields are not present
388 EXPECT_FALSE(entry.hasExpiration());
389 EXPECT_FALSE(entry.getExpiration().has_value());
390 EXPECT_FALSE(entry.hasDomainID());
391 EXPECT_FALSE(entry.getDomainID().has_value());
392 EXPECT_FALSE(entry.hasAdditionalBooks());
393 EXPECT_FALSE(entry.getAdditionalBooks().has_value());
394}
395}
std::shared_ptr< SLE const > getSle() const
Get the underlying SLE object.
Derived & setLedgerIndex(uint256 const &value)
Set the ledger index.
Derived & setFlags(uint32_t value)
Set the flags.
OfferBuilder & setExpiration(std::decay_t< typename SF_UINT32::type::value_type > const &value)
Set sfExpiration (soeOPTIONAL)
OfferBuilder & setDomainID(std::decay_t< typename SF_UINT256::type::value_type > const &value)
Set sfDomainID (soeOPTIONAL)
OfferBuilder & setAdditionalBooks(STArray const &value)
Set sfAdditionalBooks (soeOPTIONAL)
Builder for Ticket ledger entries.
Definition Ticket.h:112
T is_same_v
TEST(AccountRootTests, BuilderSettersRoundTrip)
void expectEqualField(T const &expected, T const &actual, char const *fieldName)