summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/tanya/memory/tests/lifetime.d173
-rw-r--r--tests/tanya/memory/tests/mallocator.d23
-rw-r--r--tests/tanya/memory/tests/mmappool.d159
-rw-r--r--tests/tanya/memory/tests/op.d64
-rw-r--r--tests/tanya/memory/tests/smartref.d250
-rw-r--r--tests/tanya/meta/tests/metafunction.d27
-rw-r--r--tests/tanya/meta/tests/trait.d169
-rw-r--r--tests/tanya/meta/tests/transform.d50
-rw-r--r--tests/tanya/os/tests/error.d9
9 files changed, 924 insertions, 0 deletions
diff --git a/tests/tanya/memory/tests/lifetime.d b/tests/tanya/memory/tests/lifetime.d
new file mode 100644
index 0000000..95da527
--- /dev/null
+++ b/tests/tanya/memory/tests/lifetime.d
@@ -0,0 +1,173 @@
+module tanya.memory.tests.lifetime;
+
+import tanya.memory;
+import tanya.test.stub;
+
+@nogc nothrow pure @safe unittest
+{
+ int[] p;
+
+ p = defaultAllocator.resize(p, 20);
+ assert(p.length == 20);
+
+ p = defaultAllocator.resize(p, 30);
+ assert(p.length == 30);
+
+ p = defaultAllocator.resize(p, 10);
+ assert(p.length == 10);
+
+ p = defaultAllocator.resize(p, 0);
+ assert(p is null);
+}
+
+@nogc nothrow pure @system unittest
+{
+ static struct S
+ {
+ ~this() @nogc nothrow pure @safe
+ {
+ }
+ }
+ auto p = cast(S[]) defaultAllocator.allocate(S.sizeof);
+
+ defaultAllocator.dispose(p);
+}
+
+// Works with interfaces.
+@nogc nothrow pure @safe unittest
+{
+ interface I
+ {
+ }
+ class C : I
+ {
+ }
+ auto c = defaultAllocator.make!C();
+ I i = c;
+
+ defaultAllocator.dispose(i);
+ defaultAllocator.dispose(i);
+}
+
+// Handles "Cannot access frame pointer" error.
+@nogc nothrow pure @safe unittest
+{
+ struct F
+ {
+ ~this() @nogc nothrow pure @safe
+ {
+ }
+ }
+ static assert(is(typeof(emplace!F((void[]).init))));
+}
+
+// Can emplace structs without a constructor
+@nogc nothrow pure @safe unittest
+{
+ static assert(is(typeof(emplace!WithDtor(null, WithDtor()))));
+ static assert(is(typeof(emplace!WithDtor(null))));
+}
+
+// Doesn't call a destructor on uninitialized elements
+@nogc nothrow pure @system unittest
+{
+ static struct SWithDtor
+ {
+ private bool canBeInvoked = false;
+ ~this() @nogc nothrow pure @safe
+ {
+ assert(this.canBeInvoked);
+ }
+ }
+ void[SWithDtor.sizeof] memory = void;
+ auto actual = emplace!SWithDtor(memory[], SWithDtor(true));
+ assert(actual.canBeInvoked);
+}
+
+// Initializes structs if no arguments are given
+@nogc nothrow pure @safe unittest
+{
+ static struct SEntry
+ {
+ byte content;
+ }
+ ubyte[1] mem = [3];
+
+ assert(emplace!SEntry(cast(void[]) mem[0 .. 1]).content == 0);
+}
+
+// Postblit is called when emplacing a struct
+@nogc nothrow pure @system unittest
+{
+ static struct S
+ {
+ bool called = false;
+ this(this) @nogc nothrow pure @safe
+ {
+ this.called = true;
+ }
+ }
+ S target;
+ S* sp = ⌖
+
+ emplace!S(sp[0 .. 1], S());
+ assert(target.called);
+}
+
+// Is pure.
+@nogc nothrow pure @system unittest
+{
+ struct S
+ {
+ this(this)
+ {
+ }
+ }
+ S source, target = void;
+ static assert(is(typeof({ moveEmplace(source, target); })));
+}
+
+// Moves nested.
+@nogc nothrow pure @system unittest
+{
+ struct Nested
+ {
+ void method() @nogc nothrow pure @safe
+ {
+ }
+ }
+ Nested source, target = void;
+ moveEmplace(source, target);
+ assert(source == target);
+}
+
+// Emplaces static arrays.
+@nogc nothrow pure @system unittest
+{
+ static struct S
+ {
+ size_t member;
+ this(size_t i) @nogc nothrow pure @safe
+ {
+ this.member = i;
+ }
+ ~this() @nogc nothrow pure @safe
+ {
+ }
+ }
+ S[2] source = [ S(5), S(5) ], target = void;
+ moveEmplace(source, target);
+ assert(source[0].member == 0);
+ assert(target[0].member == 5);
+ assert(source[1].member == 0);
+ assert(target[1].member == 5);
+}
+
+// Moves if source is target.
+@nogc nothrow pure @safe unittest
+{
+ int x = 5;
+ move(x, x);
+ assert(x == 5);
+}
+
diff --git a/tests/tanya/memory/tests/mallocator.d b/tests/tanya/memory/tests/mallocator.d
new file mode 100644
index 0000000..941f9a8
--- /dev/null
+++ b/tests/tanya/memory/tests/mallocator.d
@@ -0,0 +1,23 @@
+module tanya.memory.tests.mallocator;
+
+version (TanyaNative)
+{
+}
+else:
+
+import tanya.memory.mallocator;
+
+// Fails with false
+@nogc nothrow pure @system unittest
+{
+ void[] p = Mallocator.instance.allocate(20);
+ void[] oldP = p;
+ assert(!Mallocator.instance.reallocate(p, size_t.max - 16));
+ assert(oldP is p);
+ Mallocator.instance.deallocate(p);
+}
+
+@nogc nothrow pure unittest
+{
+ assert(Mallocator.instance.alignment == (void*).alignof);
+}
diff --git a/tests/tanya/memory/tests/mmappool.d b/tests/tanya/memory/tests/mmappool.d
new file mode 100644
index 0000000..0e5b257
--- /dev/null
+++ b/tests/tanya/memory/tests/mmappool.d
@@ -0,0 +1,159 @@
+module tanya.memory.tests.mmappool;
+
+version (TanyaNative):
+
+import tanya.memory.mmappool;
+
+@nogc nothrow pure @system unittest
+{
+ auto p = MmapPool.instance.allocate(20);
+ assert(p);
+ MmapPool.instance.deallocate(p);
+
+ p = MmapPool.instance.allocate(0);
+ assert(p.length == 0);
+}
+
+@nogc nothrow pure @system unittest
+{
+ // allocate() check.
+ size_t tooMuchMemory = size_t.max
+ - MmapPool.alignment_
+ - BlockEntry.sizeof * 2
+ - RegionEntry.sizeof
+ - pageSize;
+ assert(MmapPool.instance.allocate(tooMuchMemory) is null);
+
+ assert(MmapPool.instance.allocate(size_t.max) is null);
+
+ // initializeRegion() check.
+ tooMuchMemory = size_t.max - MmapPool.alignment_;
+ assert(MmapPool.instance.allocate(tooMuchMemory) is null);
+}
+
+@nogc nothrow pure @system unittest
+{
+ auto p = MmapPool.instance.allocate(20);
+
+ assert(MmapPool.instance.deallocate(p));
+}
+
+@nogc nothrow pure @system unittest
+{
+ void[] p;
+ assert(!MmapPool.instance.reallocateInPlace(p, 5));
+ assert(p is null);
+
+ p = MmapPool.instance.allocate(1);
+ auto orig = p.ptr;
+
+ assert(MmapPool.instance.reallocateInPlace(p, 2));
+ assert(p.length == 2);
+ assert(p.ptr == orig);
+
+ assert(MmapPool.instance.reallocateInPlace(p, 4));
+ assert(p.length == 4);
+ assert(p.ptr == orig);
+
+ assert(MmapPool.instance.reallocateInPlace(p, 2));
+ assert(p.length == 2);
+ assert(p.ptr == orig);
+
+ MmapPool.instance.deallocate(p);
+}
+
+@nogc nothrow pure @system unittest
+{
+ void[] p;
+ MmapPool.instance.reallocate(p, 10 * int.sizeof);
+ (cast(int[]) p)[7] = 123;
+
+ assert(p.length == 40);
+
+ MmapPool.instance.reallocate(p, 8 * int.sizeof);
+
+ assert(p.length == 32);
+ assert((cast(int[]) p)[7] == 123);
+
+ MmapPool.instance.reallocate(p, 20 * int.sizeof);
+ (cast(int[]) p)[15] = 8;
+
+ assert(p.length == 80);
+ assert((cast(int[]) p)[15] == 8);
+ assert((cast(int[]) p)[7] == 123);
+
+ MmapPool.instance.reallocate(p, 8 * int.sizeof);
+
+ assert(p.length == 32);
+ assert((cast(int[]) p)[7] == 123);
+
+ MmapPool.instance.deallocate(p);
+}
+
+@nogc nothrow pure @system unittest
+{
+ assert(instance is instance);
+}
+
+@nogc nothrow pure @system unittest
+{
+ assert(MmapPool.instance.alignment == MmapPool.alignment_);
+}
+
+// A lot of allocations/deallocations, but it is the minimum caused a
+// segmentation fault because MmapPool reallocateInPlace moves a block wrong.
+@nogc nothrow pure @system unittest
+{
+ auto a = MmapPool.instance.allocate(16);
+ auto d = MmapPool.instance.allocate(16);
+ auto b = MmapPool.instance.allocate(16);
+ auto e = MmapPool.instance.allocate(16);
+ auto c = MmapPool.instance.allocate(16);
+ auto f = MmapPool.instance.allocate(16);
+
+ MmapPool.instance.deallocate(a);
+ MmapPool.instance.deallocate(b);
+ MmapPool.instance.deallocate(c);
+
+ a = MmapPool.instance.allocate(50);
+ MmapPool.instance.reallocateInPlace(a, 64);
+ MmapPool.instance.deallocate(a);
+
+ a = MmapPool.instance.allocate(1);
+ auto tmp1 = MmapPool.instance.allocate(1);
+ auto h1 = MmapPool.instance.allocate(1);
+ auto tmp2 = cast(ubyte[]) MmapPool.instance.allocate(1);
+
+ auto h2 = MmapPool.instance.allocate(2);
+ tmp1 = MmapPool.instance.allocate(1);
+ MmapPool.instance.deallocate(h2);
+ MmapPool.instance.deallocate(h1);
+
+ h2 = MmapPool.instance.allocate(2);
+ h1 = MmapPool.instance.allocate(1);
+ MmapPool.instance.deallocate(h2);
+
+ auto rep = cast(void[]) tmp2;
+ MmapPool.instance.reallocate(rep, tmp1.length);
+ tmp2 = cast(ubyte[]) rep;
+
+ MmapPool.instance.reallocate(tmp1, 9);
+
+ rep = cast(void[]) tmp2;
+ MmapPool.instance.reallocate(rep, tmp1.length);
+ tmp2 = cast(ubyte[]) rep;
+ MmapPool.instance.reallocate(tmp1, 17);
+
+ tmp2[$ - 1] = 0;
+
+ MmapPool.instance.deallocate(tmp1);
+
+ b = MmapPool.instance.allocate(16);
+
+ MmapPool.instance.deallocate(h1);
+ MmapPool.instance.deallocate(a);
+ MmapPool.instance.deallocate(b);
+ MmapPool.instance.deallocate(d);
+ MmapPool.instance.deallocate(e);
+ MmapPool.instance.deallocate(f);
+}
diff --git a/tests/tanya/memory/tests/op.d b/tests/tanya/memory/tests/op.d
new file mode 100644
index 0000000..61aa99b
--- /dev/null
+++ b/tests/tanya/memory/tests/op.d
@@ -0,0 +1,64 @@
+module tanya.memory.tests.op;
+
+import tanya.memory.op;
+
+@nogc nothrow pure @system unittest
+{
+ ubyte[2] buffer = 1;
+ fill!0(buffer[1 .. $]);
+ assert(buffer[0] == 1 && buffer[1] == 0);
+}
+
+@nogc nothrow pure @safe unittest
+{
+ assert(equal(null, null));
+}
+
+@nogc nothrow pure @safe unittest
+{
+ ubyte[0] source, target;
+ source.copy(target);
+}
+
+@nogc nothrow pure @safe unittest
+{
+ ubyte[1] source = [1];
+ ubyte[1] target;
+ source.copy(target);
+ assert(target[0] == 1);
+}
+
+@nogc nothrow pure @safe unittest
+{
+ ubyte[8] source = [1, 2, 3, 4, 5, 6, 7, 8];
+ ubyte[8] target;
+ source.copy(target);
+ assert(equal(source, target));
+}
+
+@nogc nothrow pure @safe unittest
+{
+ ubyte[9] r1 = [ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i' ];
+ ubyte[9] r2;
+
+ copyBackward(r1, r2);
+ assert(equal(r1, r2));
+}
+
+// Compares unanligned memory
+@nogc nothrow pure @safe unittest
+{
+ ubyte[16] r1 = [
+ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
+ 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
+ ];
+ ubyte[16] r2 = [
+ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
+ 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
+ ];
+
+ assert(equal(r1, r2));
+ assert(equal(r1[1 .. $], r2[1 .. $]));
+ assert(equal(r1[0 .. $ - 1], r2[0 .. $ - 1]));
+ assert(equal(r1[0 .. 8], r2[0 .. 8]));
+}
diff --git a/tests/tanya/memory/tests/smartref.d b/tests/tanya/memory/tests/smartref.d
new file mode 100644
index 0000000..b91e275
--- /dev/null
+++ b/tests/tanya/memory/tests/smartref.d
@@ -0,0 +1,250 @@
+module tanya.memory.tests.smartref;
+
+import tanya.memory;
+import tanya.memory.smartref;
+import tanya.meta.trait;
+import tanya.test.stub;
+
+@nogc @system unittest
+{
+ auto rc = defaultAllocator.refCounted!int(5);
+ rc = defaultAllocator.make!int(7);
+ assert(*rc == 7);
+}
+
+@nogc @system unittest
+{
+ RefCounted!int rc;
+ assert(!rc.isInitialized);
+ rc = null;
+ assert(!rc.isInitialized);
+}
+
+@nogc @system unittest
+{
+ auto rc = defaultAllocator.refCounted!int(5);
+
+ void func(RefCounted!int param) @nogc
+ {
+ assert(param.count == 2);
+ param = defaultAllocator.make!int(7);
+ assert(param.count == 1);
+ assert(*param == 7);
+ }
+ func(rc);
+ assert(rc.count == 1);
+ assert(*rc == 5);
+}
+
+@nogc @system unittest
+{
+ RefCounted!int rc;
+
+ void func(RefCounted!int param) @nogc
+ {
+ assert(param.count == 0);
+ param = defaultAllocator.make!int(7);
+ assert(param.count == 1);
+ assert(*param == 7);
+ }
+ func(rc);
+ assert(rc.count == 0);
+}
+
+@nogc @system unittest
+{
+ RefCounted!int rc1, rc2;
+ static assert(is(typeof(rc1 = rc2)));
+}
+
+@nogc @system unittest
+{
+ auto rc = RefCounted!int(defaultAllocator);
+ assert(!rc.isInitialized);
+ assert(rc.allocator is defaultAllocator);
+}
+
+@nogc @system unittest
+{
+ auto rc = defaultAllocator.refCounted!int(5);
+ assert(rc.count == 1);
+
+ void func(RefCounted!int rc) @nogc
+ {
+ assert(rc.count == 2);
+ rc = null;
+ assert(!rc.isInitialized);
+ assert(rc.count == 0);
+ }
+
+ assert(rc.count == 1);
+ func(rc);
+ assert(rc.count == 1);
+
+ rc = null;
+ assert(!rc.isInitialized);
+ assert(rc.count == 0);
+}
+
+@nogc @system unittest
+{
+ auto rc = defaultAllocator.refCounted!int(5);
+ assert(*rc == 5);
+
+ void func(RefCounted!int rc) @nogc
+ {
+ assert(rc.count == 2);
+ rc = defaultAllocator.refCounted!int(4);
+ assert(*rc == 4);
+ assert(rc.count == 1);
+ }
+ func(rc);
+ assert(*rc == 5);
+}
+
+@nogc @system unittest
+{
+ auto rc = defaultAllocator.refCounted!(int[])(5);
+ assert(rc.length == 5);
+}
+
+@nogc @system unittest
+{
+ auto p1 = defaultAllocator.make!int(5);
+ auto p2 = p1;
+ auto rc = RefCounted!int(p1, defaultAllocator);
+ assert(rc.get() is p2);
+}
+
+@nogc @system unittest
+{
+ size_t destroyed;
+ {
+ auto rc = defaultAllocator.refCounted!WithDtor(destroyed);
+ }
+ assert(destroyed == 1);
+}
+
+@nogc nothrow pure @system unittest
+{
+ auto s = defaultAllocator.unique!int(5);
+ assert(*s == 5);
+
+ s = null;
+ assert(s is null);
+}
+
+@nogc nothrow pure @system unittest
+{
+ auto s = defaultAllocator.unique!int(5);
+ assert(*s == 5);
+
+ s = defaultAllocator.unique!int(4);
+ assert(*s == 4);
+}
+
+@nogc nothrow pure @system unittest
+{
+ auto p1 = defaultAllocator.make!int(5);
+ auto p2 = p1;
+
+ auto rc = Unique!int(p1, defaultAllocator);
+ assert(rc.get() is p2);
+}
+
+@nogc nothrow pure @system unittest
+{
+ auto rc = Unique!int(defaultAllocator);
+ assert(rc.allocator is defaultAllocator);
+}
+
+@nogc @system unittest
+{
+ uint destroyed;
+ auto a = defaultAllocator.make!A(destroyed);
+
+ assert(destroyed == 0);
+ {
+ auto rc = RefCounted!A(a, defaultAllocator);
+ assert(rc.count == 1);
+
+ void func(RefCounted!A rc) @nogc @system
+ {
+ assert(rc.count == 2);
+ }
+ func(rc);
+
+ assert(rc.count == 1);
+ }
+ assert(destroyed == 1);
+
+ RefCounted!int rc;
+ assert(rc.count == 0);
+ rc = defaultAllocator.make!int(8);
+ assert(rc.count == 1);
+}
+
+@nogc nothrow pure @safe unittest
+{
+ static assert(is(ReturnType!(RefCounted!int.get) == inout int*));
+ static assert(is(ReturnType!(RefCounted!A.get) == inout A));
+ static assert(is(ReturnType!(RefCounted!B.get) == inout B*));
+}
+
+@nogc nothrow pure @safe unittest
+{
+ static assert(is(RefCounted!B));
+ static assert(is(RefCounted!A));
+}
+
+@nogc @system unittest
+{
+ struct E
+ {
+ }
+ auto b = defaultAllocator.refCounted!B(15);
+ static assert(is(typeof(b.prop) == int));
+ static assert(!is(typeof(defaultAllocator.refCounted!B())));
+
+ static assert(is(typeof(defaultAllocator.refCounted!E())));
+ static assert(!is(typeof(defaultAllocator.refCounted!E(5))));
+ {
+ auto rc = defaultAllocator.refCounted!B(3);
+ assert(rc.get().prop == 3);
+ }
+ {
+ auto rc = defaultAllocator.refCounted!E();
+ assert(rc.count);
+ }
+}
+
+@nogc nothrow pure @safe unittest
+{
+ static assert(is(typeof(defaultAllocator.unique!B(5))));
+ static assert(is(typeof(defaultAllocator.unique!(int[])(5))));
+}
+
+private class A
+{
+ uint *destroyed;
+
+ this(ref uint destroyed) @nogc
+ {
+ this.destroyed = &destroyed;
+ }
+
+ ~this() @nogc
+ {
+ ++(*destroyed);
+ }
+}
+
+private struct B
+{
+ int prop;
+ @disable this();
+ this(int param1) @nogc
+ {
+ prop = param1;
+ }
+}
diff --git a/tests/tanya/meta/tests/metafunction.d b/tests/tanya/meta/tests/metafunction.d
new file mode 100644
index 0000000..bea3014
--- /dev/null
+++ b/tests/tanya/meta/tests/metafunction.d
@@ -0,0 +1,27 @@
+module tanya.meta.tests.metafunction;
+
+import tanya.meta.metafunction;
+
+@nogc nothrow pure @safe unittest
+{
+ enum cmp(int x, int y) = x - y;
+ static assert(isSorted!(cmp));
+ static assert(isSorted!(cmp, 1));
+ static assert(isSorted!(cmp, 1, 2, 2));
+ static assert(isSorted!(cmp, 1, 2, 2, 4));
+ static assert(isSorted!(cmp, 1, 2, 2, 4, 8));
+ static assert(!isSorted!(cmp, 32, 2, 2, 4, 8));
+ static assert(isSorted!(cmp, 32, 32));
+}
+
+@nogc nothrow pure @safe unittest
+{
+ enum cmp(int x, int y) = x < y;
+ static assert(isSorted!(cmp));
+ static assert(isSorted!(cmp, 1));
+ static assert(isSorted!(cmp, 1, 2, 2));
+ static assert(isSorted!(cmp, 1, 2, 2, 4));
+ static assert(isSorted!(cmp, 1, 2, 2, 4, 8));
+ static assert(!isSorted!(cmp, 32, 2, 2, 4, 8));
+ static assert(isSorted!(cmp, 32, 32));
+}
diff --git a/tests/tanya/meta/tests/trait.d b/tests/tanya/meta/tests/trait.d
new file mode 100644
index 0000000..bc06aef
--- /dev/null
+++ b/tests/tanya/meta/tests/trait.d
@@ -0,0 +1,169 @@
+module tanya.meta.tests.trait;
+
+import tanya.meta.metafunction;
+import tanya.meta.trait;
+
+// typeof(null) is not a pointer.
+@nogc nothrow pure @safe unittest
+{
+ static assert(!isPointer!(typeof(null)));
+ static assert(!isPointer!(const shared typeof(null)));
+
+ enum typeOfNull : typeof(null)
+ {
+ null_ = null,
+ }
+ static assert(!isPointer!typeOfNull);
+}
+
+@nogc nothrow pure @safe unittest
+{
+ static struct S
+ {
+ @property int opCall()
+ {
+ return 0;
+ }
+ }
+ S s;
+ static assert(isCallable!S);
+ static assert(isCallable!s);
+}
+
+@nogc nothrow pure @safe unittest
+{
+ static assert(is(FunctionTypeOf!(void delegate()) == function));
+
+ static void staticFunc()
+ {
+ }
+ auto functionPointer = &staticFunc;
+ static assert(is(FunctionTypeOf!staticFunc == function));
+ static assert(is(FunctionTypeOf!functionPointer == function));
+
+ void func()
+ {
+ }
+ auto dg = &func;
+ static assert(is(FunctionTypeOf!func == function));
+ static assert(is(FunctionTypeOf!dg == function));
+
+ interface I
+ {
+ @property int prop();
+ }
+ static assert(is(FunctionTypeOf!(I.prop) == function));
+
+ static struct S
+ {
+ void opCall()
+ {
+ }
+ }
+ class C
+ {
+ static void opCall()
+ {
+ }
+ }
+ S s;
+
+ static assert(is(FunctionTypeOf!s == function));
+ static assert(is(FunctionTypeOf!C == function));
+ static assert(is(FunctionTypeOf!S == function));
+}
+
+@nogc nothrow pure @safe unittest
+{
+ static struct S2
+ {
+ @property int opCall()
+ {
+ return 0;
+ }
+ }
+ S2 s2;
+ static assert(is(FunctionTypeOf!S2 == function));
+ static assert(is(FunctionTypeOf!s2 == function));
+}
+
+@nogc nothrow pure @safe unittest
+{
+ static assert(!hasElaborateAssign!int);
+
+ static struct S1
+ {
+ void opAssign(S1)
+ {
+ }
+ }
+ static struct S2
+ {
+ void opAssign(int)
+ {
+ }
+ }
+ static struct S3
+ {
+ S1 s;
+ alias s this;
+ }
+ static assert(hasElaborateAssign!S1);
+ static assert(!hasElaborateAssign!(const S1));
+ static assert(hasElaborateAssign!(S1[1]));
+ static assert(!hasElaborateAssign!(S1[0]));
+ static assert(!hasElaborateAssign!S2);
+ static assert(hasElaborateAssign!S3);
+
+ static struct S4
+ {
+ void opAssign(S4)
+ {
+ }
+ @disable this(this);
+ }
+ static assert(hasElaborateAssign!S4);
+}
+
+// Produces a tuple for an enum with only one member
+@nogc nothrow pure @safe unittest
+{
+ enum E : int
+ {
+ one = 0,
+ }
+ static assert(EnumMembers!E == AliasSeq!0);
+}
+
+@nogc nothrow pure @safe unittest
+{
+ class RefCountedStore(T)
+ {
+ }
+ static assert(!isInnerClass!(RefCountedStore!int));
+}
+
+@nogc nothrow pure @safe unittest
+{
+ static struct DisabledOpEquals
+ {
+ @disable bool opEquals(typeof(this)) @nogc nothrow pure @safe;
+
+ int opCmp(typeof(this)) @nogc nothrow pure @safe
+ {
+ return 0;
+ }
+ }
+ static assert(!isEqualityComparable!DisabledOpEquals);
+ static assert(isOrderingComparable!DisabledOpEquals);
+
+ static struct OpEquals
+ {
+ bool opEquals(typeof(this)) @nogc nothrow pure @safe
+ {
+ return true;
+ }
+ }
+ static assert(isEqualityComparable!OpEquals);
+ static assert(!isOrderingComparable!OpEquals);
+}
diff --git a/tests/tanya/meta/tests/transform.d b/tests/tanya/meta/tests/transform.d
new file mode 100644
index 0000000..c81232c
--- /dev/null
+++ b/tests/tanya/meta/tests/transform.d
@@ -0,0 +1,50 @@
+module tanya.meta.tests.transform;
+
+import tanya.meta.transform;
+
+@nogc nothrow pure @safe unittest
+{
+ static assert(is(CommonType!(void*, int*) == void*));
+ static assert(is(CommonType!(void*, const(int)*) == const(void)*));
+ static assert(is(CommonType!(void*, const(void)*) == const(void)*));
+ static assert(is(CommonType!(int*, void*) == void*));
+ static assert(is(CommonType!(const(int)*, void*) == const(void)*));
+ static assert(is(CommonType!(const(void)*, void*) == const(void)*));
+
+ static assert(is(CommonType!() == void));
+ static assert(is(CommonType!(int*, const(int)*) == const(int)*));
+ static assert(is(CommonType!(int**, const(int)**) == const(int*)*));
+
+ static assert(is(CommonType!(float, double) == double));
+ static assert(is(CommonType!(float, int) == void));
+
+ static assert(is(CommonType!(bool, const bool) == bool));
+ static assert(is(CommonType!(int, bool) == void));
+ static assert(is(CommonType!(int, void) == void));
+ static assert(is(CommonType!(Object, void*) == void));
+
+ class A
+ {
+ }
+ static assert(is(CommonType!(A, Object) == Object));
+ static assert(is(CommonType!(const(A)*, Object*) == const(Object)*));
+ static assert(is(CommonType!(A, typeof(null)) == A));
+
+ class B : A
+ {
+ }
+ class C : A
+ {
+ }
+ static assert(is(CommonType!(B, C) == A));
+
+ static struct S
+ {
+ int opCast(T : int)()
+ {
+ return 1;
+ }
+ }
+ static assert(is(CommonType!(S, int) == void));
+ static assert(is(CommonType!(const S, S) == const S));
+}
diff --git a/tests/tanya/os/tests/error.d b/tests/tanya/os/tests/error.d
new file mode 100644
index 0000000..c224438
--- /dev/null
+++ b/tests/tanya/os/tests/error.d
@@ -0,0 +1,9 @@
+module tanya.os.tests.error;
+
+import tanya.os.error;
+
+@nogc nothrow pure @safe unittest
+{
+ ErrorCode ec = cast(ErrorCode.ErrorNo) -1;
+ assert(ec.toString() is null);
+}