Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
stefanpenner committed Aug 2, 2021
1 parent 9286e89 commit cde065f
Show file tree
Hide file tree
Showing 10 changed files with 531 additions and 3 deletions.
29 changes: 29 additions & 0 deletions addon-test-support/asserts/expect-deprecation.js
@@ -0,0 +1,29 @@
import { getDeprecationsForCallback, 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 => {
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.'
});
}

if (typeof cb !== 'function') {
test(getDeprecations());
} else {
const maybeThenable = getDeprecationsForCallback(cb);
if (maybeThenable !== null && typeof maybeThenable === 'object' && typeof maybeThenable.then === 'function') {
return maybeThenable.then(test);
} else {
test(maybeThenable);
}
}

}
27 changes: 27 additions & 0 deletions addon-test-support/asserts/expect-no-runloop.js
@@ -0,0 +1,27 @@
import { end, _currentRunloop, _hasScheduledTimers, _cancelTimers } from '@ember/runloop';

export default function expectNoRunloop() {
if (_currentRunLoop) {
this.pushResult({
result: false,
actual: run.currentRunLoop,
expected: null,
message: 'Should not be in a run loop at end of test'
});

while (_currentRunLoop) {
end();
}
}

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

_cancelTimers();
}
}
@@ -1,9 +1,8 @@
import { getDeprecations } from '@ember/test-helpers';
import toAssertionMessage from './utils/to-assertion-message';

export default function noDeprecations() {
this.deepEqual(
getDeprecations().map(toAssertionMessage),
getDeprecations(),
[],
'Expected no deprecations during test.'
);
Expand Down
12 changes: 12 additions & 0 deletions addon-test-support/asserts/utils/check-matcher.js
@@ -0,0 +1,12 @@
export 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.`);
}

// No matcher always returns true. Makes the code easier elsewhere.
return true;
}
72 changes: 72 additions & 0 deletions addon-test-support/asserts/warning.js
@@ -0,0 +1,72 @@
import { checkMatcher } from './utils';


export default function() {
let warnings;

QUnit.testStart(function() {
warnings = [];
});

Ember.Debug.registerWarnHandler(function(message, options, next) {
// It's possible for warnings to trigger before the test has started.
if (warnings) {
warnings.push({ message, options });
}
next(message, options);
});

function assertWarnings(qunitAssert, matcher) {
let matchedWarnings = warnings.filter(warning => {
return checkMatcher(warning.message, matcher);
});
qunitAssert.pushResult({
result: matchedWarnings.length !== 0,
actual: matchedWarnings,
expected: null,
message: 'Expected warnings during test, but no warnings were found.'
});
}

function assertNoWarnings(qunitAssert) {
let warningStr = warnings.reduce((a, b) => {
return `${b}${a.message}\n`;
}, '');

qunitAssert.pushResult({
result: warnings.length === 0,
actual: warnings,
expected: [],
message: `Expected no warnings during test, but warnings were found.\n${warningStr}`
});
}

QUnit.assert.expectWarning = function(cb, matcher) {
let originalWarnings = warnings;

if (typeof cb !== 'function') {
matcher = cb;
cb = null;
}

if (cb) {
warnings = [];
cb();
}

assertWarnings(this, matcher);
warnings = originalWarnings;
};

QUnit.assert.expectNoWarning = function(cb) {
let originalWarnings = warnings;

if (cb) {
warnings = [];
cb();
}

assertNoWarnings(this);
warnings = originalWarnings;
};
}
11 changes: 10 additions & 1 deletion addon-test-support/index.js
Expand Up @@ -29,12 +29,21 @@ let waitForSettled = true;

import deprecationsInclude from './asserts/deprecations-include';
import deprecations from './asserts/deprecations';
import noDeprecations from './asserts/no-depreactions';
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) {
// 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.expectDeprecation = expectDeprecation; // compat
assert.expectNoRunloop = expectNoRunloop; // compat but fixed name
// around for compat
assert.exepectNoRunLoop = expectNoRunloop; // compat but wrong camelization
}

export function setupTest(hooks, _options) {
Expand Down
46 changes: 46 additions & 0 deletions tests/unit/assertions/assertion-test.js
@@ -0,0 +1,46 @@
import { module, test } from 'qunit';
import expectAssertion from 'ember-qunit/asserts/expect-assertion';
import { assert as emberAssert } from '@ember/debug';

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

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

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

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

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

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

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');
});

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');
});
});
145 changes: 145 additions & 0 deletions tests/unit/assertions/expect-deprecation-test.js
@@ -0,0 +1,145 @@
import { module, test } from 'qunit';
import expectDeprecation from 'ember-qunit/asserts/expect-deprecation';
import { deprecate } from '@ember/debug';

// ............................................................
// Deprecation outside of a test. Should not cause test failures.
deprecate('Deprecation outside of a test', false, { id: 'deprecation-test', until: '3.0.0' });
// ............................................................

module('expectDeprecation', function(hooks) {
let mockAssert;

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

test('expectDeprecation called after test and with deprecation', function(assert) {
deprecate('Something deprecated', false, { id: 'deprecation-test', until: '3.0.0' });

mockAssert.expectDeprecation();

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

test('expectDeprecation called after test and without deprecation', function(assert) {
mockAssert.expectDeprecation();
assert.notOk(mockAssert.pushedResults[0].result, '`expectDeprecation` logged failed result');
});

test('expectDeprecation called with callback and with deprecation', function(assert) {
mockAssert.expectDeprecation(() => {
deprecate('Something deprecated', false, { id: 'deprecation-test', until: '3.0.0' });
});

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

test('expectDeprecation called with callback and without deprecation', function(assert) {
mockAssert.expectDeprecation(() => { });
assert.notOk(mockAssert.pushedResults[0].result, '`expectDeprecation` logged failed result');
});

test('expectDeprecation called with callback and after test', function(assert) {
mockAssert.expectDeprecation(() => {
deprecate('Something deprecated', false, { id: 'deprecation-test', until: '3.0.0' });
});

mockAssert.expectDeprecation();
assert.ok(mockAssert.pushedResults[0].result, 'first `expectDeprecation` captured deprecation call');
assert.notOk(mockAssert.pushedResults[1].result, 'second `expectDeprecation` logged failed result');
});

test('expectDeprecation called after test, with matcher and matched deprecation', function(assert) {
deprecate('Something deprecated', false, { id: 'deprecation-test', until: '3.0.0' });

mockAssert.expectDeprecation(/Something deprecated/);
assert.ok(mockAssert.pushedResults[0].result, '`expectDeprecation` captured deprecation call');
});

test('expectDeprecation called after test, with matcher and unmatched deprecation', function(assert) {
deprecate('Something deprecated', false, { id: 'deprecation-test', until: '3.0.0' });

mockAssert.expectDeprecation(/different deprecation/);
assert.notOk(mockAssert.pushedResults[0].result, '`expectDeprecation` logged failed result');
});

test('expectDeprecation called with callback, matcher and matched deprecation', function(assert) {
mockAssert.expectDeprecation(() => {
deprecate('Something deprecated', false, { id: 'deprecation-test', until: '3.0.0' });
}, /Something deprecated/);

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

test('expectDeprecation called with callback, matcher and unmatched deprecation', function(assert) {
mockAssert.expectDeprecation(() => {
deprecate('Something deprecated', false, { id: 'deprecation-test', until: '3.0.0' });
}, /different deprecation/);

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

test('expectNoDeprecation called after test and without deprecation', function(assert) {
assert.expectNoDeprecation();
assert.ok(mockAssert.pushedResults[0].result, '`expectNoDeprecation` caught no deprecation');
});

test('expectNoDeprecation called after test and with deprecation', function(assert) {
deprecate('Something deprecated', false, { id: 'deprecation-test', until: '3.0.0' });

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

test('expectNoDeprecation called with callback and with deprecation', function(assert) {
assert.expectNoDeprecation(() => {
deprecate('Something deprecated', false, { id: 'deprecation-test', until: '3.0.0' });
});

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

test('expectNoDeprecation called with callback and without deprecation', function(assert) {
assert.expectNoDeprecation(() => { });
assert.ok(mockAssert.pushedResults[0].result, '`expectNoDeprecation` caught no deprecation');
});

test('expectNoDeprecation called with callback and after test', function(assert) {
assert.expectNoDeprecation(() => {
deprecate('Something deprecated', false, { id: 'deprecation-test', until: '3.0.0' });
});

assert.expectNoDeprecation();
assert.notOk(mockAssert.pushedResults[0].result, 'first `expectNoDeprecation` caught logged failed result');
assert.ok(mockAssert.pushedResults[1].result, 'second `expectNoDeprecation` caught no deprecation');
});

test('expectDeprecation with regex matcher', function(assert) {
mockAssert.expectDeprecation(() => {
deprecate('Something deprecated', false, { id: 'deprecation-test', until: '3.0.0' });
}, /Somethi[a-z ]*ecated/);
mockAssert.expectDeprecation(() => {
deprecate('/Something* deprecated/', false, { id: 'deprecation-test', until: '3.0.0' });
}, /Something* deprecated/);

assert.ok(mockAssert.pushedResults[0].result, '`expectDeprecation` matched RegExp');
assert.notOk(mockAssert.pushedResults[1].result, '`expectDeprecation` didn\'t RegExp as String match');
});

test('expectDeprecation with string matcher', function(assert) {
mockAssert.expectDeprecation(() => {
deprecate('Something deprecated', false, { id: 'deprecation-test', until: '3.0.0' });
}, 'Something');

mockAssert.expectDeprecation(() => {
deprecate('Something deprecated', false, { id: 'deprecation-test', until: '3.0.0' });
}, 'Something.*');

assert.ok(mockAssert.pushedResults[0].result, '`expectDeprecation` captured deprecation for partial String match');
assert.notOk(mockAssert.pushedResults[1].result, '`expectDeprecation` didn\'t test a String match as RegExp');
});
});

0 comments on commit cde065f

Please sign in to comment.