Skip to content

Commit

Permalink
feat(valid-title): allow custom matcher messages (#913)
Browse files Browse the repository at this point in the history
  • Loading branch information
G-Rath committed Sep 29, 2021
1 parent 14a2d13 commit ffc9392
Show file tree
Hide file tree
Showing 3 changed files with 252 additions and 43 deletions.
32 changes: 30 additions & 2 deletions docs/rules/valid-title.md
Expand Up @@ -198,8 +198,9 @@ describe('the proper way to handle things', () => {});
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`).
Expression, with an optional message. An object can be provided to apply
different Regular Expressions (with optional messages) to specific Jest test
function groups (`describe`, `test`, and `it`).

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

Expand All @@ -226,3 +227,30 @@ describe('the tests that will be run', () => {});
test('that the stuff works', () => {});
xtest('that errors that thrown have messages', () => {});
```

Optionally you can provide a custom message to show for a particular matcher by
using a tuple at any level where you can provide a matcher:

```js
const prefixes = ['when', 'with', 'without', 'if', 'unless', 'for'];
const prefixesList = prefixes.join(' - \n');

module.exports = {
rules: {
'jest/valid-title': [
'error',
{
mustNotMatch: ['\\.$', 'Titles should not end with a full-stop'],
mustMatch: {
describe: [
new RegExp(`^(?:[A-Z]|\\b(${prefixes.join('|')})\\b`, 'u').source,
`Describe titles should either start with a capital letter or one of the following prefixes: ${prefixesList}`,
],
test: [/[^A-Z]/u.source],
it: /[^A-Z]/u.source,
},
},
],
},
};
```
148 changes: 146 additions & 2 deletions src/rules/__tests__/valid-title.test.ts
Expand Up @@ -107,12 +107,16 @@ ruleTester.run('mustMatch & mustNotMatch options', rule, {
'test("that all is as it should be", () => {});',
{
code: 'it("correctly sets the value", () => {});',
options: [{ mustMatch: undefined }],
options: [{ mustMatch: {} }],
},
{
code: 'it("correctly sets the value", () => {});',
options: [{ mustMatch: / /u.source }],
},
{
code: 'it("correctly sets the value", () => {});',
options: [{ mustMatch: [/ /u.source] }],
},
{
code: 'it("correctly sets the value #unit", () => {});',
options: [{ mustMatch: /#(?:unit|integration|e2e)/u.source }],
Expand Down Expand Up @@ -200,7 +204,56 @@ ruleTester.run('mustMatch & mustNotMatch options', rule, {
`,
options: [
{
mustNotMatch: { describe: /(?:#(?!unit|e2e))\w+/u.source },
mustNotMatch: [
/(?:#(?!unit|e2e))\w+/u.source,
'Please include "#unit" or "#e2e" in titles',
],
mustMatch: [
/^[^#]+$|(?:#(?:unit|e2e))/u.source,
'Please include "#unit" or "#e2e" in titles',
],
},
],
errors: [
{
messageId: 'mustNotMatchCustom',
data: {
jestFunctionName: 'describe',
pattern: /(?:#(?!unit|e2e))\w+/u,
message: 'Please include "#unit" or "#e2e" in titles',
},
column: 12,
line: 8,
},
{
messageId: 'mustNotMatchCustom',
data: {
jestFunctionName: 'it',
pattern: /(?:#(?!unit|e2e))\w+/u,
message: 'Please include "#unit" or "#e2e" in titles',
},
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 },
},
],
Expand Down Expand Up @@ -230,6 +283,44 @@ ruleTester.run('mustMatch & mustNotMatch options', rule, {
});
});
`,
options: [
{
mustNotMatch: {
describe: [
/(?:#(?!unit|e2e))\w+/u.source,
'Please include "#unit" or "#e2e" in describe titles',
],
},
mustMatch: { describe: /^[^#]+$|(?:#(?:unit|e2e))/u.source },
},
],
errors: [
{
messageId: 'mustNotMatchCustom',
data: {
jestFunctionName: 'describe',
pattern: /(?:#(?!unit|e2e))\w+/u,
message: 'Please include "#unit" or "#e2e" in describe titles',
},
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 },
Expand All @@ -248,6 +339,59 @@ ruleTester.run('mustMatch & mustNotMatch options', rule, {
},
],
},
{
code: dedent`
describe('things to test', () => {
describe('unit tests #unit', () => {
it('is true #jest4life', () => {
expect(true).toBe(true);
});
});
describe('e2e tests #e4e', () => {
it('is another test #e2e #jest4life', () => {});
});
});
`,
options: [
{
mustNotMatch: {
describe: [
/(?:#(?!unit|e2e))\w+/u.source,
'Please include "#unit" or "#e2e" in describe titles',
],
},
mustMatch: {
it: [
/^[^#]+$|(?:#(?:unit|e2e))/u.source,
'Please include "#unit" or "#e2e" in it titles',
],
},
},
],
errors: [
{
messageId: 'mustMatchCustom',
data: {
jestFunctionName: 'it',
pattern: /^[^#]+$|(?:#(?:unit|e2e))/u,
message: 'Please include "#unit" or "#e2e" in it titles',
},
column: 8,
line: 3,
},
{
messageId: 'mustNotMatchCustom',
data: {
jestFunctionName: 'describe',
pattern: /(?:#(?!unit|e2e))\w+/u,
message: 'Please include "#unit" or "#e2e" in describe titles',
},
column: 12,
line: 8,
},
],
},
{
code: 'test("the correct way to properly handle all things", () => {});',
options: [{ mustMatch: /#(?:unit|integration|e2e)/u.source }],
Expand Down

0 comments on commit ffc9392

Please sign in to comment.