diff --git a/docs/rules/lowercase-name.md b/docs/rules/lowercase-name.md index 0e0f4fd85..8c653a986 100644 --- a/docs/rules/lowercase-name.md +++ b/docs/rules/lowercase-name.md @@ -70,3 +70,19 @@ Example of **correct** code for the `{ "ignore": ["it"] }` option: it('Uppercase description'); ``` + +### `allow` + +This array option whitelists prefixes that titles can start with with capitals. +This can be useful when writing tests for api endpoints, where you'd like to +prefix with the HTTP method. + +By default, nothing is allowed (the equivalent of `{ "allow": [] }`). + +Example of **correct** code for the `{ "allow": ["GET"] }` option: + +```js +/* eslint jest/lowercase-name: ["error", { "allow": ["GET"] }] */ + +describe('GET /live'); +``` diff --git a/src/rules/__tests__/lowercase-name.test.ts b/src/rules/__tests__/lowercase-name.test.ts index bbf68cb14..f06fa9452 100644 --- a/src/rules/__tests__/lowercase-name.test.ts +++ b/src/rules/__tests__/lowercase-name.test.ts @@ -46,6 +46,10 @@ ruleTester.run('lowercase-name', rule, { 'describe(``)', 'describe("")', 'describe(42)', + { + code: 'describe(42)', + options: [{ ignore: undefined, allowedPrefixes: undefined }], + }, ], invalid: [ @@ -225,3 +229,21 @@ ruleTester.run('lowercase-name with ignore=it', rule, { ], invalid: [], }); + +ruleTester.run('lowercase-name with allowedPrefixes', rule, { + valid: [ + { + code: "it('GET /live', function () {})", + options: [{ allowedPrefixes: ['GET'] }], + }, + { + code: 'it("POST /live", function () {})', + options: [{ allowedPrefixes: ['GET', 'POST'] }], + }, + { + code: 'it(`PATCH /live`, function () {})', + options: [{ allowedPrefixes: ['GET', 'PATCH'] }], + }, + ], + invalid: [], +}); diff --git a/src/rules/lowercase-name.ts b/src/rules/lowercase-name.ts index 367a9812f..1a1f801f0 100644 --- a/src/rules/lowercase-name.ts +++ b/src/rules/lowercase-name.ts @@ -54,9 +54,13 @@ const testDescription = (argument: ArgumentLiteral): string | null => { const jestFunctionName = ( node: CallExpressionWithCorrectCalleeAndArguments, + allowedPrefixes: readonly string[], ) => { const description = testDescription(node.arguments[0]); - if (description === null) { + if ( + description === null || + allowedPrefixes.some(name => description.startsWith(name)) + ) { return null; } @@ -73,7 +77,15 @@ const jestFunctionName = ( return null; }; -export default createRule({ +export default createRule< + [ + Partial<{ + ignore: readonly JestFunctionName[]; + allowedPrefixes: readonly string[]; + }>, + ], + 'unexpectedLowercase' +>({ name: __filename, meta: { type: 'suggestion', @@ -96,19 +108,24 @@ export default createRule({ items: { enum: ['describe', 'test', 'it'] }, additionalItems: false, }, + allowedPrefixes: { + type: 'array', + items: { type: 'string' }, + additionalItems: false, + }, }, additionalProperties: false, }, ], } as const, - defaultOptions: [{ ignore: [] } as { ignore: readonly JestFunctionName[] }], - create(context, [{ ignore }]) { + defaultOptions: [{ ignore: [], allowedPrefixes: [] }], + create(context, [{ ignore = [], allowedPrefixes = [] }]) { return { CallExpression(node) { if (!isJestFunctionWithLiteralArg(node)) { return; } - const erroneousMethod = jestFunctionName(node); + const erroneousMethod = jestFunctionName(node, allowedPrefixes); if (erroneousMethod && !ignore.includes(node.callee.name)) { context.report({