Hey Scott

oh I thought stop() would actually hold the execution of the test...

Well thanks a lot for the superb and detailed answer. You helped me a
lot.

Matthias

On Jan 12, 6:17 pm, Scott Sauyet <scott.sau...@gmail.com> wrote:
> On Jan 12, 10:27 am, Matthias <matthias.lueb...@gmail.com> wrote:
>
> > I have an object with a member function that changes something on the
> > objects state. This works perfectly fine in the easy case. But when I
> > use an $.ajax call within the function it doesn't work.
>
> > Here is the example code and failing QUnit tests:http://pastie.org/774900
>
> There are two different problems here.  One is that unless your code
> is running atwww.google.de, cross-site scripting restrictions will
> not allow you to AJAX in content from there.  Since this is clearly a
> simple test, just checking if an AJAX call returns with any content,
> you can set the url for now to document.location.href.
>
> The main problem, though, is with the ordering of your asynchronous
> code.
>
> This is what you have:
>
>     test('testing MyObject2 async', function() {
>         var o2 = new MyObject2();
>         stop();
>         setTimeout(function(){
>             o2.myfunction(function(){start()});
>         }, 100);
>         equals(o2.mycollection.length, 1); //<== fails
>     });
>
> I think this might have been copied from the examples and modified
> incorrectly.  In that case, the setTimeout call was supposed to be the
> asynchronous call in question, as that's simpler to demonstrate than
> actual AJAX calls.
>
> The order of execution here is as follows:
>
>     1. o2 is created
>     2. stop is called, so no tests will be executed
>     3. setTimeout is called
>     4. equals is called, being passed the values 0 and 1.  It defers
> actually running the QUnit test because stop had been called.
>     5. (100ms later) the argument to setTimeout is started
>     6. o2.myfunction is called
>     7. an AJAX request is made, initiating an HTTP request
>     8. The HTTP request completes
>     9. The AJAX callback pushes "test" onto o2's mycollection.  Only
> now does the length change
>    10. Your anonymous callback function is called, which calls start
>    11. QUint checks if the two parameters supplied earlier are equal.
> This fails.
>
> This can be fixed relatively easily:
>
>     test('testing MyObject2 async', function() {
>         var o2 = new MyObject2();
>         stop();
>         o2.myfunction(function() {
>             equals(o2.mycollection.length, 1); //<== works now
>             start();
>         });
>     });
>
> This moves the call to equals *inside* the callback.  Although the
> equals test is now earlier in the source code, it is executed later,
> after the value you're checking has actually been updated.
>
> I've posted an example of this to
>
>    http://jsbin.com/oxegu(codehttp://jsbin.com/oxegu/edit)
>
> Good luck,
>
>   -- Scott

Reply via email to