Review: A new stab at a potential std.unittests

Jonathan M Davis jmdavisProg at gmx.com
Sun Nov 21 05:06:37 PST 2010


On Sunday 21 November 2010 04:19:51 Jacob Carlborg wrote:
> On 2010-11-21 02:34, Jonathan M Davis wrote:
> > On Saturday 20 November 2010 16:23:32 Jonathan M Davis wrote:
> >> The lazy solution sounds pretty good actually. Can anyone think of any
> >> real downsides to that? So, it would look something like
> >> 
> >> assertExcThrown(E : Throwable, T)(lazy T, string file = __FILE__, size_t
> >> line = __LINE__);
> > 
> > Wait. No. I didn't think that one through enough. It doesn't work. You
> > You don't actually get a delegate out of lazy, and what you need for
> > assertExcThrown!() is a delegate. It would be great to be able to
> > implicitly create a delegate like that, but lazy does it underneath the
> > hood, so to speak, and when the function call is made, you still get the
> > result of the function call, and by that point, it's too late, since to
> > get the result of the function call, you obviously need to have called
> > it. So, the question remains whether it would be better to pass a string
> > which gets mixed in or a delegate which gets called.
> 
> Ok, now I'm not sure what you mean. If you don't get a delegate what do
> you get? And what to you mean by "and by that point, it's too late", do
> late for what?
> 
> > I think that the delegate solution is uglier to use, but that's
> > debatable. It's less efficient at runtime, but it would be faster to
> > compile and would result in less code bloat (though how much code bloat
> > matters for unit tests is debatable, since they shouldn't end up in
> > released binaries). I'm really not sure which is better. I like the
> > mixin solution, but the delegate solution has its advantages as well.
> > 
> > Anyone else have an opinion on whether (and why) the string mixin
> > approach or the delegate approach is better?
> > 
> > - Jonathan M Davis
> 
> This works according to the documentation of assertExcThrown:
> 
> void foo (int, int)
> {
>      throw new Throwable("");
> }
> 
> void assertExcThrown (E = Throwable, T) (lazy T dg, string file =
> __FILE__, size_t line = __LINE__)
> {
>      bool thrown;
> 
>      try
>          dg();
> 
>      catch (E e)
>          thrown = true;
> 
>      if (!thrown)
>          throw new AssertError(format("assertExcThrown() failed: No %s
> was thrown.", E.stringof), file, line);
> }
> 
> void main ()
> {
>      assertExcThrown(foo(3, 4));
> }


Okay. I obviously don't use lazy enough and am probably posting too often 
without enough sleep. I was thinking that with a lazy parameter, whatever 
delegate which was created for it was called and the value assigned to the 
function argument before the function body was actually entered. So, internally 
to the function, it didn't matter at all whether a parameter was lazy or not, as 
if the laziness of the parameters affected the outside of the function only and 
not the inside. But that would completely defeat the point of lazy and makes no 
sense at all.

Now, the code that you give works, and I think that it shows that using lazy is 
exactly what assertExcThrown _should_ do. It allows for you to do a normal 
function call and then have it explicitly called within the function block 
without having to create a delegate or give the function call as a string. It 
annoys me a bit to have the extra overhead of the delegate, and part of me does 
think that it's silly to have a lazy parameter which is _always_ called, but it 
does the job, and it creates less code bloat than the mixin solution, and if 
speed is the main concern, the extra compilation overhead of the mixin solution 
is probably greater than the overhead of the delegate, so if you expect to 
compile and then immediately run the unit tests, the overall result of using a 
delegate is likely faster. And the lazy parameter gets rid of any ugliness that 
creating a delegate might have over the string mixin.

So, I'll change it to work with a lazy parameter instead. Thanks for your help.

- Jonathan M Davis


More information about the Digitalmars-d mailing list