August 17, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=4644



--- Comment #10 from Andrej Mitrovic <andrej.mitrovich@gmail.com> 2010-08-17 08:04:24 PDT ---
I have a revamped edition, this one is much nicer:

void assertExceptionThrown(alias E, alias func, T...)(lineFile info, T args)
    if(__traits(compiles, {try{}catch(E e){}}))
{
    try
        func(args);
    catch(E e)
        return;     // Expected exception was thrown

    throw new AssertError(format("assertExceptionThrown() failed: No %s was
thrown from %s()", E.stringof, __traits(identifier, func)), info._file,
info._line);
}

void assertExceptionThrown(string msg, alias E, alias func, T...)(lineFile
info, T args)
    if(__traits(compiles, {try{}catch(E e){}}))
{
    try
        func(args);
    catch(E e)
        return;     // Expected exception was thrown

    throw new AssertError(format("assertExceptionThrown() failed: No %s was
thrown from %s(): %s", E.stringof, __traits(identifier, func), msg),
info._file, info._line);
}

void assertExceptionNotThrown(alias E, alias func, T...)(lineFile info, T args)
    if(__traits(compiles, {try{}catch(E e){}}))
{
    try
        func(args);
    catch(E e)
        throw new AssertError(format("assertExceptionNotThrown() failed: %s was
thrown from %s()", E.stringof, __traits(identifier, func)), info._file,
info._line);
}

void assertExceptionNotThrown(string msg, alias E, alias func, T...)(lineFile
info, T args)
    if(__traits(compiles, {try{}catch(E e){}}))
{
    try
        func(args);
    catch(E e)
        throw new AssertError(format("assertExceptionNotThrown() failed: %s was
thrown from %s(): %s", E.stringof, __traits(identifier, func), msg),
info._file, info._line);
}


import std.stdio, std.stream, core.exception, std.string, std.typecons;

int myfunc(int i)
{
    return i;
}

struct lineFile
{
    string _file;
    uint _line;

    @property
    auto call(string file = __FILE__, uint line = __LINE__)
    {
        _file = file;
        _line = line;
        return this;
    }
}

void main()
{
    lineFile info;
    assertExceptionThrown!(core.exception.AssertError, myfunc)(info.call, 5);
}

Btw, I'm not sure I understand how you're supossed to call the template that has "string msg" as a type parameter? Isn't that supossed to be next to the function arguments, as in this:

void assertExceptionThrown(alias E, alias func, T...)(string msg, lineFile
info, T args)

instead of this:

void assertExceptionThrown(string msg, alias E, alias func, T...)(lineFile
info, T args)

?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
August 17, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=4644



--- Comment #11 from Jonathan M Davis <jmdavisProg@gmail.com> 2010-08-17 12:08:49 PDT ---
I'm not sure that I understand your question about the msg parameter. If you put it in with the function arguments, then you _have_ to give a message every time because you can't use default parameters for the first argument. And since it would likely be the rare case to add an additional message, that would be annoying. With it as an additional template argument, you can have two templates - the normal one which omits the message and the more rarely used one which includes it.

I'd argue that for simplicity's sake, your lineFile struct really shouldn't need to be declared. You should just be able to make a function call (be it a standalone function or a static one on the struct itself) and have it return the struct. I think that the struct should get in the way as little as possible (since ideally, it wouldn't even be there at all). You could probably just use opCall() and do this:

assertExceptionThrown!(AssertError, myfunc)(LineInfo(), 5);

Also, we might want to rename the template functions to assertExcThrown() and
assertExcNotThrown() just because the names are painfully long, albeit nicely
descriptive.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
August 17, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=4644



--- Comment #12 from Jonathan M Davis <jmdavisProg@gmail.com> 2010-08-17 12:10:30 PDT ---
Oh, and for correctness' sake, I believe that __LINE__ is in fact size_t, not uint.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
August 17, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=4644



--- Comment #13 from Andrej Mitrovic <andrej.mitrovich@gmail.com> 2010-08-17 12:41:48 PDT ---
(In reply to comment #11)
> I'm not sure that I understand your question about the msg parameter. If you put it in with the function arguments, then you _have_ to give a message every time because you can't use default parameters for the first argument. And since it would likely be the rare case to add an additional message, that would be annoying. With it as an additional template argument, you can have two templates - the normal one which omits the message and the more rarely used one which includes it.
> 
> I'd argue that for simplicity's sake, your lineFile struct really shouldn't need to be declared. You should just be able to make a function call (be it a standalone function or a static one on the struct itself) and have it return the struct. I think that the struct should get in the way as little as possible (since ideally, it wouldn't even be there at all). You could probably just use opCall() and do this:
> 
> assertExceptionThrown!(AssertError, myfunc)(LineInfo(), 5);
> 
> Also, we might want to rename the template functions to assertExcThrown() and
> assertExcNotThrown() just because the names are painfully long, albeit nicely
> descriptive.

Yeah, I was looking for a way to get rid of having to create a struct. You'll have to forgive me, I'm still learning about structs from TDPL and didn't know about opCall(). :)

As for size_t, well usually I try to request a type of an identifier with
typeid(), and in this case I get an int back (not sure why I've put uint
there). I guess size_t is aliased to int..?

As for the template, I didn't know you could put both type parameters and value parameters in the first pair of paranthesis. Btw, I'm getting errors with this call:

lineFile info;
assertExceptionThrown!("test", core.exception.AssertError, myfunc)(info.call,
5);

test.d(86): Error: tuple T is used as a type

It only works if I comment out the first overloaded template.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
August 17, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=4644



--- Comment #14 from Jonathan M Davis <jmdavisProg@gmail.com> 2010-08-17 15:48:08 PDT ---
Created an attachment (id=722)
Implementation for assertExcThrown() and assertExcNotThrown()

Thanks, to Andrej's help, I think that I have an acceptable, working version of these functions. So, I'm attaching them along with unit tests for them. They also include ddoc comments.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
August 17, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=4644



--- Comment #15 from Jonathan M Davis <jmdavisProg@gmail.com> 2010-08-17 15:57:03 PDT ---
@Andrej

size_t is an alias appropriate for whatever your architecture is. IIRC, it's the same size as pointers are, but I'm not 100% sure on that. It's also the type used for indexing arrays. For 32-bit, that would be int or uint. For 64-bit, that's going to be long or ulong.

I'm not sure why you're getting that error, but it works fine with the version that I just attached to the bug. Overall, I think that the functions look good. Ideally, you wouldn't have to use LineInfo at all, but thanks to variadic templates, we're kind of stuck. It was a good idea though. In any case, I think that we now have a proper, working implementation of these functions. Now if they'd only be put into Phobos... ;)

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
August 17, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=4644



--- Comment #16 from Andrej Mitrovic <andrej.mitrovich@gmail.com> 2010-08-17 16:00:36 PDT ---
Nicely done with the formatting and documentation, I hope it gets added. I can confirm that the unittests run fine now.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
March 22, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=4644


Jonathan M Davis <jmdavisProg@gmx.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |FIXED


--- Comment #17 from Jonathan M Davis <jmdavisProg@gmx.com> 2011-03-21 22:54:37 PDT ---
Reviewed on D newsgroup and an improved version added to Phobos:

https://github.com/D-Programming-Language/phobos/pull/12 https://github.com/D-Programming-Language/phobos/commit/169f4225bf8410040165ac38a0e17fc7f5d79b2b

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
1 2
Next ›   Last »