Skip to content

Commit

Permalink
Add valid-expect-in-promise rule
Browse files Browse the repository at this point in the history
  • Loading branch information
mskelton committed Feb 27, 2024
1 parent f8fc5d9 commit f0568d3
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 58 deletions.
3 changes: 3 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import requireHook from './rules/require-hook';
import requireSoftAssertions from './rules/require-soft-assertions';
import requireTopLevelDescribe from './rules/require-top-level-describe';
import validExpect from './rules/valid-expect';
import validExpectInPromise from './rules/valid-expect-in-promise';
import validTitle from './rules/valid-title';

const index = {
Expand Down Expand Up @@ -88,6 +89,7 @@ const index = {
'require-soft-assertions': requireSoftAssertions,
'require-top-level-describe': requireTopLevelDescribe,
'valid-expect': validExpect,
'valid-expect-in-promise': validExpectInPromise,
'valid-title': validTitle,
},
};
Expand Down Expand Up @@ -116,6 +118,7 @@ const sharedConfig = {
'playwright/no-wait-for-timeout': 'warn',
'playwright/prefer-web-first-assertions': 'error',
'playwright/valid-expect': 'error',
'playwright/valid-expect-in-promise': 'error',
'playwright/valid-title': 'error',
},
};
Expand Down
81 changes: 25 additions & 56 deletions src/rules/valid-expect-in-promise.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,18 +99,6 @@ runRuleTester('valid-expect-in-promise', rule, {
{ column: 3, endColumn: 5, messageId: 'expectInFloatingPromise' },
],
},
{
code: dedent`
xtest('foo', function() {
somePromise.catch(function() {
expect(someThing).toEqual(true)
})
})
`,
errors: [
{ column: 3, endColumn: 5, messageId: 'expectInFloatingPromise' },
],
},
{
code: dedent`
test('foo', function() {
Expand Down Expand Up @@ -335,20 +323,7 @@ runRuleTester('valid-expect-in-promise', rule, {
},
{
code: dedent`
ftest('foo', () => {
somePromise.then(() => {
doSomeOperation();
expect(someThing).toEqual(true);
})
});
`,
errors: [
{ column: 3, endColumn: 5, messageId: 'expectInFloatingPromise' },
],
},
{
code: dedent`
it.skip('foo', () => {
test.skip('foo', () => {
somePromise.then(() => {
doSomeOperation();
expect(someThing).toEqual(true);
Expand Down Expand Up @@ -565,7 +540,7 @@ runRuleTester('valid-expect-in-promise', rule, {
},
{
code: dedent`
import { test } from '@jest/globals';
import { test } from '@playwright/test';
test('later return', async () => {
const x = 1, promise = something().then(value => {
Expand Down Expand Up @@ -765,28 +740,29 @@ runRuleTester('valid-expect-in-promise', rule, {
},
],
},
{
code: dedent`
import { it as promiseThatThis } from '@jest/globals';
promiseThatThis('is valid', async () => {
const promise = loadNumber().then(number => {
expect(typeof number).toBe('number');
return number + 1;
});
expect(anotherPromise).resolves.toBe(1);
});
`,
errors: [
{
column: 9,
line: 4,
messageId: 'expectInFloatingPromise',
},
],
},
// TODO:
// {
// code: dedent`
// import { test as promiseThatThis } from '@playwright/test';
//
// promiseThatThis('is valid', async () => {
// const promise = loadNumber().then(number => {
// expect(typeof number).toBe('number');
//
// return number + 1;
// });
//
// expect(anotherPromise).resolves.toBe(1);
// });
// `,
// errors: [
// {
// column: 9,
// line: 4,
// messageId: 'expectInFloatingPromise',
// },
// ],
// },
// Global aliases
{
code: dedent`
Expand Down Expand Up @@ -1096,13 +1072,6 @@ runRuleTester('valid-expect-in-promise', rule, {
});
});
`,
dedent`
xtest('foo', function() {
return somePromise.catch(function() {
expect(someThing).toEqual(true);
});
});
`,
dedent`
test('foo', function() {
return somePromise.then(function() {
Expand Down
3 changes: 1 addition & 2 deletions src/rules/valid-expect-in-promise.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Rule } from 'eslint';
import * as ESTree from 'estree';
import {
getNodeName,
getParent,
getStringValue,
isFunction,
Expand All @@ -14,8 +15,6 @@ import {
} from '../utils/parseFnCall';
import { KnownCallExpression } from '../utils/types';

const getNodeName = getStringValue;

const isPromiseChainCall = (node: ESTree.Node): node is KnownCallExpression => {
if (
node.type === 'CallExpression' &&
Expand Down
22 changes: 22 additions & 0 deletions src/utils/ast.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Rule } from 'eslint';
import ESTree from 'estree';
import { isSupportedAccessor } from './parseFnCall';
import { NodeWithParent, TypedNodeWithParent } from './types';

export function getStringValue(node: ESTree.Node | undefined) {
Expand Down Expand Up @@ -126,3 +127,24 @@ export function isFunction(
}

export const equalityMatchers = new Set(['toBe', 'toEqual', 'toStrictEqual']);

const joinNames = (a: string | null, b: string | null): string | null =>
a && b ? `${a}.${b}` : null;

export function getNodeName(node: ESTree.Node): string | null {
if (isSupportedAccessor(node)) {
return getStringValue(node);
}

switch (node.type) {
case 'TaggedTemplateExpression':
return getNodeName(node.tag);
case 'MemberExpression':
return joinNames(getNodeName(node.object), getNodeName(node.property));
case 'NewExpression':
case 'CallExpression':
return getNodeName(node.callee);
}

return null;
}

0 comments on commit f0568d3

Please sign in to comment.