rippled
Loading...
Searching...
No Matches
Issue_test.cpp
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github.com/ripple/rippled
4 Copyright (c) 2012, 2013 Ripple Labs Inc.
5
6 Permission to use, copy, modify, and/or distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#include <xrpl/basics/UnorderedContainers.h>
21#include <xrpl/beast/unit_test.h>
22#include <xrpl/protocol/Book.h>
23#include <xrpl/protocol/Issue.h>
24
25#include <map>
26#include <set>
27#include <typeinfo>
28#include <unordered_set>
29
30#if BEAST_MSVC
31#define STL_SET_HAS_EMPLACE 1
32#else
33#define STL_SET_HAS_EMPLACE 0
34#endif
35
36#ifndef RIPPLE_ASSETS_ENABLE_STD_HASH
37#if BEAST_MAC || BEAST_IOS
38#define RIPPLE_ASSETS_ENABLE_STD_HASH 0
39#else
40#define RIPPLE_ASSETS_ENABLE_STD_HASH 1
41#endif
42#endif
43
44namespace ripple {
45
47{
48public:
49 // Comparison, hash tests for uint60 (via base_uint)
50 template <typename Unsigned>
51 void
53 {
54 Unsigned const u1(1);
55 Unsigned const u2(2);
56 Unsigned const u3(3);
57
58 BEAST_EXPECT(u1 != u2);
59 BEAST_EXPECT(u1 < u2);
60 BEAST_EXPECT(u1 <= u2);
61 BEAST_EXPECT(u2 <= u2);
62 BEAST_EXPECT(u2 == u2);
63 BEAST_EXPECT(u2 >= u2);
64 BEAST_EXPECT(u3 >= u2);
65 BEAST_EXPECT(u3 > u2);
66
68
69 BEAST_EXPECT(hash(u1) == hash(u1));
70 BEAST_EXPECT(hash(u2) == hash(u2));
71 BEAST_EXPECT(hash(u3) == hash(u3));
72 BEAST_EXPECT(hash(u1) != hash(u2));
73 BEAST_EXPECT(hash(u1) != hash(u3));
74 BEAST_EXPECT(hash(u2) != hash(u3));
75 }
76
77 //--------------------------------------------------------------------------
78
79 // Comparison, hash tests for Issue
80 template <class Issue>
81 void
83 {
84 Currency const c1(1);
85 AccountID const i1(1);
86 Currency const c2(2);
87 AccountID const i2(2);
88 Currency const c3(3);
89 AccountID const i3(3);
90
91 BEAST_EXPECT(Issue(c1, i1) != Issue(c2, i1));
92 BEAST_EXPECT(Issue(c1, i1) < Issue(c2, i1));
93 BEAST_EXPECT(Issue(c1, i1) <= Issue(c2, i1));
94 BEAST_EXPECT(Issue(c2, i1) <= Issue(c2, i1));
95 BEAST_EXPECT(Issue(c2, i1) == Issue(c2, i1));
96 BEAST_EXPECT(Issue(c2, i1) >= Issue(c2, i1));
97 BEAST_EXPECT(Issue(c3, i1) >= Issue(c2, i1));
98 BEAST_EXPECT(Issue(c3, i1) > Issue(c2, i1));
99 BEAST_EXPECT(Issue(c1, i1) != Issue(c1, i2));
100 BEAST_EXPECT(Issue(c1, i1) < Issue(c1, i2));
101 BEAST_EXPECT(Issue(c1, i1) <= Issue(c1, i2));
102 BEAST_EXPECT(Issue(c1, i2) <= Issue(c1, i2));
103 BEAST_EXPECT(Issue(c1, i2) == Issue(c1, i2));
104 BEAST_EXPECT(Issue(c1, i2) >= Issue(c1, i2));
105 BEAST_EXPECT(Issue(c1, i3) >= Issue(c1, i2));
106 BEAST_EXPECT(Issue(c1, i3) > Issue(c1, i2));
107
108 std::hash<Issue> hash;
109
110 BEAST_EXPECT(hash(Issue(c1, i1)) == hash(Issue(c1, i1)));
111 BEAST_EXPECT(hash(Issue(c1, i2)) == hash(Issue(c1, i2)));
112 BEAST_EXPECT(hash(Issue(c1, i3)) == hash(Issue(c1, i3)));
113 BEAST_EXPECT(hash(Issue(c2, i1)) == hash(Issue(c2, i1)));
114 BEAST_EXPECT(hash(Issue(c2, i2)) == hash(Issue(c2, i2)));
115 BEAST_EXPECT(hash(Issue(c2, i3)) == hash(Issue(c2, i3)));
116 BEAST_EXPECT(hash(Issue(c3, i1)) == hash(Issue(c3, i1)));
117 BEAST_EXPECT(hash(Issue(c3, i2)) == hash(Issue(c3, i2)));
118 BEAST_EXPECT(hash(Issue(c3, i3)) == hash(Issue(c3, i3)));
119 BEAST_EXPECT(hash(Issue(c1, i1)) != hash(Issue(c1, i2)));
120 BEAST_EXPECT(hash(Issue(c1, i1)) != hash(Issue(c1, i3)));
121 BEAST_EXPECT(hash(Issue(c1, i1)) != hash(Issue(c2, i1)));
122 BEAST_EXPECT(hash(Issue(c1, i1)) != hash(Issue(c2, i2)));
123 BEAST_EXPECT(hash(Issue(c1, i1)) != hash(Issue(c2, i3)));
124 BEAST_EXPECT(hash(Issue(c1, i1)) != hash(Issue(c3, i1)));
125 BEAST_EXPECT(hash(Issue(c1, i1)) != hash(Issue(c3, i2)));
126 BEAST_EXPECT(hash(Issue(c1, i1)) != hash(Issue(c3, i3)));
127 }
128
129 template <class Set>
130 void
132 {
133 Currency const c1(1);
134 AccountID const i1(1);
135 Currency const c2(2);
136 AccountID const i2(2);
137 Issue const a1(c1, i1);
138 Issue const a2(c2, i2);
139
140 {
141 Set c;
142
143 c.insert(a1);
144 if (!BEAST_EXPECT(c.size() == 1))
145 return;
146 c.insert(a2);
147 if (!BEAST_EXPECT(c.size() == 2))
148 return;
149
150 if (!BEAST_EXPECT(c.erase(Issue(c1, i2)) == 0))
151 return;
152 if (!BEAST_EXPECT(c.erase(Issue(c1, i1)) == 1))
153 return;
154 if (!BEAST_EXPECT(c.erase(Issue(c2, i2)) == 1))
155 return;
156 if (!BEAST_EXPECT(c.empty()))
157 return;
158 }
159
160 {
161 Set c;
162
163 c.insert(a1);
164 if (!BEAST_EXPECT(c.size() == 1))
165 return;
166 c.insert(a2);
167 if (!BEAST_EXPECT(c.size() == 2))
168 return;
169
170 if (!BEAST_EXPECT(c.erase(Issue(c1, i2)) == 0))
171 return;
172 if (!BEAST_EXPECT(c.erase(Issue(c1, i1)) == 1))
173 return;
174 if (!BEAST_EXPECT(c.erase(Issue(c2, i2)) == 1))
175 return;
176 if (!BEAST_EXPECT(c.empty()))
177 return;
178
179#if STL_SET_HAS_EMPLACE
180 c.emplace(c1, i1);
181 if (!BEAST_EXPECT(c.size() == 1))
182 return;
183 c.emplace(c2, i2);
184 if (!BEAST_EXPECT(c.size() == 2))
185 return;
186#endif
187 }
188 }
189
190 template <class Map>
191 void
193 {
194 Currency const c1(1);
195 AccountID const i1(1);
196 Currency const c2(2);
197 AccountID const i2(2);
198 Issue const a1(c1, i1);
199 Issue const a2(c2, i2);
200
201 {
202 Map c;
203
204 c.insert(std::make_pair(a1, 1));
205 if (!BEAST_EXPECT(c.size() == 1))
206 return;
207 c.insert(std::make_pair(a2, 2));
208 if (!BEAST_EXPECT(c.size() == 2))
209 return;
210
211 if (!BEAST_EXPECT(c.erase(Issue(c1, i2)) == 0))
212 return;
213 if (!BEAST_EXPECT(c.erase(Issue(c1, i1)) == 1))
214 return;
215 if (!BEAST_EXPECT(c.erase(Issue(c2, i2)) == 1))
216 return;
217 if (!BEAST_EXPECT(c.empty()))
218 return;
219 }
220
221 {
222 Map c;
223
224 c.insert(std::make_pair(a1, 1));
225 if (!BEAST_EXPECT(c.size() == 1))
226 return;
227 c.insert(std::make_pair(a2, 2));
228 if (!BEAST_EXPECT(c.size() == 2))
229 return;
230
231 if (!BEAST_EXPECT(c.erase(Issue(c1, i2)) == 0))
232 return;
233 if (!BEAST_EXPECT(c.erase(Issue(c1, i1)) == 1))
234 return;
235 if (!BEAST_EXPECT(c.erase(Issue(c2, i2)) == 1))
236 return;
237 if (!BEAST_EXPECT(c.empty()))
238 return;
239 }
240 }
241
242 void
244 {
245 testcase("std::set <Issue>");
246 testIssueSet<std::set<Issue>>();
247
248 testcase("std::set <Issue>");
249 testIssueSet<std::set<Issue>>();
250
251#if RIPPLE_ASSETS_ENABLE_STD_HASH
252 testcase("std::unordered_set <Issue>");
253 testIssueSet<std::unordered_set<Issue>>();
254
255 testcase("std::unordered_set <Issue>");
256 testIssueSet<std::unordered_set<Issue>>();
257#endif
258
259 testcase("hash_set <Issue>");
260 testIssueSet<hash_set<Issue>>();
261
262 testcase("hash_set <Issue>");
263 testIssueSet<hash_set<Issue>>();
264 }
265
266 void
268 {
269 testcase("std::map <Issue, int>");
270 testIssueMap<std::map<Issue, int>>();
271
272 testcase("std::map <Issue, int>");
273 testIssueMap<std::map<Issue, int>>();
274
275#if RIPPLE_ASSETS_ENABLE_STD_HASH
276 testcase("std::unordered_map <Issue, int>");
277 testIssueMap<std::unordered_map<Issue, int>>();
278
279 testcase("std::unordered_map <Issue, int>");
280 testIssueMap<std::unordered_map<Issue, int>>();
281
282 testcase("hash_map <Issue, int>");
283 testIssueMap<hash_map<Issue, int>>();
284
285 testcase("hash_map <Issue, int>");
286 testIssueMap<hash_map<Issue, int>>();
287
288#endif
289 }
290
291 //--------------------------------------------------------------------------
292
293 // Comparison, hash tests for Book
294 template <class Book>
295 void
297 {
298 Currency const c1(1);
299 AccountID const i1(1);
300 Currency const c2(2);
301 AccountID const i2(2);
302 Currency const c3(3);
303 AccountID const i3(3);
304
305 Issue a1(c1, i1);
306 Issue a2(c1, i2);
307 Issue a3(c2, i2);
308 Issue a4(c3, i2);
309
310 BEAST_EXPECT(Book(a1, a2) != Book(a2, a3));
311 BEAST_EXPECT(Book(a1, a2) < Book(a2, a3));
312 BEAST_EXPECT(Book(a1, a2) <= Book(a2, a3));
313 BEAST_EXPECT(Book(a2, a3) <= Book(a2, a3));
314 BEAST_EXPECT(Book(a2, a3) == Book(a2, a3));
315 BEAST_EXPECT(Book(a2, a3) >= Book(a2, a3));
316 BEAST_EXPECT(Book(a3, a4) >= Book(a2, a3));
317 BEAST_EXPECT(Book(a3, a4) > Book(a2, a3));
318
319 std::hash<Book> hash;
320
321 // log << std::hex << hash (Book (a1, a2));
322 // log << std::hex << hash (Book (a1, a2));
323 //
324 // log << std::hex << hash (Book (a1, a3));
325 // log << std::hex << hash (Book (a1, a3));
326 //
327 // log << std::hex << hash (Book (a1, a4));
328 // log << std::hex << hash (Book (a1, a4));
329 //
330 // log << std::hex << hash (Book (a2, a3));
331 // log << std::hex << hash (Book (a2, a3));
332 //
333 // log << std::hex << hash (Book (a2, a4));
334 // log << std::hex << hash (Book (a2, a4));
335 //
336 // log << std::hex << hash (Book (a3, a4));
337 // log << std::hex << hash (Book (a3, a4));
338
339 BEAST_EXPECT(hash(Book(a1, a2)) == hash(Book(a1, a2)));
340 BEAST_EXPECT(hash(Book(a1, a3)) == hash(Book(a1, a3)));
341 BEAST_EXPECT(hash(Book(a1, a4)) == hash(Book(a1, a4)));
342 BEAST_EXPECT(hash(Book(a2, a3)) == hash(Book(a2, a3)));
343 BEAST_EXPECT(hash(Book(a2, a4)) == hash(Book(a2, a4)));
344 BEAST_EXPECT(hash(Book(a3, a4)) == hash(Book(a3, a4)));
345
346 BEAST_EXPECT(hash(Book(a1, a2)) != hash(Book(a1, a3)));
347 BEAST_EXPECT(hash(Book(a1, a2)) != hash(Book(a1, a4)));
348 BEAST_EXPECT(hash(Book(a1, a2)) != hash(Book(a2, a3)));
349 BEAST_EXPECT(hash(Book(a1, a2)) != hash(Book(a2, a4)));
350 BEAST_EXPECT(hash(Book(a1, a2)) != hash(Book(a3, a4)));
351 }
352
353 //--------------------------------------------------------------------------
354
355 template <class Set>
356 void
358 {
359 Currency const c1(1);
360 AccountID const i1(1);
361 Currency const c2(2);
362 AccountID const i2(2);
363 Issue const a1(c1, i1);
364 Issue const a2(c2, i2);
365 Book const b1(a1, a2);
366 Book const b2(a2, a1);
367
368 {
369 Set c;
370
371 c.insert(b1);
372 if (!BEAST_EXPECT(c.size() == 1))
373 return;
374 c.insert(b2);
375 if (!BEAST_EXPECT(c.size() == 2))
376 return;
377
378 if (!BEAST_EXPECT(c.erase(Book(a1, a1)) == 0))
379 return;
380 if (!BEAST_EXPECT(c.erase(Book(a1, a2)) == 1))
381 return;
382 if (!BEAST_EXPECT(c.erase(Book(a2, a1)) == 1))
383 return;
384 if (!BEAST_EXPECT(c.empty()))
385 return;
386 }
387
388 {
389 Set c;
390
391 c.insert(b1);
392 if (!BEAST_EXPECT(c.size() == 1))
393 return;
394 c.insert(b2);
395 if (!BEAST_EXPECT(c.size() == 2))
396 return;
397
398 if (!BEAST_EXPECT(c.erase(Book(a1, a1)) == 0))
399 return;
400 if (!BEAST_EXPECT(c.erase(Book(a1, a2)) == 1))
401 return;
402 if (!BEAST_EXPECT(c.erase(Book(a2, a1)) == 1))
403 return;
404 if (!BEAST_EXPECT(c.empty()))
405 return;
406
407#if STL_SET_HAS_EMPLACE
408 c.emplace(a1, a2);
409 if (!BEAST_EXPECT(c.size() == 1))
410 return;
411 c.emplace(a2, a1);
412 if (!BEAST_EXPECT(c.size() == 2))
413 return;
414#endif
415 }
416 }
417
418 template <class Map>
419 void
421 {
422 Currency const c1(1);
423 AccountID const i1(1);
424 Currency const c2(2);
425 AccountID const i2(2);
426 Issue const a1(c1, i1);
427 Issue const a2(c2, i2);
428 Book const b1(a1, a2);
429 Book const b2(a2, a1);
430
431 // typename Map::value_type value_type;
432 // std::pair <Book const, int> value_type;
433
434 {
435 Map c;
436
437 // c.insert (value_type (b1, 1));
438 c.insert(std::make_pair(b1, 1));
439 if (!BEAST_EXPECT(c.size() == 1))
440 return;
441 // c.insert (value_type (b2, 2));
442 c.insert(std::make_pair(b2, 1));
443 if (!BEAST_EXPECT(c.size() == 2))
444 return;
445
446 if (!BEAST_EXPECT(c.erase(Book(a1, a1)) == 0))
447 return;
448 if (!BEAST_EXPECT(c.erase(Book(a1, a2)) == 1))
449 return;
450 if (!BEAST_EXPECT(c.erase(Book(a2, a1)) == 1))
451 return;
452 if (!BEAST_EXPECT(c.empty()))
453 return;
454 }
455
456 {
457 Map c;
458
459 // c.insert (value_type (b1, 1));
460 c.insert(std::make_pair(b1, 1));
461 if (!BEAST_EXPECT(c.size() == 1))
462 return;
463 // c.insert (value_type (b2, 2));
464 c.insert(std::make_pair(b2, 1));
465 if (!BEAST_EXPECT(c.size() == 2))
466 return;
467
468 if (!BEAST_EXPECT(c.erase(Book(a1, a1)) == 0))
469 return;
470 if (!BEAST_EXPECT(c.erase(Book(a1, a2)) == 1))
471 return;
472 if (!BEAST_EXPECT(c.erase(Book(a2, a1)) == 1))
473 return;
474 if (!BEAST_EXPECT(c.empty()))
475 return;
476 }
477 }
478
479 void
481 {
482 testcase("std::set <Book>");
483 testBookSet<std::set<Book>>();
484
485 testcase("std::set <Book>");
486 testBookSet<std::set<Book>>();
487
488#if RIPPLE_ASSETS_ENABLE_STD_HASH
489 testcase("std::unordered_set <Book>");
490 testBookSet<std::unordered_set<Book>>();
491
492 testcase("std::unordered_set <Book>");
493 testBookSet<std::unordered_set<Book>>();
494#endif
495
496 testcase("hash_set <Book>");
497 testBookSet<hash_set<Book>>();
498
499 testcase("hash_set <Book>");
500 testBookSet<hash_set<Book>>();
501 }
502
503 void
505 {
506 testcase("std::map <Book, int>");
507 testBookMap<std::map<Book, int>>();
508
509 testcase("std::map <Book, int>");
510 testBookMap<std::map<Book, int>>();
511
512#if RIPPLE_ASSETS_ENABLE_STD_HASH
513 testcase("std::unordered_map <Book, int>");
514 testBookMap<std::unordered_map<Book, int>>();
515
516 testcase("std::unordered_map <Book, int>");
517 testBookMap<std::unordered_map<Book, int>>();
518
519 testcase("hash_map <Book, int>");
520 testBookMap<hash_map<Book, int>>();
521
522 testcase("hash_map <Book, int>");
523 testBookMap<hash_map<Book, int>>();
524#endif
525 }
526
527 //--------------------------------------------------------------------------
528
529 void
530 run() override
531 {
532 testcase("Currency");
533 testUnsigned<Currency>();
534
535 testcase("AccountID");
536 testUnsigned<AccountID>();
537
538 // ---
539
540 testcase("Issue");
541 testIssue<Issue>();
542
543 testcase("Issue");
544 testIssue<Issue>();
545
548
549 // ---
550
551 testcase("Book");
552 testBook<Book>();
553
554 testcase("Book");
555 testBook<Book>();
556
557 testBookSets();
558 testBookMaps();
559 }
560};
561
562BEAST_DEFINE_TESTSUITE(Issue, protocol, ripple);
563
564} // namespace ripple
A testsuite class.
Definition: suite.h:55
testcase_t testcase
Memberspace for declaring test cases.
Definition: suite.h:155
Specifies an order book.
Definition: Book.h:35
void run() override
Runs the suite.
Definition: Issue_test.cpp:530
A currency issued by an account.
Definition: Issue.h:36
T make_pair(T... args)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: algorithm.h:26