Skip to content

Commit

Permalink
fix(no-input-rename): allow input aliases that match the directive na…
Browse files Browse the repository at this point in the history
…me applied to an element (#1207)
  • Loading branch information
abaran30 committed Nov 20, 2022
1 parent 1c356ec commit aff3344
Show file tree
Hide file tree
Showing 3 changed files with 168 additions and 3 deletions.
94 changes: 94 additions & 0 deletions packages/eslint-plugin/docs/rules/no-input-rename.md
Expand Up @@ -365,6 +365,38 @@ class Test {
}
```

<br>

---

<br>

#### Default Config

```json
{
"rules": {
"@angular-eslint/no-input-rename": [
"error"
]
}
}
```

<br>

#### ❌ Invalid Code

```ts
@Directive({
selector: 'img[fooDirective]',
})
class Test {
@Input('notFooDirective') foo: Foo;
~~~~~~~~~~~~~~~~~
}
```

</details>

<br>
Expand Down Expand Up @@ -887,6 +919,68 @@ class Test {
}
```

<br>

---

<br>

#### Default Config

```json
{
"rules": {
"@angular-eslint/no-input-rename": [
"error"
]
}
}
```

<br>

#### ✅ Valid Code

```ts
@Directive({
selector: 'img[fooDirective]'
})
class Test {
@Input foo: Foo;
}
```

<br>

---

<br>

#### Default Config

```json
{
"rules": {
"@angular-eslint/no-input-rename": [
"error"
]
}
}
```

<br>

#### ✅ Valid Code

```ts
@Directive({
selector: 'img[fooDirective]'
})
class Test {
@Input('fooDirective') foo: Foo;
}
```

</details>

<br>
30 changes: 27 additions & 3 deletions packages/eslint-plugin/src/rules/no-input-rename.ts
Expand Up @@ -55,13 +55,21 @@ export default createESLintRule<Options, MessageIds>({
create(context, [{ allowedNames = [] }]) {
let selectors: ReadonlySet<string> = new Set();
const ariaAttributeKeys = getAriaAttributeKeys();
let selectorDirectiveName: string;

return {
[Selectors.COMPONENT_OR_DIRECTIVE_SELECTOR_LITERAL](
node: TSESTree.Literal | TSESTree.TemplateElement,
) {
const nodeRawText = ASTUtils.getRawText(node);
const bracketMatchResults = nodeRawText.match(/\[(.*?)\]/);

if (bracketMatchResults) {
selectorDirectiveName = bracketMatchResults[1];
}

selectors = new Set(
withoutBracketsAndWhitespaces(ASTUtils.getRawText(node)).split(','),
withoutBracketsAndWhitespaces(nodeRawText).split(','),
);
},
[Selectors.INPUT_ALIAS](
Expand Down Expand Up @@ -98,7 +106,14 @@ export default createESLintRule<Options, MessageIds>({
messageId: 'noInputRename',
fix: (fixer) => fixer.remove(node),
});
} else if (!isAliasNameAllowed(selectors, propertyName, aliasName)) {
} else if (
!isAliasNameAllowed(
selectors,
propertyName,
aliasName,
selectorDirectiveName,
)
) {
context.report({
node,
messageId: 'noInputRename',
Expand Down Expand Up @@ -147,7 +162,14 @@ export default createESLintRule<Options, MessageIds>({
ASTUtils.getReplacementText(node, propertyName),
),
});
} else if (!isAliasNameAllowed(selectors, propertyName, aliasName)) {
} else if (
!isAliasNameAllowed(
selectors,
propertyName,
aliasName,
selectorDirectiveName,
)
) {
context.report({
node,
messageId: 'noInputRename',
Expand Down Expand Up @@ -182,10 +204,12 @@ function isAliasNameAllowed(
selectors: ReadonlySet<string>,
propertyName: string,
aliasName: string,
selectorDirectiveName: string,
): boolean {
return [...selectors].some((selector) => {
return (
selector === aliasName ||
selectorDirectiveName === aliasName ||
composedName(selector, propertyName) === aliasName
);
});
Expand Down
47 changes: 47 additions & 0 deletions packages/eslint-plugin/tests/rules/no-input-rename/cases.ts
Expand Up @@ -146,6 +146,22 @@ export const valid = [
@Input('fooMyColor') myColor: string;
}
`,
`
@Directive({
selector: 'img[fooDirective]'
})
class Test {
@Input foo: Foo;
}
`,
`
@Directive({
selector: 'img[fooDirective]'
})
class Test {
@Input('fooDirective') foo: Foo;
}
`,
];

export const invalid = [
Expand Down Expand Up @@ -447,4 +463,35 @@ export const invalid = [
`,
})),
}),
convertAnnotatedSourceToFailureCase({
description:
'should fail if input property alias does not match the directive name when applied to an element in the selector',
annotatedSource: `
@Directive({
selector: 'img[fooDirective]',
})
class Test {
@Input('notFooDirective') foo: Foo;
~~~~~~~~~~~~~~~~~
}
`,
messageId,
suggestions: (
[
[suggestRemoveAliasName, 'foo'],
[suggestReplaceOriginalNameWithAliasName, 'notFooDirective'],
] as const
).map(([messageId, propertyName]) => ({
messageId,
output: `
@Directive({
selector: 'img[fooDirective]',
})
class Test {
@Input() ${propertyName}: Foo;
}
`,
})),
}),
];

0 comments on commit aff3344

Please sign in to comment.