Skip to content

Commit

Permalink
fix(valid-expect-in-promise): support awaited promises in arguments
Browse files Browse the repository at this point in the history
  • Loading branch information
G-Rath committed Oct 11, 2021
1 parent c171942 commit 585dde6
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 0 deletions.
58 changes: 58 additions & 0 deletions src/rules/__tests__/valid-expect-in-promise.test.ts
Expand Up @@ -15,6 +15,46 @@ ruleTester.run('valid-expect-in-promise', rule, {
"test('something', () => Promise.resolve().then(() => expect(1).toBe(2)));",
'Promise.resolve().then(() => expect(1).toBe(2))',
'const x = Promise.resolve().then(() => expect(1).toBe(2))',
dedent`
it('is valid', async () => {
const promise = loadNumber().then(number => {
expect(typeof number).toBe('number');
return number + 1;
});
expect(await promise).toBeGreaterThan(1);
});
`,
dedent`
it('is valid', async () => {
const promise = loadNumber().then(number => {
expect(typeof number).toBe('number');
return number + 1;
});
logValue(await promise);
});
`,
dedent`
it('is valid', async () => {
const promise = loadNumber().then(number => {
expect(typeof number).toBe('number');
return 1;
});
expect.assertions(await promise);
});
`,
dedent`
it('is valid', async () => {
await loadNumber().then(number => {
expect(typeof number).toBe('number');
});
});
`,
dedent`
it('it1', () => new Promise((done) => {
test()
Expand Down Expand Up @@ -1356,5 +1396,23 @@ ruleTester.run('valid-expect-in-promise', rule, {
},
],
},
{
code: dedent`
test('that we error on this', () => {
const promise = something().then(value => {
expect(value).toBe('red');
});
log(promise);
});
`,
errors: [
{
messageId: 'expectInFloatingPromise',
line: 2,
column: 9,
},
],
},
],
});
35 changes: 35 additions & 0 deletions src/rules/valid-expect-in-promise.ts
Expand Up @@ -144,6 +144,33 @@ const isPromiseMethodThatUsesValue = (
);
};

/**
* Attempts to determine if the runtime value represented by the given `identifier`
* is `await`ed as an argument along the given call expression
*/
const isValueAwaitedInArguments = (
name: string,
node: TSESTree.CallExpression,
): boolean => {
for (const argument of node.arguments) {
if (
argument.type === AST_NODE_TYPES.AwaitExpression &&
isIdentifier(argument.argument, name)
) {
return true;
}
}

if (
node.callee.type === AST_NODE_TYPES.MemberExpression &&
node.callee.object.type === AST_NODE_TYPES.CallExpression
) {
return isValueAwaitedInArguments(name, node.callee.object);
}

return false;
};

/**
* Attempts to determine if the runtime value represented by the given `identifier`
* is `await`ed or `return`ed within the given `body` of statements
Expand All @@ -166,6 +193,14 @@ const isValueAwaitedOrReturned = (
}

if (node.type === AST_NODE_TYPES.ExpressionStatement) {
// it's possible that we're awaiting the value as an argument
if (
node.expression.type === AST_NODE_TYPES.CallExpression &&
isValueAwaitedInArguments(name, node.expression)
) {
return true;
}

if (node.expression.type === AST_NODE_TYPES.AwaitExpression) {
return isPromiseMethodThatUsesValue(node.expression, identifier);
}
Expand Down

0 comments on commit 585dde6

Please sign in to comment.