Skip to content

Commit

Permalink
feat(valid-title): support mustMatch & mustNotMatch options (#608)
Browse files Browse the repository at this point in the history
Closes #233
  • Loading branch information
G-Rath committed Jul 5, 2020
1 parent 94fa724 commit 4c7207e
Show file tree
Hide file tree
Showing 3 changed files with 362 additions and 8 deletions.
40 changes: 38 additions & 2 deletions docs/rules/valid-title.md
Expand Up @@ -152,9 +152,11 @@ describe('foo', () => {
## Options

```ts
interface {
interface Options {
ignoreTypeOfDescribeName?: boolean;
disallowedWords?: string[];
mustNotMatch?: Partial<Record<'describe' | 'test' | 'it', string>> | string;
mustMatch?: Partial<Record<'describe' | 'test' | 'it', string>> | string;
}
```

Expand All @@ -172,7 +174,7 @@ Default: `[]`
A string array of words that are not allowed to be used in test titles. Matching
is not case-sensitive, and looks for complete words:

Examples of **incorrect** code using `disallowedWords`:
Examples of **incorrect** code when using `disallowedWords`:

```js
// with disallowedWords: ['correct', 'all', 'every', 'properly']
Expand All @@ -190,3 +192,37 @@ it('correctly sets the value', () => {});
test('that everything is as it should be', () => {});
describe('the proper way to handle things', () => {});
```

#### `mustMatch` & `mustNotMatch`

Defaults: `{}`

Allows enforcing that titles must match or must not match a given Regular
Expression. An object can be provided to apply different Regular Expressions to
specific Jest test function groups (`describe`, `test`, and `it`).

Examples of **incorrect** code when using `mustMatch`:

```js
// with mustMatch: '$that'
describe('the correct way to do things', () => {});
fit('this there!', () => {});

// with mustMatch: { test: '$that' }
describe('the tests that will be run', () => {});
test('the stuff works', () => {});
xtest('errors that are thrown have messages', () => {});
```

Examples of **correct** code when using `mustMatch`:

```js
// with mustMatch: '$that'
describe('that thing that needs to be done', () => {});
fit('that this there!', () => {});

// with mustMatch: { test: '$that' }
describe('the tests that will be run', () => {});
test('that the stuff works', () => {});
xtest('that errors that thrown have messages', () => {});
```
217 changes: 217 additions & 0 deletions src/rules/__tests__/valid-title.test.ts
@@ -1,4 +1,5 @@
import { TSESLint } from '@typescript-eslint/experimental-utils';
import dedent from 'dedent';
import resolveFrom from 'resolve-from';
import rule from '../valid-title';

Expand Down Expand Up @@ -100,6 +101,222 @@ ruleTester.run('disallowedWords option', rule, {
],
});

ruleTester.run('mustMatch & mustNotMatch options', rule, {
valid: [
'describe("the correct way to properly handle all the things", () => {});',
'test("that all is as it should be", () => {});',
{
code: 'it("correctly sets the value", () => {});',
options: [{ mustMatch: undefined }],
},
{
code: 'it("correctly sets the value", () => {});',
options: [{ mustMatch: / /u.source }],
},
{
code: 'it("correctly sets the value #unit", () => {});',
options: [{ mustMatch: /#(?:unit|integration|e2e)/u.source }],
},
{
code: 'it("correctly sets the value", () => {});',
options: [{ mustMatch: /^[^#]+$|(?:#(?:unit|e2e))/u.source }],
},
{
code: 'it("correctly sets the value", () => {});',
options: [{ mustMatch: { test: /#(?:unit|integration|e2e)/u.source } }],
},
{
code: dedent`
describe('things to test', () => {
describe('unit tests #unit', () => {
it('is true', () => {
expect(true).toBe(true);
});
});
describe('e2e tests #e2e', () => {
it('is another test #jest4life', () => {});
});
});
`,
options: [{ mustMatch: { test: /^[^#]+$|(?:#(?:unit|e2e))/u.source } }],
},
],
invalid: [
{
code: dedent`
describe('things to test', () => {
describe('unit tests #unit', () => {
it('is true', () => {
expect(true).toBe(true);
});
});
describe('e2e tests #e4e', () => {
it('is another test #e2e #jest4life', () => {});
});
});
`,
options: [
{
mustNotMatch: /(?:#(?!unit|e2e))\w+/u.source,
mustMatch: /^[^#]+$|(?:#(?:unit|e2e))/u.source,
},
],
errors: [
{
messageId: 'mustNotMatch',
data: {
jestFunctionName: 'describe',
pattern: /(?:#(?!unit|e2e))\w+/u,
},
column: 12,
line: 8,
},
{
messageId: 'mustNotMatch',
data: {
jestFunctionName: 'it',
pattern: /(?:#(?!unit|e2e))\w+/u,
},
column: 8,
line: 9,
},
],
},
{
code: dedent`
describe('things to test', () => {
describe('unit tests #unit', () => {
it('is true', () => {
expect(true).toBe(true);
});
});
describe('e2e tests #e4e', () => {
it('is another test #e2e #jest4life', () => {});
});
});
`,
options: [
{
mustNotMatch: { describe: /(?:#(?!unit|e2e))\w+/u.source },
mustMatch: { describe: /^[^#]+$|(?:#(?:unit|e2e))/u.source },
},
],
errors: [
{
messageId: 'mustNotMatch',
data: {
jestFunctionName: 'describe',
pattern: /(?:#(?!unit|e2e))\w+/u,
},
column: 12,
line: 8,
},
],
},
{
code: dedent`
describe('things to test', () => {
describe('unit tests #unit', () => {
it('is true', () => {
expect(true).toBe(true);
});
});
describe('e2e tests #e4e', () => {
it('is another test #e2e #jest4life', () => {});
});
});
`,
options: [
{
mustNotMatch: { describe: /(?:#(?!unit|e2e))\w+/u.source },
mustMatch: { it: /^[^#]+$|(?:#(?:unit|e2e))/u.source },
},
],
errors: [
{
messageId: 'mustNotMatch',
data: {
jestFunctionName: 'describe',
pattern: /(?:#(?!unit|e2e))\w+/u,
},
column: 12,
line: 8,
},
],
},
{
code: 'test("the correct way to properly handle all things", () => {});',
options: [{ mustMatch: /#(?:unit|integration|e2e)/u.source }],
errors: [
{
messageId: 'mustMatch',
data: {
jestFunctionName: 'test',
pattern: /#(?:unit|integration|e2e)/u,
},
column: 6,
line: 1,
},
],
},
{
code: 'describe("the test", () => {});',
options: [
{ mustMatch: { describe: /#(?:unit|integration|e2e)/u.source } },
],
errors: [
{
messageId: 'mustMatch',
data: {
jestFunctionName: 'describe',
pattern: /#(?:unit|integration|e2e)/u,
},
column: 10,
line: 1,
},
],
},
{
code: 'xdescribe("the test", () => {});',
options: [
{ mustMatch: { describe: /#(?:unit|integration|e2e)/u.source } },
],
errors: [
{
messageId: 'mustMatch',
data: {
jestFunctionName: 'describe',
pattern: /#(?:unit|integration|e2e)/u,
},
column: 11,
line: 1,
},
],
},
{
code: 'describe.skip("the test", () => {});',
options: [
{ mustMatch: { describe: /#(?:unit|integration|e2e)/u.source } },
],
errors: [
{
messageId: 'mustMatch',
data: {
jestFunctionName: 'describe',
pattern: /#(?:unit|integration|e2e)/u,
},
column: 15,
line: 1,
},
],
},
],
});

ruleTester.run('title-must-be-string', rule, {
valid: [
'it("is a string", () => {});',
Expand Down

0 comments on commit 4c7207e

Please sign in to comment.