std.unittests for (final?) review

Jonathan M Davis jmdavisProg at gmx.com
Thu Jan 6 08:34:48 PST 2011


On Thursday 06 January 2011 05:30:56 Michel Fortin wrote:
> There's an other issue that's bothering me with these assertion
> functions... with 'assert', assertions behaves differently depending on
> where you write them. In regular code, on failure it calls _d_assert*,
> in a unit test on failure it calls _d_unittest*, and in contracts for
> virtual function... well that case I don't understand it fully but it
> does something very special to implement contract inheritance.
> 
> What does assertPred do? It does "throw new AssertError(...)",
> irrespective of the context. I'm pretty sure that'll break contract
> inheritance if used inside a contract. To be truly a replacement for
> assert, assertPred would need to know in which context it is called and
> generate the appropriate code, although I somewhat doubt it is even
> possible to generate the right code for contracts without the compiler
> doing it.

I don't know anything about this. As far as I know, there's no difference between 
assert in unittest blocks and assert in contracts. That being said, you're 
probably more knowledgeable than I am about that.

I would have thought was that all it would take would be for the AssertError to 
be handled appropriately by whatever catches it. In the case of contracts, I 
would think that it's an issue of the right contract code being called in the 
right order, and that which contract threw the test would be irrelevant (the 
stack track would show where it was; all that matters from the runtime's 
perspective is that there _was_ an AssertError thrown and that execution is 
therefore going to be stopping).

As for unittest blocks, I thought that it caught the AssertError from the 
unittest block and dealt with it. If it does that, then I don't see why it would 
need a special version of assert. I know that it _used_ to be different, because 
Walter temporarily made it so that within unittest blocks assert set a flag 
saying that the test failed and printed the error rather than throwing an 
AssertError, but Andrei and others complained about that (both that assert would 
have different behavior in different places and that a unittest block would 
continue after a failure), and it was agreed that assert would throw an 
AssertError like it normally does.

So, I don't know if assert does something different depending on where it is 
called. The only special case for assert that I'm aware of is assert(0), which 
becomes the halt instruction with -release rather than going away. If there is a 
difference, then we probably need to understand what it is and what issues it 
could cause. Ideally, there wouldn't be any difference.

However, I _have_ been using these functions in unit tests, and they work fine 
there. So, as far as unit testing goes, they work. I have _not_ been using them 
in contracts. I created them specifically with unit testing in mind (and in fact, 
with the current code, the entire module is in a version(unittest) block). It 
sounds like there are some folks (including Andrei) who think that it should be 
useable in normal contracts just like assert is. That's simple to fix by removing 
the version(unittest) block, but I don't know if there are any issues with 
throwing an AssertError from a function called within a contract rather than 
asserting directly inside a contract. If there is, I would think that that's a 
more general problem. I've been doing that all the time with invariants (just 
not with any of my unit testing functions), and that's worked as far as I can 
tell, but I've been using structs primarily, which wouldn't have contract 
inheritance. So, I think that assert should _definitely_ work normally when 
called from a function called from a contract rather than when used directly in 
a contract, but I don't know that that never causes problems. We need someone 
who actually knows what assert does in each case to say whether there's an 
issue, I think.

- Jonathan M Davis


More information about the Digitalmars-d mailing list