From a36b51f0c3c176d4107e7ea84a4c0dd51197b8dd Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Thu, 21 Mar 2019 14:54:16 +0100 Subject: [PATCH] Fix MmapPool private tests; move remaining tests --- dub.json | 16 ++ middle/tanya/memory/mmappool.d | 17 ++ source/tanya/bitmanip.d | 43 +---- source/tanya/conv.d | 204 --------------------- source/tanya/format.d | 251 -------------------------- source/tanya/typecons.d | 227 ----------------------- tests/tanya/memory/tests/mmappool.d | 27 --- tests/tanya/tests/bitmanip.d | 54 ++++++ tests/tanya/tests/conv.d | 206 +++++++++++++++++++++ tests/tanya/tests/format.d | 269 ++++++++++++++++++++++++++++ tests/tanya/tests/typecons.d | 238 ++++++++++++++++++++++++ 11 files changed, 801 insertions(+), 751 deletions(-) create mode 100644 tests/tanya/tests/bitmanip.d create mode 100644 tests/tanya/tests/conv.d create mode 100644 tests/tanya/tests/format.d create mode 100644 tests/tanya/tests/typecons.d diff --git a/dub.json b/dub.json index 9883955..8a30c7b 100644 --- a/dub.json +++ b/dub.json @@ -52,6 +52,22 @@ }, { "name": "unittest", + "versions": ["TanyaPhobos"], + "importPaths": [ + "./source", + "./tests" + ], + "sourcePaths": [ + "./source", + "./tests" + ] + }, + { + "name": "unittest-native", + "platforms": ["linux-x86_64-gdc"], + "preBuildCommands": ["ninja -C arch"], + "lflags": ["arch/tanya.a"], + "versions": ["TanyaNative"], "importPaths": [ "./source", "./tests" diff --git a/middle/tanya/memory/mmappool.d b/middle/tanya/memory/mmappool.d index 05f71c6..b6cd7d0 100644 --- a/middle/tanya/memory/mmappool.d +++ b/middle/tanya/memory/mmappool.d @@ -501,3 +501,20 @@ final class MmapPool : Allocator } private alias Block = shared BlockEntry*; } + +@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); +} diff --git a/source/tanya/bitmanip.d b/source/tanya/bitmanip.d index 98e7042..c4526d8 100644 --- a/source/tanya/bitmanip.d +++ b/source/tanya/bitmanip.d @@ -5,7 +5,7 @@ /** * Bit manipulation. * - * Copyright: Eugene Wissner 2018. + * Copyright: Eugene Wissner 2018-2019. * License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/, * Mozilla Public License, v. 2.0). * Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner) @@ -276,47 +276,6 @@ if (isBitFlagEnum!E) } } -@nogc nothrow pure @safe unittest -{ - enum E : int - { - one = 1, - } - - // Casts to a boolean - assert(BitFlags!E(E.one)); - assert(!BitFlags!E()); - - // Assigns to and compares with a single value - { - BitFlags!E bitFlags; - bitFlags = E.one; - assert(bitFlags == E.one); - } - // Assigns to and compares with the same type - { - auto bitFlags1 = BitFlags!E(E.one); - BitFlags!E bitFlags2; - bitFlags2 = bitFlags1; - assert(bitFlags1 == bitFlags2); - } - assert((BitFlags!E() | E.one) == BitFlags!E(E.one)); - assert((BitFlags!E() | BitFlags!E(E.one)) == BitFlags!E(E.one)); - - assert(!(BitFlags!E() & BitFlags!E(E.one))); - - assert(!(BitFlags!E(E.one) ^ E.one)); - assert(BitFlags!E() ^ BitFlags!E(E.one)); - - assert(~BitFlags!E()); - - assert(BitFlags!E().toHash() == 0); - assert(BitFlags!E(E.one).toHash() != 0); - - // opBinaryRight is allowed - static assert(is(typeof({ E.one | BitFlags!E(); }))); -} - /** * Creates a $(D_PSYMBOL BitFlags) object initialized with $(D_PARAM field). * diff --git a/source/tanya/conv.d b/source/tanya/conv.d index 4010cb5..13e9235 100644 --- a/source/tanya/conv.d +++ b/source/tanya/conv.d @@ -22,12 +22,6 @@ import tanya.meta.trait; import tanya.meta.transform; import tanya.range; -version (unittest) -{ - import tanya.test.assertion; - import tanya.test.stub; -} - /** * Thrown if a type conversion fails. */ @@ -143,86 +137,6 @@ do return n; } -// ':' is not a hex value -@nogc nothrow pure @safe unittest -{ - string colon = ":"; - auto actual = readIntegral!ubyte(colon, 16); - assert(actual == 0); - assert(colon.length == 1); -} - -// reads ubyte.max -@nogc nothrow pure @safe unittest -{ - string number = "255"; - assert(readIntegral!ubyte(number) == 255); - assert(number.empty); -} - -// detects integer overflow -@nogc nothrow pure @safe unittest -{ - string number = "500"; - readIntegral!ubyte(number); - assert(number.front == '0'); - assert(number.length == 1); -} - -// stops on a non-digit -@nogc nothrow pure @safe unittest -{ - string number = "10-"; - readIntegral!ubyte(number); - assert(number.front == '-'); -} - -// returns false if the number string is empty -@nogc nothrow pure @safe unittest -{ - string number = ""; - readIntegral!ubyte(number); - assert(number.empty); -} - -@nogc nothrow pure @safe unittest -{ - string number = "29"; - assert(readIntegral!ubyte(number) == 29); - assert(number.empty); -} - -@nogc nothrow pure @safe unittest -{ - string number = "25467"; - readIntegral!ubyte(number); - assert(number.front == '6'); -} - -// Converts lower case hexadecimals -@nogc nothrow pure @safe unittest -{ - string number = "a"; - assert(readIntegral!ubyte(number, 16) == 10); - assert(number.empty); -} - -// Converts upper case hexadecimals -@nogc nothrow pure @safe unittest -{ - string number = "FF"; - assert(readIntegral!ubyte(number, 16) == 255); - assert(number.empty); -} - -// Handles small overflows -@nogc nothrow pure @safe unittest -{ - string number = "256"; - assert(readIntegral!ubyte(number, 10) == 25); - assert(number.front == '6'); -} - /** * If the source type $(D_PARAM From) and the target type $(D_PARAM To) are * equal, does nothing. If $(D_PARAM From) can be implicitly converted to @@ -262,12 +176,6 @@ template to(To) static assert(is(typeof(val) == int)); } -@nogc nothrow pure @safe unittest -{ - int val = 5; - assert(val.to!int() == 5); -} - /** * Performs checked conversion from an integral type $(D_PARAM From) to an * integral type $(D_PARAM To). @@ -330,83 +238,6 @@ if (isIntegral!From } } -@nogc nothrow pure @safe unittest -{ - // ubyte -> ushort - assert((cast(ubyte) 0).to!ushort == 0); - assert((cast(ubyte) 1).to!ushort == 1); - assert((cast(ubyte) (ubyte.max - 1)).to!ushort == ubyte.max - 1); - assert((cast(ubyte) ubyte.max).to!ushort == ubyte.max); - - // ubyte -> short - assert((cast(ubyte) 0).to!short == 0); - assert((cast(ubyte) 1).to!short == 1); - assert((cast(ubyte) (ubyte.max - 1)).to!short == ubyte.max - 1); - assert((cast(ubyte) ubyte.max).to!short == ubyte.max); -} - -@nogc pure @safe unittest -{ - // ubyte <- ushort - assert((cast(ushort) 0).to!ubyte == 0); - assert((cast(ushort) 1).to!ubyte == 1); - assert((cast(ushort) (ubyte.max - 1)).to!ubyte == ubyte.max - 1); - assert((cast(ushort) ubyte.max).to!ubyte == ubyte.max); - - // ubyte <- short - assert((cast(short) 0).to!ubyte == 0); - assert((cast(short) 1).to!ubyte == 1); - assert((cast(short) (ubyte.max - 1)).to!ubyte == ubyte.max - 1); - assert((cast(short) ubyte.max).to!ubyte == ubyte.max); - - // short <-> int - assert(short.min.to!int == short.min); - assert((short.min + 1).to!int == short.min + 1); - assert((cast(short) -1).to!int == -1); - assert((cast(short) 0).to!int == 0); - assert((cast(short) 1).to!int == 1); - assert((short.max - 1).to!int == short.max - 1); - assert(short.max.to!int == short.max); - - assert((cast(int) short.min).to!short == short.min); - assert((cast(int) short.min + 1).to!short == short.min + 1); - assert((cast(int) -1).to!short == -1); - assert((cast(int) 0).to!short == 0); - assert((cast(int) 1).to!short == 1); - assert((cast(int) short.max - 1).to!short == short.max - 1); - assert((cast(int) short.max).to!short == short.max); - - // uint <-> int - assert((cast(uint) 0).to!int == 0); - assert((cast(uint) 1).to!int == 1); - assert((cast(uint) (int.max - 1)).to!int == int.max - 1); - assert((cast(uint) int.max).to!int == int.max); - - assert((cast(int) 0).to!uint == 0); - assert((cast(int) 1).to!uint == 1); - assert((cast(int) (int.max - 1)).to!uint == int.max - 1); - assert((cast(int) int.max).to!uint == int.max); -} - -@nogc pure @safe unittest -{ - assertThrown!ConvException(&to!(short, int), int.min); - assertThrown!ConvException(&to!(short, int), int.max); - assertThrown!ConvException(&to!(ushort, uint), uint.max); - assertThrown!ConvException(&to!(uint, int), -1); -} - -@nogc nothrow pure @safe unittest -{ - enum Test : int - { - one, - two, - } - assert(Test.one.to!int == 0); - assert(Test.two.to!int == 1); -} - /** * Converts a floating point number to an integral type. * @@ -449,13 +280,6 @@ if (isFloatingPoint!From assert(2147483646.5.to!uint == 2147483646); } -@nogc pure @safe unittest -{ - assertThrown!ConvException(&to!(int, double), 2147483647.5); - assertThrown!ConvException(&to!(int, double), -2147483648.5); - assertThrown!ConvException(&to!(uint, double), -21474.5); -} - /** * Performs checked conversion from an integral type $(D_PARAM From) to an * $(D_KEYWORD enum). @@ -497,16 +321,6 @@ if (isIntegral!From && is(To == enum)) assert(1.to!Test == Test.two); } -@nogc pure @safe unittest -{ - enum Test : uint - { - one, - two, - } - assertThrown!ConvException(&to!(Test, int), 5); -} - /** * Converts $(D_PARAM from) to a boolean. * @@ -558,12 +372,6 @@ if (isNumeric!From && is(Unqual!To == bool) && !is(Unqual!To == Unqual!From)) assert(1.to!bool); } -@nogc pure @safe unittest -{ - assertThrown!ConvException(&to!(bool, int), -1); - assertThrown!ConvException(&to!(bool, int), 2); -} - /// ditto To to(To, From)(auto ref const From from) if ((is(From == String) || isSomeString!From) && is(Unqual!To == bool)) @@ -590,11 +398,6 @@ if ((is(From == String) || isSomeString!From) && is(Unqual!To == bool)) } -@nogc pure @safe unittest -{ - assertThrown!ConvException(() => "1".to!bool); -} - /** * Converts a boolean to $(D_PARAM To). * @@ -761,12 +564,5 @@ if (isInputRange!From && isSomeChar!(ElementType!From) && isIntegral!To) assert("010".to!int() == 8); assert("-010".to!int() == -8); - assert("-128".to!byte == cast(byte) -128); - - assertThrown!ConvException(() => "".to!int); - assertThrown!ConvException(() => "-".to!int); - assertThrown!ConvException(() => "-5".to!uint); - assertThrown!ConvException(() => "-129".to!byte); - assertThrown!ConvException(() => "256".to!ubyte); } diff --git a/source/tanya/format.d b/source/tanya/format.d index db372c4..5c63a5e 100644 --- a/source/tanya/format.d +++ b/source/tanya/format.d @@ -124,18 +124,6 @@ if (isIntegral!T) return buffer[$ - l - 1 .. $ - 1]; } -// Converting an integer to string. -@nogc nothrow pure @system unittest -{ - char[21] buf; - - assert(integral2String(80, buf) == "80"); - assert(integral2String(-80, buf) == "-80"); - assert(integral2String(0, buf) == "0"); - assert(integral2String(uint.max, buf) == "4294967295"); - assert(integral2String(int.min, buf) == "-2147483648"); -} - private int frexp(const double x) @nogc nothrow pure @safe { const FloatBits!double bits = { x }; @@ -2419,245 +2407,6 @@ if (isOutputRange!(R, const(char)[])) return output; } -// doesn't print the first argument repeatedly -@nogc nothrow pure @safe unittest -{ - assert(format!"{}{}"(1, 2) == "12"); -} - -@nogc nothrow pure @safe unittest -{ - assert(format!"Without arguments"() == "Without arguments"); - assert(format!""().length == 0); - - static assert(!is(typeof(format!"{}"()))); - static assert(!is(typeof(format!"{j}"(5)))); -} - -// Enum. -@nogc nothrow pure @safe unittest -{ - enum E1 : int - { - one, - two, - } - assert(format!"{}"(E1.one) == "one"); - - const E1 e1; - assert(format!"{}"(e1) == "one"); -} - -// One argument tests. -@nogc pure @safe unittest -{ - // Modifiers. - assert(format!"{}"(8.5) == "8.5"); - assert(format!"{}"(8.6) == "8.6"); - assert(format!"{}"(1000) == "1000"); - assert(format!"{}"(1) == "1"); - assert(format!"{}"(10.25) == "10.25"); - assert(format!"{}"(1) == "1"); - assert(format!"{}"(0.01) == "0.01"); - - // String printing. - assert(format!"{}"("Some weired string") == "Some weired string"); - assert(format!"{}"(cast(string) null) == ""); - assert(format!"{}"('c') == "c"); - - // Integer. - assert(format!"{}"(8) == "8"); - assert(format!"{}"(8) == "8"); - assert(format!"{}"(-8) == "-8"); - assert(format!"{}"(-8L) == "-8"); - assert(format!"{}"(8) == "8"); - assert(format!"{}"(100000001) == "100000001"); - assert(format!"{}"(99999999L) == "99999999"); - assert(format!"{}"(10) == "10"); - assert(format!"{}"(10L) == "10"); - - // Floating point. - assert(format!"{}"(0.1234) == "0.1234"); - assert(format!"{}"(0.3) == "0.3"); - assert(format!"{}"(0.333333333333) == "0.333333"); - assert(format!"{}"(38234.1234) == "38234.1"); - assert(format!"{}"(-0.3) == "-0.3"); - assert(format!"{}"(0.000000000000000006) == "6e-18"); - assert(format!"{}"(0.0) == "0"); - assert(format!"{}"(double.init) == "NaN"); - assert(format!"{}"(-double.init) == "-NaN"); - assert(format!"{}"(double.infinity) == "Inf"); - assert(format!"{}"(-double.infinity) == "-Inf"); - assert(format!"{}"(0.000000000000000000000000003) == "3e-27"); - assert(format!"{}"(0.23432e304) == "2.3432e+303"); - assert(format!"{}"(-0.23432e8) == "-2.3432e+07"); - assert(format!"{}"(1e-307) == "1e-307"); - assert(format!"{}"(1e+8) == "1e+08"); - assert(format!"{}"(111234.1) == "111234"); - assert(format!"{}"(0.999) == "0.999"); - assert(format!"{}"(0x1p-16382L) == "0"); - assert(format!"{}"(1e+3) == "1000"); - assert(format!"{}"(38234.1234) == "38234.1"); - assert(format!"{}"(double.max) == "1.79769e+308"); - - // typeof(null). - assert(format!"{}"(null) == "null"); - - // Boolean. - assert(format!"{}"(true) == "true"); - assert(format!"{}"(false) == "false"); -} - -// Unsafe tests with pointers. -@nogc pure @system unittest -{ - // Pointer convesions - assert(format!"{}"(cast(void*) 1) == "0x1"); - assert(format!"{}"(cast(void*) 20) == "0x14"); - assert(format!"{}"(cast(void*) null) == "0x0"); -} - -// Structs. -@nogc pure @safe unittest -{ - static struct WithoutStringify1 - { - int a; - void func() - { - } - } - assert(format!"{}"(WithoutStringify1(6)) == "WithoutStringify1(6)"); - - static struct WithoutStringify2 - { - } - assert(format!"{}"(WithoutStringify2()) == "WithoutStringify2()"); - - static struct WithoutStringify3 - { - int a = -2; - int b = 8; - } - assert(format!"{}"(WithoutStringify3()) == "WithoutStringify3(-2, 8)"); - - struct Nested - { - int i; - - void func() - { - } - } - assert(format!"{}"(Nested()) == "Nested(0)"); - - static struct WithToString - { - OR toString(OR)(OR range) const - { - put(range, "toString method"); - return range; - } - } - assert(format!"{}"(WithToString()) == "toString method"); -} - -// Aggregate types. -@system unittest // Object.toString has no attributes. -{ - import tanya.memory; - import tanya.memory.smartref; - - interface I - { - } - class A : I - { - } - auto instance = defaultAllocator.unique!A(); - assert(format!"{}"(instance.get()) == instance.get().toString()); - assert(format!"{}"(cast(I) instance.get()) == I.classinfo.name); - assert(format!"{}"(cast(A) null) == "null"); - - class B - { - OR toString(OR)(OR range) const - { - put(range, "Class B"); - return range; - } - } - assert(format!"{}"(cast(B) null) == "null"); -} - -// Unions. -unittest -{ - union U - { - int i; - char c; - } - assert(format!"{}"(U(2)) == "U"); -} - -// Ranges. -@nogc pure @safe unittest -{ - static struct Stringish - { - private string content = "Some content"; - - immutable(char) front() const @nogc nothrow pure @safe - { - return this.content[0]; - } - - void popFront() @nogc nothrow pure @safe - { - this.content = this.content[1 .. $]; - } - - bool empty() const @nogc nothrow pure @safe - { - return this.content.length == 0; - } - } - assert(format!"{}"(Stringish()) == "Some content"); - - static struct Intish - { - private int front_ = 3; - - int front() const @nogc nothrow pure @safe - { - return this.front_; - } - - void popFront() @nogc nothrow pure @safe - { - --this.front_; - } - - bool empty() const @nogc nothrow pure @safe - { - return this.front == 0; - } - } - assert(format!"{}"(Intish()) == "[3, 2, 1]"); -} - -// Typeid. -nothrow pure @safe unittest -{ - assert(format!"{}"(typeid(int[])) == "int[]"); - - class C - { - } - assert(format!"{}"(typeid(C)) == typeid(C).toString()); -} - private struct FormatSpec { const size_t position; diff --git a/source/tanya/typecons.d b/source/tanya/typecons.d index 700e2dd..507cd3c 100644 --- a/source/tanya/typecons.d +++ b/source/tanya/typecons.d @@ -21,7 +21,6 @@ import tanya.format; import tanya.memory.lifetime; import tanya.meta.metafunction; import tanya.meta.trait; -version (unittest) import tanya.test.stub; /** * $(D_PSYMBOL Tuple) can store two or more heterogeneous objects. @@ -117,25 +116,6 @@ template Tuple(Specs...) assert(pair[1] == "second"); } -@nogc nothrow pure @safe unittest -{ - static assert(is(Tuple!(int, int))); - static assert(!is(Tuple!(int, 5))); - - static assert(is(Tuple!(int, "first", int))); - static assert(is(Tuple!(int, "first", int, "second"))); - static assert(is(Tuple!(int, "first", int))); - - static assert(is(Tuple!(int, int, "second"))); - static assert(!is(Tuple!("first", int, "second", int))); - static assert(!is(Tuple!(int, int, int))); - - static assert(!is(Tuple!(int, "first"))); - - static assert(!is(Tuple!(int, double, char))); - static assert(!is(Tuple!(int, "first", double, "second", char, "third"))); -} - /** * Creates a new $(D_PSYMBOL Tuple). * @@ -428,112 +408,6 @@ struct Option(T) assert(option.isNothing); } -// Assigns a new value -@nogc nothrow pure @safe unittest -{ - { - Option!int option = 5; - option = 8; - assert(!option.isNothing); - assert(option == 8); - } - { - Option!int option; - const int newValue = 8; - assert(option.isNothing); - option = newValue; - assert(!option.isNothing); - assert(option == newValue); - } - { - Option!int option1; - Option!int option2 = 5; - assert(option1.isNothing); - option1 = option2; - assert(!option1.isNothing); - assert(option1.get == 5); - } -} - -// Constructs with a value passed by reference -@nogc nothrow pure @safe unittest -{ - int i = 5; - assert(Option!int(i).get == 5); -} - -// Moving -@nogc nothrow pure @safe unittest -{ - static assert(is(typeof(Option!NonCopyable(NonCopyable())))); - // The value cannot be returned by reference because the default value - // isn't passed by reference - static assert(!is(typeof(Option!DisabledPostblit().or(NonCopyable())))); - { - NonCopyable notCopyable; - static assert(is(typeof(Option!NonCopyable().or(notCopyable)))); - } - { - Option!NonCopyable option; - assert(option.isNothing); - option = NonCopyable(); - assert(!option.isNothing); - } - { - Option!NonCopyable option; - assert(option.isNothing); - option = Option!NonCopyable(NonCopyable()); - assert(!option.isNothing); - } -} - -// Cast to bool is done before touching the encapsulated value -@nogc nothrow pure @safe unittest -{ - assert(Option!bool(false)); -} - -// Option can be const -@nogc nothrow pure @safe unittest -{ - assert((const Option!int(5)).get == 5); - assert((const Option!int()).or(5) == 5); -} - -// Equality -@nogc nothrow pure @safe unittest -{ - assert(Option!int() == Option!int()); - assert(Option!int(0) != Option!int()); - assert(Option!int(5) == Option!int(5)); - assert(Option!int(5) == 5); - assert(Option!int(5) == cast(ubyte) 5); -} - -// Returns default value -@nogc nothrow pure @safe unittest -{ - int i = 5; - assert(((ref e) => e)(Option!int().or(i)) == 5); -} - -// Implements toHash() for nothing -@nogc nothrow pure @safe unittest -{ - alias OptionT = Option!Hashable; - assert(OptionT().toHash() == 0U); - assert(OptionT(Hashable(1U)).toHash() == 1U); -} - -// Can assign Option that is nothing -@nogc nothrow pure @safe unittest -{ - auto option1 = Option!int(5); - Option!int option2; - option1 = option2; - assert(option1.isNothing); -} - /** * Creates a new $(D_PSYMBOL Option). * @@ -829,104 +703,3 @@ if (isTypeTuple!Specs && NoDuplicates!Specs.length == Specs.length) assert(!variant.peek!int); assert(variant.get!double == 5.4); } - -@nogc nothrow pure @safe unittest -{ - Variant!(int, double) variant; - variant = 5; - assert(variant.peek!int); -} - -@nogc nothrow pure @safe unittest -{ - Variant!(int, double) variant; - variant = 5.0; - assert(!variant.peek!int); -} - -@nogc nothrow pure @safe unittest -{ - Variant!(int, double) variant = 5; - assert(variant.get!int == 5); -} - -@nogc nothrow pure @safe unittest -{ - static assert(is(Variant!(int, float))); - static assert(is(Variant!int)); -} - -@nogc nothrow pure @safe unittest -{ - static struct WithDestructorAndCopy - { - this(this) @nogc nothrow pure @safe - { - } - - ~this() @nogc nothrow pure @safe - { - } - } - static assert(is(Variant!WithDestructorAndCopy)); -} - -// Equality compares the underlying objects -@nogc nothrow pure @safe unittest -{ - Variant!(int, double) variant1 = 5; - Variant!(int, double) variant2 = 5; - assert(variant1 == variant2); -} - -@nogc nothrow pure @safe unittest -{ - Variant!(int, double) variant1 = 5; - Variant!(int, double) variant2 = 6; - assert(variant1 != variant2); -} - -// Differently typed variants aren't equal -@nogc nothrow pure @safe unittest -{ - Variant!(int, double) variant1 = 5; - Variant!(int, double) variant2 = 5.0; - assert(variant1 != variant2); -} - -// Uninitialized variants are equal -@nogc nothrow pure @safe unittest -{ - Variant!(int, double) variant1, variant2; - assert(variant1 == variant2); -} - -// Calls postblit constructor of the active type -@nogc nothrow pure @safe unittest -{ - static struct S - { - bool called; - - this(this) - { - this.called = true; - } - } - Variant!(int, S) variant1 = S(); - auto variant2 = variant1; - assert(variant2.get!S.called); -} - -// Variant.type is null if the Variant doesn't have a value -@nogc nothrow pure @safe unittest -{ - Variant!(int, uint) variant; - assert(variant.type is null); -} - -// Variant can contain only distinct types -@nogc nothrow pure @safe unittest -{ - static assert(!is(Variant!(int, int))); -} diff --git a/tests/tanya/memory/tests/mmappool.d b/tests/tanya/memory/tests/mmappool.d index cdfee8a..adef1ab 100644 --- a/tests/tanya/memory/tests/mmappool.d +++ b/tests/tanya/memory/tests/mmappool.d @@ -17,23 +17,6 @@ import tanya.memory.mmappool; 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); @@ -93,16 +76,6 @@ import tanya.memory.mmappool; 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 diff --git a/tests/tanya/tests/bitmanip.d b/tests/tanya/tests/bitmanip.d new file mode 100644 index 0000000..06d71f8 --- /dev/null +++ b/tests/tanya/tests/bitmanip.d @@ -0,0 +1,54 @@ +module tanya.tests.bitmanip; + +import tanya.bitmanip; + +// Casts to a boolean +@nogc nothrow pure @safe unittest +{ + assert(BitFlags!One(One.one)); + assert(!BitFlags!One()); +} + +// Assigns to and compares with a single value +@nogc nothrow pure @safe unittest +{ + BitFlags!One bitFlags; + bitFlags = One.one; + assert(bitFlags == One.one); +} + +// Assigns to and compares with the same type +@nogc nothrow pure @safe unittest +{ + auto bitFlags1 = BitFlags!One(One.one); + BitFlags!One bitFlags2; + bitFlags2 = bitFlags1; + assert(bitFlags1 == bitFlags2); +} + +@nogc nothrow pure @safe unittest +{ + assert((BitFlags!One() | One.one) == BitFlags!One(One.one)); + assert((BitFlags!One() | BitFlags!One(One.one)) == BitFlags!One(One.one)); + + assert(!(BitFlags!One() & BitFlags!One(One.one))); + + assert(!(BitFlags!One(One.one) ^ One.one)); + assert(BitFlags!One() ^ BitFlags!One(One.one)); + + assert(~BitFlags!One()); + + assert(BitFlags!One().toHash() == 0); + assert(BitFlags!One(One.one).toHash() != 0); +} + +// opBinaryRight is allowed +@nogc nothrow pure @safe unittest +{ + static assert(is(typeof({ One.one | BitFlags!One(); }))); +} + +private enum One : int +{ + one = 1, +} diff --git a/tests/tanya/tests/conv.d b/tests/tanya/tests/conv.d new file mode 100644 index 0000000..2b8e76d --- /dev/null +++ b/tests/tanya/tests/conv.d @@ -0,0 +1,206 @@ +module tanya.tests.conv; + +import tanya.conv; +import tanya.range; +import tanya.test.assertion; +import tanya.test.stub; + +// ':' is not a hex value +@nogc nothrow pure @safe unittest +{ + string colon = ":"; + auto actual = readIntegral!ubyte(colon, 16); + assert(actual == 0); + assert(colon.length == 1); +} + +// reads ubyte.max +@nogc nothrow pure @safe unittest +{ + string number = "255"; + assert(readIntegral!ubyte(number) == 255); + assert(number.empty); +} + +// detects integer overflow +@nogc nothrow pure @safe unittest +{ + string number = "500"; + readIntegral!ubyte(number); + assert(number.front == '0'); + assert(number.length == 1); +} + +// stops on a non-digit +@nogc nothrow pure @safe unittest +{ + string number = "10-"; + readIntegral!ubyte(number); + assert(number.front == '-'); +} + +// returns false if the number string is empty +@nogc nothrow pure @safe unittest +{ + string number = ""; + readIntegral!ubyte(number); + assert(number.empty); +} + +@nogc nothrow pure @safe unittest +{ + string number = "29"; + assert(readIntegral!ubyte(number) == 29); + assert(number.empty); +} + +@nogc nothrow pure @safe unittest +{ + string number = "25467"; + readIntegral!ubyte(number); + assert(number.front == '6'); +} + +// Converts lower case hexadecimals +@nogc nothrow pure @safe unittest +{ + string number = "a"; + assert(readIntegral!ubyte(number, 16) == 10); + assert(number.empty); +} + +// Converts upper case hexadecimals +@nogc nothrow pure @safe unittest +{ + string number = "FF"; + assert(readIntegral!ubyte(number, 16) == 255); + assert(number.empty); +} + +// Handles small overflows +@nogc nothrow pure @safe unittest +{ + string number = "256"; + assert(readIntegral!ubyte(number, 10) == 25); + assert(number.front == '6'); +} + +@nogc nothrow pure @safe unittest +{ + int val = 5; + assert(val.to!int() == 5); +} + +@nogc nothrow pure @safe unittest +{ + // ubyte -> ushort + assert((cast(ubyte) 0).to!ushort == 0); + assert((cast(ubyte) 1).to!ushort == 1); + assert((cast(ubyte) (ubyte.max - 1)).to!ushort == ubyte.max - 1); + assert((cast(ubyte) ubyte.max).to!ushort == ubyte.max); + + // ubyte -> short + assert((cast(ubyte) 0).to!short == 0); + assert((cast(ubyte) 1).to!short == 1); + assert((cast(ubyte) (ubyte.max - 1)).to!short == ubyte.max - 1); + assert((cast(ubyte) ubyte.max).to!short == ubyte.max); +} + +@nogc pure @safe unittest +{ + // ubyte <- ushort + assert((cast(ushort) 0).to!ubyte == 0); + assert((cast(ushort) 1).to!ubyte == 1); + assert((cast(ushort) (ubyte.max - 1)).to!ubyte == ubyte.max - 1); + assert((cast(ushort) ubyte.max).to!ubyte == ubyte.max); + + // ubyte <- short + assert((cast(short) 0).to!ubyte == 0); + assert((cast(short) 1).to!ubyte == 1); + assert((cast(short) (ubyte.max - 1)).to!ubyte == ubyte.max - 1); + assert((cast(short) ubyte.max).to!ubyte == ubyte.max); + + // short <-> int + assert(short.min.to!int == short.min); + assert((short.min + 1).to!int == short.min + 1); + assert((cast(short) -1).to!int == -1); + assert((cast(short) 0).to!int == 0); + assert((cast(short) 1).to!int == 1); + assert((short.max - 1).to!int == short.max - 1); + assert(short.max.to!int == short.max); + + assert((cast(int) short.min).to!short == short.min); + assert((cast(int) short.min + 1).to!short == short.min + 1); + assert((cast(int) -1).to!short == -1); + assert((cast(int) 0).to!short == 0); + assert((cast(int) 1).to!short == 1); + assert((cast(int) short.max - 1).to!short == short.max - 1); + assert((cast(int) short.max).to!short == short.max); + + // uint <-> int + assert((cast(uint) 0).to!int == 0); + assert((cast(uint) 1).to!int == 1); + assert((cast(uint) (int.max - 1)).to!int == int.max - 1); + assert((cast(uint) int.max).to!int == int.max); + + assert((cast(int) 0).to!uint == 0); + assert((cast(int) 1).to!uint == 1); + assert((cast(int) (int.max - 1)).to!uint == int.max - 1); + assert((cast(int) int.max).to!uint == int.max); +} + +@nogc pure @safe unittest +{ + assertThrown!ConvException(&to!(short, int), int.min); + assertThrown!ConvException(&to!(short, int), int.max); + assertThrown!ConvException(&to!(ushort, uint), uint.max); + assertThrown!ConvException(&to!(uint, int), -1); +} + +@nogc nothrow pure @safe unittest +{ + enum Test : int + { + one, + two, + } + assert(Test.one.to!int == 0); + assert(Test.two.to!int == 1); +} + +@nogc pure @safe unittest +{ + assertThrown!ConvException(&to!(int, double), 2147483647.5); + assertThrown!ConvException(&to!(int, double), -2147483648.5); + assertThrown!ConvException(&to!(uint, double), -21474.5); +} + +@nogc pure @safe unittest +{ + enum Test : uint + { + one, + two, + } + assertThrown!ConvException(&to!(Test, int), 5); +} + +@nogc pure @safe unittest +{ + assertThrown!ConvException(&to!(bool, int), -1); + assertThrown!ConvException(&to!(bool, int), 2); +} + +@nogc pure @safe unittest +{ + assertThrown!ConvException(() => "1".to!bool); +} + +@nogc pure @safe unittest +{ + assertThrown!ConvException(() => "".to!int); + assertThrown!ConvException(() => "-".to!int); + assertThrown!ConvException(() => "-5".to!uint); + assertThrown!ConvException(() => "-129".to!byte); + assertThrown!ConvException(() => "256".to!ubyte); +} diff --git a/tests/tanya/tests/format.d b/tests/tanya/tests/format.d new file mode 100644 index 0000000..b4a019d --- /dev/null +++ b/tests/tanya/tests/format.d @@ -0,0 +1,269 @@ +module tanya.tests.format; + +import tanya.format; +import tanya.range; + +// Converting an integer to string. +@nogc nothrow pure @system unittest +{ + char[21] buf; + + assert(integral2String(80, buf) == "80"); + assert(integral2String(-80, buf) == "-80"); + assert(integral2String(0, buf) == "0"); + assert(integral2String(uint.max, buf) == "4294967295"); + assert(integral2String(int.min, buf) == "-2147483648"); +} + +// Doesn't print the first argument repeatedly +@nogc nothrow pure @safe unittest +{ + assert(format!"{}{}"(1, 2) == "12"); +} + +@nogc nothrow pure @safe unittest +{ + assert(format!"Without arguments"() == "Without arguments"); + assert(format!""().length == 0); + + static assert(!is(typeof(format!"{}"()))); + static assert(!is(typeof(format!"{j}"(5)))); +} + +// Enum +@nogc nothrow pure @safe unittest +{ + enum E1 : int + { + one, + two, + } + assert(format!"{}"(E1.one) == "one"); + + const E1 e1; + assert(format!"{}"(e1) == "one"); +} + +// Modifiers +@nogc pure @safe unittest +{ + assert(format!"{}"(8.5) == "8.5"); + assert(format!"{}"(8.6) == "8.6"); + assert(format!"{}"(1000) == "1000"); + assert(format!"{}"(1) == "1"); + assert(format!"{}"(10.25) == "10.25"); + assert(format!"{}"(1) == "1"); + assert(format!"{}"(0.01) == "0.01"); +} + +// String printing +@nogc pure @safe unittest +{ + assert(format!"{}"("Some weired string") == "Some weired string"); + assert(format!"{}"(cast(string) null) == ""); + assert(format!"{}"('c') == "c"); +} + +// Integer +@nogc pure @safe unittest +{ + assert(format!"{}"(8) == "8"); + assert(format!"{}"(8) == "8"); + assert(format!"{}"(-8) == "-8"); + assert(format!"{}"(-8L) == "-8"); + assert(format!"{}"(8) == "8"); + assert(format!"{}"(100000001) == "100000001"); + assert(format!"{}"(99999999L) == "99999999"); + assert(format!"{}"(10) == "10"); + assert(format!"{}"(10L) == "10"); +} + +// Floating point +@nogc pure @safe unittest +{ + assert(format!"{}"(0.1234) == "0.1234"); + assert(format!"{}"(0.3) == "0.3"); + assert(format!"{}"(0.333333333333) == "0.333333"); + assert(format!"{}"(38234.1234) == "38234.1"); + assert(format!"{}"(-0.3) == "-0.3"); + assert(format!"{}"(0.000000000000000006) == "6e-18"); + assert(format!"{}"(0.0) == "0"); + assert(format!"{}"(double.init) == "NaN"); + assert(format!"{}"(-double.init) == "-NaN"); + assert(format!"{}"(double.infinity) == "Inf"); + assert(format!"{}"(-double.infinity) == "-Inf"); + assert(format!"{}"(0.000000000000000000000000003) == "3e-27"); + assert(format!"{}"(0.23432e304) == "2.3432e+303"); + assert(format!"{}"(-0.23432e8) == "-2.3432e+07"); + assert(format!"{}"(1e-307) == "1e-307"); + assert(format!"{}"(1e+8) == "1e+08"); + assert(format!"{}"(111234.1) == "111234"); + assert(format!"{}"(0.999) == "0.999"); + assert(format!"{}"(0x1p-16382L) == "0"); + assert(format!"{}"(1e+3) == "1000"); + assert(format!"{}"(38234.1234) == "38234.1"); + assert(format!"{}"(double.max) == "1.79769e+308"); +} + +// typeof(null) +@nogc pure @safe unittest +{ + assert(format!"{}"(null) == "null"); +} + +// Boolean +@nogc pure @safe unittest +{ + assert(format!"{}"(true) == "true"); + assert(format!"{}"(false) == "false"); +} + +// Unsafe tests with pointers +@nogc pure @system unittest +{ + // Pointer convesions + assert(format!"{}"(cast(void*) 1) == "0x1"); + assert(format!"{}"(cast(void*) 20) == "0x14"); + assert(format!"{}"(cast(void*) null) == "0x0"); +} + +// Structs +@nogc pure @safe unittest +{ + static struct WithoutStringify1 + { + int a; + void func() + { + } + } + assert(format!"{}"(WithoutStringify1(6)) == "WithoutStringify1(6)"); + + static struct WithoutStringify2 + { + } + assert(format!"{}"(WithoutStringify2()) == "WithoutStringify2()"); + + static struct WithoutStringify3 + { + int a = -2; + int b = 8; + } + assert(format!"{}"(WithoutStringify3()) == "WithoutStringify3(-2, 8)"); + + struct Nested + { + int i; + + void func() + { + } + } + assert(format!"{}"(Nested()) == "Nested(0)"); + + static struct WithToString + { + OR toString(OR)(OR range) const + { + put(range, "toString method"); + return range; + } + } + assert(format!"{}"(WithToString()) == "toString method"); +} + +// Aggregate types +@system unittest // Object.toString has no attributes. +{ + import tanya.memory; + import tanya.memory.smartref; + + interface I + { + } + class A : I + { + } + auto instance = defaultAllocator.unique!A(); + assert(format!"{}"(instance.get()) == instance.get().toString()); + assert(format!"{}"(cast(I) instance.get()) == I.classinfo.name); + assert(format!"{}"(cast(A) null) == "null"); + + class B + { + OR toString(OR)(OR range) const + { + put(range, "Class B"); + return range; + } + } + assert(format!"{}"(cast(B) null) == "null"); +} + +// Unions +unittest +{ + union U + { + int i; + char c; + } + assert(format!"{}"(U(2)) == "U"); +} + +// Ranges +@nogc pure @safe unittest +{ + static struct Stringish + { + private string content = "Some content"; + + immutable(char) front() const @nogc nothrow pure @safe + { + return this.content[0]; + } + + void popFront() @nogc nothrow pure @safe + { + this.content = this.content[1 .. $]; + } + + bool empty() const @nogc nothrow pure @safe + { + return this.content.length == 0; + } + } + assert(format!"{}"(Stringish()) == "Some content"); + + static struct Intish + { + private int front_ = 3; + + int front() const @nogc nothrow pure @safe + { + return this.front_; + } + + void popFront() @nogc nothrow pure @safe + { + --this.front_; + } + + bool empty() const @nogc nothrow pure @safe + { + return this.front == 0; + } + } + assert(format!"{}"(Intish()) == "[3, 2, 1]"); +} + +// Typeid +nothrow pure @safe unittest +{ + assert(format!"{}"(typeid(int[])) == "int[]"); + + class C + { + } + assert(format!"{}"(typeid(C)) == typeid(C).toString()); +} diff --git a/tests/tanya/tests/typecons.d b/tests/tanya/tests/typecons.d new file mode 100644 index 0000000..c49c266 --- /dev/null +++ b/tests/tanya/tests/typecons.d @@ -0,0 +1,238 @@ +module tanya.tests.typecons; + +import tanya.test.stub; +import tanya.typecons; + +@nogc nothrow pure @safe unittest +{ + static assert(is(Tuple!(int, int))); + static assert(!is(Tuple!(int, 5))); + + static assert(is(Tuple!(int, "first", int))); + static assert(is(Tuple!(int, "first", int, "second"))); + static assert(is(Tuple!(int, "first", int))); + + static assert(is(Tuple!(int, int, "second"))); + static assert(!is(Tuple!("first", int, "second", int))); + static assert(!is(Tuple!(int, int, int))); + + static assert(!is(Tuple!(int, "first"))); + + static assert(!is(Tuple!(int, double, char))); + static assert(!is(Tuple!(int, "first", double, "second", char, "third"))); +} + +// Assigns a new value +@nogc nothrow pure @safe unittest +{ + Option!int option = 5; + option = 8; + assert(!option.isNothing); + assert(option == 8); +} + +@nogc nothrow pure @safe unittest +{ + Option!int option; + const int newValue = 8; + assert(option.isNothing); + option = newValue; + assert(!option.isNothing); + assert(option == newValue); +} + +@nogc nothrow pure @safe unittest +{ + Option!int option1; + Option!int option2 = 5; + assert(option1.isNothing); + option1 = option2; + assert(!option1.isNothing); + assert(option1.get == 5); +} + +// Constructs with a value passed by reference +@nogc nothrow pure @safe unittest +{ + int i = 5; + assert(Option!int(i).get == 5); +} + +// Moving +@nogc nothrow pure @safe unittest +{ + static assert(is(typeof(Option!NonCopyable(NonCopyable())))); + // The value cannot be returned by reference because the default value + // isn't passed by reference + static assert(!is(typeof(Option!DisabledPostblit().or(NonCopyable())))); +} + +@nogc nothrow pure @safe unittest +{ + NonCopyable notCopyable; + static assert(is(typeof(Option!NonCopyable().or(notCopyable)))); +} + +@nogc nothrow pure @safe unittest +{ + Option!NonCopyable option; + assert(option.isNothing); + option = NonCopyable(); + assert(!option.isNothing); +} + +@nogc nothrow pure @safe unittest +{ + Option!NonCopyable option; + assert(option.isNothing); + option = Option!NonCopyable(NonCopyable()); + assert(!option.isNothing); +} + +// Cast to bool is done before touching the encapsulated value +@nogc nothrow pure @safe unittest +{ + assert(Option!bool(false)); +} + +// Option can be const +@nogc nothrow pure @safe unittest +{ + assert((const Option!int(5)).get == 5); + assert((const Option!int()).or(5) == 5); +} + +// Equality +@nogc nothrow pure @safe unittest +{ + assert(Option!int() == Option!int()); + assert(Option!int(0) != Option!int()); + assert(Option!int(5) == Option!int(5)); + assert(Option!int(5) == 5); + assert(Option!int(5) == cast(ubyte) 5); +} + +// Returns default value +@nogc nothrow pure @safe unittest +{ + int i = 5; + assert(((ref e) => e)(Option!int().or(i)) == 5); +} + +// Implements toHash() for nothing +@nogc nothrow pure @safe unittest +{ + alias OptionT = Option!Hashable; + assert(OptionT().toHash() == 0U); + assert(OptionT(Hashable(1U)).toHash() == 1U); +} + +// Can assign Option that is nothing +@nogc nothrow pure @safe unittest +{ + auto option1 = Option!int(5); + Option!int option2; + option1 = option2; + assert(option1.isNothing); +} + +@nogc nothrow pure @safe unittest +{ + Variant!(int, double) variant; + variant = 5; + assert(variant.peek!int); +} + +@nogc nothrow pure @safe unittest +{ + Variant!(int, double) variant; + variant = 5.0; + assert(!variant.peek!int); +} + +@nogc nothrow pure @safe unittest +{ + Variant!(int, double) variant = 5; + assert(variant.get!int == 5); +} + +@nogc nothrow pure @safe unittest +{ + static assert(is(Variant!(int, float))); + static assert(is(Variant!int)); +} + +@nogc nothrow pure @safe unittest +{ + static struct WithDestructorAndCopy + { + this(this) @nogc nothrow pure @safe + { + } + + ~this() @nogc nothrow pure @safe + { + } + } + static assert(is(Variant!WithDestructorAndCopy)); +} + +// Equality compares the underlying objects +@nogc nothrow pure @safe unittest +{ + Variant!(int, double) variant1 = 5; + Variant!(int, double) variant2 = 5; + assert(variant1 == variant2); +} + +@nogc nothrow pure @safe unittest +{ + Variant!(int, double) variant1 = 5; + Variant!(int, double) variant2 = 6; + assert(variant1 != variant2); +} + +// Differently typed variants aren't equal +@nogc nothrow pure @safe unittest +{ + Variant!(int, double) variant1 = 5; + Variant!(int, double) variant2 = 5.0; + assert(variant1 != variant2); +} + +// Uninitialized variants are equal +@nogc nothrow pure @safe unittest +{ + Variant!(int, double) variant1, variant2; + assert(variant1 == variant2); +} + +// Calls postblit constructor of the active type +@nogc nothrow pure @safe unittest +{ + static struct S + { + bool called; + + this(this) + { + this.called = true; + } + } + Variant!(int, S) variant1 = S(); + auto variant2 = variant1; + assert(variant2.get!S.called); +} + +// Variant.type is null if the Variant doesn't have a value +@nogc nothrow pure @safe unittest +{ + Variant!(int, uint) variant; + assert(variant.type is null); +} + +// Variant can contain only distinct types +@nogc nothrow pure @safe unittest +{ + static assert(!is(Variant!(int, int))); +}