Skip to content

Commit

Permalink
Improve "class-name-casing" to accept an options object with an "allo…
Browse files Browse the repository at this point in the history
…wUnderscorePrefix" feature
  • Loading branch information
octogonz committed Aug 3, 2019
1 parent 3351e8e commit a58c9a8
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 5 deletions.
16 changes: 16 additions & 0 deletions packages/eslint-plugin/docs/rules/class-name-casing.md
Expand Up @@ -5,6 +5,17 @@ This rule enforces PascalCased names for classes and interfaces.
## Rule Details

This rule aims to make it easy to differentiate classes from regular variables at a glance.
The `_` prefix is sometimes used to designate a private declaration, so the rule also supports a name
that might be `_Example` instead of `Example`.

## Options

This rule has an object option:

- `"allowUnderscorePrefix": false`: (default) does not allow the name to have an underscore prefix
- `"allowUnderscorePrefix": true`: allows the name to optionally have an underscore prefix

## Examples

Examples of **incorrect** code for this rule:

Expand All @@ -16,6 +27,8 @@ class Another_Invalid_Class_Name {}
var bar = class invalidName {};

interface someInterface {}

class _InternalClass {}
```

Examples of **correct** code for this rule:
Expand All @@ -28,6 +41,9 @@ export default class {}
var foo = class {};

interface SomeInterface {}

/* eslint @typescript-eslint/class-name-casing: { "allowUnderscorePrefix": true } */
class _InternalClass {}
```

## When Not To Use It
Expand Down
32 changes: 27 additions & 5 deletions packages/eslint-plugin/src/rules/class-name-casing.ts
Expand Up @@ -4,7 +4,14 @@ import {
} from '@typescript-eslint/experimental-utils';
import * as util from '../util';

export default util.createRule({
type Options = [
{
allowUnderscorePrefix?: boolean;
},
];
type MessageIds = 'notPascalCased';

export default util.createRule<Options, MessageIds>({
name: 'class-name-casing',
meta: {
type: 'suggestion',
Expand All @@ -16,16 +23,31 @@ export default util.createRule({
messages: {
notPascalCased: "{{friendlyName}} '{{name}}' must be PascalCased.",
},
schema: [],
schema: [
{
type: 'object',
properties: {
allowUnderscorePrefix: {
type: 'boolean',
default: false,
},
},
additionalProperties: false,
},
],
},
defaultOptions: [],
create(context) {
defaultOptions: [{ allowUnderscorePrefix: false }],
create(context, [options]) {
/**
* Determine if the identifier name is PascalCased
* @param name The identifier name
*/
function isPascalCase(name: string): boolean {
return /^[A-Z][0-9A-Za-z]*$/.test(name);
if (options.allowUnderscorePrefix) {
return /^_?[A-Z][0-9A-Za-z]*$/.test(name);
} else {
return /^[A-Z][0-9A-Za-z]*$/.test(name);
}
}

/**
Expand Down
18 changes: 18 additions & 0 deletions packages/eslint-plugin/tests/rules/class-name-casing.test.ts
Expand Up @@ -14,6 +14,10 @@ ruleTester.run('class-name-casing', rule, {
sourceType: 'module',
},
},
{
code: 'class _NameWithUnderscore {}',
options: [{ allowUnderscorePrefix: true }],
},
'var Foo = class {};',
'interface SomeInterface {}',
'class ClassNameWithDigit2 {}',
Expand Down Expand Up @@ -50,6 +54,20 @@ ruleTester.run('class-name-casing', rule, {
},
],
},
{
code: 'class _NameWithUnderscore {}',
errors: [
{
messageId: 'notPascalCased',
data: {
friendlyName: 'Class',
name: '_NameWithUnderscore',
},
line: 1,
column: 7,
},
],
},
{
code: 'var foo = class {};',
errors: [
Expand Down

0 comments on commit a58c9a8

Please sign in to comment.