I've been trying to implement a Parrot port of xUnit so we can write
tests natively in parrot and things were going reasonably well until I
reached the point where I needed to do exception handling.
Exception handling hurt my head, badly, so eventually I gave up and
used a continuation instead. Here's the basic 'run' and 'exception
failure' parts of my code (The current full suite is in the tar file
attached):
.sub run method
.param pmc testResult
.local Sub handler
.local Sub exceptRet
.local pmc name
.local string nameString
name = self."name"()
self."setResult"(testResult)
save nameString
handler = new Continuation
set_addr handler, catch0
self."setFailureHandler"(handler)
self."setUp"()
self.name()
testResult."pass"(nameString)
finally:
self."tearDown"()
.pcc_begin_return
.pcc_end_return
catch0:
P17 = self."name"()
S16 = P17
P16 = P2."testResult"()
P16."fail"(S16)
branch finally
.end
.sub assertion_failed method
.param string rawMsg
.local pmc handler
handler = self."failureHandler"()
# invoke handler
handler()
.end
Now, depending on whether I use C<handler()> or C<handler>, teardown
gets run 3 (handler()) or two (invoke) times.
If I create the handler continuation using C<handler = newcont break0>
then it makes it to branch0, but there are problems with self, the first
method call works fine, but after that things go haywire and self
appears to get trashed so method lookups fail after the first one. Very
frustrating.
BTW, you can make Leo's test program go into an infinite loop simply by
replacing the n
conti = newcont _end
with
new conti, .Continuation
set_addr conti, _end
which is weird because I *thought* they were supposed to do equivalent
things.