Thread overview
throws or the like
Apr 21, 2008
bearophile
Apr 21, 2008
Sean Kelly
Apr 24, 2008
Christopher Wright
April 21, 2008
I don't feel (yet) the need for fancy unittest systems, but in my unittests I need to assert that something works as specified, for that I use assert(). I also need to assert that something throws the specified exceptions, for that in my D libs (that I suggest you to start using, because they are refined enough now) I have added the following:


/****************************************
Function template that takes as types one or more exception types, and
as argument a (lazy) expression. It returns true if once called the
expression throws one of the specified exception(s).

Examples:
void f(int i) { throw new Excep1("f msg"); }<br>
assert( Throws!(Excep1, Excep2)( f(10) ) );<br>
void bar(int i) {}<br>
assert( Throws!()( bar(10) ) );

The second example asserts that bar doesn't throw exceptions.
*/
bool Throws(TyExceptions...)(lazy void deleg) {
    try
        deleg();
    catch (Exception e) {
        foreach(TyExc; TyExceptions)
            if (cast(TyExc)e !is null) // like C++ dynamic_cast
                return true;
        return false;
    }
    return !TyExceptions.length;
}


The syntax of that Throws is bad still:
assert( Throws!(Exception1, Excep2)(foo(10)) );
assert( Throws!(Exception1, Exception2, ...)(foo(10)) );

Note that I have used that nested syntax because I need the line where the expected exception isn't thrown.

I'd like something in the D language like:
throws(foo(10), Exception1);
throws(foo(10), Exception1, Exception2, ...);

Later I have found that I use static asserts in my templates/functions, and I need to unittestes those too, so I'd probably enjoy a static version, able to catch static asserts etc:

static throws(foo(10), StaticException1);
static throws(foo(10), StaticException1, StaticException2, ...);

So far I haven't found a way to test such static assertions/errors, if you have suggestions I'd love to hear them.

Bye,
bearophile
April 21, 2008
== Quote from bearophile (bearophileHUGS@lycos.com)'s article
> I don't feel (yet) the need for fancy unittest systems, but in my unittests I need to assert that something
works as specified, for that I use assert(). I also need to assert that something throws the specified exceptions

I think an argument could be made for adding some functionality related to this to contracts.  Either extend the functionality of the "out" clause, or add a "throw" clause as well.  Your template example is pretty cool, however.


Sean
April 24, 2008
bearophile wrote:
> Later I have found that I use static asserts in my templates/functions, and I need to unittestes those too, so I'd probably enjoy a static version, able to catch static asserts etc:
> 
> static throws(foo(10), StaticException1);
> static throws(foo(10), StaticException1, StaticException2, ...);
> 
> So far I haven't found a way to test such static assertions/errors, if you have suggestions I'd love to hear them.

template template_throws(alias theTemplate, Args...)
{
	// If you have d2, you can use:
	// static if (__traits(compiles, theTemplate!(Args)))
	static if (is (typeof (theTemplate!(Args))))
	{
		enum template_throws = false;
	}
	else
	{
		enum template_throws = true;
	}
}

template Foo(int i)
{
	static assert (i > 1);
	const Foo = i;
}

static assert (template_throws!(Foo, 1));
static assert (!template_throws!(Foo, 2));

I don't see any static exceptions in D, so I can't handle them.

> Bye,
> bearophile