Jonathan M Davis wrote: > Is there a standard and/or acceptable way to make sure that pre-conditions, > post-conditions, or invariants _fail_ when running unit tests? That is, lets > say I had a function like this > > void func(int x) > in > { > assert(x < 8); > } > body > { > //... > } > > > and I wanted to test to make sure that func() couldn't be called with any int > greater or equal to 8, what would I do? The best that I can think of is to > catch an AssertError and ignore it. e.g. > > unittest > { > try > { > func(8); > assert(0); > } > catch(AssertionError ae) > {} > } > > > But catching AssertionErrors is generally a bad idea. As I understand it, when > anything derived from Error is thrown, code is not left in a proper state, > with stuff like destructors being skipped. Would it be okay to catch it in a > case like this, or is it a really bad idea? If it's a bad idea, I haven't a > clue how to verify that pre-condition, post-conditions, and invariants are > correct. > > - Jonathan M Davis
Thats a good one. It used to be so that dmd would assume a halt and you could get segfaults for continuing on. I *believe* this has changed and it is ok to catch AssertError in this scenario. The only thing I can think of is that nothrow functions can be optimized by the compiler, but are not typechecked for throwing Error. Even if this is correct, you still have the problem foo could call other functions that assert, which invalidates at least two contract checks. This may require some care. Perhaps an idea is to define a PreconditionError and PostconditionError and wrap them in a function similar to enforce, so you can differentiate more easily where the error is coming from. This way you also get better error messages and have one point where to change the behavior if this may be required.