Skip to content

Commit 285d8ba

Browse files
Merge pull request #2414 from NullVoxPopuli/nvp/template-lint-extract-rule-template-no-capital-arguments
Extract rule: template-no-capital-arguments
2 parents 4810446 + c79bc9a commit 285d8ba

File tree

4 files changed

+173
-9
lines changed

4 files changed

+173
-9
lines changed

README.md

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -189,15 +189,16 @@ rules in templates can be disabled with eslint directives with mustache or html
189189

190190
### Best Practices
191191

192-
| Name | Description | 💼 | 🔧 | 💡 |
193-
| :----------------------------------------------------------------------------------------------------- | :-------------------------------------------------------- | :- | :- | :- |
194-
| [template-builtin-component-arguments](docs/rules/template-builtin-component-arguments.md) | disallow setting certain attributes on builtin components | | | |
195-
| [template-no-action-modifiers](docs/rules/template-no-action-modifiers.md) | disallow usage of {{action}} modifiers | | | |
196-
| [template-no-arguments-for-html-elements](docs/rules/template-no-arguments-for-html-elements.md) | disallow @arguments on HTML elements | | | |
197-
| [template-no-array-prototype-extensions](docs/rules/template-no-array-prototype-extensions.md) | disallow usage of Ember Array prototype extensions | | | |
198-
| [template-no-block-params-for-html-elements](docs/rules/template-no-block-params-for-html-elements.md) | disallow block params on HTML elements | | | |
199-
| [template-no-debugger](docs/rules/template-no-debugger.md) | disallow {{debugger}} in templates | | | |
200-
| [template-no-log](docs/rules/template-no-log.md) | disallow {{log}} in templates | | | |
192+
| Name                                       | Description | 💼 | 🔧 | 💡 |
193+
| :----------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------- | :- | :- | :- |
194+
| [template-builtin-component-arguments](docs/rules/template-builtin-component-arguments.md) | disallow setting certain attributes on builtin components | | | |
195+
| [template-no-action-modifiers](docs/rules/template-no-action-modifiers.md) | disallow usage of {{action}} modifiers | | | |
196+
| [template-no-arguments-for-html-elements](docs/rules/template-no-arguments-for-html-elements.md) | disallow @arguments on HTML elements | | | |
197+
| [template-no-array-prototype-extensions](docs/rules/template-no-array-prototype-extensions.md) | disallow usage of Ember Array prototype extensions | | | |
198+
| [template-no-block-params-for-html-elements](docs/rules/template-no-block-params-for-html-elements.md) | disallow block params on HTML elements | | | |
199+
| [template-no-capital-arguments](docs/rules/template-no-capital-arguments.md) | disallow capital arguments (use lowercase @arg instead of @Arg) | | | |
200+
| [template-no-debugger](docs/rules/template-no-debugger.md) | disallow {{debugger}} in templates | | | |
201+
| [template-no-log](docs/rules/template-no-log.md) | disallow {{log}} in templates | | | |
201202

202203
### Components
203204

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# ember/template-no-capital-arguments
2+
3+
<!-- end auto-generated rule header -->
4+
5+
Disallow capital letters in argument names. Use lowercase argument names (e.g., `@arg` instead of `@Arg`).
6+
7+
## Rule Details
8+
9+
This rule enforces the convention that argument names should start with lowercase letters.
10+
11+
## Examples
12+
13+
Examples of **incorrect** code for this rule:
14+
15+
```gjs
16+
<template>
17+
<div>{{@Arg}}</div>
18+
</template>
19+
```
20+
21+
```gjs
22+
<template>
23+
<div>{{@MyArgument}}</div>
24+
</template>
25+
```
26+
27+
Examples of **correct** code for this rule:
28+
29+
```gjs
30+
<template>
31+
<div>{{@arg}}</div>
32+
</template>
33+
```
34+
35+
```gjs
36+
<template>
37+
<div>{{@myArgument}}</div>
38+
</template>
39+
```
40+
41+
## References
42+
43+
- [Ember Style Guide](https://github.com/ember-cli/ember-styleguide)
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/** @type {import('eslint').Rule.RuleModule} */
2+
module.exports = {
3+
meta: {
4+
type: 'suggestion',
5+
docs: {
6+
description: 'disallow capital arguments (use lowercase @arg instead of @Arg)',
7+
category: 'Best Practices',
8+
recommended: false,
9+
url: 'https://github.com/ember-cli/eslint-plugin-ember/tree/master/docs/rules/template-no-capital-arguments.md',
10+
},
11+
fixable: null,
12+
schema: [],
13+
messages: {
14+
noCapitalArguments:
15+
'Argument names should start with lowercase. Use @{{lowercase}} instead of @{{name}}.',
16+
},
17+
strictGjs: true,
18+
strictGts: true,
19+
},
20+
21+
create(context) {
22+
function checkPath(node, path) {
23+
if (!path || !path.head) {
24+
return;
25+
}
26+
27+
const name = path.head.name || path.head;
28+
if (typeof name === 'string' && name.startsWith('@') && /^@[A-Z]/.test(name)) {
29+
const lowercase = name.charAt(0) + name.charAt(1).toLowerCase() + name.slice(2);
30+
context.report({
31+
node,
32+
messageId: 'noCapitalArguments',
33+
data: {
34+
name,
35+
lowercase,
36+
},
37+
});
38+
}
39+
}
40+
41+
return {
42+
GlimmerPathExpression(node) {
43+
checkPath(node, node);
44+
},
45+
};
46+
},
47+
};
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
const { RuleTester } = require('eslint');
2+
const rule = require('../../../lib/rules/template-no-capital-arguments');
3+
4+
const ruleTester = new RuleTester({
5+
parser: require.resolve('ember-eslint-parser'),
6+
parserOptions: { ecmaVersion: 2022, sourceType: 'module' },
7+
});
8+
9+
ruleTester.run('template-no-capital-arguments', rule, {
10+
valid: [
11+
{
12+
filename: 'my-component.gjs',
13+
code: `
14+
import Component from '@glimmer/component';
15+
export default class MyComponent extends Component {
16+
<template>
17+
<div>{{@arg}}</div>
18+
</template>
19+
}
20+
`,
21+
output: null,
22+
},
23+
{
24+
filename: 'my-component.gjs',
25+
code: `
26+
import Component from '@glimmer/component';
27+
export default class MyComponent extends Component {
28+
<template>
29+
<div>{{@myArgument}}</div>
30+
</template>
31+
}
32+
`,
33+
output: null,
34+
},
35+
],
36+
37+
invalid: [
38+
{
39+
filename: 'my-component.gjs',
40+
code: `
41+
import Component from '@glimmer/component';
42+
export default class MyComponent extends Component {
43+
<template>
44+
<div>{{@Arg}}</div>
45+
</template>
46+
}
47+
`,
48+
output: null,
49+
errors: [
50+
{
51+
messageId: 'noCapitalArguments',
52+
},
53+
],
54+
},
55+
{
56+
filename: 'my-component.gjs',
57+
code: `
58+
import Component from '@glimmer/component';
59+
export default class MyComponent extends Component {
60+
<template>
61+
<div>{{@MyArgument}}</div>
62+
</template>
63+
}
64+
`,
65+
output: null,
66+
errors: [
67+
{
68+
messageId: 'noCapitalArguments',
69+
},
70+
],
71+
},
72+
],
73+
});

0 commit comments

Comments
 (0)