Skip to content

Commit

Permalink
move hasPendingTransitions function to setupApplicationContext and re…
Browse files Browse the repository at this point in the history
…solve some PR comments
  • Loading branch information
AlexTraher authored and rwjblue committed Jan 26, 2019
1 parent 7e646a2 commit 7aa6a57
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 92 deletions.
21 changes: 2 additions & 19 deletions addon-test-support/@ember/test-helpers/settled.ts
Expand Up @@ -4,9 +4,9 @@ import jQuery from 'jquery';

import Ember from 'ember';

import { getContext } from './setup-context';
import { nextTick } from './-utils';
import waitUntil from './wait-until';
import { hasPendingTransitions } from './setup-application-context';

// Ember internally tracks AJAX requests in the same way that we do here for
// legacy style "acceptance" tests using the `ember-testing.js` asset provided
Expand Down Expand Up @@ -43,23 +43,6 @@ function pendingRequests() {
return localRequestsPending + internalRequestsPending;
}

/**
@private
@returns {boolean} if there are any pending router transitions
*/
function hasPendingTransitions() {
const context = getContext();
const owner = context && context.owner;

if (!owner) {
return false;
}

const router = owner.lookup('router:main');
const isLoading = router._routerMicrolib && !!router._routerMicrolib.activeTransition;
return isLoading;
}

/**
@private
@param {Event} event (unused)
Expand Down Expand Up @@ -166,7 +149,7 @@ export interface SettledState {
hasPendingTimers: boolean;
hasPendingWaiters: boolean;
hasPendingRequests: boolean;
hasPendingTransitions: boolean;
hasPendingTransitions: boolean | null;
pendingRequestCount: number;
}

Expand Down
Expand Up @@ -9,11 +9,61 @@ export interface ApplicationTestContext extends TestContext {
element?: Element | null;
}

const CAN_USE_ROUTER_EVENTS = hasEmberVersion(3, 6);
let routerTransitionsPending = false;
const ROUTER = new WeakMap();

// eslint-disable-next-line require-jsdoc
export function isApplicationTestContext(context: BaseContext): context is ApplicationTestContext {
return isTestContext(context);
}

/**
Resets the flag determining if transitions are pending (used by hasPendingTransitions)
@public
@returns {undefined}
*/
export function resetRouterTransitionPendingState() {
routerTransitionsPending = false;
}

/**
Determines if we have any pending router transtions (used to determine `settled` state)
@public
@returns {(boolean|null)} if there are pending transitions
*/
export function hasPendingTransitions(): boolean | null {
if (CAN_USE_ROUTER_EVENTS) {
return routerTransitionsPending;
}

let context = getContext();

// there is no current context, we cannot check
if (context === undefined) {
return null;
}

let router = ROUTER.get(context);

if (router === undefined) {
// if there is no router (e.g. no `visit` calls made yet), we cannot
// check for pending transitions but this is explicitly not an error
// condition
return null;
}

let routerMicrolib = router._routerMicrolib || router.router;

if (routerMicrolib === undefined) {
return null;
}

return !!routerMicrolib.activeTransition;
}

/**
Navigate the application to the provided URL.
Expand All @@ -32,7 +82,22 @@ export function visit(url: string, options?: { [key: string]: any }): Promise<vo

return nextTickPromise()
.then(() => {
return owner.visit(url, options);
let visitResult = owner.visit(url, options);

if (CAN_USE_ROUTER_EVENTS) {
let router = owner.lookup('service:router');

// track pending transitions via the public routeWillChange / routeDidChange APIs
// routeWillChange can fire many times and is only useful to know when we have _started_
// transitioning, we can then use routeDidChange to signal that the transition has settled
router.on('routeWillChange', () => (routerTransitionsPending = true));
router.on('routeDidChange', () => (routerTransitionsPending = false));
} else {
let router = owner.lookup('router:main');
ROUTER.set(context, router);
}

return visitResult;
})
.then(() => {
if (global.EmberENV._APPLICATION_TEMPLATE_WRAPPER !== false) {
Expand Down
@@ -1,6 +1,6 @@
import { nextTickPromise } from './-utils';
import settled from './settled';

import { resetRouterTransitionPendingState } from './setup-application-context';
/**
Used by test framework addons to tear down the provided context after testing is completed.
Expand All @@ -11,6 +11,8 @@ import settled from './settled';
@returns {Promise<void>} resolves when settled
*/
export default function(context: object, options?: { waitForSettled?: boolean }): Promise<void> {
resetRouterTransitionPendingState();

let waitForSettled = true;
if (options !== undefined && 'waitForSettled' in options) {
waitForSettled = options.waitForSettled!;
Expand Down
84 changes: 13 additions & 71 deletions tests/unit/settled-test.js
@@ -1,6 +1,6 @@
import Ember from 'ember';
import { module, test } from 'qunit';
import { isSettled, getSettledState, setContext, unsetContext } from '@ember/test-helpers';
import { isSettled, getSettledState } from '@ember/test-helpers';
import hasEmberVersion from '@ember/test-helpers/has-ember-version';
import { _setupAJAXHooks, _teardownAJAXHooks } from '@ember/test-helpers/settled';
import { next, later, run, schedule } from '@ember/runloop';
Expand All @@ -26,7 +26,7 @@ module('settled', function(hooks) {
hasPendingRequests: false,
hasPendingTimers: false,
hasPendingWaiters: false,
hasPendingTransitions: false,
hasPendingTransitions: null,
hasRunLoop: false,
pendingRequestCount: 0,
},
Expand Down Expand Up @@ -145,32 +145,6 @@ module('settled', function(hooks) {

assert.strictEqual(isSettled(), true, 'post cond');
});

test('when router is transitioning', async function(assert) {
assert.expect(3);

setContext(this);
assert.strictEqual(isSettled(), true);

this.owner = {
lookup: () => ({
_routerMicrolib: {
activeTransition: {},
},
}),
};
assert.strictEqual(isSettled(), false);

this.owner = {
lookup: () => ({
_routerMicrolib: {
activeTransition: null,
},
}),
};
assert.strictEqual(isSettled(), true);
unsetContext();
});
});

module('getSettledState', function() {
Expand All @@ -179,7 +153,7 @@ module('settled', function(hooks) {
hasPendingRequests: false,
hasPendingTimers: false,
hasPendingWaiters: false,
hasPendingTransitions: false,
hasPendingTransitions: null,
hasRunLoop: false,
pendingRequestCount: 0,
});
Expand All @@ -197,7 +171,7 @@ module('settled', function(hooks) {
hasPendingRequests: false,
hasPendingTimers: true,
hasPendingWaiters: false,
hasPendingTransitions: false,
hasPendingTransitions: null,
hasRunLoop: true,
pendingRequestCount: 0,
});
Expand All @@ -216,7 +190,7 @@ module('settled', function(hooks) {
hasPendingRequests: false,
hasPendingTimers: true,
hasPendingWaiters: false,
hasPendingTransitions: false,
hasPendingTransitions: null,
hasRunLoop: false,
pendingRequestCount: 0,
});
Expand All @@ -235,7 +209,7 @@ module('settled', function(hooks) {
hasPendingRequests: false,
hasPendingTimers: true,
hasPendingWaiters: false,
hasPendingTransitions: false,
hasPendingTransitions: null,
hasRunLoop: false,
pendingRequestCount: 0,
});
Expand All @@ -251,7 +225,7 @@ module('settled', function(hooks) {
hasPendingRequests: false,
hasPendingTimers: false,
hasPendingWaiters: false,
hasPendingTransitions: false,
hasPendingTransitions: null,
hasRunLoop: true,
pendingRequestCount: 0,
});
Expand Down Expand Up @@ -279,7 +253,7 @@ module('settled', function(hooks) {
hasPendingRequests: true,
hasPendingTimers: false,
hasPendingWaiters: false,
hasPendingTransitions: false,
hasPendingTransitions: null,
hasRunLoop: false,
pendingRequestCount: 1,
});
Expand All @@ -288,7 +262,7 @@ module('settled', function(hooks) {
hasPendingRequests: false,
hasPendingTimers: false,
hasPendingWaiters: true,
hasPendingTransitions: false,
hasPendingTransitions: null,
hasRunLoop: false,
pendingRequestCount: 0,
});
Expand All @@ -306,7 +280,7 @@ module('settled', function(hooks) {
hasPendingRequests: false,
hasPendingTimers: false,
hasPendingWaiters: true,
hasPendingTransitions: false,
hasPendingTransitions: null,
hasRunLoop: false,
pendingRequestCount: 0,
});
Expand All @@ -316,38 +290,6 @@ module('settled', function(hooks) {
assert.strictEqual(isSettled(), true, 'post cond');
});

test('when router is transitioning', function(assert) {
assert.expect(3);
assert.strictEqual(isSettled(), true);

setContext(this);
this.owner = {
lookup: () => ({
_routerMicrolib: {
activeTransition: {},
},
}),
};
assert.deepEqual(getSettledState(), {
hasPendingRequests: false,
hasPendingTimers: false,
hasPendingWaiters: false,
hasPendingTransitions: true,
hasRunLoop: false,
pendingRequestCount: 0,
});

this.owner = {
lookup: () => ({
_routerMicrolib: {
activeTransition: null,
},
}),
};
assert.strictEqual(isSettled(), true, 'post cond');
unsetContext();
});

test('all the things!', function(assert) {
assert.expect(6);
let done = assert.async();
Expand All @@ -359,7 +301,7 @@ module('settled', function(hooks) {
hasPendingRequests: false,
hasPendingTimers: false,
hasPendingWaiters: true,
hasPendingTransitions: false,
hasPendingTransitions: null,
hasRunLoop: false,
pendingRequestCount: 0,
});
Expand All @@ -369,7 +311,7 @@ module('settled', function(hooks) {
hasPendingRequests: false,
hasPendingTimers: false,
hasPendingWaiters: true,
hasPendingTransitions: false,
hasPendingTransitions: null,
hasRunLoop: true,
pendingRequestCount: 0,
});
Expand All @@ -380,7 +322,7 @@ module('settled', function(hooks) {
hasPendingRequests: false,
hasPendingTimers: true,
hasPendingWaiters: true,
hasPendingTransitions: false,
hasPendingTransitions: null,
hasRunLoop: true,
pendingRequestCount: 0,
});
Expand Down

0 comments on commit 7aa6a57

Please sign in to comment.