Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(eslint-plugin): [naming-convention] allow not check format #1455

Merged
merged 3 commits into from Jan 14, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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,
armano2 marked this conversation as resolved.
Show resolved Hide resolved
},
{
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