Issue with async and rules

10 views
Skip to first unread message

kris

unread,
Aug 10, 2010, 8:50:21 AM8/10/10
to Flexunit Contributors
Hi,

I was planning on a tutorial for morefluent + u-input + flexunit4 but
I got into very strange situation.

When I have a [Before(async)] then the rule that enables async does
not work anymore and I have to add async to each individual test. Once
I take out async from the Before things work normal again.

Here is snippet from the rule code:

override public function apply(base:IAsyncStatement,
method:FrameworkMethod, test:Object):IAsyncStatement
{
//This will tell you if someone marked the method with async
already so we don't apply the ExpectAsync code twice
var async:Boolean = ExpectAsync.hasAsync(method);
//If it already has async, then just go ahead and use the
existing statement, else wrap it in ExpectAsync
var statement:* = async ? base : new ExpectAsync(test, base);
//You have access to the method and test if you need it
integrate(test);
return super.apply(statement, method, test);
}

Any idea how to fix it?

Regards,
Kris

kris

unread,
Aug 10, 2010, 9:01:18 AM8/10/10
to Flexunit Contributors
Things get even worse if I install any async from the setup() marked
with async. The first test runs fine but the second one fails
miserably.

Weird.

Kris

Michael Labriola

unread,
Aug 10, 2010, 9:03:02 AM8/10/10
to flexunit-c...@googlegroups.com
Kris:

So that sample Rule I wrote only looks for the async on the Test metadata. It isn't checking the Before and After at all.To clarify though, you are saying that if you add the async to the Before, then the rule stops working? Can you give me a quick sample to debug?

Mike

Michael Labriola

unread,
Aug 10, 2010, 9:03:35 AM8/10/10
to flexunit-c...@googlegroups.com
Okay, get me a test case and I will debug today. I am at a client this morning but should be able to look around my lunch time.

Mike

Kris

unread,
Aug 10, 2010, 9:07:32 AM8/10/10
to flexunit-c...@googlegroups.com
#1 The fact that it works only for the test method is not that huge problem, the worse thing is that once you add async to [Before] then the rule does not work for the test anymore
#2 Let me clean up the code to the bare flex unit and send it to you

Thanks!
Kris

Kris

unread,
Aug 10, 2010, 9:22:41 AM8/10/10
to flexunit-c...@googlegroups.com
OK when trying to reproduce only with FlexUnit stuff it turned out that the second issue may be somehow related to the morefluent and polling as it does not fail the same when used with Async.handleAsync. Not sure what this might be if I can't reproduce it with bare flex unit I'll give you the morefluent case.

Here is the code for the first issue:

package {
import flash.events.Event;

import org.flexunit.async.Async;
import org.flexunit.rules.IMethodRule;

public class RuleDoesNotEnableAsyncWhenBeforeHasAsync
{

    [Rule]
    public var rule:IMethodRule = new AsyncRule();

    [Before(async)]
    public function setUp():void
    {
    }

    [Test]
    public function shouldBeRecognizedAsAnAsyncTest():void
    {
        Async.asyncHandler(this,
                           function (e:Event = null, passThrough:* = null):void
                           {
                           },
                           1000);
    }
}
}

import org.flexunit.internals.runners.statements.ExpectAsync;
import org.flexunit.internals.runners.statements.IAsyncStatement;
import org.flexunit.internals.runners.statements.MethodRuleBase;
import org.flexunit.rules.IMethodRule;
import org.flexunit.runners.model.FrameworkMethod;
import org.flexunit.token.AsyncTestToken;

class AsyncRule extends MethodRuleBase implements IMethodRule
{
    public function MorefluentRule()
    {
    }

    override public function evaluate(parentToken:AsyncTestToken):void
    {
        super.evaluate(parentToken);
        proceedToNextStatement();

    }

    override public function apply(base:IAsyncStatement, method:FrameworkMethod, test:Object):IAsyncStatement
    {
        //This will tell you if someone marked the method with async already so we don't apply the ExpectAsync code twice
        var async:Boolean = ExpectAsync.hasAsync(method);
        //If it already has async, then just go ahead and use the existing statement, else wrap it in ExpectAsync
        var statement:* = async ? base : new ExpectAsync(test, base);
        //You have access to the method and test if you need it
        return super.apply(statement, method, test);
    }
}

Kris

unread,
Aug 10, 2010, 10:30:48 AM8/10/10
to flexunit-c...@googlegroups.com
OK please disregard the second issue. I fixed it in my rule yet it still looks strange to me.

I overrode:

    override protected function handleStatementComplete(result:ChildResult):void

hoping to have a safe rule level teardown.

Apparently this is not the best place as I got it executed at the wrong moment when used with the async Before.

Any idea where to perform this kind of stuff?

Regards,
Kris

Michael Labriola

unread,
Aug 10, 2010, 3:33:46 PM8/10/10
to flexunit-c...@googlegroups.com
Kris:

Couple of things:

Let's not call this AsyncRule as it is just going to confuse people when we rework all of the Async as a rule in the future. Your AsyncRule is specifically designed to remove the need for people to set async. This is cool for your use case and really, really bad for general testing so I want to be sure we keep the name of this more specific.

Explain more what you are trying to do and I am sure I can help. Are you just trying to have some type of cleanup when the method is all done executing or something else?

Mike

Kris

unread,
Aug 10, 2010, 3:50:57 PM8/10/10
to flexunit-c...@googlegroups.com
Mike,

I'm fine with whatever name. My real rule is called MorefluentRule I reworked the test and the code to let you reproduce easily but the name may be unfortunate and it was not meant to be an official AsyncRule.

The case I've send depicts broken behavior when you set the [Before(async)]. That's it. Take out async from Before and it works so there is something else that needs to happen on my rule or there is something wrong with guts of the execution.

The second thing I'm trying to do is to call to my framework when the test goes down. It must be after all async has completed/failed but before executing the rule again on another test.

Specifically I want to avoid leaks since the MorefluentRule sets a global 'currentTestCase' that is needed to perform Async registration. After I'm done with the test I want to set the global 'currentTestCase' to null. For whatever reason the function I used got called in the middle of the polling.

Also maybe you could rethink the Async API and keep the current test reference internally somehow?

Kris


Michael Labriola

unread,
Aug 10, 2010, 5:05:05 PM8/10/10
to flexunit-c...@googlegroups.com
Kris:

We do have a current test reference, it is just buried in there a bit. Thanks for the info. I will debug this tonight and give you some feedback.

Mike

Michael Labriola

unread,
Aug 11, 2010, 9:48:05 AM8/11/10
to Flexunit Contributors

Kris,

Thanks for this. I see the issue and the cause is pretty simple.
Unfortunately, the effect is actually further reaching than even just
rules. I will get back to you later today on this but it may cause me
to accelerate the solution to the other thread about Rules.

Mike

Kris

unread,
Aug 11, 2010, 9:51:47 AM8/11/10
to flexunit-c...@googlegroups.com
No problem. Thanks for taking care of it.

Kris
Reply all
Reply to author
Forward
0 new messages