Skip to content

Commit

Permalink
Merge pull request #10463 from teddyzeenny/async-helpers
Browse files Browse the repository at this point in the history
Fix async test helpers
  • Loading branch information
rwjblue committed Mar 15, 2015
2 parents 223683b + 8beb7f7 commit d6f42c2
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 46 deletions.
14 changes: 2 additions & 12 deletions packages/ember-testing/lib/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import EmberError from "ember-metal/error";
import run from "ember-metal/run_loop";
import jQuery from "ember-views/system/jquery";
import Test from "ember-testing/test";
import RSVP from "ember-runtime/ext/rsvp";

/**
* @module ember
Expand All @@ -12,7 +13,6 @@ import Test from "ember-testing/test";

var helper = Test.registerHelper;
var asyncHelper = Test.registerAsyncHelper;
var countAsync = 0;

function currentRouteName(app) {
var appController = app.__container__.lookup('controller:application');
Expand Down Expand Up @@ -199,12 +199,7 @@ function andThen(app, callback) {
}

function wait(app, value) {
return Test.promise(function(resolve) {
// If this is the first async promise, kick off the async test
if (++countAsync === 1) {
Test.adapter.asyncStart();
}

return new RSVP.Promise(function(resolve) {
// Every 10ms, poll for the async thing to have finished
var watcher = setInterval(function() {
var router = app.__container__.lookup('router:main');
Expand All @@ -228,11 +223,6 @@ function wait(app, value) {
// Stop polling
clearInterval(watcher);

// If this is the last async promise, end the async test
if (--countAsync === 0) {
Test.adapter.asyncEnd();
}

// Synchronously resolve the promise
run(null, resolve, value);
}, 10);
Expand Down
47 changes: 20 additions & 27 deletions packages/ember-testing/lib/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ function helper(app, name) {

return function() {
var args = slice.call(arguments);
var lastPromise = Test.lastPromise;
var lastPromise;

args.unshift(app);

Expand All @@ -292,35 +292,28 @@ function helper(app, name) {
return fn.apply(app, args);
}

if (!lastPromise) {
// It's the first async helper in current context
lastPromise = fn.apply(app, args);
} else {
// wait for last helper's promise to resolve and then
// execute. To be safe, we need to tell the adapter we're going
// asynchronous here, because fn may not be invoked before we
// return.
Test.adapter.asyncStart();
run(function() {
lastPromise = Test.resolve(lastPromise).then(function() {
try {
return fn.apply(app, args);
} finally {
Test.adapter.asyncEnd();
}
});
});
}
lastPromise = run(function() {
return Test.resolve(Test.lastPromise);
});

return lastPromise;
// wait for last helper's promise to resolve and then
// execute. To be safe, we need to tell the adapter we're going
// asynchronous here, because fn may not be invoked before we
// return.
Test.adapter.asyncStart();
return lastPromise.then(function() {
return fn.apply(app, args);
}).finally(function() {
Test.adapter.asyncEnd();
});
};
}

function run(fn) {
if (!emberRun.currentRunLoop) {
emberRun(fn);
return emberRun(fn);
} else {
fn();
return fn();
}
}

Expand Down Expand Up @@ -484,6 +477,7 @@ Test.Promise = function() {

Test.Promise.prototype = create(RSVP.Promise.prototype);
Test.Promise.prototype.constructor = Test.Promise;
Test.Promise.resolve = Test.resolve;

// Patch `then` to isolate async methods
// specifically `Ember.Test.lastPromise`
Expand All @@ -500,7 +494,6 @@ Test.Promise.prototype.then = function(onSuccess, onFailure) {
// 1. Set `Ember.Test.lastPromise` to null
// 2. Invoke method
// 3. Return the last promise created during method
// 4. Restore `Ember.Test.lastPromise` to original value
function isolate(fn, val) {
var value, lastPromise;

Expand All @@ -510,19 +503,19 @@ function isolate(fn, val) {
value = fn(val);

lastPromise = Test.lastPromise;
Test.lastPromise = null;

// If the method returned a promise
// return that promise. If not,
// return the last async helper's promise
if ((value && (value instanceof Test.Promise)) || !lastPromise) {
return value;
} else {
run(function() {
lastPromise = Test.resolve(lastPromise).then(function() {
return run(function() {
return Test.resolve(lastPromise).then(function() {
return value;
});
});
return lastPromise;
}
}

Expand Down
3 changes: 2 additions & 1 deletion packages/ember-testing/tests/acceptance_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import "ember-testing/initializers"; // ensure the initializer is setup
import EmberApplication from "ember-application/system/application";
import EmberRoute from "ember-routing/system/route";
import compile from "ember-template-compiler/system/compile";
import RSVP from "ember-runtime/ext/rsvp";

//ES6TODO: we need {{link-to}} and {{outlet}} to exist here
import "ember-routing"; //ES6TODO: fixme?
Expand Down Expand Up @@ -70,7 +71,7 @@ QUnit.module("ember-testing Acceptance", {
});

Test.registerAsyncHelper('slowHelper', function() {
return Test.promise(function(resolve) {
return new RSVP.Promise(function(resolve) {
setTimeout(resolve, 10);
});
});
Expand Down
12 changes: 6 additions & 6 deletions packages/ember-testing/tests/helpers_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -643,9 +643,9 @@ if (Ember.FEATURES.isEnabled('ember-testing-checkbox-helpers')) {
visit = App.testHelpers.visit;

visit('/').then(function() {
expectAssertion(function() {
check('#text');
}, /must be a checkbox/);
check('#text').catch(function(error) {
ok(/must be a checkbox/.test(error.message));
});
});
});

Expand All @@ -662,9 +662,9 @@ if (Ember.FEATURES.isEnabled('ember-testing-checkbox-helpers')) {
uncheck = App.testHelpers.uncheck;

visit('/').then(function() {
expectAssertion(function() {
uncheck('#text');
}, /must be a checkbox/);
uncheck('#text').catch(function(error) {
ok(/must be a checkbox/.test(error.message));
});
});
});
}
Expand Down

0 comments on commit d6f42c2

Please sign in to comment.