This repository has been archived by the owner on Aug 18, 2020. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
419b858
commit d5df939
Showing
9 changed files
with
189 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
# Prevent catch assertions in tests. (jest/no-if) | ||
This rule prevents the use of `expect` inside `catch` blocks. | ||
|
||
## Rule Details | ||
|
||
Expectations inside a `catch` block can be silently skipped. While Jest provides an `expect.assertions(number)` helper, Shopify rarely uses this feature. Using `toThrow` concisely guarantees that an exception was thrown, and that its contents match expectations. | ||
|
||
Examples of **incorrect** code for this rule: | ||
|
||
```js | ||
it('foo', () => { | ||
try { | ||
foo(); // `foo` may be refactored to not throw exceptions, yet still appears to be tested here. | ||
} catch (err) { | ||
expect(err).toMatch(/foo error/); | ||
} | ||
}) | ||
|
||
it('bar', async () => { | ||
try { | ||
await foo(); | ||
} catch (err) { | ||
expect(err).toMatch(/foo error/); | ||
} | ||
}) | ||
``` | ||
|
||
Examples of **correct** code for this rule: | ||
|
||
```js | ||
it('foo', () => { | ||
expect(() => foo()).toThrow(/foo error/); | ||
}) | ||
|
||
it('bar', async () => { | ||
await expect(fooPromise).rejects.toThrow(/foo error/); | ||
}) | ||
``` | ||
|
||
## When Not To Use It | ||
|
||
If you do not wish to prevent the use of catch expectations in tests, you can safely disable this rule. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
const {docsUrl} = require('../../utilities'); | ||
const {isTestDefinition} = require('../../utilities/jest'); | ||
|
||
module.exports = { | ||
meta: { | ||
docs: { | ||
description: 'Prefer using toThrow for exception tests.', | ||
category: 'Best Practices', | ||
recommended: false, | ||
uri: docsUrl('jest/no-try-expect'), | ||
}, | ||
messages: { | ||
noTryExpect: [ | ||
'Tests should use Jest‘s exception helpers.', | ||
'Use "expect(() => yourFunction()).toThrow()" for synchronous tests,', | ||
'or "await expect(yourFunction()).rejects.toThrow()" for async tests', | ||
].join(' '), | ||
}, | ||
}, | ||
create(context) { | ||
let isTest = false; | ||
let catchDepth = 0; | ||
|
||
function isThrowExpectCall(node) { | ||
return catchDepth > 0 && node.callee.name === 'expect'; | ||
} | ||
|
||
return { | ||
CallExpression(node) { | ||
if (isTestDefinition(node)) { | ||
isTest = true; | ||
} else if (isTest && isThrowExpectCall(node)) { | ||
context.report({ | ||
messageId: 'noTryExpect', | ||
node, | ||
}); | ||
} | ||
}, | ||
CatchClause() { | ||
if (isTest) { | ||
++catchDepth; | ||
} | ||
}, | ||
'CatchClause:exit': function() { | ||
if (isTest) { | ||
--catchDepth; | ||
} | ||
}, | ||
'CallExpression:exit': (node) => { | ||
if (isTestDefinition(node)) { | ||
isTest = false; | ||
} | ||
}, | ||
}; | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
const {RuleTester} = require('eslint'); | ||
const rule = require('../../../../lib/rules/jest/no-try-expect'); | ||
require('babel-eslint'); | ||
|
||
const parser = 'babel-eslint'; | ||
const ruleTester = new RuleTester(); | ||
|
||
ruleTester.run('no-try-expect', rule, { | ||
valid: [ | ||
{ | ||
code: `it('foo', () => { | ||
expect('foo').toEqual('foo'); | ||
})`, | ||
parser, | ||
}, | ||
{ | ||
code: ` | ||
it('foo', () => { | ||
expect('bar').toEqual('bar'); | ||
}); | ||
try { | ||
} catch { | ||
expect('foo').toEqual('foo'); | ||
}`, | ||
parser, | ||
}, | ||
{ | ||
code: ` | ||
it.skip('foo'); | ||
try { | ||
} catch { | ||
expect('foo').toEqual('foo'); | ||
}`, | ||
parser, | ||
}, | ||
], | ||
invalid: [ | ||
{ | ||
code: `it('foo', () => { | ||
try { | ||
} catch (err) { | ||
expect(err).toMatch('Error'); | ||
} | ||
})`, | ||
parser, | ||
errors: [ | ||
{ | ||
messageId: 'noTryExpect', | ||
}, | ||
], | ||
}, | ||
{ | ||
code: `it('foo', async () => { | ||
await wrapper('production', async () => { | ||
try { | ||
} catch (err) { | ||
expect(err).toMatch('Error'); | ||
} | ||
}) | ||
})`, | ||
parser, | ||
errors: [ | ||
{ | ||
messageId: 'noTryExpect', | ||
}, | ||
], | ||
}, | ||
], | ||
}); |