Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
stefanpenner committed Aug 12, 2021
1 parent 0bdf3c6 commit 53de824
Show file tree
Hide file tree
Showing 17 changed files with 2,030 additions and 2,127 deletions.
4 changes: 3 additions & 1 deletion addon-test-support/assertions/deprecations-include.js
@@ -1,7 +1,9 @@
import { getDeprecations } from '@ember/test-helpers';

export default function deprecationsInclude(expected) {
const deprecations = getDeprecations().map(deprecation => deprecation.message);
const deprecations = getDeprecations().map(
(deprecation) => deprecation.message
);

this.pushResult({
result: deprecations.indexOf(expected) > -1,
Expand Down
2 changes: 1 addition & 1 deletion addon-test-support/assertions/deprecations.js
Expand Up @@ -5,7 +5,7 @@ export default async function deprecations(callback, expectedDeprecations) {

const operation = (deprecations) => {
this.deepEqual(
deprecations.map(deprecation => deprecation.message),
deprecations.map((deprecation) => deprecation.message),
expectedDeprecations,
'Expected deprecations during test.'
);
Expand Down
30 changes: 19 additions & 11 deletions addon-test-support/assertions/expect-deprecation.js
@@ -1,29 +1,37 @@
import { getDeprecationsForCallback, getDeprecations } from '@ember/test-helpers';
import {
getDeprecationsDuringCallback,
getDeprecations,
} from '@ember/test-helpers';
import checkMatcher from './utils/check-matcher';

export default function expectDeprecation(cb, matcher) {
const test = deprecations => {
const matchedDeprecations = deprecations.filter(deprecation => {
const test = (deprecations, matcher) => {
const matchedDeprecations = deprecations.filter((deprecation) => {
return checkMatcher(deprecation.message, matcher);
});

this.pushResult({
result: matchedDeprecations.length !== 0,
actual: matchedDeprecations,
expected: null,
message: 'Expected deprecations during test, but no deprecations were found.'
message:
'Expected deprecations during test, but no deprecations were found.',
});
}
};

if (typeof cb !== 'function') {
test(getDeprecations());
// cb is not a callback, so we assume it is the matcher
test(getDeprecations(), cb);
} else {
const maybeThenable = getDeprecationsForCallback(cb);
if (maybeThenable !== null && typeof maybeThenable === 'object' && typeof maybeThenable.then === 'function') {
return maybeThenable.then(test);
const maybeThenable = getDeprecationsDuringCallback(cb);
if (
maybeThenable !== null &&
typeof maybeThenable === 'object' &&
typeof maybeThenable.then === 'function'
) {
return maybeThenable.then((deprecations) => test(deprecations, matcher));
} else {
test(maybeThenable);
test(maybeThenable, matcher);
}
}

}
37 changes: 37 additions & 0 deletions addon-test-support/assertions/expect-no-deprecation.js
@@ -0,0 +1,37 @@
import checkMatcher from './utils/check-matcher';
import {
getDeprecations,
getDeprecationsDuringCallback,
} from '@ember/test-helpers';

export default function expectNoDeprecation(cb, matcher) {
const test = (deprecations, matcher) => {
const matchedDeprecations = deprecations.filter((deprecation) => {
return checkMatcher(deprecation.message, matcher);
});

this.pushResult({
result: matchedDeprecations.length === 0,
actual: matchedDeprecations,
expected: [],
message:
'Expected no deprecations during test, but deprecations were found.',
});
};

if (typeof cb !== 'function') {
// cb is not a callback, so we assume it is the matcher
test(getDeprecations(), cb);
} else {
const maybeThenable = getDeprecationsDuringCallback(cb);
if (
maybeThenable !== null &&
typeof maybeThenable === 'object' &&
typeof maybeThenable.then === 'function'
) {
return maybeThenable.then((deprecations) => test(deprecations, matcher));
} else {
test(maybeThenable, matcher);
}
}
}
50 changes: 44 additions & 6 deletions addon-test-support/assertions/expect-no-runloop.js
@@ -1,27 +1,65 @@
import { end, _currentRunloop, _hasScheduledTimers, _cancelTimers } from '@ember/runloop';
import {
run,
end,
_getCurrentRunLoop,
_hasScheduledTimers,
_cancelTimers,
} from '@ember/runloop';

function getCurrentRunLoop() {
// Ember 3.24.4 does not have _getCurrentRunLoop, but does have run.currentRunLoop;
if ('currentRunLoop' in run) {
return run.currentRunLoop;
} else {
return _getCurrentRunLoop();
}
}

// TODO: It seems very odd to mix runloop + timers into a runloop
// specific assertion.
//
// We should likely:
//
// * have timer specific expectations
// * have runloop specific expectations
// * not have either cancel timers or runloop, rather those should
// be the explicitly choosen by the user
export default function expectNoRunloop() {
if (_currentRunLoop) {
if (getCurrentRunLoop()) {
this.pushResult({
result: false,
actual: run.currentRunLoop,
actual: getCurrentRunLoop(),
expected: null,
message: 'Should not be in a run loop at end of test'
message: 'expected no active runloop',
});

while (_currentRunLoop) {
while (getCurrentRunLoop()) {
end();
}
} else {
this.pushResult({
result: true,
actual: null,
expected: null,
message: 'expected no active runloop',
});
}

if (_hasScheduledTimers()) {
this.pushResult({
result: false,
actual: true,
expected: false,
message: 'Ember run should not have scheduled timers at end of test'
message: 'expected no active timers',
});

_cancelTimers();
} else {
this.pushResult({
result: true,
actual: false,
expected: false,
message: 'expected no active timers',
});
}
}
15 changes: 15 additions & 0 deletions addon-test-support/assertions/expect-no-warning.js
@@ -0,0 +1,15 @@
import { getWarnings, getWarningsDuringCallback } from '@ember/test-helpers';

export default function expectNoWarning(callback) {
const warnings =
typeof callback === 'function'
? getWarningsDuringCallback(callback)
: getWarnings();

this.pushResult({
result: warnings.length === 0,
actual: warnings,
expected: [],
message: 'Expected no warnings during test, but warnings were found.',
});
}
16 changes: 0 additions & 16 deletions addon-test-support/assertions/expect-no-warnings.js

This file was deleted.

@@ -1,7 +1,7 @@
import checkMatcher from './utils/check-matcher';
import { getWarningsDuringCallback } from '@ember/test-helpers';
import { getWarningsDuringCallback, getWarnings } from '@ember/test-helpers';

export default function expectWarnings(callback, matcher) {
export default function expectWarning(callback, matcher) {
let warnings;
if (typeof callback === 'function') {
warnings = getWarningsDuringCallback(callback);
Expand All @@ -10,12 +10,15 @@ export default function expectWarnings(callback, matcher) {
warnings = getWarnings();
}

const matchedWarnings = warnings.filter(warning => checkMatcher(warning.message, matcher);
const actual = warnings.filter((warning) =>
checkMatcher(warning.message, matcher)
);

const result = actual.length !== 0;
this.pushResult({
result: matchedWarnings.length !== 0,
actual: matchedWarnings,
result,
actual,
expected: null,
message: 'Expected warnings during test, but no warnings were found.'
message: 'Expected warnings during test, but no warnings were found.',
});
}
11 changes: 0 additions & 11 deletions addon-test-support/assertions/no-deprecations.js

This file was deleted.

13 changes: 11 additions & 2 deletions addon-test-support/assertions/utils/check-matcher.js
@@ -1,10 +1,19 @@
export function checkMatcher(message, matcher) {
function includes(message, search) {
return message.includes
? message.includes(search)
: message.indexOf(search) !== -1;
}

// TODO: test
export default function checkMatcher(message, matcher) {
if (typeof matcher === 'string') {
return includes(message, matcher);
} else if (matcher instanceof RegExp) {
return !!message.match(matcher);
} else if (matcher) {
throw new Error(`[ember-qunit] can only match Strings and RegExps. "${typeof matcher}" was provided.`);
throw new Error(
`[ember-qunit] can only match Strings and RegExps. "${typeof matcher}" was provided.`
);
}

// No matcher always returns true. Makes the code easier elsewhere.
Expand Down
23 changes: 13 additions & 10 deletions addon-test-support/index.js
Expand Up @@ -27,19 +27,18 @@ import { installTestNotIsolatedHook } from './test-isolation-validation';

let waitForSettled = true;

import deprecationsInclude from './asserts/deprecations-include';
import deprecations from './asserts/deprecations';
import noDeprecations from './asserts/no-deprecations';
import expectDeprecation from './asserts/expect-deprecation';
import expectNoRunloop from './asserts/expect-no-runloop';
import expectWarning from './asserts/expect-warning';

export function setup(assert) {
import deprecationsInclude from './assertions/deprecations-include';
import deprecations from './assertions/deprecations';
import expectNoDeprecation from './assertions/expect-no-deprecation';
import expectDeprecation from './assertions/expect-deprecation';
import expectNoRunloop from './assertions/expect-no-runloop';
// import expectWarning from './assertions/expect-warning';
//
export function setupAsserts(assert) {
// TODO: decide which of these we should keep, which depreacte and which drop.
assert.deprecationsInclude = deprecationsInclude;
assert.deprecations = deprecations;
assert.expectNoDeprecations = noDeprecations; // compat
assert.noDeprecations = noDeprecations;
assert.expectNoDeprecation = expectNoDeprecation;
assert.expectDeprecation = expectDeprecation; // compat
assert.expectNoRunloop = expectNoRunloop; // compat but fixed name
// around for compat
Expand Down Expand Up @@ -241,5 +240,9 @@ export function start(options = {}) {
startTests();
}

if (options.setupAssertAdditions !== false) {
setupAsserts(QUnit.assert);
}

setupResetOnerror();
}
1 change: 1 addition & 0 deletions server/index.js
@@ -0,0 +1 @@
module.exports = (app) => app.get('/', (_, res) => res.redirect('/tests'));
34 changes: 23 additions & 11 deletions tests/unit/assertions/assertion-test.js
@@ -1,46 +1,58 @@
import { module, test } from 'qunit';
import expectAssertion from 'ember-qunit/assertions/expect-assertion';
// import expectAssertion from 'ember-qunit/assertions/expect-assertion';
import { assert as emberAssert } from '@ember/debug';

module('expectAssertion', function(hooks) {
module.skip('expectAssertion', function (hooks) {
let mockAssert;

hooks.beforeEach(() => {
mockAssert = {
pushedResults: [],
expectAssertion
expectAssertion,
};
});

test('called with assert', function(assert) {
test('called with assert', function (assert) {
mockAssert.expectAssertion(() => {
emberAssert('testing assert');
});

assert.ok(mockAssert.pushedResults[0].result, '`expectAssertion` captured deprecation call');
assert.ok(
mockAssert.pushedResults[0].result,
'`expectAssertion` captured deprecation call'
);
});

test('called without deprecation', function(assert) {
test('called without deprecation', function (assert) {
mockAssert.expectAssertion(() => {
emberAssert('testing assert', true);
});

assert.notOk(mockAssert.pushedResults[0].result, '`expectAssertion` logged failed result');
assert.notOk(
mockAssert.pushedResults[0].result,
'`expectAssertion` logged failed result'
);
});

test('called with deprecation and matched assert', function(assert) {
test('called with deprecation and matched assert', function (assert) {
mockAssert.expectAssertion(() => {
emberAssert('testing assert');
}, /testing/);

assert.ok(mockAssert.pushedResults[0].result, '`expectAssertion` captured deprecation call');
assert.ok(
mockAssert.pushedResults[0].result,
'`expectAssertion` captured deprecation call'
);
});

test('called with deprecation and unmatched assert', function(assert) {
test('called with deprecation and unmatched assert', function (assert) {
mockAssert.expectAssertion(() => {
emberAssert('testing assert');
}, /different/);

assert.notOk(mockAssert.pushedResults[0].result, '`expectAssertion` logged failed result');
assert.notOk(
mockAssert.pushedResults[0].result,
'`expectAssertion` logged failed result'
);
});
});

0 comments on commit 53de824

Please sign in to comment.