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: make naming-convention rule more strict #128

Merged
merged 1 commit into from
May 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .changeset/young-stingrays-sin.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"@infinum/eslint-plugin": major
---

Changed `@typescript-eslint/naming-convention` rule to be StrictPascalCase for:
- enums (with members)
- booleans (with is, should, has prefixes)
- typeLikes (class, enum, interface, typeAlias, typeParameter)
20 changes: 20 additions & 0 deletions src/configs/typescript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,26 @@ export default {
match: true,
},
},
{
selector: ['enum', 'enumMember'],
format: ['StrictPascalCase'],
},
{
selector: 'variable',
types: ['boolean'],
format: ['StrictPascalCase'],
prefix: ['is', 'should', 'has'],
},
{
selector: 'variable',
types: ['boolean'],
modifiers: ['destructured'],
format: null,
},
{
selector: 'typeLike',
format: ['StrictPascalCase'],
},
],
'@typescript-eslint/no-inferrable-types': 'warn',
'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_', ignoreRestSiblings: true }],
Expand Down
95 changes: 95 additions & 0 deletions tests/configs/typescript/naming-convention.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ const ruleName = '@typescript-eslint/naming-convention';

const { test, validate } = getTypescriptTester(ruleName);

/**
* Interface
*/
test('should alow PascalCase interface with I prefix', () => validate(`interface ITestInterface {}`));

test('should disallow PascalCase interface without I prefix', () =>
Expand All @@ -20,4 +23,96 @@ test('should disallow non-PascalCase interface with I prefix (2)', () =>
test('should disallow non-PascalCase interface without I prefix', () =>
validate(`interface Test_Interface {}`, ['Interface name `Test_Interface` must match the RegExp: /^I[A-Z]/u']));

/**
* Enum
*/
test('should allow PascalCase enum naming', () =>
validate(`
enum TestEnum {
Foo,
Bar,
FooBar,
BarFoo,
}
`));

test('should disallow non-PascalCase enum naming', () =>
validate(
`
enum testEnum {
foo,
bar,
fooBar,
barFoo,
}
`,
[
'Enum name `testEnum` must match one of the following formats: StrictPascalCase',
'Enum Member name `foo` must match one of the following formats: StrictPascalCase',
'Enum Member name `bar` must match one of the following formats: StrictPascalCase',
'Enum Member name `fooBar` must match one of the following formats: StrictPascalCase',
'Enum Member name `barFoo` must match one of the following formats: StrictPascalCase',
]
));

/**
* Boolean variable naming
*/
test('should allow StrictPascalCase boolean variable naming with is, should, has prefix', async () => {
await validate(`const isTest = true;`);
await validate(`const shouldTest = true;`);
await validate(`const hasTest = true;`);
});

test('should disallow non-StrictPascalCase boolean variable naming with is, should, has prefix', async () => {
await validate(`const istest = true;`, [
'Variable name `istest` trimmed as `test` must match one of the following formats: StrictPascalCase',
]);
await validate(`const shouldtest = true;`, [
'Variable name `shouldtest` trimmed as `test` must match one of the following formats: StrictPascalCase',
]);
await validate(`const hastest = true;`, [
'Variable name `hastest` trimmed as `test` must match one of the following formats: StrictPascalCase',
]);
});

/**
* modifier: destructured - boolean variable naming
*/
test('should allow destructed boolean variable naming without is, should, has prefix', async () =>
validate(`const { test } = { test: true };`));

test('should allow destructed boolean variable naming without is, should, has prefix', async () => {
await validate(`const { test: isTest } = { test: true };`);
await validate(`const { test: shouldTest } = { test: true };`);
await validate(`const { test: hasTest } = { test: true };`);
});

test('should disallow destructed renamed boolean variable naming without is, should, has prefix', () =>
validate(`const { test: test2 } = { test: true };`, [
'Variable name `test2` must have one of the following prefixes: is, should, has',
]));

/**
* typeLike
*/
test('should allow PascalCase class naming', () => validate(`class TestClass {}`));

test('should disallow non-PascalCase class naming', () =>
validate(`class testClass {}`, ['Class name `testClass` must match one of the following formats: StrictPascalCase']));

test('should allow PascalCase typeParameter naming', () => validate(`type TestType<T> = T;`));

test('should disallow non-PascalCase typeParameter naming', () =>
validate(`type TestType<t> = t;`, [
'Type Parameter name `t` must match one of the following formats: StrictPascalCase',
]));

test('should allow PascalCase typeAlias naming', () => validate(`type TestType = string;`));

test('should disallow non-PascalCase typeAlias naming', () =>
validate(`type testType = string;`, [
'Type Alias name `testType` must match one of the following formats: StrictPascalCase',
]));

test.run();
6 changes: 3 additions & 3 deletions tests/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ function once<T extends (...args: Array<any>) => ReturnType<T>>(
func: T
): (...funcArgs: Parameters<T>) => ReturnType<T> {
let result: ReturnType<T>;
let called = false;
let isCalled = false;

return function (this: ThisParameterType<T>, ...args: Parameters<T>): ReturnType<T> {
if (!called) {
called = true;
if (!isCalled) {
isCalled = true;
result = func.apply(this, args);
}

Expand Down