Skip to content

Commit

Permalink
Ensure await settled() avoids creating an autorun.
Browse files Browse the repository at this point in the history
  • Loading branch information
rwjblue committed Nov 2, 2018
1 parent e54b603 commit c260ad0
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 6 deletions.
53 changes: 49 additions & 4 deletions addon-test-support/@ember/test-helpers/-utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,43 @@
/* globals Promise */
import { Promise as RSVPPromise } from 'rsvp';

import RSVP from 'rsvp';
import Ember from 'ember';
import { run } from '@ember/runloop';
import hasEmberVersion from './has-ember-version';

const backburner = (run as any).backburner;

export class _Promise extends RSVP.Promise<void> {}

RSVP.configure('async', (callback, promise) => {
if (promise instanceof _Promise) {
if (typeof Promise !== 'undefined') {
// use real native promise semantics whenever possible
Promise.resolve().then(() => callback(promise));
} else {
// fallback to using RSVP's natural `asap` (**not** the fake
// one configured by Ember...)
RSVP.asap(callback, promise);
}
} else {
// this is the default behaviors from Ember:
// https://github.com/emberjs/ember.js/blob/v3.4.6/packages/ember-testing/lib/ext/rsvp.js

// if schedule will cause autorun, we need to inform the test adapter
if (Ember.testing && !backburner.currentInstance) {
let adapter = Ember.Test.adapter as any;

adapter && adapter.asyncStart();

backburner.schedule('actions', () => {
adapter && adapter.asyncEnd();
callback(promise);
});
} else {
backburner.schedule('actions', () => callback(promise));
}
}
});

export const nextTick: Function =
typeof Promise === 'undefined' ? setTimeout : cb => Promise.resolve().then(cb);
Expand All @@ -10,9 +48,16 @@ export const futureTick = setTimeout;
@returns {Promise<void>} Promise which can not be forced to be ran synchronously
*/
export function nextTickPromise() {
return new RSVPPromise(resolve => {
nextTick(resolve);
});
// Ember 3.4 removed the auto-run assertion, in 3.4+ we can (and should) avoid the "psuedo promisey" run loop configuration
// for our `nextTickPromise` implementation. This allows us to have real microtask based next tick timing...
if (hasEmberVersion(3,4)) {
return _Promise.resolve();
} else {
// on older Ember's fallback to RSVP.Promise + a setTimeout
return new RSVP.Promise(resolve => {
nextTick(resolve);
});
}
}

/**
Expand Down
3 changes: 1 addition & 2 deletions addon-test-support/@ember/test-helpers/wait-until.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Promise } from 'rsvp';
import { futureTick } from './-utils';
import { futureTick, _Promise as Promise } from './-utils';

const TIMEOUTS = [0, 1, 2, 5, 7];
const MAX_TIMEOUT = 10;
Expand Down

0 comments on commit c260ad0

Please sign in to comment.