From e316631f6e9b75ded1b00192e26170257efc6979 Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Thu, 12 Oct 2017 07:41:35 +0200 Subject: [PATCH] Add test package --- README.md | 1 + source/tanya/container/string.d | 29 +++------ source/tanya/net/uri.d | 93 +++++----------------------- source/tanya/test/assertion.d | 105 ++++++++++++++++++++++++++++++++ source/tanya/test/package.d | 17 ++++++ 5 files changed, 146 insertions(+), 99 deletions(-) create mode 100644 source/tanya/test/assertion.d create mode 100644 source/tanya/test/package.d diff --git a/README.md b/README.md index 384b724..fc8c053 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,7 @@ After finishing the new socket implementation will land in the `net` package and `network` will be deprecated. * `os`: Platform-independent interfaces to operating system functionality. * `range`: Generic functions and templates for D ranges. +* `test`: Test suite for unittest-blocks. * `typecons`: Templates that allow to build new types based on the available ones. diff --git a/source/tanya/container/string.d b/source/tanya/container/string.d index 813fe8a..c0751d4 100644 --- a/source/tanya/container/string.d +++ b/source/tanya/container/string.d @@ -36,6 +36,11 @@ import tanya.meta.transform; import tanya.range.array; import tanya.range.primitive; +version (unittest) +{ + import tanya.test.assertion; +} + /** * Thrown on encoding errors. */ @@ -612,17 +617,7 @@ struct String @nogc pure @safe unittest { - UTFException exception; - try - { - auto s = String(1, cast(wchar) 0xd900); - } - catch (UTFException e) - { - exception = e; - } - assert(exception !is null); - defaultAllocator.dispose(exception); + assertThrown!UTFException(() => String(1, cast(wchar) 0xd900)); } /// ditto @@ -648,17 +643,7 @@ struct String @nogc pure @safe unittest { - UTFException exception; - try - { - auto s = String(1, cast(dchar) 0xd900); - } - catch (UTFException e) - { - exception = e; - } - assert(exception !is null); - defaultAllocator.dispose(exception); + assertThrown!UTFException(() => String(1, cast(dchar) 0xd900)); } /** diff --git a/source/tanya/net/uri.d b/source/tanya/net/uri.d index 11983e0..7184f1c 100644 --- a/source/tanya/net/uri.d +++ b/source/tanya/net/uri.d @@ -17,6 +17,11 @@ module tanya.net.uri; import tanya.encoding.ascii; import tanya.memory; +version (unittest) +{ + import tanya.test.assertion; +} + /** * Thrown if an invalid URI was specified. */ @@ -324,7 +329,7 @@ struct URL } /// -@nogc unittest +@nogc pure @system unittest { auto u = URL("example.org"); assert(u.path == "example.org"); @@ -377,7 +382,7 @@ struct URL assert(u.fragment == "fragment"); } -private @nogc unittest +@nogc pure @system unittest { auto u = URL("127.0.0.1"); assert(u.path == "127.0.0.1"); @@ -446,83 +451,17 @@ private @nogc unittest assert(u.path == "h_tp:asdf"); } -private @nogc unittest +@nogc pure @system unittest { - URIException exception; - try - { - auto u = URL("http://:80"); - } - catch (URIException e) - { - exception = e; - } - assert(exception !is null); - defaultAllocator.dispose(exception); -} - -private @nogc unittest -{ - URIException exception; - try - { - auto u = URL(":80"); - } - catch (URIException e) - { - exception = e; - } - assert(exception !is null); - defaultAllocator.dispose(exception); -} - -private @nogc unittest -{ - URIException exception; - try - { - auto u = URL("http://user1:pass1@user2:pass2@example.org"); - } - catch (URIException e) - { - exception = e; - } - assert(exception !is null); - defaultAllocator.dispose(exception); -} - -private @nogc unittest -{ - URIException exception; - try - { - auto u = URL("http://blah.com:port"); - } - catch (URIException e) - { - exception = e; - } - assert(exception !is null); - defaultAllocator.dispose(exception); -} - -private @nogc unittest -{ - URIException exception; - try - { - auto u = URL("http://blah.com:66000"); - } - catch (URIException e) - { - exception = e; - } - assert(exception !is null); - defaultAllocator.dispose(exception); + assertThrown!URIException(() => URL("http://:80")); + assertThrown!URIException(() => URL(":80")); + assertThrown!URIException(() => URL("http://u1:p1@u2:p2@example.org")); + assertThrown!URIException(() => URL("http://blah.com:port")); + assertThrown!URIException(() => URL("http://blah.com:66000")); } // Issue 254: https://issues.caraus.io/issues/254. -private @system @nogc unittest +@nogc pure @system unittest { auto u = URL("ftp://"); assert(u.scheme == "ftp"); @@ -554,13 +493,13 @@ if (T == "scheme" } /// ditto -URL parseURL(const char[] source) @nogc +URL parseURL(const char[] source) @nogc pure { return URL(source); } /// -@nogc unittest +@nogc pure @system unittest { auto u = parseURL("http://example.org:5326"); assert(u.scheme == parseURL!"scheme"("http://example.org:5326")); diff --git a/source/tanya/test/assertion.d b/source/tanya/test/assertion.d new file mode 100644 index 0000000..4a82102 --- /dev/null +++ b/source/tanya/test/assertion.d @@ -0,0 +1,105 @@ +/* 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/. */ + +/** + * Additional assertions. + * + * This module provides functions that assert whether a given expression + * satisfies some complex condition, that can't be tested with + * $(D_KEYWORD assert) in a single line. Internally all the functions + * just evaluate the expression and call $(D_KEYWORD assert). + * + * The functions can cause segmentation fault if the module is compiled + * in production mode and the condition fails. + * + * Copyright: Eugene Wissner 2017. + * 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) + * Source: $(LINK2 https://github.com/caraus-ecms/tanya/blob/master/source/tanya/test/assertion.d, + * tanya/test/assertion.d) + */ +module tanya.test.assertion; + +import tanya.memory; +import tanya.meta.trait; + +/** + * Asserts whether the function $(D_PARAM expr) throws an exception of type + * $(D_PARAM E). If it does, the exception is catched and properly destroyed. + * If it doesn't, an assertion error is thrown. If the exception doesn't match + * $(D_PARAM E) type, it isn't catched and escapes. + * + * Params: + * E = Expected exception type. + * T = Throwing function type. + * Args = Argument types of the throwing function. + * expr = Throwing function. + * args = Arguments for $(D_PARAM expr). + */ +void assertThrown(E : Exception, T, Args...)(T expr, auto ref Args args) +if (isSomeFunction!T) +{ + try + { + cast(void) expr(args); + assert(false, "Expected exception not thrown"); + } + catch (E exception) + { + defaultAllocator.dispose(exception); + } +} + +/// +@nogc nothrow pure @safe unittest +{ + // If you want to test that an expression throws, you can wrap it into an + // arrow function. + static struct CtorThrows + { + this(int i) @nogc pure @safe + { + throw defaultAllocator.make!Exception(); + } + } + assertThrown!Exception(() => CtorThrows(8)); +} + +/** + * Asserts that the function $(D_PARAM expr) doesn't throw. + * + * If it does, the thrown exception is catched, properly destroyed and an + * assertion error is thrown instead. + * + * Params: + * T = Tested function type. + * Args = Argument types of $(D_PARAM expr). + * expr = Tested function. + * args = Arguments for $(D_PARAM expr). + */ +void assertNotThrown(T, Args...)(T expr, auto ref Args args) +if (isSomeFunction!T) +{ + try + { + cast(void) expr(args); + } + catch (Exception exception) + { + defaultAllocator.dispose(exception); + assert(false, "Unexpected exception thrown"); + } +} + +/// +@nogc nothrow pure @safe unittest +{ + // If you want to test that an expression doesn't throw, you can wrap it + // into an arrow function. + static struct S + { + } + assertNotThrown(() => S()); +} diff --git a/source/tanya/test/package.d b/source/tanya/test/package.d new file mode 100644 index 0000000..a1e339f --- /dev/null +++ b/source/tanya/test/package.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/. */ + +/** + * Test suite for $(D_KEYWORD unittest)-blocks. + * + * Copyright: Eugene Wissner 2017. + * 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) + * Source: $(LINK2 https://github.com/caraus-ecms/tanya/blob/master/source/tanya/test/package.d, + * tanya/test/package.d) + */ +module tanya.test; + +public import tanya.test.assertion;