Re: Review: A new stab at a potential std.unittests

2010-11-19 Thread Sean Kelly
Jonathan M Davis Wrote:
> 
> In particular, needing to pass LineInfo() to assertExcThrown!() to know the 
> file 
> and line number was disliked (though it was by far the best solution that I'd 
> been able to come up with).

Not sure if this helps, but if you default-initialize template function 
parameters with __LINE__ and __FILE__ they get the line and file of where the 
template was instantiated.


Re: Review: A new stab at a potential std.unittests

2010-11-19 Thread Jonathan M Davis
On Friday, November 19, 2010 11:37:16 Sean Kelly wrote:
> Jonathan M Davis Wrote:
> > In particular, needing to pass LineInfo() to assertExcThrown!() to know
> > the file and line number was disliked (though it was by far the best
> > solution that I'd been able to come up with).
> 
> Not sure if this helps, but if you default-initialize template function
> parameters with __LINE__ and __FILE__ they get the line and file of where
> the template was instantiated.

Yes. The problem was that the function was a _variadic_ template. So, you 
couldn't have default arguments. LineInfo had default arguments in its opCall() 
which were the file and line number, so you passed LineInfo() as the first 
argument to the function, thereby not having to pass __FILE__ and __LINE__, but 
ideally, they would be default arguments of the original function as you 
suggest. It's just that the variadic part got in the way. The new version is 
neither variadic (since whole call is a single string rather than passing the 
function name and arguments separately), and it doesn't even need the __FILE__ 
and __LINE__ number as default arguments, since they're just used directly in 
the string that's mixed in.

- Jonathan M Davis


Re: Review: A new stab at a potential std.unittests

2010-11-19 Thread Sean Kelly
Jonathan M Davis Wrote:

> On Friday, November 19, 2010 11:37:16 Sean Kelly wrote:
> > Jonathan M Davis Wrote:
> > > In particular, needing to pass LineInfo() to assertExcThrown!() to know
> > > the file and line number was disliked (though it was by far the best
> > > solution that I'd been able to come up with).
> > 
> > Not sure if this helps, but if you default-initialize template function
> > parameters with __LINE__ and __FILE__ they get the line and file of where
> > the template was instantiated.
> 
> Yes. The problem was that the function was a _variadic_ template. So, you 
> couldn't have default arguments.

This should work:

void func(string x = __FILE__, T...)(T args);

D allows defaulted template arguments to occur before non-defaulted ones.


Re: Review: A new stab at a potential std.unittests

2010-11-19 Thread Jonathan M Davis
On Friday 19 November 2010 11:59:18 Sean Kelly wrote:
> Jonathan M Davis Wrote:
> > On Friday, November 19, 2010 11:37:16 Sean Kelly wrote:
> > > Jonathan M Davis Wrote:
> > > > In particular, needing to pass LineInfo() to assertExcThrown!() to
> > > > know the file and line number was disliked (though it was by far the
> > > > best solution that I'd been able to come up with).
> > > 
> > > Not sure if this helps, but if you default-initialize template function
> > > parameters with __LINE__ and __FILE__ they get the line and file of
> > > where the template was instantiated.
> > 
> > Yes. The problem was that the function was a _variadic_ template. So, you
> > couldn't have default arguments.
> 
> This should work:
> 
> void func(string x = __FILE__, T...)(T args);
> 
> D allows defaulted template arguments to occur before non-defaulted ones.

If so, then I obviously assumed that that wouldn't work. You certainly can't do 
that with the function arguments. I think that the new solution is still better 
though, because it allows you to write the function call like you normally 
would. You just have to put it in string form. That, and there were problems 
with passing the function as an alias. Still, it's definitely good to know that 
you can have default template arguments before non-defaulted ones. Thanks.

- Jonathan M Davis


Re: Review: A new stab at a potential std.unittests

2010-11-19 Thread Leandro Lucarella
Sean Kelly, el 19 de noviembre a las 14:59 me escribiste:
> Jonathan M Davis Wrote:
> 
> > On Friday, November 19, 2010 11:37:16 Sean Kelly wrote:
> > > Jonathan M Davis Wrote:
> > > > In particular, needing to pass LineInfo() to assertExcThrown!() to know
> > > > the file and line number was disliked (though it was by far the best
> > > > solution that I'd been able to come up with).
> > > 
> > > Not sure if this helps, but if you default-initialize template function
> > > parameters with __LINE__ and __FILE__ they get the line and file of where
> > > the template was instantiated.
> > 
> > Yes. The problem was that the function was a _variadic_ template. So, you 
> > couldn't have default arguments.
> 
> This should work:
> 
> void func(string x = __FILE__, T...)(T args);
> 
> D allows defaulted template arguments to occur before non-defaulted ones.

And what is func!("blah")(); is supposed to do, make x = "blah"? args[0]
= "blah"? both?

(I don't have a compiler at hand to try it =P)

-- 
Leandro Lucarella (AKA luca) http://llucax.com.ar/
--
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)
--
He used to do surgery
On girls in the eighties
But gravity always wins


Re: Review: A new stab at a potential std.unittests

2010-11-19 Thread Jonathan M Davis
On Friday 19 November 2010 12:39:20 Leandro Lucarella wrote:
> Sean Kelly, el 19 de noviembre a las 14:59 me escribiste:
> > Jonathan M Davis Wrote:
> > > On Friday, November 19, 2010 11:37:16 Sean Kelly wrote:
> > > > Jonathan M Davis Wrote:
> > > > > In particular, needing to pass LineInfo() to assertExcThrown!() to
> > > > > know the file and line number was disliked (though it was by far
> > > > > the best solution that I'd been able to come up with).
> > > > 
> > > > Not sure if this helps, but if you default-initialize template
> > > > function parameters with __LINE__ and __FILE__ they get the line and
> > > > file of where the template was instantiated.
> > > 
> > > Yes. The problem was that the function was a _variadic_ template. So,
> > > you couldn't have default arguments.
> > 
> > This should work:
> > 
> > void func(string x = __FILE__, T...)(T args);
> > 
> > D allows defaulted template arguments to occur before non-defaulted ones.
> 
> And what is func!("blah")(); is supposed to do, make x = "blah"? args[0]
> = "blah"? both?
> 
> (I don't have a compiler at hand to try it =P)

T... is filled in be args, so if there are no args, T is empty. It can't 
confuse 
x for T...

- Jonathan M Davis


Re: Review: A new stab at a potential std.unittests

2010-11-19 Thread Sean Kelly
Leandro Lucarella Wrote:

> Sean Kelly, el 19 de noviembre a las 14:59 me escribiste:
> > 
> > This should work:
> > 
> > void func(string x = __FILE__, T...)(T args);
> > 
> > D allows defaulted template arguments to occur before non-defaulted ones.
> 
> And what is func!("blah")(); is supposed to do, make x = "blah"? args[0]
> = "blah"? both?

void func(string x = __FILE__, T...)(T args)
{
writeln( x, ' ', args.length );
}

void main()
{
func!("hi")();
}

prints:

hi 0


Re: Review: A new stab at a potential std.unittests

2010-11-19 Thread Leandro Lucarella
Jonathan M Davis, el 19 de noviembre a las 13:24 me escribiste:
> On Friday 19 November 2010 12:39:20 Leandro Lucarella wrote:
> > Sean Kelly, el 19 de noviembre a las 14:59 me escribiste:
> > > Jonathan M Davis Wrote:
> > > > On Friday, November 19, 2010 11:37:16 Sean Kelly wrote:
> > > > > Jonathan M Davis Wrote:
> > > > > > In particular, needing to pass LineInfo() to assertExcThrown!() to
> > > > > > know the file and line number was disliked (though it was by far
> > > > > > the best solution that I'd been able to come up with).
> > > > > 
> > > > > Not sure if this helps, but if you default-initialize template
> > > > > function parameters with __LINE__ and __FILE__ they get the line and
> > > > > file of where the template was instantiated.
> > > > 
> > > > Yes. The problem was that the function was a _variadic_ template. So,
> > > > you couldn't have default arguments.
> > > 
> > > This should work:
> > > 
> > > void func(string x = __FILE__, T...)(T args);
> > > 
> > > D allows defaulted template arguments to occur before non-defaulted ones.
> > 
> > And what is func!("blah")(); is supposed to do, make x = "blah"? args[0]
> > = "blah"? both?
> > 
> > (I don't have a compiler at hand to try it =P)
> 
> T... is filled in be args, so if there are no args, T is empty. It can't 
> confuse 
> x for T...

Good point, thanks for the clarification.

-- 
Leandro Lucarella (AKA luca) http://llucax.com.ar/
--
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)
--
Sometimes you got to suffer a little in your youth to motivate you to
succeed later in life. Do you think if Bill Gates got laid in high
school, do you think there'd be a Microsoft? Of course not. You gotta
spend a lot of time stuffin your own locker with your underwear wedged
up your arse before you think "I'm gona take over the world with
computers! You'll see I'll show them."


Re: Review: A new stab at a potential std.unittests

2010-11-20 Thread Fawzi Mohamed


On 19-nov-10, at 23:44, Sean Kelly wrote:


Leandro Lucarella Wrote:


Sean Kelly, el 19 de noviembre a las 14:59 me escribiste:


This should work:

void func(string x = __FILE__, T...)(T args);

D allows defaulted template arguments to occur before non- 
defaulted ones.


I wasn't aware that __FILE__ and __LINE__ did expand at the  
instantiation place, it is nice,  but that seems to be the case only  
for D2 :(


Re: Review: A new stab at a potential std.unittests

2010-11-20 Thread Jacob Carlborg

On 2010-11-19 19:16, Jonathan M Davis wrote:

Updated code: http://is.gd/hqPb2

Okay. As mentioned before, I have helper unit test functions which I use heavily
in std.datetime and which are pretty much going to have to either end up as
private helper functions in std.datetime or actually get added in a separate
module for everyone to use (I'd prefer the latter). My last post on it seems to
have met with positive feedback overall for the basic idea but not necessarily
the execution.

In particular, needing to pass LineInfo() to assertExcThrown!() to know the file
and line number was disliked (though it was by far the best solution that I'd
been able to come up with). Overall, it's worked quite well, but periodically
(for reasons that I _still_ don't understand) passing the function as an alias
didn't work properly (sometimes the template constraint which checked that
calling the function - exactly how it was called in the code - compiled failed,
whereas the template would compile if the constraint was removed, which makes no
sense at all to me). So, there were enough problems in using it and enough
dislike for how it worked, that I mucked around with it a bit to find a better
way to do it, and I believe that I've found one. You end up passing the entire
function call as a string (preferably a WYSIWYG string). So, instead of

assertExcThrown!(Exception, myfunc)(LineInfo(), param1, param2);

you get the much shorter and cleaner

mixin(assertExcThrown!(Exception, `myfunc(param1, param2)`));


It mixes the whole thing in on that one line, so it doesn't affect the line 
count
and the call is actually done at the local scope, so it's exactly as if you'd
written the function call directly in the function (since that's how it gets
compiled in). It also manages to deal with __FILE__ and __LINE__  internally
this way without even needing to pass them as default parameters. The one
downside is that - being a string mixin - it does come with higher compilation
overhead. But that should improve as the compiler improves (
http://d.puremagic.com/issues/show_bug.cgi?id=1382 is likely the main culprit).

The list of functions is unchanged, but a few of them became eponymous templates
to be mixed in as strings rather than being templated function calls. It is bit
annoying to have to use mixin to do it, but the result is much cleaner on the
whole, I believe. So, it's a huge useability change.

In any case, I'm presenting the updated for your review, so tell me what you
think.

- Jonathan M Davis


P.S. My most recent update of std.datetime doesn't use the updated unit test
functions yet, so the only examples of how to use them are in the docs and
source of my unittest module - both of which are included in the link above.
I'll likely post a version of std.datetime with the updated unit tests later
today, so if you really want to see the functions used on a larger scale, you
can check that out then.


Why don't you use delegates instead of string mixins? For example, 
assertExcThrown, could take a delegate which calls the function you want 
to test instead of a string that represents the call. The mixin want be 
needed as well. Am I missing something?


--
/Jacob Carlborg


Re: Review: A new stab at a potential std.unittests

2010-11-20 Thread Lutger Blijdestijn
I'm not particularly fond of this interface and think that a solution with a 
delegate / lazy or alias template parameter would be more convenient. 
However, until we have ast macros I do see the added value in this approach.

Some remarks about the api, not a proper review of the code itself:

- core.exception and std.string must be imported to use the module, relevant 
symbols should be selectively and publicy imported instead.

- exception would be better abbreviated as ex instead of exc, I believe this 
is more conventional. (assertExThrown instead of assertExcThrown)

- assertExcThrown should fail if an exception is thrown that is not T or a 
subclass of T. (catch and throw AssertError)

- assertEqual and assertNotEqual is inconsistent in naming with the 
assertOpFoo class of functions

I believe these assertions should be added:

- assertExcThrown and assertExcNotThrown with a default T (should be 
Exception, not Throwable)

- something equivalent to std.algorithm.equal, the latter is very useful in 
unittests

- assertOpBinary, assertTrue and perhaps assertPred (where the predicate is 
an template alias parameter)





Re: Review: A new stab at a potential std.unittests

2010-11-20 Thread Andrej Mitrovic
What about debug vs release compilation for this new module?

We know we have assert for debug mode, and enforce for release mode
(except the special assert false case). If I want assertExcThrown to
be compiled in release mode it seems I'd need an enforced version of
it, possibly called enforceExcThrown that uses enforce internally.

I'd prefer if we could somehow mark assert's to be compiled in release
mode instead of having to duplicate code for assert and enforce
versions of these new unittest functions.

On 11/20/10, Jacob Carlborg  wrote:
> On 2010-11-19 19:16, Jonathan M Davis wrote:
>> Updated code: http://is.gd/hqPb2
>>
>> Okay. As mentioned before, I have helper unit test functions which I use
>> heavily
>> in std.datetime and which are pretty much going to have to either end up
>> as
>> private helper functions in std.datetime or actually get added in a
>> separate
>> module for everyone to use (I'd prefer the latter). My last post on it
>> seems to
>> have met with positive feedback overall for the basic idea but not
>> necessarily
>> the execution.
>>
>> In particular, needing to pass LineInfo() to assertExcThrown!() to know
>> the file
>> and line number was disliked (though it was by far the best solution that
>> I'd
>> been able to come up with). Overall, it's worked quite well, but
>> periodically
>> (for reasons that I _still_ don't understand) passing the function as an
>> alias
>> didn't work properly (sometimes the template constraint which checked that
>> calling the function - exactly how it was called in the code - compiled
>> failed,
>> whereas the template would compile if the constraint was removed, which
>> makes no
>> sense at all to me). So, there were enough problems in using it and enough
>> dislike for how it worked, that I mucked around with it a bit to find a
>> better
>> way to do it, and I believe that I've found one. You end up passing the
>> entire
>> function call as a string (preferably a WYSIWYG string). So, instead of
>>
>> assertExcThrown!(Exception, myfunc)(LineInfo(), param1, param2);
>>
>> you get the much shorter and cleaner
>>
>> mixin(assertExcThrown!(Exception, `myfunc(param1, param2)`));
>>
>>
>> It mixes the whole thing in on that one line, so it doesn't affect the
>> line count
>> and the call is actually done at the local scope, so it's exactly as if
>> you'd
>> written the function call directly in the function (since that's how it
>> gets
>> compiled in). It also manages to deal with __FILE__ and __LINE__
>> internally
>> this way without even needing to pass them as default parameters. The one
>> downside is that - being a string mixin - it does come with higher
>> compilation
>> overhead. But that should improve as the compiler improves (
>> http://d.puremagic.com/issues/show_bug.cgi?id=1382 is likely the main
>> culprit).
>>
>> The list of functions is unchanged, but a few of them became eponymous
>> templates
>> to be mixed in as strings rather than being templated function calls. It
>> is bit
>> annoying to have to use mixin to do it, but the result is much cleaner on
>> the
>> whole, I believe. So, it's a huge useability change.
>>
>> In any case, I'm presenting the updated for your review, so tell me what
>> you
>> think.
>>
>> - Jonathan M Davis
>>
>>
>> P.S. My most recent update of std.datetime doesn't use the updated unit
>> test
>> functions yet, so the only examples of how to use them are in the docs and
>> source of my unittest module - both of which are included in the link
>> above.
>> I'll likely post a version of std.datetime with the updated unit tests
>> later
>> today, so if you really want to see the functions used on a larger scale,
>> you
>> can check that out then.
>
> Why don't you use delegates instead of string mixins? For example,
> assertExcThrown, could take a delegate which calls the function you want
> to test instead of a string that represents the call. The mixin want be
> needed as well. Am I missing something?
>
> --
> /Jacob Carlborg
>


Re: Review: A new stab at a potential std.unittests

2010-11-20 Thread Jonathan M Davis
On Saturday 20 November 2010 08:03:52 Jacob Carlborg wrote:
> Why don't you use delegates instead of string mixins? For example,
> assertExcThrown, could take a delegate which calls the function you want
> to test instead of a string that represents the call. The mixin want be
> needed as well. Am I missing something?

Well, delegates wouldn't be a bad idea, but they're unwieldy too. Would you 
rather write

assertExcThrown!Exception((){func(param1, param2);});

or

mixin(assertExcThrown!(Exception, `func(param1, param2)`));


The delegate would be less efficient, but you could reduce code duplication by 
going that route, since then __FILE__ and __LINE__ could be default parameters 
to assertExcThrown!(). It would also make it so that __FILE__ and __LINE__ 
could 
be replace if you reall wanted to (which could be useful), but you could do 
that 
by changing it so that the mixin version of assertExcThrown!() took __FILE__ 
and 
__LINE__ as default parameters instead of them being internal to the mixin. 
Neither is pretty, but they both have their pros and cons. It looks like if I 
do 
keep the mixin version, I should probably move __FILE__ and __LINE__ to 
parameters instead of mixing them in directly, so that it's more flexible. I 
suppose that you could just make the function call parameter a lazy one and 
templatize assertExcThrown!() on the return type of the function (I _think_ 
that 
that would still work with void). That way, you could avoid having to type 
(){;} 
around the function call. In a way though, it is a bit silly to declare it as 
lazy, since it _always_ gets called. That could be the best way to go though.

Honestly, it never even occurred to me to make it a delegate. I was originally 
trying to pass the function and its arguments separately, and that didn't work 
as well as I'd have liked, and the mixin solution is what I arrived at. I do 
find 
having to pass a delegate uglier than having to use a mixin, but that's 
probably 
pretty subjective and debatable. Using delegates will make for less efficient 
unit 
tests, but it would mean less code duplication, and thus faster compilation. 
So, 
it's not entirely a straightforward choice, I think.

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__);

- Jonathan M Davis


Re: Review: A new stab at a potential std.unittests

2010-11-20 Thread Jonathan M Davis
On Saturday 20 November 2010 10:16:55 Lutger Blijdestijn wrote:
> I'm not particularly fond of this interface and think that a solution with
> a delegate / lazy or alias template parameter would be more convenient.
> However, until we have ast macros I do see the added value in this
> approach.
> 
> Some remarks about the api, not a proper review of the code itself:
> 
> - core.exception and std.string must be imported to use the module,
> relevant symbols should be selectively and publicy imported instead.

I hadn't thought of that. Good idea.

> - exception would be better abbreviated as ex instead of exc, I believe
> this is more conventional. (assertExThrown instead of assertExcThrown)

I'll think about it. I don't think that I've often seen it abbreviated at all. 
But if Ex really is more common, then that would be better.

> - assertExcThrown should fail if an exception is thrown that is not T or a
> subclass of T. (catch and throw AssertError)

It currently catches the exact exception (well, throwable) that you tell it to. 
The others are let through exactly like they would be with an assert. It also 
means that you get to see exactly what the erroneous exception was so that you 
can deal with it. An AssertError would be less informative, maybe even 
misleading. You get an AssertError because it didn't throw any exception, 
whereas you get the wrong exception if it threw the wrong one.

I suppose that I could see an argument that because it didn't throw that exact 
exception, it should throw an AssertError, but I think that it's worse, because 
you can't see what the unexpected exception was. It would be less helpful in 
debugging rather than more.

> - assertEqual and assertNotEqual is inconsistent in naming with the
> assertOpFoo class of functions

Not quite. assertEqual() doesn't explicitly test opEqual(). It uses ==. So, it 
works with primitives as well as structs that didn't declare an opEquals(). 
assertOpCmp() on the other hand, explicitly calls opCmp() - so, for instance, 
assertOpCmp!"=="() specifically tests that opCmp() returned zero rather than 
using ==. However, assertOpOpAssign doesn't actually call opOpAssign(), so 
there 
arguably is an inconsistency there. I'll have to think about how it would be 
best to adjust those names. I think that assertEqual() should definitely stay 
assertEqual() - it doesn't explicitly call opEquals() and other unit testing 
frameworks frequent have a function named assertEquals(), so it will be more 
familiar to many. I also think that assertOpCmp!() should stay as it is, since 
it is explicitly calling opCmp(). The really question is what to rename 
assertOpOpAssign!() to, since like with assertEqual(), it would be too 
restrictive to directly call opOpAssign(), and I can't rename it 
assertOpAssign() because opAssign() is something else entirely. So, if a 
different name would be better, I'm going to have to find one, since I don't 
know 
what else to name it.

> I believe these assertions should be added:
> 
> - assertExcThrown and assertExcNotThrown with a default T (should be
> Exception, not Throwable)

That's not a bad idea, though personally, I tend to think that if someone used 
an Exception rather than a derived type that they aren't be specific enough 
(I'm 
sure that many would argue with me on that one though). It might work to just 
give it a default parameter (and I do agree that the default should be 
Exception 
rather than Throwable).

> - something equivalent to std.algorithm.equal, the latter is very useful in
> unittests

I'm not sure that I'd noticed std.algorithm.equal() before. That's a good idea. 
assertEqual() could simply be templatized in the same manner as 
std.algorithm.equal().

> - assertOpBinary, assertTrue and perhaps assertPred (where the predicate is
> an template alias parameter)

I decided that assertTrue() was a waste of time, because that's what a bare 
assert does. The same goes for assertFalse(), because all you have to do is add 
! in front of the expression. All of the functions that I have are there to 
either improve the output (such as printing out the actual values of the two 
values being compared in assertEqual()), or they get rid of boilerplate code 
(such as the try-catch block and other details in assertExcThrown!()).

As for assertOpBinary, are you suggesting a function which does the given 
binary 
operation and then compares the result with the given expected result? That 
would be a good addition.

As for assertPred. I don't know what that would do. Would that take a predicate 
and its parameters and then assert that the result was true? If that's what 
you're looking for, then assertPredTrue and assertPredFalse would be better. I 
think that you need to clarify quite what you meant though.

I pretty much created the unit test functions which I needed for std.datetime. 
So, I'm sure that there are other good ones which could be added. And I think 
that we should do so. My main concern though has b

Re: Review: A new stab at a potential std.unittests

2010-11-20 Thread Jonathan M Davis
On Saturday 20 November 2010 10:23:36 Andrej Mitrovic wrote:
> What about debug vs release compilation for this new module?
> 
> We know we have assert for debug mode, and enforce for release mode
> (except the special assert false case). If I want assertExcThrown to
> be compiled in release mode it seems I'd need an enforced version of
> it, possibly called enforceExcThrown that uses enforce internally.
> 
> I'd prefer if we could somehow mark assert's to be compiled in release
> mode instead of having to duplicate code for assert and enforce
> versions of these new unittest functions.

It's specifically versioned on unittest. So, if you have unit tests enable, 
they'll be compiled in. If you don't, then they won't. Their entire purpose is 
for improving unit tests, and they aren't really intended for use anywhere 
else. 
And since they all throw AssertError on failure, they would be exactly as 
useful 
as an assert would be if it were compiled in.

Why would you be looking to use them outside of unit tests? What would you be 
trying to do with them?

- Jonathan M Davis


Re: Review: A new stab at a potential std.unittests

2010-11-20 Thread Jonathan M Davis
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.

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


Re: Review: A new stab at a potential std.unittests

2010-11-21 Thread Jacob Carlborg

On 2010-11-21 01:23, Jonathan M Davis wrote:

On Saturday 20 November 2010 08:03:52 Jacob Carlborg wrote:

Why don't you use delegates instead of string mixins? For example,
assertExcThrown, could take a delegate which calls the function you want
to test instead of a string that represents the call. The mixin want be
needed as well. Am I missing something?


Well, delegates wouldn't be a bad idea, but they're unwieldy too. Would you
rather write

assertExcThrown!Exception((){func(param1, param2);});

or

mixin(assertExcThrown!(Exception, `func(param1, param2)`));


I would go with the delegate, but when you format the code like that it 
doesn't look any good (btw, no need for the extra pair of empty 
parentheses). I think this looks better:


assertExcThrown!Exception({
func(param1, param2);
});

And BTW, D needs a better way to pass a delegates to a function, 
something like the syntax that can be used in Scala:


assertExcThrown!Exception {
func(param1, param2);
}

I think that someone has talked about this syntax before on this mailing 
list.



The delegate would be less efficient, but you could reduce code duplication by
going that route, since then __FILE__ and __LINE__ could be default parameters
to assertExcThrown!(). It would also make it so that __FILE__ and __LINE__ could
be replace if you reall wanted to (which could be useful), but you could do that
by changing it so that the mixin version of assertExcThrown!() took __FILE__ and
__LINE__ as default parameters instead of them being internal to the mixin.
Neither is pretty, but they both have their pros and cons. It looks like if I do
keep the mixin version, I should probably move __FILE__ and __LINE__ to
parameters instead of mixing them in directly, so that it's more flexible. I
suppose that you could just make the function call parameter a lazy one and
templatize assertExcThrown!() on the return type of the function (I _think_ that
that would still work with void). That way, you could avoid having to type (){;}
around the function call. In a way though, it is a bit silly to declare it as
lazy, since it _always_ gets called. That could be the best way to go though.

Honestly, it never even occurred to me to make it a delegate. I was originally
trying to pass the function and its arguments separately, and that didn't work
as well as I'd have liked, and the mixin solution is what I arrived at. I do 
find
having to pass a delegate uglier than having to use a mixin, but that's probably
pretty subjective and debatable. Using delegates will make for less efficient 
unit
tests, but it would mean less code duplication, and thus faster compilation. So,
it's not entirely a straightforward choice, I think.


I guess you're right and I would choose the delegates.


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__);

- Jonathan M Davis


--
/Jacob Carlborg


Re: Review: A new stab at a potential std.unittests

2010-11-21 Thread Jacob Carlborg

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));
}

--
/Jacob Carlborg


Re: Review: A new stab at a potential std.unittests

2010-11-21 Thread Jonathan M Davis
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


Re: Review: A new stab at a potential std.unittests

2010-11-21 Thread Jacob Carlborg

On 2010-11-21 14:06, Jonathan M Davis wrote:

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


I don't know if the compiler can inline delegates or not but if it can I 
think this case would be very easy for the compiler to inline the delegate.


--
/Jacob Carlborg


Re: Review: A new stab at a potential std.unittests

2010-11-21 Thread Jonathan M Davis
On Sunday 21 November 2010 05:44:15 Jacob Carlborg wrote:
> I don't know if the compiler can inline delegates or not but if it can I
> think this case would be very easy for the compiler to inline the delegate.

It can't. That's one of the big issues with enforce. At the moment, it actually 
makes it so that if you use enforce in a function, that function can't be 
inlined. Assuming that that gets fixed, assertExcThrown!() might then be 
inlineable, depending on how picky the inliner is, at which point perhaps the 
delegate could be inlined, but I don't think that delegates will ever be 
inlineable unless the function they're called in is inlined, because the 
delegate to inline would change every time that the function is called.

In any case, it's definitely true that the compiler may be able to better 
optimize assertExcThrown!(). But much as I'd like fast unit testing code, I'd 
much rather have useable and readily maintainable unit testing code than fast 
unit testing code. It would be nice to have both though.

- Jonathan M Davis


Re: Review: A new stab at a potential std.unittests

2010-11-21 Thread Lutger Blijdestijn
Jonathan M Davis wrote:

> On Saturday 20 November 2010 10:16:55 Lutger Blijdestijn wrote:
>> I'm not particularly fond of this interface and think that a solution
>> with a delegate / lazy or alias template parameter would be more
>> convenient. However, until we have ast macros I do see the added value in
>> this approach.
>> 
>> Some remarks about the api, not a proper review of the code itself:
>> 
>> - core.exception and std.string must be imported to use the module,
>> relevant symbols should be selectively and publicy imported instead.
> 
> I hadn't thought of that. Good idea.
> 
>> - exception would be better abbreviated as ex instead of exc, I believe
>> this is more conventional. (assertExThrown instead of assertExcThrown)
> 
> I'll think about it. I don't think that I've often seen it abbreviated at
> all. But if Ex really is more common, then that would be better.

I know of std.exception.enforceEx, and catch(Exception ex) is also regularly 
used in examples.
 
>> - assertExcThrown should fail if an exception is thrown that is not T or
>> a subclass of T. (catch and throw AssertError)
> 
> It currently catches the exact exception (well, throwable) that you tell
> it to. The others are let through exactly like they would be with an
> assert. It also means that you get to see exactly what the erroneous
> exception was so that you can deal with it. An AssertError would be less
> informative, maybe even misleading. You get an AssertError because it
> didn't throw any exception, whereas you get the wrong exception if it
> threw the wrong one.

Suppose you want assert that a FileNotFoundException is thrown. Now if you 
get an Exception then:
- technically the unittest has passed because no AssertError has been thrown 
(splitting hairs) 
- if for whatever reason you catch this error in the unittest, things will 
get screwed up
- You (or possibly some other script) won' t get the same command line 
output, it's then harder to correlate the exception with the assertion

I agree about wanting to know the original Exception though. I think this is 
possible by setting the .next field of AssertError with that exception.

...
> 
>> I believe these assertions should be added:
>> 
>> - assertExcThrown and assertExcNotThrown with a default T (should be
>> Exception, not Throwable)
> 
> That's not a bad idea, though personally, I tend to think that if someone
> used an Exception rather than a derived type that they aren't be specific
> enough (I'm sure that many would argue with me on that one though). It
> might work to just give it a default parameter (and I do agree that the
> default should be Exception rather than Throwable).

I agree but it doesn't matter for general use, people will want this and 
this is also practice in phobos (mostly through the use of enforce I think).
 
...
> 
>> - assertOpBinary, assertTrue and perhaps assertPred (where the predicate
>> is an template alias parameter)
> 
> I decided that assertTrue() was a waste of time, because that's what a
> bare assert does. The same goes for assertFalse(), because all you have to
> do is add ! in front of the expression. All of the functions that I have
> are there to either improve the output (such as printing out the actual
> values of the two values being compared in assertEqual()), or they get rid
> of boilerplate code (such as the try-catch block and other details in
> assertExcThrown!()).

Except that assert does not print the expression which resulted in the 
assertion like all other functions do, so assertTrue does improve the output 
too.
 
> As for assertOpBinary, are you suggesting a function which does the given
> binary operation and then compares the result with the given expected
> result? That would be a good addition.
> 
> As for assertPred. I don't know what that would do. Would that take a
> predicate and its parameters and then assert that the result was true? If
> that's what you're looking for, then assertPredTrue and assertPredFalse
> would be better. I think that you need to clarify quite what you meant
> though.

bool isSorted();
int[] numbers = getSortedNumbers();
assertPred!isSorted(numbers);

It's the same as assert(isSorted(numbers)), except it allows for improved 
output. Not very important, but I find it common to use such predicates for 
testing so it might help. 

Alternatively assertTrue and assertFalse could take an optional predicate, 
defaulting to the identity and negation respectively:

assertTrue!isSorted(numbers);


Re: Review: A new stab at a potential std.unittests

2010-11-21 Thread Lutger Blijdestijn
Jacob Carlborg wrote:

> On 2010-11-21 01:23, Jonathan M Davis wrote:
>> On Saturday 20 November 2010 08:03:52 Jacob Carlborg wrote:
>>> Why don't you use delegates instead of string mixins? For example,
>>> assertExcThrown, could take a delegate which calls the function you want
>>> to test instead of a string that represents the call. The mixin want be
>>> needed as well. Am I missing something?
>>
>> Well, delegates wouldn't be a bad idea, but they're unwieldy too. Would
>> you rather write
>>
>> assertExcThrown!Exception((){func(param1, param2);});
>>
>> or
>>
>> mixin(assertExcThrown!(Exception, `func(param1, param2)`));
> 
> I would go with the delegate, but when you format the code like that it
> doesn't look any good (btw, no need for the extra pair of empty
> parentheses). I think this looks better:
> 
> assertExcThrown!Exception({
>  func(param1, param2);
> });
> 
> And BTW, D needs a better way to pass a delegates to a function,
> something like the syntax that can be used in Scala:
> 
> assertExcThrown!Exception {
>  func(param1, param2);
> }

This is possible, but too surprising:

assertExcThrown!Exception = {
func(param1, param2);
};

with lazy:

assertExcThrown!Exception = func(param1, param2);


Re: Review: A new stab at a potential std.unittests

2010-11-21 Thread Jacob Carlborg

On 2010-11-21 17:20, Lutger Blijdestijn wrote:

Jacob Carlborg wrote:


On 2010-11-21 01:23, Jonathan M Davis wrote:

On Saturday 20 November 2010 08:03:52 Jacob Carlborg wrote:

Why don't you use delegates instead of string mixins? For example,
assertExcThrown, could take a delegate which calls the function you want
to test instead of a string that represents the call. The mixin want be
needed as well. Am I missing something?


Well, delegates wouldn't be a bad idea, but they're unwieldy too. Would
you rather write

assertExcThrown!Exception((){func(param1, param2);});

or

mixin(assertExcThrown!(Exception, `func(param1, param2)`));


I would go with the delegate, but when you format the code like that it
doesn't look any good (btw, no need for the extra pair of empty
parentheses). I think this looks better:

assertExcThrown!Exception({
  func(param1, param2);
});

And BTW, D needs a better way to pass a delegates to a function,
something like the syntax that can be used in Scala:

assertExcThrown!Exception {
  func(param1, param2);
}


This is possible, but too surprising:

assertExcThrown!Exception = {
 func(param1, param2);
};

with lazy:

assertExcThrown!Exception = func(param1, param2);


There's also the operator overload abuse which overloads opIn:

assertExcThrown!Exception in {
func(param1, param2);
};

--
/Jacob Carlborg


Re: Review: A new stab at a potential std.unittests

2010-11-21 Thread Jonathan M Davis
On Sunday 21 November 2010 08:11:06 Lutger Blijdestijn wrote:
> Jonathan M Davis wrote:
> > On Saturday 20 November 2010 10:16:55 Lutger Blijdestijn wrote:
> >> I'm not particularly fond of this interface and think that a solution
> >> with a delegate / lazy or alias template parameter would be more
> >> convenient. However, until we have ast macros I do see the added value
> >> in this approach.
> >> 
> >> Some remarks about the api, not a proper review of the code itself:
> >> 
> >> - core.exception and std.string must be imported to use the module,
> >> relevant symbols should be selectively and publicy imported instead.
> > 
> > I hadn't thought of that. Good idea.
> > 
> >> - exception would be better abbreviated as ex instead of exc, I believe
> >> this is more conventional. (assertExThrown instead of assertExcThrown)
> > 
> > I'll think about it. I don't think that I've often seen it abbreviated at
> > all. But if Ex really is more common, then that would be better.
> 
> I know of std.exception.enforceEx, and catch(Exception ex) is also
> regularly used in examples.z

Then, I'll change it to assertExThrown.

> >> - assertExcThrown should fail if an exception is thrown that is not T or
> >> a subclass of T. (catch and throw AssertError)
> > 
> > It currently catches the exact exception (well, throwable) that you tell
> > it to. The others are let through exactly like they would be with an
> > assert. It also means that you get to see exactly what the erroneous
> > exception was so that you can deal with it. An AssertError would be less
> > informative, maybe even misleading. You get an AssertError because it
> > didn't throw any exception, whereas you get the wrong exception if it
> > threw the wrong one.
> 
> Suppose you want assert that a FileNotFoundException is thrown. Now if you
> get an Exception then:
> - technically the unittest has passed because no AssertError has been
> thrown (splitting hairs)
> - if for whatever reason you catch this error in the unittest, things will
> get screwed up
> - You (or possibly some other script) won' t get the same command line
> output, it's then harder to correlate the exception with the assertion
> 
> I agree about wanting to know the original Exception though. I think this
> is possible by setting the .next field of AssertError with that exception.

Actually, not only does AssertError not take a next as one if its constructor 
parameters, but even if you set it directly before throwing it, it still 
doesn't 
print out the other exception. So, if you throw an AssertError in the case of 
the wrong exception, the best that you're going to get is a message saying what 
type of exception was thrown and maybe what it said, but you couldn't get its 
stack trace, which could be far more important.

> >> I believe these assertions should be added:
> >> 
> >> - assertExcThrown and assertExcNotThrown with a default T (should be
> >> Exception, not Throwable)
> > 
> > That's not a bad idea, though personally, I tend to think that if someone
> > used an Exception rather than a derived type that they aren't be specific
> > enough (I'm sure that many would argue with me on that one though). It
> > might work to just give it a default parameter (and I do agree that the
> > default should be Exception rather than Throwable).
> 
> I agree but it doesn't matter for general use, people will want this and
> this is also practice in phobos (mostly through the use of enforce I
> think).

I'll do it, but I do think that it's generally bad practice to throw an 
Exception rather than a subtype of Exception (except perhaps in a script or 
other similarly short program).

> >> - assertOpBinary, assertTrue and perhaps assertPred (where the predicate
> >> is an template alias parameter)
> > 
> > I decided that assertTrue() was a waste of time, because that's what a
> > bare assert does. The same goes for assertFalse(), because all you have
> > to do is add ! in front of the expression. All of the functions that I
> > have are there to either improve the output (such as printing out the
> > actual values of the two values being compared in assertEqual()), or
> > they get rid of boilerplate code (such as the try-catch block and other
> > details in assertExcThrown!()).
> 
> Except that assert does not print the expression which resulted in the
> assertion like all other functions do, so assertTrue does improve the
> output too.

Neither do any of the others. They print the value. So if 
assertEqual(func("hello", "world"), 2); on line 115 of config.d failed because 
func("hello", "world") returned a 3, you'd get

core.exception.asserter...@config.d(115): assertEquals() failed: actual [3], 
expected [2].

whereas with assert(func("hello", "world") == 2); you'd get

core.exception.asserter...@config(115): unittest failure

assertEqual() is way more informative, but it doesn't print the actual 
expression, just the result of the expression. Short of using string mixins, I 
don't know how to

Re: Review: A new stab at a potential std.unittests [Update]

2010-11-26 Thread Jonathan M Davis
Most recent code: http://is.gd/hO8HP

Per the suggestions in this thread, I changed the string mixin templates to 
functions using lazy. I also added assertOpBinary and made assertOpOpAssign() 
call opOpAssign() directly. Finally, I made assertEqual() and assertNotEqual() 
templatized on a predicate (like std.algorithm.equal()) as suggested.

I did not add an assertPred(), because on further reflection, it didn't really 
make sense. Aside from the issue of unary vs binary predicates (which could be 
solved with assertUniPred() and assertBiPred()), what a predicate does varies 
so 
much from function to function, that testing one generically just doesn't make 
sense. For instance, find() is looking for equality whereas sort() is looking 
for 
a comparison. You could test that all elements in a range return true for a 
predicate like you might want with find(), but doing the same thing with 
sort()'s 
predicate makes no sense at all. So, I didn't add assertPred() or anything 
similar.

Any more feedback on my potential std.unittests, or is looking good overall? I 
definitely think that it's better than when I first posted it, so the feedback 
thus far has definitely been helpful, and I do find these functions extremely 
useful in my own code.

- Jonathan M Davis


P.S. My most recent update for std.datetime does include the most recent 
version 
of unittests.d, so if you want to see them in more large scale use, you can 
look 
there.


Re: Review: A new stab at a potential std.unittests [Update]

2010-11-27 Thread Jacob Carlborg

On 2010-11-26 09:10, Jonathan M Davis wrote:

Any more feedback on my potential std.unittests, or is looking good overall? I
definitely think that it's better than when I first posted it, so the feedback
thus far has definitely been helpful, and I do find these functions extremely
useful in my own code.

- Jonathan M Davis


P.S. My most recent update for std.datetime does include the most recent version
of unittests.d, so if you want to see them in more large scale use, you can look
there.


How about catching AssertErrors (if possible), collecting them and then 
at the end of the unit test output all failed unit tests. This will 
allow the unit tests after a failing unit test to also run.


Feel free to have a look at my rspec inspired unit test "framework": 
http://dsource.org/projects/orange/browser/orange/test/UnitTester.d


--
/Jacob Carlborg


Re: Review: A new stab at a potential std.unittests [Update]

2010-11-27 Thread Jonathan M Davis
On Saturday 27 November 2010 09:00:36 Jacob Carlborg wrote:
> On 2010-11-26 09:10, Jonathan M Davis wrote:
> > Any more feedback on my potential std.unittests, or is looking good
> > overall? I definitely think that it's better than when I first posted
> > it, so the feedback thus far has definitely been helpful, and I do find
> > these functions extremely useful in my own code.
> > 
> > - Jonathan M Davis
> > 
> > 
> > P.S. My most recent update for std.datetime does include the most recent
> > version of unittests.d, so if you want to see them in more large scale
> > use, you can look there.
> 
> How about catching AssertErrors (if possible), collecting them and then
> at the end of the unit test output all failed unit tests. This will
> allow the unit tests after a failing unit test to also run.
> 
> Feel free to have a look at my rspec inspired unit test "framework":
> http://dsource.org/projects/orange/browser/orange/test/UnitTester.d

All of my functions work essentially the same as assert does. That means that 
once an assertion fails (or one of my functions fails) in a unittest block, 
that 
block has failed and is done. This has been discussed before, and the general 
consensus is that this is the correct and desired behavior. It can be a bit 
annoying if you have a whole bunch of unrelated assertions in a single unittest 
block, but if you're doing anything where each assertion relies on state with 
an 
assertion relying on previous assertions passing, and assertions didn't really 
stop the test from running, you'd get a ton of irrelevant errors after a single 
failure.

My functions are intended to expand on assert, giving you better error messages 
on failures and reducing boiler plate code, not change how unit tests in D 
fundamentally work. And I don't want to introduce stuff into Phobos which 
changes 
how unit tests in D fundamentally work. I think that it's great as is. It's 
just 
that helper functions that produce better error messages than assert, and 
helper 
functions which reduce boiler plate code in common test cases can improve on 
assert and make for better unit tests, and I think that they would be a good 
addition to Phobos.

Currently, if a unittest block fails, then none of the other unittest blocks in 
that module run, but unittest blocks in other modules do run. It's supposed to 
be changed so that all unittest blocks in a module are run even if one fails, 
but that change hasn't been made yet. Once that is made, you'll be able to 
split 
up your unittest blocks to more thoroughly to allow for more tests to run on a 
single failure if you'd like to. But it is by design that once you have an 
error 
in a unittest block, that unittest block does not continue to run.

- Jonathan M Davis


Re: Review: A new stab at a potential std.unittests [Update]

2010-11-27 Thread Jacob Carlborg

On 2010-11-27 21:36, Jonathan M Davis wrote:

On Saturday 27 November 2010 09:00:36 Jacob Carlborg wrote:

On 2010-11-26 09:10, Jonathan M Davis wrote:

Any more feedback on my potential std.unittests, or is looking good
overall? I definitely think that it's better than when I first posted
it, so the feedback thus far has definitely been helpful, and I do find
these functions extremely useful in my own code.

- Jonathan M Davis


P.S. My most recent update for std.datetime does include the most recent
version of unittests.d, so if you want to see them in more large scale
use, you can look there.


How about catching AssertErrors (if possible), collecting them and then
at the end of the unit test output all failed unit tests. This will
allow the unit tests after a failing unit test to also run.

Feel free to have a look at my rspec inspired unit test "framework":
http://dsource.org/projects/orange/browser/orange/test/UnitTester.d


All of my functions work essentially the same as assert does. That means that
once an assertion fails (or one of my functions fails) in a unittest block, that
block has failed and is done. This has been discussed before, and the general
consensus is that this is the correct and desired behavior. It can be a bit
annoying if you have a whole bunch of unrelated assertions in a single unittest
block, but if you're doing anything where each assertion relies on state with an
assertion relying on previous assertions passing, and assertions didn't really
stop the test from running, you'd get a ton of irrelevant errors after a single
failure.


This how it works in my unit test library:

For every test you call a testing function that takes a delegate, in 
this delegate you have your assertions. This function will call the 
delegate and catch all assert exceptions/errors and collected them for 
later outputting. Now this delegate will end execution if an exception 
is thrown and the remaining code in the delegate will not be run.


If you want your test to stop after a failing assert you put all the 
asserts into one call to the testing function. If you want your test to 
continue after a failing assert you call the testing function multiple 
times.



My functions are intended to expand on assert, giving you better error messages
on failures and reducing boiler plate code, not change how unit tests in D
fundamentally work. And I don't want to introduce stuff into Phobos which 
changes
how unit tests in D fundamentally work. I think that it's great as is. It's just
that helper functions that produce better error messages than assert, and helper
functions which reduce boiler plate code in common test cases can improve on
assert and make for better unit tests, and I think that they would be a good
addition to Phobos.


I guess your functions are like assert helpers and my library is at a 
higher level.



Currently, if a unittest block fails, then none of the other unittest blocks in
that module run, but unittest blocks in other modules do run. It's supposed to
be changed so that all unittest blocks in a module are run even if one fails,
but that change hasn't been made yet. Once that is made, you'll be able to split
up your unittest blocks to more thoroughly to allow for more tests to run on a
single failure if you'd like to. But it is by design that once you have an error
in a unittest block, that unittest block does not continue to run.

- Jonathan M Davis


--
/Jacob Carlborg


Re: Review: A new stab at a potential std.unittests [Update]

2010-11-27 Thread Jonathan M Davis
On Saturday 27 November 2010 15:30:23 Jacob Carlborg wrote:
> On 2010-11-27 21:36, Jonathan M Davis wrote:
> > On Saturday 27 November 2010 09:00:36 Jacob Carlborg wrote:
> >> On 2010-11-26 09:10, Jonathan M Davis wrote:
> >>> Any more feedback on my potential std.unittests, or is looking good
> >>> overall? I definitely think that it's better than when I first posted
> >>> it, so the feedback thus far has definitely been helpful, and I do find
> >>> these functions extremely useful in my own code.
> >>> 
> >>> - Jonathan M Davis
> >>> 
> >>> 
> >>> P.S. My most recent update for std.datetime does include the most
> >>> recent version of unittests.d, so if you want to see them in more
> >>> large scale use, you can look there.
> >> 
> >> How about catching AssertErrors (if possible), collecting them and then
> >> at the end of the unit test output all failed unit tests. This will
> >> allow the unit tests after a failing unit test to also run.
> >> 
> >> Feel free to have a look at my rspec inspired unit test "framework":
> >> http://dsource.org/projects/orange/browser/orange/test/UnitTester.d
> > 
> > All of my functions work essentially the same as assert does. That means
> > that once an assertion fails (or one of my functions fails) in a
> > unittest block, that block has failed and is done. This has been
> > discussed before, and the general consensus is that this is the correct
> > and desired behavior. It can be a bit annoying if you have a whole bunch
> > of unrelated assertions in a single unittest block, but if you're doing
> > anything where each assertion relies on state with an assertion relying
> > on previous assertions passing, and assertions didn't really stop the
> > test from running, you'd get a ton of irrelevant errors after a single
> > failure.
> 
> This how it works in my unit test library:
> 
> For every test you call a testing function that takes a delegate, in
> this delegate you have your assertions. This function will call the
> delegate and catch all assert exceptions/errors and collected them for
> later outputting. Now this delegate will end execution if an exception
> is thrown and the remaining code in the delegate will not be run.
> 
> If you want your test to stop after a failing assert you put all the
> asserts into one call to the testing function. If you want your test to
> continue after a failing assert you call the testing function multiple
> times.

I confess that I don't see any real difference between that and simply 
splitting 
up unittest blocks (assuming, of course, that subsequent unittest blocks in a 
module get run after one fails, which hasn't been implmented yet), and the 
delegate solution at least sounds more complicated.

> > My functions are intended to expand on assert, giving you better error
> > messages on failures and reducing boiler plate code, not change how unit
> > tests in D fundamentally work. And I don't want to introduce stuff into
> > Phobos which changes how unit tests in D fundamentally work. I think
> > that it's great as is. It's just that helper functions that produce
> > better error messages than assert, and helper functions which reduce
> > boiler plate code in common test cases can improve on assert and make
> > for better unit tests, and I think that they would be a good addition to
> > Phobos.
> 
> I guess your functions are like assert helpers and my library is at a
> higher level.

That's probably a good way to put it. I think that higher level libraries 
certainly have their place, but I don't think that it necessarily makes sense 
to 
put that sort of thing in Phobos.

- Jonathan M Davis


Re: Review: A new stab at a potential std.unittests [Update]

2010-11-28 Thread Jacob Carlborg

On 2010-11-28 01:17, Jonathan M Davis wrote:

On Saturday 27 November 2010 15:30:23 Jacob Carlborg wrote:

On 2010-11-27 21:36, Jonathan M Davis wrote:

On Saturday 27 November 2010 09:00:36 Jacob Carlborg wrote:

On 2010-11-26 09:10, Jonathan M Davis wrote:

Any more feedback on my potential std.unittests, or is looking good
overall? I definitely think that it's better than when I first posted
it, so the feedback thus far has definitely been helpful, and I do find
these functions extremely useful in my own code.

- Jonathan M Davis


P.S. My most recent update for std.datetime does include the most
recent version of unittests.d, so if you want to see them in more
large scale use, you can look there.


How about catching AssertErrors (if possible), collecting them and then
at the end of the unit test output all failed unit tests. This will
allow the unit tests after a failing unit test to also run.

Feel free to have a look at my rspec inspired unit test "framework":
http://dsource.org/projects/orange/browser/orange/test/UnitTester.d


All of my functions work essentially the same as assert does. That means
that once an assertion fails (or one of my functions fails) in a
unittest block, that block has failed and is done. This has been
discussed before, and the general consensus is that this is the correct
and desired behavior. It can be a bit annoying if you have a whole bunch
of unrelated assertions in a single unittest block, but if you're doing
anything where each assertion relies on state with an assertion relying
on previous assertions passing, and assertions didn't really stop the
test from running, you'd get a ton of irrelevant errors after a single
failure.


This how it works in my unit test library:

For every test you call a testing function that takes a delegate, in
this delegate you have your assertions. This function will call the
delegate and catch all assert exceptions/errors and collected them for
later outputting. Now this delegate will end execution if an exception
is thrown and the remaining code in the delegate will not be run.

If you want your test to stop after a failing assert you put all the
asserts into one call to the testing function. If you want your test to
continue after a failing assert you call the testing function multiple
times.


I confess that I don't see any real difference between that and simply splitting
up unittest blocks (assuming, of course, that subsequent unittest blocks in a
module get run after one fails, which hasn't been implmented yet), and the
delegate solution at least sounds more complicated.


As you said, it hasn't been implemented yet and I wanted that behavior now.


My functions are intended to expand on assert, giving you better error
messages on failures and reducing boiler plate code, not change how unit
tests in D fundamentally work. And I don't want to introduce stuff into
Phobos which changes how unit tests in D fundamentally work. I think
that it's great as is. It's just that helper functions that produce
better error messages than assert, and helper functions which reduce
boiler plate code in common test cases can improve on assert and make
for better unit tests, and I think that they would be a good addition to
Phobos.


I guess your functions are like assert helpers and my library is at a
higher level.


That's probably a good way to put it. I think that higher level libraries
certainly have their place, but I don't think that it necessarily makes sense to
put that sort of thing in Phobos.

- Jonathan M Davis



--
/Jacob Carlborg