std.unittests [updated] for review

Jonathan M Davis jmdavisProg at gmx.com
Tue Feb 1 12:50:43 PST 2011


On Tuesday 01 February 2011 11:32:08 Andrei Alexandrescu wrote:
> On 2/1/11 11:29 AM, Jonathan M Davis wrote:
> > On Tuesday 01 February 2011 09:12:16 Andrei Alexandrescu wrote:
> >> On 2/1/11 10:51 AM, Michel Fortin wrote:
> >>> On 2011-02-01 11:31:54 -0500, Andrei Alexandrescu
> >>> <SeeWebsiteForEmail at erdani.org>  said:
> >>> TypeInfo holds a pointer to the toString function, so if the compiler
> >>> passes the two operands as D-style variadic arguments to the assert
> >>> handler, the assert handler can use toString to print them. The
> >>> operator should be passed as a string.
> >> 
> >> In that case problem solved. Don, if you arrange things such that this
> >> user-level code:
> >> 
> >> int a = 42;
> >> double b = 3.14;
> >> assert(a<= b, "Something odd happened");
> >> 
> >> ultimately calls this runtime function:
> >> 
> >> assertCmpFailed("<=", "42", "3.14", "Something odd happened");
> >> 
> >> I promise I'll discuss with Sean and implement what it takes in druntime
> >> to get that completed.
> >> 
> >> We need to finalize that before Feb 7 though because on that date the
> >> vote for Jonathan's library closes. If you do implement that, probably
> >> we'll need to reject the library in the current form and propose back an
> >> amended version.
> > 
> > You do need to remember to take into account though that expressions can
> > be quite a bit more complex than a<= b, and you still want to be able to
> > print out something useful.
> > 
> > It's been discussed a bit already, but IIRC what appeared to be the best
> > solution was that when an expression evaluated to false, you take the
> > expression to evaluated and stop evaluating it when all that was left is
> > operators or functions which resulted in bool. Then the value of those
> > operands would be printed. e.g.
> > 
> > assert(min(5 + 2, 4)<  2&&  max(5, 7)<  10);
> > 
> > would print out the values
> > 
> > 4, 2, 7, and 10.
> 
> It's all about the top-level AST node. In this case I think it's
> reasonable to print "false && __unevaluated__" or simply "false". If the
> user wants the separate values, they can always write:
> 
> assert(min(5 + 2, 4) <  2);
> assert(max(5, 7) <  10);
> 
> > and
> > 
> > assert(canFind("hello world", "goodbye"));
> > 
> > would print out the values
> > 
> > "hello world" and "goodbye".
> 
> I guess again taking the function call as the top node, assert could
> print the arguments passed into the function.

Well, what the best way to handle it is and what exactly is possible, I don't 
know. However, it needs to print out the actual values of the expression and be 
reasonably close to what the programmer would be looking for in terms of which 
values would be printed. The simple examples are obvious. The complex ones 
aren't as obvious. And it may be that we can't get it to quite print out what 
your average programmer would want, but if we're close - particularly if we get 
the simple expressions right, then it may be good enough. Whatever assert can be 
made to do, it's unlikely to be as flexible as assertPred, but if we can get to 
do most of what assertPred does, then the remainder could be broken out into 
other functions for that purpose, or maybe those functions don't need to make it 
into Phobos.

Regardless, I think that we definitely need better error reporting on unit test 
failure. assertPred does that. But if the built in assert could do that, then 
we'd have the best assert out of any language that I've ever seen.

- Jonathan M Davis


More information about the Digitalmars-d mailing list