diff options
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/tanya/algorithm/tests/comparison.d | 97 | ||||
| -rw-r--r-- | tests/tanya/algorithm/tests/iteration.d | 127 | ||||
| -rw-r--r-- | tests/tanya/algorithm/tests/mutation.d | 128 | ||||
| -rw-r--r-- | tests/tanya/algorithm/tests/searching.d | 17 | ||||
| -rw-r--r-- | tests/tanya/async/tests/loop.d | 97 | ||||
| -rw-r--r-- | tests/tanya/container/tests/array.d | 196 | ||||
| -rw-r--r-- | tests/tanya/container/tests/buffer.d | 17 | ||||
| -rw-r--r-- | tests/tanya/container/tests/entry.d | 17 | ||||
| -rw-r--r-- | tests/tanya/container/tests/hashtable.d | 133 | ||||
| -rw-r--r-- | tests/tanya/container/tests/list.d | 120 | ||||
| -rw-r--r-- | tests/tanya/container/tests/set.d | 155 | ||||
| -rw-r--r-- | tests/tanya/container/tests/string.d | 121 |
12 files changed, 1225 insertions, 0 deletions
diff --git a/tests/tanya/algorithm/tests/comparison.d b/tests/tanya/algorithm/tests/comparison.d new file mode 100644 index 0000000..5bd561a --- /dev/null +++ b/tests/tanya/algorithm/tests/comparison.d @@ -0,0 +1,97 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +module tanya.algorithm.tests.comparison; + +import tanya.algorithm.comparison; +import tanya.math; +import tanya.range; + +@nogc nothrow pure @safe unittest +{ + static assert(!is(typeof(min(1, 1UL)))); +} + +@nogc nothrow pure @safe unittest +{ + assert(min(5, 3) == 3); + assert(min(4, 4) == 4); + assert(min(5.2, 3.0) == 3.0); + + assert(min(5.2, double.nan) == 5.2); + assert(min(double.nan, 3.0) == 3.0); + assert(isNaN(min(double.nan, double.nan))); +} + +@nogc nothrow pure @safe unittest +{ + assert(min(cast(ubyte[]) []).empty); +} + +@nogc nothrow pure @safe unittest +{ + static assert(!is(typeof(max(1, 1UL)))); +} + +@nogc nothrow pure @safe unittest +{ + assert(max(5, 3) == 5); + assert(max(4, 4) == 4); + assert(max(5.2, 3.0) == 5.2); + + assert(max(5.2, double.nan) == 5.2); + assert(max(double.nan, 3.0) == 3.0); + assert(isNaN(max(double.nan, double.nan))); +} + +@nogc nothrow pure @safe unittest +{ + assert(max(cast(ubyte[]) []).empty); +} + +// min/max compare const and mutable structs. +@nogc nothrow pure @safe unittest +{ + static struct S + { + int s; + + int opCmp(typeof(this) that) const @nogc nothrow pure @safe + { + return this.s - that.s; + } + } + { + const s1 = S(1); + assert(min(s1, S(2)).s == 1); + assert(max(s1, S(2)).s == 2); + } + { + auto s2 = S(2), s3 = S(3); + assert(min(s2, s3).s == 2); + assert(max(s2, s3).s == 3); + } +} + +@nogc nothrow pure @safe unittest +{ + static struct OpCmp(int value) + { + int opCmp(OpCmp) @nogc nothrow pure @safe + { + return value; + } + } + { + OpCmp!(-1)[1] range; + assert(compare(range[], range[]) < 0); + } + { + OpCmp!1[1] range; + assert(compare(range[], range[]) > 0); + } + { + OpCmp!0[1] range; + assert(compare(range[], range[]) == 0); + } +} diff --git a/tests/tanya/algorithm/tests/iteration.d b/tests/tanya/algorithm/tests/iteration.d new file mode 100644 index 0000000..52e99b3 --- /dev/null +++ b/tests/tanya/algorithm/tests/iteration.d @@ -0,0 +1,127 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +module tanya.algorithm.tests.iteration; + +import tanya.algorithm.iteration; +import tanya.range; +import tanya.test.stub; + +// length is unknown when taking from a range without length +@nogc nothrow pure @safe unittest +{ + static struct R + { + mixin InputRangeStub; + } + auto actual = take(R(), 100); + + static assert(!hasLength!(typeof(actual))); +} + +// Takes minimum length if the range length > n +@nogc nothrow pure @safe unittest +{ + auto range = take(cast(int[]) null, 8); + assert(range.length == 0); +} + +@nogc nothrow pure @safe unittest +{ + const int[9] range = [1, 2, 3, 4, 5, 6, 7, 8, 9]; + { + auto slice = take(range[], 8)[1 .. 3]; + + assert(slice.length == 2); + assert(slice.front == 2); + assert(slice.back == 3); + } + { + auto slice = takeExactly(range[], 8)[1 .. 3]; + + assert(slice.length == 2); + assert(slice.front == 2); + assert(slice.back == 3); + } +} + +// Elements are accessible in reverse order +@nogc nothrow pure @safe unittest +{ + const int[3] given = [1, 2, 3]; + auto actual = retro(given[]); + + assert(actual.back == given[].front); + assert(actual[0] == 3); + assert(actual[2] == 1); + + actual.popBack(); + assert(actual.back == 2); + assert(actual[1] == 2); + + // Check slicing. + auto slice = retro(given[])[1 .. $]; + assert(slice.length == 2 && slice.front == 2 && slice.back == 1); +} + +// Elements can be assigned +@nogc nothrow pure @safe unittest +{ + int[4] given = [1, 2, 3, 4]; + auto actual = retro(given[]); + + actual.front = 5; + assert(given[].back == 5); + + actual.back = 8; + assert(given[].front == 8); + + actual[2] = 10; + assert(given[1] == 10); +} + +// Singleton range is bidirectional and random-access +@nogc nothrow pure @safe unittest +{ + static assert(isBidirectionalRange!(typeof(singleton('a')))); + static assert(isRandomAccessRange!(typeof(singleton('a')))); + + assert({ char a; return isBidirectionalRange!(typeof(singleton(a))); }); + assert({ char a; return isRandomAccessRange!(typeof(singleton(a))); }); +} + +@nogc nothrow pure @safe unittest +{ + char a = 'a'; + auto single = singleton(a); + + assert(single.front == 'a'); + assert(single.back == 'a'); + assert(single[0] == 'a'); + assert(single.length == 1); + assert(!single.empty); +} + +// popFront makes SingletonByRef empty +@nogc nothrow pure @safe unittest +{ + char a = 'a'; + auto single = singleton(a); + + single.popFront(); + assert(single.empty); + assert(single.length == 0); + assert(single.empty); +} + +// popBack makes SingletonByRef empty +@nogc nothrow pure @safe unittest +{ + char a = 'b'; + auto single = singleton(a); + + single.popBack(); + assert(single.empty); + assert(single.length == 0); + assert(single.empty); +} diff --git a/tests/tanya/algorithm/tests/mutation.d b/tests/tanya/algorithm/tests/mutation.d new file mode 100644 index 0000000..5d98233 --- /dev/null +++ b/tests/tanya/algorithm/tests/mutation.d @@ -0,0 +1,128 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +module tanya.algorithm.tests.mutation; + +import tanya.algorithm.mutation; +import tanya.range; +import tanya.test.stub; + +// Returns advanced target +@nogc nothrow pure @safe unittest +{ + int[5] input = [1, 2, 3, 4, 5]; + assert(copy(input[3 .. 5], input[]).front == 3); +} + +// Copies overlapping arrays +@nogc nothrow pure @safe unittest +{ + import tanya.algorithm.comparison : equal; + + int[6] actual = [1, 2, 3, 4, 5, 6]; + const int[6] expected = [1, 2, 1, 2, 3, 4]; + + copy(actual[0 .. 4], actual[2 .. 6]); + assert(equal(actual[], expected[])); +} + +@nogc nothrow pure @safe unittest +{ + static assert(is(typeof(copy((ubyte[]).init, (ushort[]).init)))); + static assert(!is(typeof(copy((ushort[]).init, (ubyte[]).init)))); +} + +@nogc nothrow pure @safe unittest +{ + static struct OutPutRange + { + int value; + + void opCall(int value) @nogc nothrow pure @safe + in (this.value == 0) + { + this.value = value; + } + } + int[1] source = [5]; + OutPutRange target; + + assert(copy(source[], target).value == 5); +} + +// [] is called where possible +@nogc nothrow pure @system unittest +{ + static struct Slice + { + bool* slicingCalled; + + int front() @nogc nothrow pure @safe + { + return 0; + } + + void front(int) @nogc nothrow pure @safe + { + } + + void popFront() @nogc nothrow pure @safe + { + } + + bool empty() @nogc nothrow pure @safe + { + return true; + } + + void opIndexAssign(int) @nogc nothrow pure @safe + { + *this.slicingCalled = true; + } + } + bool slicingCalled; + auto range = Slice(&slicingCalled); + fill(range, 0); + assert(slicingCalled); +} + +@nogc nothrow pure @safe unittest +{ + NonCopyable[] nonCopyable; + initializeAll(nonCopyable); +} + +@nogc nothrow pure @safe unittest +{ + import tanya.algorithm.comparison : equal; + + const int[5] expected = [1, 2, 3, 4, 5]; + int[5] actual = [4, 5, 1, 2, 3]; + + rotate(actual[0 .. 2], actual[2 .. $]); + assert(equal(actual[], expected[])); +} + +// Doesn't cause an infinite loop if back is shorter than the front +@nogc nothrow pure @safe unittest +{ + import tanya.algorithm.comparison : equal; + + const int[5] expected = [1, 2, 3, 4, 5]; + int[5] actual = [3, 4, 5, 1, 2]; + + rotate(actual[0 .. 3], actual[3 .. $]); + assert(equal(actual[], expected[])); +} + +// Doesn't call .front on an empty front +@nogc nothrow pure @safe unittest +{ + import tanya.algorithm.comparison : equal; + + const int[2] expected = [2, 8]; + int[2] actual = expected; + + rotate(actual[0 .. 0], actual[]); + assert(equal(actual[], expected[])); +} diff --git a/tests/tanya/algorithm/tests/searching.d b/tests/tanya/algorithm/tests/searching.d new file mode 100644 index 0000000..ca8fdb0 --- /dev/null +++ b/tests/tanya/algorithm/tests/searching.d @@ -0,0 +1,17 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +module tanya.algorithm.tests.searching; + +import tanya.algorithm.searching; +import tanya.test.stub; + +@nogc nothrow pure @safe unittest +{ + @Count(3) + static struct Range + { + mixin InputRangeStub!int; + } + assert(count(Range()) == 3); +} diff --git a/tests/tanya/async/tests/loop.d b/tests/tanya/async/tests/loop.d new file mode 100644 index 0000000..60841b1 --- /dev/null +++ b/tests/tanya/async/tests/loop.d @@ -0,0 +1,97 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +module tanya.async.tests.loop; + +import core.time; +import tanya.async.loop; +import tanya.async.watcher; +import tanya.memory; + +private final class DummyWatcher : Watcher +{ + bool invoked; + + override void invoke() @nogc + { + this.invoked = true; + } +} + +private final class TestLoop : Loop +{ + override protected bool reify(SocketWatcher watcher, + EventMask oldEvents, + EventMask events) @nogc + { + return true; + } + + override protected void poll() @nogc + { + assert(!this.done); + unloop(); + } + + override protected @property uint maxEvents() + const pure nothrow @safe @nogc + { + return 64U; + } + + @nogc @system unittest + { + auto loop = defaultAllocator.make!TestLoop; + assert(loop.blockTime == 1.dur!"minutes"); + + loop.blockTime = 2.dur!"minutes"; + assert(loop.blockTime == 2.dur!"minutes"); + + defaultAllocator.dispose(loop); + } + + @nogc @system unittest + { + auto loop = defaultAllocator.make!TestLoop; + assert(loop.done); + + loop.run(); + assert(loop.done); + + defaultAllocator.dispose(loop); + } + + @nogc @system unittest + { + auto loop = defaultAllocator.make!TestLoop; + auto watcher = defaultAllocator.make!DummyWatcher; + loop.pendings.insertBack(watcher); + + assert(!watcher.invoked); + loop.run(); + assert(watcher.invoked); + + defaultAllocator.dispose(loop); + defaultAllocator.dispose(watcher); + } +} + +@nogc @system unittest +{ + auto loop = defaultAllocator.make!TestLoop; + assert(loop.maxEvents == 64); + + defaultAllocator.dispose(loop); +} + +@nogc @system unittest +{ + auto oldLoop = defaultLoop; + auto loop = defaultAllocator.make!TestLoop; + + defaultLoop = loop; + assert(defaultLoop is loop); + + defaultLoop = oldLoop; + defaultAllocator.dispose(loop); +} diff --git a/tests/tanya/container/tests/array.d b/tests/tanya/container/tests/array.d new file mode 100644 index 0000000..f551fb9 --- /dev/null +++ b/tests/tanya/container/tests/array.d @@ -0,0 +1,196 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +module tanya.container.tests.array; + +import tanya.algorithm.comparison; +import tanya.container.array; +import tanya.memory; +import tanya.test.stub; + +// const arrays return usable ranges +@nogc nothrow pure @safe unittest +{ + auto v = const Array!int([1, 2, 4]); + auto r1 = v[]; + + assert(r1.back == 4); + r1.popBack(); + assert(r1.back == 2); + r1.popBack(); + assert(r1.back == 1); + r1.popBack(); + assert(r1.length == 0); + + static assert(!is(typeof(r1[0] = 5))); + static assert(!is(typeof(v[0] = 5))); + + const r2 = r1[]; + static assert(is(typeof(r2[]))); +} + +@nogc nothrow pure @safe unittest +{ + Array!int v1; + const Array!int v2; + + auto r1 = v1[]; + auto r2 = v1[]; + + assert(r1.length == 0); + assert(r2.empty); + assert(r1 == r2); + + v1.insertBack([1, 2, 4]); + assert(v1[] == v1); + assert(v2[] == v2); + assert(v2[] != v1); + assert(v1[] != v2); + assert(v1[].equal(v1[])); + assert(v2[].equal(v2[])); + assert(!v1[].equal(v2[])); +} + +@nogc nothrow pure @safe unittest +{ + struct MutableEqualsStruct + { + bool opEquals(typeof(this) that) @nogc nothrow pure @safe + { + return true; + } + } + struct ConstEqualsStruct + { + bool opEquals(const typeof(this) that) const @nogc nothrow pure @safe + { + return true; + } + } + auto v1 = Array!ConstEqualsStruct(); + auto v2 = Array!ConstEqualsStruct(); + assert(v1 == v2); + assert(v1[] == v2); + assert(v1 == v2[]); + assert(v1[].equal(v2[])); + + auto v3 = const Array!ConstEqualsStruct(); + auto v4 = const Array!ConstEqualsStruct(); + assert(v3 == v4); + assert(v3[] == v4); + assert(v3 == v4[]); + assert(v3[].equal(v4[])); + + auto v7 = Array!MutableEqualsStruct(1, MutableEqualsStruct()); + auto v8 = Array!MutableEqualsStruct(1, MutableEqualsStruct()); + assert(v7 == v8); + assert(v7[] == v8); + assert(v7 == v8[]); + assert(v7[].equal(v8[])); +} + +// Destructor can destroy empty arrays +@nogc nothrow pure @safe unittest +{ + auto v = Array!WithDtor(); +} + +@nogc nothrow pure @safe unittest +{ + class A + { + } + A a1, a2; + auto v1 = Array!A([a1, a2]); + + static assert(is(Array!(A*))); +} + +@nogc nothrow pure @safe unittest +{ + auto v = Array!int([5, 15, 8]); + { + size_t i; + + foreach (e; v) + { + assert(i != 0 || e == 5); + assert(i != 1 || e == 15); + assert(i != 2 || e == 8); + ++i; + } + assert(i == 3); + } + { + size_t i = 3; + + foreach_reverse (e; v) + { + --i; + assert(i != 2 || e == 8); + assert(i != 1 || e == 15); + assert(i != 0 || e == 5); + } + assert(i == 0); + } +} + +// const constructor tests +@nogc nothrow pure @safe unittest +{ + auto v1 = const Array!int([1, 2, 3]); + auto v2 = Array!int(v1); + assert(v1.get !is v2.get); + assert(v1 == v2); + + auto v3 = const Array!int(Array!int([1, 2, 3])); + assert(v1 == v3); + assert(v3.length == 3); + assert(v3.capacity == 3); +} + +@nogc nothrow pure @safe unittest +{ + auto v1 = Array!int(defaultAllocator); +} + +@nogc nothrow pure @safe unittest +{ + Array!int v; + auto r = v[]; + assert(r.length == 0); + assert(r.empty); +} + +@nogc nothrow pure @safe unittest +{ + auto v1 = const Array!int([5, 15, 8]); + Array!int v2; + v2 = v1[0 .. 2]; + assert(equal(v1[0 .. 2], v2[])); +} + +// Move assignment +@nogc nothrow pure @safe unittest +{ + Array!int v1; + v1 = Array!int([5, 15, 8]); +} + +// Postblit is safe +@nogc nothrow pure @safe unittest +{ + auto array = Array!int(3); + void func(Array!int arg) + { + assert(arg.capacity == 3); + } + func(array); +} + +// Can have non-copyable elements +@nogc nothrow pure @safe unittest +{ + static assert(is(Array!NonCopyable)); + static assert(is(typeof({ Array!NonCopyable.init[0] = NonCopyable(); }))); +} diff --git a/tests/tanya/container/tests/buffer.d b/tests/tanya/container/tests/buffer.d new file mode 100644 index 0000000..7071976 --- /dev/null +++ b/tests/tanya/container/tests/buffer.d @@ -0,0 +1,17 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +module tanya.container.tests.buffer; + +import tanya.container.buffer; + +@nogc nothrow pure @safe unittest +{ + static assert(is(ReadBuffer!int)); +} + +@nogc nothrow pure @safe unittest +{ + static assert(is(typeof(WriteBuffer!int(5)))); +} + diff --git a/tests/tanya/container/tests/entry.d b/tests/tanya/container/tests/entry.d new file mode 100644 index 0000000..e4a13c1 --- /dev/null +++ b/tests/tanya/container/tests/entry.d @@ -0,0 +1,17 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +module tanya.container.tests.entry; + +import tanya.container.entry; +import tanya.test.stub; + +// Can be constructed with non-copyable key/values +@nogc nothrow pure @safe unittest +{ + static assert(is(Bucket!NonCopyable)); + static assert(is(Bucket!(NonCopyable, NonCopyable))); + + static assert(is(HashArray!((ref NonCopyable) => 0U, NonCopyable))); + static assert(is(HashArray!((ref NonCopyable) => 0U, NonCopyable, NonCopyable))); +} diff --git a/tests/tanya/container/tests/hashtable.d b/tests/tanya/container/tests/hashtable.d new file mode 100644 index 0000000..98c9c53 --- /dev/null +++ b/tests/tanya/container/tests/hashtable.d @@ -0,0 +1,133 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +module tanya.container.tests.hashtable; + +import tanya.container.hashtable; +import tanya.test.stub; + +@nogc nothrow pure @safe unittest +{ + import tanya.range.primitive : isForwardRange; + static assert(is(HashTable!(string, int) a)); + static assert(is(const HashTable!(string, int))); + static assert(isForwardRange!(HashTable!(string, int).Range)); + + static assert(is(HashTable!(int, int, (ref const int) => size_t.init))); + static assert(is(HashTable!(int, int, (int) => size_t.init))); +} + +// Constructs by reference +@nogc nothrow pure @safe unittest +{ + auto hashTable1 = HashTable!(string, int)(7); + auto hashTable2 = HashTable!(string, int)(hashTable1); + assert(hashTable1.length == hashTable2.length); + assert(hashTable1.capacity == hashTable2.capacity); +} + +// Constructs by value +@nogc nothrow pure @safe unittest +{ + auto hashTable = HashTable!(string, int)(HashTable!(string, int)(7)); + assert(hashTable.capacity == 7); +} + +// Assigns by reference +@nogc nothrow pure @safe unittest +{ + auto hashTable1 = HashTable!(string, int)(7); + HashTable!(string, int) hashTable2; + hashTable1 = hashTable2; + assert(hashTable1.length == hashTable2.length); + assert(hashTable1.capacity == hashTable2.capacity); +} + +// Assigns by value +@nogc nothrow pure @safe unittest +{ + HashTable!(string, int) hashTable; + hashTable = HashTable!(string, int)(7); + assert(hashTable.capacity == 7); +} + +// Postblit copies +@nogc nothrow pure @safe unittest +{ + auto hashTable = HashTable!(string, int)(7); + void testFunc(HashTable!(string, int) hashTable) + { + assert(hashTable.capacity == 7); + } + testFunc(hashTable); +} + +// Issue 53: https://github.com/caraus-ecms/tanya/issues/53 +@nogc nothrow pure @safe unittest +{ + { + HashTable!(uint, uint) hashTable; + foreach (uint i; 0 .. 14) + { + hashTable[i + 1] = i; + } + assert(hashTable.length == 14); + } + { + HashTable!(int, int) hashtable; + + hashtable[1194250162] = 3; + hashtable[-1131293824] = 6; + hashtable[838100082] = 9; + + hashtable.rehash(11); + + assert(hashtable[-1131293824] == 6); + } +} + +@nogc nothrow pure @safe unittest +{ + static struct String + { + bool opEquals(string) const @nogc nothrow pure @safe + { + return true; + } + + bool opEquals(ref const string) const @nogc nothrow pure @safe + { + return true; + } + + bool opEquals(String) const @nogc nothrow pure @safe + { + return true; + } + + bool opEquals(ref const String) const @nogc nothrow pure @safe + { + return true; + } + + size_t toHash() const @nogc nothrow pure @safe + { + return 0; + } + } + static assert(is(typeof("asdf" in HashTable!(String, int)()))); + static assert(is(typeof(HashTable!(String, int)()["asdf"]))); +} + +// Can have non-copyable keys and elements +@nogc nothrow pure @safe unittest +{ + @NonCopyable @Hashable + static struct S + { + mixin StructStub; + } + static assert(is(HashTable!(S, int))); + static assert(is(HashTable!(int, S))); + static assert(is(HashTable!(S, S))); +} diff --git a/tests/tanya/container/tests/list.d b/tests/tanya/container/tests/list.d new file mode 100644 index 0000000..58fb34e --- /dev/null +++ b/tests/tanya/container/tests/list.d @@ -0,0 +1,120 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +module tanya.container.tests.list; + +import tanya.container.list; +import tanya.test.stub; + +@nogc nothrow pure @safe unittest +{ + interface Stuff + { + } + static assert(is(SList!Stuff)); +} + +@nogc nothrow pure @safe unittest +{ + auto l = SList!int(0, 0); + assert(l.empty); +} + +// foreach called using opIndex(). +@nogc nothrow pure @safe unittest +{ + SList!int l; + size_t i; + + l.insertFront(5); + l.insertFront(4); + l.insertFront(9); + foreach (e; l) + { + assert(i != 0 || e == 9); + assert(i != 1 || e == 4); + assert(i != 2 || e == 5); + ++i; + } +} + +@nogc nothrow pure @safe unittest +{ + auto l1 = SList!int(); + auto l2 = SList!int([9, 4]); + l1 = l2[]; + assert(l1 == l2); +} + +@nogc nothrow pure @safe unittest +{ + class A + { + } + static assert(is(SList!(A*))); + static assert(is(DList!(A*))); +} + +// Removes all elements +@nogc nothrow pure @safe unittest +{ + auto l = DList!int([5]); + assert(l.remove(l[]).empty); +} + +@nogc nothrow pure @safe unittest +{ + auto l1 = DList!int([5, 234, 30, 1]); + auto l2 = DList!int([5, 1]); + auto r = l1[]; + + r.popFront(); + r.popBack(); + assert(r.front == 234); + assert(r.back == 30); + + assert(!l1.remove(r).empty); + assert(l1 == l2); +} + +@nogc nothrow pure @safe unittest +{ + auto l = DList!int(0, 0); + assert(l.empty); +} + +@nogc nothrow pure @safe unittest +{ + DList!int l; + l.insertAfter(l[], 234); + assert(l.front == 234); + assert(l.back == 234); +} + +@nogc nothrow pure @safe unittest +{ + auto l1 = DList!int(); + auto l2 = DList!int([9, 4]); + l1 = l2[]; + assert(l1 == l2); +} + +// Sets the new head +@nogc nothrow pure @safe unittest +{ + auto l1 = DList!int([5, 234, 30, 1]); + auto l2 = DList!int([1]); + auto r = l1[]; + + r.popBack(); + + assert(!l1.remove(r).empty); + assert(l1 == l2); +} + +// Can have non-copyable elements +@nogc nothrow pure @safe unittest +{ + static assert(is(SList!NonCopyable)); + static assert(is(DList!NonCopyable)); +} diff --git a/tests/tanya/container/tests/set.d b/tests/tanya/container/tests/set.d new file mode 100644 index 0000000..187869f --- /dev/null +++ b/tests/tanya/container/tests/set.d @@ -0,0 +1,155 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +module tanya.container.tests.set; + +import tanya.container.set; +import tanya.memory; +import tanya.test.stub; + +// Basic insertion logic. +@nogc nothrow pure @safe unittest +{ + Set!int set; + + assert(set.insert(5) == 1); + assert(5 in set); + assert(set.capacity == 3); + + assert(set.insert(5) == 0); + assert(5 in set); + assert(set.capacity == 3); + + assert(set.insert(9) == 1); + assert(9 in set); + assert(5 in set); + assert(set.capacity == 3); + + assert(set.insert(7) == 1); + assert(set.insert(8) == 1); + assert(8 in set); + assert(5 in set); + assert(9 in set); + assert(7 in set); + assert(set.capacity == 7); + + assert(set.insert(16) == 1); + assert(16 in set); + assert(set.capacity == 7); +} + +// Static checks. +@nogc nothrow pure @safe unittest +{ + import tanya.range.primitive; + + static assert(isBidirectionalRange!(Set!int.ConstRange)); + static assert(isBidirectionalRange!(Set!int.Range)); + + static assert(!isInfinite!(Set!int.Range)); + static assert(!hasLength!(Set!int.Range)); + + static assert(is(Set!uint)); + static assert(is(Set!long)); + static assert(is(Set!ulong)); + static assert(is(Set!short)); + static assert(is(Set!ushort)); + static assert(is(Set!bool)); +} + +@nogc nothrow pure @safe unittest +{ + const Set!int set; + assert(set[].empty); +} + +@nogc nothrow pure @safe unittest +{ + Set!int set; + set.insert(8); + + auto r1 = set[]; + auto r2 = r1.save(); + + r1.popFront(); + assert(r1.empty); + + r2.popBack(); + assert(r2.empty); +} + +// Initial capacity is 0. +@nogc nothrow pure @safe unittest +{ + auto set = Set!int(defaultAllocator); + assert(set.capacity == 0); +} + +// Capacity is set to a prime. +@nogc nothrow pure @safe unittest +{ + auto set = Set!int(8); + assert(set.capacity == 13); +} + +// Constructs by reference +@nogc nothrow pure @safe unittest +{ + auto set1 = Set!int(7); + auto set2 = Set!int(set1); + assert(set1.length == set2.length); + assert(set1.capacity == set2.capacity); +} + +// Constructs by value +@nogc nothrow pure @safe unittest +{ + auto set = Set!int(Set!int(7)); + assert(set.capacity == 7); +} + +// Assigns by reference +@nogc nothrow pure @safe unittest +{ + auto set1 = Set!int(7); + Set!int set2; + set1 = set2; + assert(set1.length == set2.length); + assert(set1.capacity == set2.capacity); +} + +// Assigns by value +@nogc nothrow pure @safe unittest +{ + Set!int set; + set = Set!int(7); + assert(set.capacity == 7); +} + +// Postblit copies +@nogc nothrow pure @safe unittest +{ + auto set = Set!int(7); + void testFunc(Set!int set) + { + assert(set.capacity == 7); + } + testFunc(set); +} + +// Hasher can take argument by ref +@nogc nothrow pure @safe unittest +{ + static assert(is(Set!(int, (const ref x) => cast(size_t) x))); +} + +// Can have non-copyable elements +@nogc nothrow pure @safe unittest +{ + @NonCopyable @Hashable + static struct S + { + mixin StructStub; + } + static assert(is(Set!S)); +} diff --git a/tests/tanya/container/tests/string.d b/tests/tanya/container/tests/string.d new file mode 100644 index 0000000..755cf22 --- /dev/null +++ b/tests/tanya/container/tests/string.d @@ -0,0 +1,121 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +module tanya.container.tests.string; + +import tanya.container.string; +import tanya.test.assertion; + +@nogc nothrow pure @safe unittest +{ + auto s = String(0, 'K'); + assert(s.length == 0); +} + +// Allocates enough space for 3-byte character. +@nogc pure @safe unittest +{ + String s; + s.insertBack('\u8100'); +} + +@nogc pure @safe unittest +{ + assertThrown!UTFException(() => String(1, cast(dchar) 0xd900)); + assertThrown!UTFException(() => String(1, cast(wchar) 0xd900)); +} + +@nogc nothrow pure @safe unittest +{ + auto s1 = String("Buttercup"); + auto s2 = String("Cap"); + s2[] = s1[6 .. $]; + assert(s2 == "cup"); +} + +@nogc nothrow pure @safe unittest +{ + auto s1 = String("Wow"); + s1[] = 'a'; + assert(s1 == "aaa"); +} + +@nogc nothrow pure @safe unittest +{ + auto s1 = String("ö"); + s1[] = "oe"; + assert(s1 == "oe"); +} + +// Postblit works +@nogc nothrow pure @safe unittest +{ + void internFunc(String arg) + { + } + void middleFunc(S...)(S args) + { + foreach (arg; args) + { + internFunc(arg); + } + } + void topFunc(String args) + { + middleFunc(args); + } + topFunc(String("asdf")); +} + +// Const range produces mutable ranges +@nogc pure @safe unittest +{ + auto s = const String("И снизу лед, и сверху - маюсь между."); + { + const constRange = s[]; + + auto fromConstRange = constRange[]; + fromConstRange.popFront(); + assert(fromConstRange.front == s[1]); + + fromConstRange = constRange[0 .. $]; + fromConstRange.popFront(); + assert(fromConstRange.front == s[1]); + + assert(constRange.get() is s.get()); + } + { + const constRange = s.byCodePoint(); + + auto fromConstRange = constRange[]; + fromConstRange.popFront(); + assert(fromConstRange.front == ' '); + } +} + +// Can pop multibyte characters +@nogc pure @safe unittest +{ + auto s = String("\U00024B62\U00002260"); + auto range = s.byCodePoint(); + + range.popFront(); + assert(!range.empty); + + range.popFront(); + assert(range.empty); + + range = s.byCodePoint(); + range.popFront(); + s[$ - 3] = 0xf0; + assertThrown!UTFException(&(range.popFront)); +} + +// Inserts own char range correctly +@nogc nothrow pure @safe unittest +{ + auto s1 = String(`ü`); + String s2; + s2.insertBack(s1[]); + assert(s1 == s2); +} |
