Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
feat(eslint-plugin): [naming-convention] allow not check format (#1455)
  • Loading branch information
bradzacher committed Jan 14, 2020
1 parent b47da0d commit 61eb434
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 24 deletions.
24 changes: 15 additions & 9 deletions packages/eslint-plugin/docs/rules/naming-convention.md
Expand Up @@ -19,14 +19,16 @@ Each property will be described in detail below. Also see the examples section b
```ts
type Options = {
// format options
format: (
| 'camelCase'
| 'strictCamelCase'
| 'PascalCase'
| 'StrictPascalCase'
| 'snake_case'
| 'UPPER_CASE'
)[];
format:
| (
| 'camelCase'
| 'strictCamelCase'
| 'PascalCase'
| 'StrictPascalCase'
| 'snake_case'
| 'UPPER_CASE'
)[]
| null;
custom?: {
regex: string;
match: boolean;
Expand Down Expand Up @@ -79,7 +81,7 @@ When the format of an identifier is checked, it is checked in the following orde
1. validate custom
1. validate format

At each step, if the identifier matches the option, the matching part will be removed.
For steps 1-4, if the identifier matches the option, the matching part will be removed.
For example, if you provide the following formatting option: `{ leadingUnderscore: 'allow', prefix: ['I'], format: ['StrictPascalCase'] }`, for the identifier `_IMyInterface`, then the following checks will occur:

1. `name = _IMyInterface`
Expand All @@ -89,6 +91,7 @@ For example, if you provide the following formatting option: `{ leadingUnderscor
1. validate prefix - pass
- Trim prefix - `name = MyInterface`
1. validate suffix - no check
1. validate custom - no check
1. validate format - pass

One final note is that if the name were to become empty via this trimming process, it is considered to match all `format`s. An example of where this might be useful is for generic type parameters, where you want all names to be prefixed with `T`, but also want to allow for the single character `T` name.
Expand All @@ -104,6 +107,9 @@ The `format` option defines the allowed formats for the identifier. This option
- `snake_case` - standard snake_case format - all characters must be lower-case, and underscores are allowed.
- `UPPER_CASE` - same as `snake_case`, except all characters must be upper-case.

Instead of an array, you may also pass `null`. This signifies "this selector shall not have its format checked".
This can be useful if you want to enforce no particular format for a specific selector, after applying a group selector.

### `custom`

The `custom` option defines a custom regex that the identifier must (or must not) match. This option allows you to have a bit more finer-grained control over identifiers, letting you ban (or force) certain patterns and substrings.
Expand Down
34 changes: 19 additions & 15 deletions packages/eslint-plugin/src/rules/naming-convention.ts
Expand Up @@ -100,7 +100,7 @@ type TypeModifiersString = keyof typeof TypeModifiers;

interface Selector {
// format options
format: PredefinedFormatsString[];
format: PredefinedFormatsString[] | null;
custom?: {
regex: string;
match: boolean;
Expand All @@ -117,7 +117,7 @@ interface Selector {
}
interface NormalizedSelector {
// format options
format: PredefinedFormats[];
format: PredefinedFormats[] | null;
custom: {
regex: RegExp;
match: boolean;
Expand Down Expand Up @@ -154,19 +154,24 @@ const PREFIX_SUFFIX_SCHEMA: JSONSchema.JSONSchema4 = {
type: 'string',
minLength: 1,
},
minItems: 1,
additionalItems: false,
};
type JSONSchemaProperties = Record<string, JSONSchema.JSONSchema4>;
const FORMAT_OPTIONS_PROPERTIES: JSONSchemaProperties = {
format: {
type: 'array',
items: {
type: 'string',
enum: util.getEnumNames(PredefinedFormats),
},
minItems: 1,
additionalItems: false,
oneOf: [
{
type: 'array',
items: {
type: 'string',
enum: util.getEnumNames(PredefinedFormats),
},
additionalItems: false,
},
{
type: 'null',
},
],
},
custom: {
type: 'object',
Expand Down Expand Up @@ -235,7 +240,6 @@ function selectorSchema(
}
const SCHEMA: JSONSchema.JSONSchema4 = {
type: 'array',
minItems: 1,
items: {
oneOf: [
...selectorSchema('default', false, util.getEnumNames(Modifiers)),
Expand Down Expand Up @@ -1024,7 +1028,7 @@ function createValidator(
originalName: string,
): boolean {
const formats = config.format;
if (formats.length === 0) {
if (formats === null || formats.length === 0) {
return true;
}

Expand Down Expand Up @@ -1189,7 +1193,7 @@ function normalizeOption(option: Selector): NormalizedSelector {

return {
// format options
format: option.format.map(f => PredefinedFormats[f]),
format: option.format ? option.format.map(f => PredefinedFormats[f]) : null,
custom: option.custom
? {
regex: new RegExp(option.custom.regex),
Expand All @@ -1204,8 +1208,8 @@ function normalizeOption(option: Selector): NormalizedSelector {
option.trailingUnderscore !== undefined
? UnderscoreOptions[option.trailingUnderscore]
: null,
prefix: option.prefix ?? null,
suffix: option.suffix ?? null,
prefix: option.prefix && option.prefix.length > 0 ? option.prefix : null,
suffix: option.suffix && option.suffix.length > 0 ? option.suffix : null,
// selector options
selector: isMetaSelector(option.selector)
? MetaSelectors[option.selector]
Expand Down
28 changes: 28 additions & 0 deletions packages/eslint-plugin/tests/rules/naming-convention.test.ts
Expand Up @@ -603,6 +603,7 @@ const cases: Cases = [

ruleTester.run('naming-convention', rule, {
valid: [
`const x = 1;`, // no options shouldn't crash
...createValidTestCases(cases),
{
code: `
Expand Down Expand Up @@ -696,6 +697,33 @@ ruleTester.run('naming-convention', rule, {
},
],
},
// no format selector
{
code: 'const snake_case = 1;',
options: [
{
selector: 'default',
format: ['camelCase'],
},
{
selector: 'variable',
format: null,
},
],
},
{
code: 'const snake_case = 1;',
options: [
{
selector: 'default',
format: ['camelCase'],
},
{
selector: 'variable',
format: [],
},
],
},
],
invalid: [
...createInvalidTestCases(cases),
Expand Down

0 comments on commit 61eb434

Please sign in to comment.