It's a great description of the current state of BDD-ish testing in
C++. I'm looking forward to seeing your screencasts.
I think you describe the strengths and weaknesses of Igloo very well.
You're right about the lack of exception assertions, and that the way
exceptions are (not) being handled could be improved. What's in Igloo
today reflects what I myself had the need for in my day to day work.
So, the container constraints turned out pretty useful, at least for
me.
I like how you get the point across about the need for DSLs that focus
on describing the intention of a spec, beyond just verifying the code
under test. I seem to have a hard time convincing C++ developers that
shorter and more compact isn't always better.
/Joakim
Thanks!
I hadn't seen CppSpec, so it was interesting to dive into. I think
CppSpec's model of specify(invoking(...),
should.raise_exception<...>()) is about as good as it gets without
C++0x lambdas.
I think we should be able to implement a similar solution in Igloo
without too much friction, but I haven't actually tried yet, so it may
be harder than it looks. It's definitely nicer than the alternatives
we've discussed earlier.
- Kim
On Mon, Oct 11, 2010 at 20:05, Kim Gräsman <kim.g...@gmail.com> wrote:
>
> I think we should be able to implement a similar solution in Igloo
> without too much friction, but I haven't actually tried yet, so it may
> be harder than it looks. It's definitely nicer than the alternatives
> we've discussed earlier.
I've hacked up a simple prototype, inspired by CppSpec's
implementation, which allows this:
--
void dangerous()
{
throw std::exception("hello!");
}
Context(WhenUsingThrowsConstraint)
{
Spec(DetectsThrowingFunction)
{
Assert::That(Calling(dangerous), Throws<std::exception>());
}
Spec(FailsIfExceptionTypesMismatch)
{
Assert::That(Calling(dangerous), Throws<std::runtime_error>());
}
};
--
The trick is the "Calling" function, which turns the function pointer
and possibly captured arguments (on the form "Calling(func, 1, 2)")
into a functor. That functor is then passed through Assert::That into
the Throws<> constraint, which executes it and catches any exceptions.
It doesn't play well with our Expected/Actual output mechanism, which
writes out "[unsupported type]" for the Actual, as it's an opaque
functor without any textual representation. Not sure if it's possible
to make this better in some way.
Would this be an interesting addition to Igloo, as-is, or should we
perhaps look into a macro-based strategy instead?
Cheers,
- Kim
Will it get messy with regards to template parameters when we start
asserting on instance methods of with different return types? Or can
the compiler deduce template parameters on calls like
class A
{
public:
int foo();
};
A a;
Assert::That(Calling<A, int>(a, &A::foo), Throws<...>());
If we need to specify the int, I think it might be too hard to read.
/J
On Tue, Oct 12, 2010 at 10:00 PM, Kim Gräsman <kim.g...@gmail.com> wrote:
> Hi guys,
I can't try it without major surgery, I think, but you can't overload
on return type anyway, so it shouldn't be a problem, right?
> A a;
> Assert::That(Calling<A, int>(a, &A::foo), Throws<...>());
>
> If we need to specify the int, I think it might be too hard to read.
Yes, that does look terrible :-)
Hopefully, you'd get away with
A a;
Assert::That(Calling(a, &A::foo), Throws<...>());
But that's not exactly easy on the eyes either...
- Kim