Skip to content

Commit

Permalink
Merge pull request #632 from scalvert/add-ember-test-waiters
Browse files Browse the repository at this point in the history
Add `ember-test-waiters` and integrate into settledness checks
  • Loading branch information
rwjblue authored May 2, 2019
2 parents f80859e + 9c7cd0f commit 2519b3f
Show file tree
Hide file tree
Showing 7 changed files with 165 additions and 36 deletions.
45 changes: 40 additions & 5 deletions addon-test-support/@ember/test-helpers/-internal/debug-info.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,33 @@ import {
} from '@ember/runloop';
import { DebugInfoHelper, debugInfoHelpers } from './debug-info-helpers';
import { assign } from '@ember/polyfills';
import {
getPendingWaiterState,
IPendingWaiterState,
ITestWaiterDebugInfo,
} from 'ember-test-waiters';

const PENDING_AJAX_REQUESTS = 'Pending AJAX requests';
const PENDING_TEST_WAITERS = 'Pending test waiters';
const SCHEDULED_ASYNC = 'Scheduled async';
const SCHEDULED_AUTORUN = 'Scheduled autorun';

type MaybeDebugInfo = BackburnerDebugInfo | null;
type WaiterDebugInfo = true | unknown[];

interface SettledState {
hasPendingTimers: boolean;
hasRunLoop: boolean;
hasPendingWaiters: boolean;
hasPendingLegacyWaiters: boolean;
hasPendingTestWaiters: boolean;
hasPendingRequests: boolean;
}

interface SummaryInfo {
hasPendingRequests: boolean;
hasPendingWaiters: boolean;
hasPendingLegacyWaiters: boolean;
hasPendingTestWaiters: boolean;
pendingTestWaiterInfo: IPendingWaiterState;
autorunStackTrace: string | undefined | null;
pendingTimersCount: number;
hasPendingTimers: boolean;
Expand Down Expand Up @@ -79,14 +88,16 @@ export class TestDebugInfo implements DebugInfo {
constructor(
hasPendingTimers: boolean,
hasRunLoop: boolean,
hasPendingWaiters: boolean,
hasPendingLegacyWaiters: boolean,
hasPendingTestWaiters: boolean,
hasPendingRequests: boolean,
debugInfo: MaybeDebugInfo = getDebugInfo()
) {
this._settledState = {
hasPendingTimers,
hasRunLoop,
hasPendingWaiters,
hasPendingLegacyWaiters,
hasPendingTestWaiters,
hasPendingRequests,
};

Expand Down Expand Up @@ -127,6 +138,10 @@ export class TestDebugInfo implements DebugInfo {
return stacks;
}, []);
}

if (this._summaryInfo.hasPendingTestWaiters) {
this._summaryInfo.pendingTestWaiterInfo = getPendingWaiterState();
}
}

return this._summaryInfo;
Expand All @@ -139,10 +154,30 @@ export class TestDebugInfo implements DebugInfo {
_console.log(PENDING_AJAX_REQUESTS);
}

if (summary.hasPendingWaiters) {
if (summary.hasPendingLegacyWaiters) {
_console.log(PENDING_TEST_WAITERS);
}

if (summary.hasPendingTestWaiters) {
if (!summary.hasPendingLegacyWaiters) {
_console.log(PENDING_TEST_WAITERS);
}

Object.keys(summary.pendingTestWaiterInfo.waiters).forEach(waiterName => {
let waiterDebugInfo: WaiterDebugInfo = summary.pendingTestWaiterInfo.waiters[waiterName];

if (Array.isArray(waiterDebugInfo)) {
_console.group(waiterName);
waiterDebugInfo.forEach((debugInfo: ITestWaiterDebugInfo) => {
_console.log(`${debugInfo.label ? debugInfo.label : 'stack'}: ${debugInfo.stack}`);
});
_console.groupEnd();
} else {
_console.log(waiterName);
}
});
}

if (summary.hasPendingTimers || summary.pendingScheduledQueueItemCount > 0) {
_console.group(SCHEDULED_ASYNC);

Expand Down
9 changes: 6 additions & 3 deletions addon-test-support/@ember/test-helpers/settled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Ember from 'ember';
import { nextTick } from './-utils';
import waitUntil from './wait-until';
import { hasPendingTransitions } from './setup-application-context';
import { hasPendingWaiters } from 'ember-test-waiters';
import DebugInfo, { TestDebugInfo } from './-internal/debug-info';

// Ember internally tracks AJAX requests in the same way that we do here for
Expand Down Expand Up @@ -180,21 +181,23 @@ export interface SettledState {
export function getSettledState(): SettledState {
let hasPendingTimers = Boolean((run as any).hasScheduledTimers());
let hasRunLoop = Boolean((run as any).currentRunLoop);
let hasPendingWaiters = checkWaiters();
let hasPendingLegacyWaiters = checkWaiters();
let hasPendingTestWaiters = hasPendingWaiters();
let pendingRequestCount = pendingRequests();
let hasPendingRequests = pendingRequestCount > 0;

return {
hasPendingTimers,
hasRunLoop,
hasPendingWaiters,
hasPendingWaiters: hasPendingLegacyWaiters || hasPendingTestWaiters,
hasPendingRequests,
hasPendingTransitions: hasPendingTransitions(),
pendingRequestCount,
debugInfo: new TestDebugInfo(
hasPendingTimers,
hasRunLoop,
hasPendingWaiters,
hasPendingLegacyWaiters,
hasPendingTestWaiters,
hasPendingRequests
),
};
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@
"broccoli-funnel": "^2.0.2",
"ember-assign-polyfill": "^2.6.0",
"ember-cli-babel": "^7.7.3",
"ember-cli-htmlbars-inline-precompile": "^2.1.0"
"ember-cli-htmlbars-inline-precompile": "^2.1.0",
"ember-test-waiters": "^0.9.0"
},
"devDependencies": {
"@ember/optional-features": "^0.7.0",
Expand Down
80 changes: 63 additions & 17 deletions tests/unit/settled-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@ import { TestDebugInfo } from '@ember/test-helpers/-internal/debug-info';
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';
import { buildWaiter, _reset as resetWaiters } from 'ember-test-waiters';
import Pretender from 'pretender';
import hasjQuery from '../helpers/has-jquery';
import ajax from '../helpers/ajax';

const WAITER_NAME = 'custom-waiter';

module('settled', function(hooks) {
if (!hasEmberVersion(2, 4)) {
return;
Expand All @@ -30,7 +33,7 @@ module('settled', function(hooks) {
hasPendingTransitions: null,
hasRunLoop: false,
pendingRequestCount: 0,
debugInfo: new TestDebugInfo(false, false, false, false),
debugInfo: new TestDebugInfo(false, false, false, false, false),
},
'post cond - getSettledState'
);
Expand All @@ -50,7 +53,7 @@ module('settled', function(hooks) {
);
});

this._waiter = () => {
this._legacyWaiter = () => {
return !this.isWaiterPending;
};

Expand All @@ -61,11 +64,14 @@ module('settled', function(hooks) {
// use:
//
// import { registerWaiter } from '@ember/test';
Ember.Test.registerWaiter(this._waiter);
Ember.Test.registerWaiter(this._legacyWaiter);

this._testWaiter = buildWaiter(WAITER_NAME);
});

hooks.afterEach(function() {
Ember.Test.unregisterWaiter(this._waiter);
Ember.Test.unregisterWaiter(this._legacyWaiter);
resetWaiters();
this.server.shutdown();
_teardownAJAXHooks();
});
Expand Down Expand Up @@ -134,7 +140,7 @@ module('settled', function(hooks) {
assert.strictEqual(isSettled(), false);
});

test('when waiters are pending', function(assert) {
test('when legacy waiters are pending', function(assert) {
assert.expect(3);

assert.strictEqual(isSettled(), true, 'precond');
Expand All @@ -147,6 +153,22 @@ module('settled', function(hooks) {

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

test('when test waiters are pending', function(assert) {
assert.expect(3);

let waiterItem = {};

assert.strictEqual(isSettled(), true, 'precond');

this._testWaiter.beginAsync(waiterItem);

assert.strictEqual(isSettled(), false);

this._testWaiter.endAsync(waiterItem);

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

module('getSettledState', function() {
Expand All @@ -158,7 +180,7 @@ module('settled', function(hooks) {
hasPendingTransitions: null,
hasRunLoop: false,
pendingRequestCount: 0,
debugInfo: new TestDebugInfo(false, false, false, false),
debugInfo: new TestDebugInfo(false, false, false, false, false),
});
});

Expand All @@ -177,7 +199,7 @@ module('settled', function(hooks) {
hasPendingTransitions: null,
hasRunLoop: true,
pendingRequestCount: 0,
debugInfo: new TestDebugInfo(true, true, false, false),
debugInfo: new TestDebugInfo(true, true, false, false, false),
});
});

Expand All @@ -197,7 +219,7 @@ module('settled', function(hooks) {
hasPendingTransitions: null,
hasRunLoop: false,
pendingRequestCount: 0,
debugInfo: new TestDebugInfo(true, false, false, false),
debugInfo: new TestDebugInfo(true, false, false, false, false),
});
});

Expand All @@ -217,7 +239,7 @@ module('settled', function(hooks) {
hasPendingTransitions: null,
hasRunLoop: false,
pendingRequestCount: 0,
debugInfo: new TestDebugInfo(true, false, false, false),
debugInfo: new TestDebugInfo(true, false, false, false, false),
});
});

Expand All @@ -234,7 +256,7 @@ module('settled', function(hooks) {
hasPendingTransitions: null,
hasRunLoop: true,
pendingRequestCount: 0,
debugInfo: new TestDebugInfo(false, true, false, false),
debugInfo: new TestDebugInfo(false, true, false, false, false),
});
});

Expand Down Expand Up @@ -263,7 +285,7 @@ module('settled', function(hooks) {
hasPendingTransitions: null,
hasRunLoop: false,
pendingRequestCount: 1,
debugInfo: new TestDebugInfo(false, false, false, true),
debugInfo: new TestDebugInfo(false, false, false, false, true),
});
} else {
assert.deepEqual(getSettledState(), {
Expand All @@ -273,12 +295,12 @@ module('settled', function(hooks) {
hasPendingTransitions: null,
hasRunLoop: false,
pendingRequestCount: 0,
debugInfo: new TestDebugInfo(false, false, true, false),
debugInfo: new TestDebugInfo(false, false, true, false, false),
});
}
});

test('when waiters are pending', function(assert) {
test('when legacy waiters are pending', function(assert) {
assert.expect(3);

assert.strictEqual(isSettled(), true, 'precond');
Expand All @@ -292,14 +314,38 @@ module('settled', function(hooks) {
hasPendingTransitions: null,
hasRunLoop: false,
pendingRequestCount: 0,
debugInfo: new TestDebugInfo(false, false, true, false),
debugInfo: new TestDebugInfo(false, false, true, false, false),
});

this.isWaiterPending = false;

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

test('when test waiters are pending', function(assert) {
assert.expect(3);

let waiterItem = {};

assert.strictEqual(isSettled(), true, 'precond');

this._testWaiter.beginAsync(waiterItem);

assert.deepEqual(getSettledState(), {
hasPendingRequests: false,
hasPendingTimers: false,
hasPendingWaiters: true,
hasPendingTransitions: null,
hasRunLoop: false,
pendingRequestCount: 0,
debugInfo: new TestDebugInfo(false, false, false, true, false),
});

this._testWaiter.endAsync(waiterItem);

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

test('all the things!', function(assert) {
assert.expect(6);
let done = assert.async();
Expand All @@ -314,7 +360,7 @@ module('settled', function(hooks) {
hasPendingTransitions: null,
hasRunLoop: false,
pendingRequestCount: 0,
debugInfo: new TestDebugInfo(false, false, true, false),
debugInfo: new TestDebugInfo(false, false, true, false, false),
});

run(() => {
Expand All @@ -325,7 +371,7 @@ module('settled', function(hooks) {
hasPendingTransitions: null,
hasRunLoop: true,
pendingRequestCount: 0,
debugInfo: new TestDebugInfo(false, true, true, false),
debugInfo: new TestDebugInfo(false, true, true, false, false),
});

next(this.confirmSettles(done));
Expand All @@ -337,7 +383,7 @@ module('settled', function(hooks) {
hasPendingTransitions: null,
hasRunLoop: true,
pendingRequestCount: 0,
debugInfo: new TestDebugInfo(true, true, true, false),
debugInfo: new TestDebugInfo(true, true, true, false, false),
});

this.isWaiterPending = false;
Expand Down
Loading

0 comments on commit 2519b3f

Please sign in to comment.