jquery/qunit — pull request #320 by mcantor (2012-09-20 01:19:30+00:00)
Title: setup() methods are called prematurely when tests are loaded asynchronously

I believe [this](http://stackoverflow.com/questions/11036514/qunit-async-tests-with-setup-and-teardown) might be an example of this problem in the wild.

If tests are loaded asynchronously, the document is loaded before they are read, which changes the values of `config.autorun` and `config.blocking` and eventually causes the callbacks queued in Test.queue() to be run out-of-sequence.

This pull request contains a separate test HTML file with accompanying JS tests that exemplify the problem.

The exact sequence of problematic events goes like this:

1. DOM loads
1. `QUnit.load()` completes, and calls `QUnit.start()`
1. `QUnit.start()` sets `config.blocking` to `false`, then calls `process()`
1. There's nothing in the queue, so `process()` calls `done()`
1. `done()` sets `config.autorun` to `true`
1. Test A queues `init()`, which is autorun by `synchronize()`
1. Test A queues the inner `run()`, which is autorun
1. Test A queues `setup()`, which is autorun
1. Test A queues `run()`, which is autorun; now we're blocking.
1. Test A queues `teardown()` and `finish()`. queue is now [A.teardown, A.finish]
1. Test B queues `init()` and inner `run()`. queue is now [A.teardown, A.finish, B.init, B.run]
1. Test C queues `init()` and inner `run()`. queue is now [A.teardown, A.finish, B.init, B.run, C.init, C.run]
1. Test A's `teardown()` and `finish()` are run; no more blocking. queue is now [B.init, B.run, C.init, C.run]
1. Test B's `init()` and inner `run()` are run. queue is now [C.init, C.run]
1. Test B queues `setup()`. queue is now [C.init, C.run, B.setup]
1. **`synchronize()` queues Test B's `setup()` and kicks off `process()`**
1. **`process()` runs the next functions in the queue, which are Test C's `init()` and `run()`.**
1. Test C queues `setup()`. queue is now [B.setup, C.setup]

And now you're thinking with portals.