Skip to content

Commit 706f5c2

Browse files
authored
feat(no-large-snapshots): deprecate whitelistedSnapshots for new name (#632)
1 parent 4cb1e88 commit 706f5c2

File tree

3 files changed

+94
-64
lines changed

3 files changed

+94
-64
lines changed

docs/rules/no-large-snapshots.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,8 @@ If only `maxSize` is provided on options, the value of `maxSize` will be used to
122122
both snapshot types (Inline and External).
123123

124124
Since `eslint-disable` comments are not preserved by Jest when updating
125-
snapshots, you can use the `whitelistedSnapshots` option to have specific
126-
snapshots allowed regardless of their size.
125+
snapshots, you can use the `allowedSnapshots` option to have specific snapshots
126+
allowed regardless of their size.
127127

128128
This option takes a map, with the key being the absolute filepath to a snapshot
129129
file, and the value an array of values made up of strings and regular
@@ -141,7 +141,7 @@ module.exports = {
141141
'jest/no-large-snapshots': [
142142
'error',
143143
{
144-
whitelistedSnapshots: {
144+
allowedSnapshots: {
145145
'/path/to/file.js.snap': ['snapshot name 1', /a big snapshot \d+/],
146146
},
147147
},
@@ -161,7 +161,7 @@ module.exports = {
161161
'jest/no-large-snapshots': [
162162
'error',
163163
{
164-
whitelistedSnapshots: {
164+
allowedSnapshots: {
165165
[path.resolve('test/__snapshots__/get.js.snap')]: ['full request'],
166166
[path.resolve('test/__snapshots__/put.js.snap')]: ['full request'],
167167
},

src/rules/__tests__/no-large-snapshots.test.ts

+67-50
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,7 @@
1-
import {
2-
AST_NODE_TYPES,
3-
TSESLint,
4-
TSESTree,
5-
} from '@typescript-eslint/experimental-utils';
1+
import { TSESLint } from '@typescript-eslint/experimental-utils';
62
import resolveFrom from 'resolve-from';
73
import rule from '../no-large-snapshots';
84

9-
const noLargeSnapshots = rule.create.bind(rule);
10-
115
const ruleTester = new TSESLint.RuleTester({
126
parser: resolveFrom(require.resolve('eslint'), 'espree'),
137
parserOptions: {
@@ -71,12 +65,12 @@ ruleTester.run('no-large-snapshots', rule, {
7165
code: generateExportsSnapshotString(20),
7266
},
7367
{
74-
// "it should not report whitelisted large snapshots"
68+
// "it should not report snapshots that are allowed to be large"
7569
filename: '/mock-component.jsx.snap',
7670
code: generateExportsSnapshotString(58),
7771
options: [
7872
{
79-
whitelistedSnapshots: {
73+
allowedSnapshots: {
8074
'/mock-component.jsx.snap': ['a big component 1'],
8175
},
8276
},
@@ -178,13 +172,12 @@ ruleTester.run('no-large-snapshots', rule, {
178172
],
179173
},
180174
{
181-
// "it should report if file is not whitelisted"
175+
// "it should report if file is not allowed"
182176
filename: '/mock-component.jsx.snap',
183-
// code: generateExportsSnapshotString(58),
184177
code: generateExportsSnapshotString(58),
185178
options: [
186179
{
187-
whitelistedSnapshots: {
180+
allowedSnapshots: {
188181
'/another-mock-component.jsx.snap': [/a big component \d+/u],
189182
},
190183
},
@@ -196,6 +189,27 @@ ruleTester.run('no-large-snapshots', rule, {
196189
},
197190
],
198191
},
192+
{
193+
// "should not report allowed large snapshots based on regexp"
194+
filename: '/mock-component.jsx.snap',
195+
code: [
196+
generateExportsSnapshotString(58, 'a big component w/ text'),
197+
generateExportsSnapshotString(58, 'a big component 2'),
198+
].join('\n\n'),
199+
options: [
200+
{
201+
allowedSnapshots: {
202+
'/mock-component.jsx.snap': [/a big component \d+/u],
203+
},
204+
},
205+
],
206+
errors: [
207+
{
208+
messageId: 'tooLongSnapshots',
209+
data: { lineLimit: 50, lineCount: 58 },
210+
},
211+
],
212+
},
199213
{
200214
// "should not report whitelisted large snapshots based on regexp"
201215
filename: '/mock-component.jsx.snap',
@@ -218,7 +232,26 @@ ruleTester.run('no-large-snapshots', rule, {
218232
],
219233
},
220234
{
221-
// "should not report whitelisted large snapshots based on regexp"
235+
filename: '/mock-component.jsx.snap',
236+
code: [
237+
generateExportsSnapshotString(58, 'a big component w/ text'),
238+
generateExportsSnapshotString(58, 'a big component 2'),
239+
].join('\n\n'),
240+
options: [
241+
{
242+
allowedSnapshots: {
243+
'/mock-component.jsx.snap': ['a big component 2'],
244+
},
245+
},
246+
],
247+
errors: [
248+
{
249+
messageId: 'tooLongSnapshots',
250+
data: { lineLimit: 50, lineCount: 58 },
251+
},
252+
],
253+
},
254+
{
222255
filename: '/mock-component.jsx.snap',
223256
code: [
224257
generateExportsSnapshotString(58, 'a big component w/ text'),
@@ -242,47 +275,31 @@ ruleTester.run('no-large-snapshots', rule, {
242275
});
243276

244277
describe('no-large-snapshots', () => {
245-
const buildBaseNode = <Type extends AST_NODE_TYPES>(
246-
type: Type,
247-
): TSESTree.BaseNode & { type: Type } => ({
248-
type,
249-
range: [0, 1],
250-
loc: {
251-
start: { line: 1, column: 0 },
252-
end: { line: 1, column: 1 },
253-
},
254-
});
255-
256-
describe('when "whitelistedSnapshots" option contains relative paths', () => {
278+
describe('when "allowedSnapshots" option contains relative paths', () => {
257279
it('should throw an exception', () => {
258-
const { ExpressionStatement = () => {} } = noLargeSnapshots({
259-
id: 'my-id',
260-
getFilename: () => '/mock-component.jsx.snap',
261-
options: [
280+
expect(() => {
281+
const linter = new TSESLint.Linter();
282+
283+
linter.defineRule('no-large-snapshots', rule);
284+
285+
linter.verify(
286+
'console.log()',
262287
{
263-
whitelistedSnapshots: {
264-
'mock-component.jsx.snap': [/a big component \d+/u],
288+
rules: {
289+
'no-large-snapshots': [
290+
'error',
291+
{
292+
allowedSnapshots: {
293+
'mock-component.jsx.snap': [/a big component \d+/u],
294+
},
295+
},
296+
],
265297
},
266298
},
267-
],
268-
parserOptions: {},
269-
parserPath: '',
270-
settings: {},
271-
getAncestors: () => [],
272-
getDeclaredVariables: () => [],
273-
getScope: jest.fn(),
274-
getSourceCode: jest.fn(),
275-
markVariableAsUsed: () => false,
276-
report: jest.fn(),
277-
});
278-
279-
expect(() =>
280-
ExpressionStatement({
281-
...buildBaseNode(AST_NODE_TYPES.ExpressionStatement),
282-
expression: buildBaseNode(AST_NODE_TYPES.JSXClosingFragment),
283-
}),
284-
).toThrow(
285-
'All paths for whitelistedSnapshots must be absolute. You can use JS config and `path.resolve`',
299+
'mock-component.jsx.snap',
300+
);
301+
}).toThrow(
302+
'All paths for allowedSnapshots must be absolute. You can use JS config and `path.resolve`',
286303
);
287304
});
288305
});

src/rules/no-large-snapshots.ts

+23-10
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
interface RuleOptions {
1515
maxSize?: number;
1616
inlineMaxSize?: number;
17+
allowedSnapshots?: Record<string, Array<string | RegExp>>;
1718
whitelistedSnapshots?: Record<string, Array<string | RegExp>>;
1819
}
1920

@@ -24,36 +25,38 @@ type RuleContext = TSESLint.RuleContext<MessageId, [RuleOptions]>;
2425
const reportOnViolation = (
2526
context: RuleContext,
2627
node: TSESTree.CallExpression | TSESTree.ExpressionStatement,
27-
{ maxSize: lineLimit = 50, whitelistedSnapshots = {} }: RuleOptions,
28+
{
29+
maxSize: lineLimit = 50,
30+
whitelistedSnapshots = {},
31+
allowedSnapshots = whitelistedSnapshots,
32+
}: RuleOptions,
2833
) => {
2934
const startLine = node.loc.start.line;
3035
const endLine = node.loc.end.line;
3136
const lineCount = endLine - startLine;
3237

33-
const allPathsAreAbsolute = Object.keys(whitelistedSnapshots).every(
34-
isAbsolute,
35-
);
38+
const allPathsAreAbsolute = Object.keys(allowedSnapshots).every(isAbsolute);
3639

3740
if (!allPathsAreAbsolute) {
3841
throw new Error(
39-
'All paths for whitelistedSnapshots must be absolute. You can use JS config and `path.resolve`',
42+
'All paths for allowedSnapshots must be absolute. You can use JS config and `path.resolve`',
4043
);
4144
}
4245

43-
let isWhitelisted = false;
46+
let isAllowed = false;
4447

4548
if (
4649
node.type === AST_NODE_TYPES.ExpressionStatement &&
4750
'left' in node.expression &&
4851
isExpectMember(node.expression.left)
4952
) {
5053
const fileName = context.getFilename();
51-
const whitelistedSnapshotsInFile = whitelistedSnapshots[fileName];
54+
const allowedSnapshotsInFile = allowedSnapshots[fileName];
5255

53-
if (whitelistedSnapshotsInFile) {
56+
if (allowedSnapshotsInFile) {
5457
const snapshotName = getAccessorValue(node.expression.left.property);
5558

56-
isWhitelisted = whitelistedSnapshotsInFile.some(name => {
59+
isAllowed = allowedSnapshotsInFile.some(name => {
5760
if (name instanceof RegExp) {
5861
return name.test(snapshotName);
5962
}
@@ -63,7 +66,7 @@ const reportOnViolation = (
6366
}
6467
}
6568

66-
if (!isWhitelisted && lineCount > lineLimit) {
69+
if (!isAllowed && lineCount > lineLimit) {
6770
context.report({
6871
messageId: lineLimit === 0 ? 'noSnapshot' : 'tooLongSnapshots',
6972
data: { lineLimit, lineCount },
@@ -96,6 +99,10 @@ export default createRule<[RuleOptions], MessageId>({
9699
inlineMaxSize: {
97100
type: 'number',
98101
},
102+
allowedSnapshots: {
103+
type: 'object',
104+
additionalProperties: { type: 'array' },
105+
},
99106
whitelistedSnapshots: {
100107
type: 'object',
101108
patternProperties: {
@@ -109,6 +116,12 @@ export default createRule<[RuleOptions], MessageId>({
109116
},
110117
defaultOptions: [{}],
111118
create(context, [options]) {
119+
if ('whitelistedSnapshots' in options) {
120+
console.warn(
121+
'jest/no-large-snapshots: the "whitelistedSnapshots" option has been renamed to "allowedSnapshots"',
122+
);
123+
}
124+
112125
if (context.getFilename().endsWith('.snap')) {
113126
return {
114127
ExpressionStatement(node) {

0 commit comments

Comments
 (0)