Hi,
I also had this problem - but I could see in debug what is causing it:
- I'm running my website in IE 8 and I have 4 async tests that must run in sequence
- in the queue() function (when each new test is queued), an internal method called run() is called through synchronize(run()) - to avoid confusion I'll call this method queue_run() !!! please take note of this rename, my post won't make sense without it.
- my first async test performs a few operations and then waits for 500ms before calling start() again
- during this time, 3 additional tests are queued, each one of them adding the queue_run() method to the processing queue
- when the first test finishes waiting and calls start, the queue starts processing in the following way:
process() => queue_run(test2) =>
synchronize(test2.setup()) =>
process() =>
queue_run(test3) =>
synchronize(test3.setup()) =>
process() =>
queue_run(test4) =>
synchronize(test4.setup()) =>
process() =>
test2.setup()
test3.setup()
test4.setup()
synchronize(test4.run()) =>
process() =>
test4.run()
synchronize(test4.teardown()) =>
process() =>
test4.teardown()
synchronize(test4.finish()) =>
process() =>
test4.finish()
synchronize(test3.run()) =>
process() =>
test3.run()
synchronize(test3.teardown()) =>
process() =>
test3.teardown()
synchronize(test3.finish()) =>
process() =>
test3.finish()
synchronize(test2.run()) =>
process() =>
test2.run()
synchronize(test2.teardown()) =>
process() =>
test2.teardown()
synchronize(test2.finish()) =>
process() =>
test2.finish()
=================
The problem is that synchronize() will always call process() every time it queues a method and the 4 test methods queued through queue_run() will be queued quite a long way apart from each other. To avoid this problem, all 4 test methods must be queued one after the other before process() is called.
Here's how I fixed it:
============================================
// Add support for arrays of callback methods
function synchronize(callback) {
if (jQuery.isArray(callback)) {
for (method in callback)
config.queue.push(callback[method]);
}
else
config.queue.push(callback);
if (config.autorun && !config.blocking) {
process();
}
}
============================================
queue: function() {
var test = this;
synchronize(function() {
test.init();
});
function run() {
// each of these can be async
// But they must be executed in strict order
// and no other callbacks should be inserted in the queue between them
// That's why I'm passing in an array of functions to be all appended to the queue
synchronize(
[function() { test.setup(); },
function() { test.run(); },
function() { test.teardown(); },
function() { test.finish(); }
]
);
}
// defer when previous test run passed, if storage is available
var bad = QUnit.config.reorder && defined.sessionStorage && +sessionStorage.getItem("qunit-" + this.module + "-" + this.testName);
if (bad) {
run();
} else {
synchronize(run);
};
}
============================================