1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 module tanya.container.tests.hashtable;
5 
6 import tanya.container.hashtable;
7 import tanya.test.stub;
8 
9 @nogc nothrow pure @safe unittest
10 {
11     import tanya.range.primitive : isForwardRange;
12     static assert(is(HashTable!(string, int) a));
13     static assert(is(const HashTable!(string, int)));
14     static assert(isForwardRange!(HashTable!(string, int).Range));
15 
16     static assert(is(HashTable!(int, int, (ref const int) => size_t.init)));
17     static assert(is(HashTable!(int, int, (int) => size_t.init)));
18 }
19 
20 // Constructs by reference
21 @nogc nothrow pure @safe unittest
22 {
23     auto hashTable1 = HashTable!(string, int)(7);
24     auto hashTable2 = HashTable!(string, int)(hashTable1);
25     assert(hashTable1.length == hashTable2.length);
26     assert(hashTable1.capacity == hashTable2.capacity);
27 }
28 
29 // Constructs by value
30 @nogc nothrow pure @safe unittest
31 {
32     auto hashTable = HashTable!(string, int)(HashTable!(string, int)(7));
33     assert(hashTable.capacity == 7);
34 }
35 
36 // Assigns by reference
37 @nogc nothrow pure @safe unittest
38 {
39     auto hashTable1 = HashTable!(string, int)(7);
40     HashTable!(string, int) hashTable2;
41     hashTable1 = hashTable2;
42     assert(hashTable1.length == hashTable2.length);
43     assert(hashTable1.capacity == hashTable2.capacity);
44 }
45 
46 // Assigns by value
47 @nogc nothrow pure @safe unittest
48 {
49     HashTable!(string, int) hashTable;
50     hashTable = HashTable!(string, int)(7);
51     assert(hashTable.capacity == 7);
52 }
53 
54 // Postblit copies
55 @nogc nothrow pure @safe unittest
56 {
57     auto hashTable = HashTable!(string, int)(7);
58     void testFunc(HashTable!(string, int) hashTable)
59     {
60         assert(hashTable.capacity == 7);
61     }
62     testFunc(hashTable);
63 }
64 
65 // Issue 53: https://github.com/caraus-ecms/tanya/issues/53
66 @nogc nothrow pure @safe unittest
67 {
68     {
69         HashTable!(uint, uint) hashTable;
70         foreach (uint i; 0 .. 14)
71         {
72             hashTable[i + 1] = i;
73         }
74         assert(hashTable.length == 14);
75     }
76     {
77         HashTable!(int, int) hashtable;
78 
79         hashtable[1194250162] = 3;
80         hashtable[-1131293824] = 6;
81         hashtable[838100082] = 9;
82 
83         hashtable.rehash(11);
84 
85         assert(hashtable[-1131293824] == 6);
86     }
87 }
88 
89 @nogc nothrow pure @safe unittest
90 {
91     static struct String
92     {
93         bool opEquals(string) const @nogc nothrow pure @safe
94         {
95             return true;
96         }
97 
98         bool opEquals(ref const string) const @nogc nothrow pure @safe
99         {
100             return true;
101         }
102 
103         bool opEquals(String) const @nogc nothrow pure @safe
104         {
105             return true;
106         }
107 
108         bool opEquals(ref const String) const @nogc nothrow pure @safe
109         {
110             return true;
111         }
112 
113         size_t toHash() const @nogc nothrow pure @safe
114         {
115             return 0;
116         }
117     }
118     static assert(is(typeof("asdf" in HashTable!(String, int)())));
119     static assert(is(typeof(HashTable!(String, int)()["asdf"])));
120 }
121 
122 // Can have non-copyable keys and elements
123 @nogc nothrow pure @safe unittest
124 {
125     @NonCopyable @Hashable
126     static struct S
127     {
128         mixin StructStub;
129     }
130     static assert(is(HashTable!(S, int)));
131     static assert(is(HashTable!(int, S)));
132     static assert(is(HashTable!(S, S)));
133 }