On Wed, Oct 13, 2010 at 10:23, Joakim Karlsson <joa...@jkarlsson.com> wrote: > On Tue, Oct 12, 2010 at 10:21 PM, Kim Gräsman <kim.gras...@gmail.com> wrote:
>> A a; >> Assert::That(Calling(a, &A::foo), Throws<...>());
> Perhaps we could have a method similar to Calling that returns the > exception thrown.
> That way we could use our existing constraints on it.
I think one difficulty is that the return type of ExceptionThrownBy() is essentially unknown, as we don't know what A::foo might throw. We'd have to explicitly specialize it;
This speaks in favor of a preprocessor-based solution, that can capture a full expression for delayed execution inside an exception handler, but I can't find a nice way to make that interact with Assert::That.
On Wed, Oct 13, 2010 at 9:42 PM, Kim Gräsman <kim.gras...@gmail.com> wrote: > Nice! But it's definitely not readable... It's a shame, because it > _is_ pretty cool.
Yeah, I know. I just had to get that out of my system.
> I can' t really think of a valid syntax at the moment, but to me it > feels important to keep the imperative call syntax;
I had a similar idea, though I don't see how to implement it. I know you have mad skills in the thinking-outside-the-box department, though, so I look forward to see your next prototype ;-)
I'll try and build something along these lines as well, and see if I can overcome my preconceptions.
On Thu, Oct 14, 2010 at 5:09 PM, Kim Gräsman <kim.gras...@gmail.com> wrote:
> I had a similar idea, though I don't see how to implement it. I know > you have mad skills in the thinking-outside-the-box department, > though, so I look forward to see your next prototype ;-)
Thanks! Getting my previously proposed syntax to compile might prove to be too hard though.
While brainstorming, I got the following to work at least:
If the AssertThrows macro succeeds, it stores the exception in a static auto_ptr.
I think it's quite readable, but there is a risk of cross-test contamination because of the static storage. And the implementation with an auto_ptr isn't as pretty as I would have wanted.
On Fri, Oct 15, 2010 at 10:41, Joakim Karlsson <joa...@jkarlsson.com> wrote: > Perhaps if we macrofy the following? > That would make it possible to have the syntax > auto_ptr<exception> last_exception = Throws(exception, > objectUnderTest.foo(5)); > It demands a proper copy constructor on the exception and the > igloo_last_exception variable would stop us from using it twice in a method. > /J > std::auto_ptr<std::logic_error> igloo_last_exception; > { > bool igloo_wrong_exception = false; > try > { > objectUnderTest.foo(5); > std::cout << "No exception!" << std::endl; > } > catch(const std::logic_error& e) > { > igloo_last_exception = std::auto_ptr<std::logic_error>(new > std::logic_error(e)); > } > catch(...) > { > igloo_wrong_exception = true; > } > std::cout << "wrong: " << igloo_wrong_exception << std::endl; > }
> On Thu, Oct 14, 2010 at 5:09 PM, Kim Gräsman <kim.gras...@gmail.com> wrote:
> > I had a similar idea, though I don't see how to implement it. I know
> > you have mad skills in the thinking-outside-the-box department,
> > though, so I look forward to see your next prototype ;-)
> Thanks! Getting my previously proposed syntax to compile might prove
> to be too hard though.
> While brainstorming, I got the following to work at least:
> If the AssertThrows macro succeeds, it stores the exception in a
> static auto_ptr.
> I think it's quite readable, but there is a risk of cross-test
> contamination because of the static storage. And the implementation
> with an auto_ptr isn't as pretty as I would have wanted.
On Fri, Oct 15, 2010 at 10:50 AM, Kim Gräsman <kim.gras...@gmail.com> wrote: > I think it will prove difficult to combine the generation of try/catch > + code and the assignment of a variable in the same expression...
Yep. I'm giving up on that one for now.
> But I wonder if we could keep a stack of caught exceptions? Or > multiple stacks, one per type, or something?
I pushed my prototype [1]. I haven't been able to clean up after each test method properly, so there is a risk of cross-test contamination.
Jonas Blunck suggested using __thread for storage, and call each test on its own thread. MIght be worth a try. We'll have to check if there are any restrictions on what platforms and compilers support TLS.
... and then instantiate LastExceptionResetter<EXCEPTION_TYPE> somewhere in the scope of AssertThrows.
If running tests in parallel is something we want to allow then last_exception needs to be thread-local, of course, though I'm not sure the rest of the framework is going to play nicely.
Now that we're degenerating into macros, maybe we should reconsider my previous (nasty!) attempt that allowed Assert::Throws(...)?
On Sat, Oct 16, 2010 at 10:59, Joakim Karlsson <joa...@jkarlsson.com> wrote:
> I pushed my prototype [1]. I haven't been able to clean up after each > test method properly, so there is a risk of cross-test contamination.
Oh, and I was sure I'd read somewhere about a new feature in C++0x that allowed direct access to the latest exception, but I couldn't find a reference to it. Then I ran into this in my blog reader: http://www.mr-edd.co.uk/blog/in_the_absence_of_exception_ptr
It looks like the library (or its techniques) might be useful to us, though I haven't read it thoroughly yet.
On Sun, Oct 17, 2010 at 2:57 PM, Kim Gräsman <kim.gras...@gmail.com> wrote:
> Maybe you could use some simple RAII to clean up the exception state > at the end of the scope?
Brilliant!
> If running tests in parallel is something we want to allow then > last_exception needs to be thread-local, of course, though I'm not > sure the rest of the framework is going to play nicely.
With your RAII solution I don't think we need to go that route for now. I'm not sure how well TLS plays with different platforms and compilers.
> Now that we're degenerating into macros, maybe we should reconsider my > previous (nasty!) attempt that allowed Assert::Throws(...)?
I think that adds too much complexity. And it might confuse users if the Throws "method" is nowhere in the intellisense list.
Since we will need macros to add __FILE__ and __LINE_ to get nicer output we should perhaps go with macros a' la AssertThat or similar.
On Sun, Oct 17, 2010 at 3:02 PM, Kim Gräsman <kim.gras...@gmail.com> wrote: > On Sat, Oct 16, 2010 at 10:59, Joakim Karlsson <joa...@jkarlsson.com> wrote:
>> I pushed my prototype [1]. I haven't been able to clean up after each >> test method properly, so there is a risk of cross-test contamination.
> Oh, and I was sure I'd read somewhere about a new feature in C++0x > that allowed direct access to the latest exception, but I couldn't > find a reference to it. Then I ran into this in my blog reader: > http://www.mr-edd.co.uk/blog/in_the_absence_of_exception_ptr
> It looks like the library (or its techniques) might be useful to us, > though I haven't read it thoroughly yet.
On Sun, Oct 17, 2010 at 6:10 PM, Joakim Karlsson <joa...@jkarlsson.com> wrote: > On Sun, Oct 17, 2010 at 2:57 PM, Kim Gräsman <kim.gras...@gmail.com> wrote:
>> Maybe you could use some simple RAII to clean up the exception state >> at the end of the scope?
> Brilliant!
>> If running tests in parallel is something we want to allow then >> last_exception needs to be thread-local, of course, though I'm not >> sure the rest of the framework is going to play nicely.
> With your RAII solution I don't think we need to go that route for > now. I'm not sure how well TLS plays with different platforms and > compilers.
>> Now that we're degenerating into macros, maybe we should reconsider my >> previous (nasty!) attempt that allowed Assert::Throws(...)?
> I think that adds too much complexity. And it might confuse users if > the Throws "method" is nowhere in the intellisense list.
> Since we will need macros to add __FILE__ and __LINE_ to get nicer > output we should perhaps go with macros a' la AssertThat or similar.
The only nit I can think of is it would be safer to decorate the name the exception storage variable even more; I've tried to add an IGLOO_ prefix to all names that are magically injected into the user's namespace. E.g.:
> On Sun, Oct 17, 2010 at 6:10 PM, Joakim Karlsson <joa...@jkarlsson.com> wrote: >> On Sun, Oct 17, 2010 at 2:57 PM, Kim Gräsman <kim.gras...@gmail.com> wrote:
>>> Maybe you could use some simple RAII to clean up the exception state >>> at the end of the scope?
>> Brilliant!
>>> If running tests in parallel is something we want to allow then >>> last_exception needs to be thread-local, of course, though I'm not >>> sure the rest of the framework is going to play nicely.
>> With your RAII solution I don't think we need to go that route for >> now. I'm not sure how well TLS plays with different platforms and >> compilers.
>>> Now that we're degenerating into macros, maybe we should reconsider my >>> previous (nasty!) attempt that allowed Assert::Throws(...)?
>> I think that adds too much complexity. And it might confuse users if >> the Throws "method" is nowhere in the intellisense list.
>> Since we will need macros to add __FILE__ and __LINE_ to get nicer >> output we should perhaps go with macros a' la AssertThat or similar.