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 at www.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 (code http://jsbin.com/oxegu/edit)

Good luck,

  -- Scott

Reply via email to