Skip to content

Commit

Permalink
fix(valid-expect): validate async expect calls
Browse files Browse the repository at this point in the history
  • Loading branch information
macklinu committed Feb 15, 2018
1 parent e0160e5 commit 4fa5083
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 5 deletions.
39 changes: 36 additions & 3 deletions rules/__tests__/valid-expect.test.js
Expand Up @@ -3,16 +3,24 @@
const RuleTester = require('eslint').RuleTester;
const rules = require('../..').rules;

const ruleTester = new RuleTester();
const ruleTester = new RuleTester({
parserOptions: {
ecmaVersion: 8,
},
});

ruleTester.run('valid-expect', rules['valid-expect'], {
valid: [
'expect("something").toEqual("else");',
'expect(true).toBeDefined();',
'expect([1, 2, 3]).toEqual([1, 2, 3]);',
'expect(undefined).not.toBeDefined();',
'expect(Promise.resolve(2)).resolves.toBeDefined();',
'expect(Promise.reject(2)).rejects.toBeDefined();',
'test("foo", () => { return expect(Promise.resolve(2)).resolves.toBeDefined(); });',
'test("foo", async () => { await expect(Promise.reject(2)).rejects.toBeDefined(); });',
'test("foo", () => expect(Promise.resolve(2)).resolves.toBeDefined());',
'test("foo", async () => await expect(Promise.reject(2)).rejects.toBeDefined());',
'test("foo", async () => { expect(await Promise.resolve(2)).resolves.toBeDefined(); });',
'test("foo", async () => { expect(await Promise.reject(2)).rejects.toBeDefined(); });',
],

invalid: [
Expand Down Expand Up @@ -131,5 +139,30 @@ ruleTester.run('valid-expect', rules['valid-expect'], {
},
],
},
{
code:
'test("foo", () => { expect(Promise.resolve(2)).resolves.toBeDefined(); });',
errors: [{ message: "Must return or await 'expect.resolves' statement" }],
},
{
code:
'test("foo", async () => { expect(Promise.resolve(2)).resolves.toBeDefined(); });',
errors: [{ message: "Must await 'expect.resolves' statement" }],
},
{
code:
'test("foo", () => { expect(Promise.reject(2)).rejects.toBeDefined(); });',
errors: [{ message: "Must return or await 'expect.rejects' statement" }],
},
{
code:
'test("foo", async () => { expect(Promise.reject(2)).rejects.toBeDefined(); });',
errors: [{ message: "Must await 'expect.rejects' statement" }],
},
{
code:
'test("foo", async () => expect(Promise.reject(2)).rejects.toBeDefined());',
errors: [{ message: 'Unexpected use of async without await' }],
},
],
});
56 changes: 54 additions & 2 deletions rules/valid-expect.js
Expand Up @@ -5,19 +5,71 @@
* MIT license, Tom Vincent.
*/

const getDocsUrl = require('./util').getDocsUrl;
const util = require('./util');

const expectProperties = ['not', 'resolves', 'rejects'];

function isResolvesOrRejectsExpression(node) {
if (node.expression.type !== 'CallExpression') {
return false;
}
const callee = node.expression.callee;
return (
callee.object &&
callee.object.object &&
callee.object.object.callee &&
callee.object.object.callee.name === 'expect' &&
callee.object.property &&
(callee.object.property.name === 'resolves' ||
callee.object.property.name === 'rejects')
);
}

module.exports = {
meta: {
docs: {
url: getDocsUrl('valid-expect.md'),
url: util.getDocsUrl('valid-expect.md'),
},
},
create(context) {
function validateAsyncExpects(node) {
const callback = node.arguments[1];
if (callback && util.isFunction(callback)) {
if (callback.body.type === 'BlockStatement') {
callback.body.body
.filter(node => node.type === 'ExpressionStatement')
.filter(isResolvesOrRejectsExpression)
.forEach(node => {
if (
node.expression.callee.object.object.arguments[0].type ===
'AwaitExpression'
) {
return;
}
const propertyName = node.expression.callee.object.property.name;
context.report({
node,
message: callback.async
? "Must await 'expect.{{ propertyName }}' statement"
: "Must return or await 'expect.{{ propertyName }}' statement",
data: { propertyName },
});
});
} else if (callback.async && callback.body.type !== 'AwaitExpression') {
context.report({
node: callback.body,
message: 'Unexpected use of async without await',
});
}
}
}

return {
CallExpression(node) {
if (util.isTestCase(node)) {
validateAsyncExpects(node);
}

const calleeName = node.callee.name;

if (calleeName === 'expect') {
Expand Down

0 comments on commit 4fa5083

Please sign in to comment.