Skip to content

Commit 776ee42

Browse files
committed
Extract rule: template-splat-attributes-only
1 parent 3b5e6b9 commit 776ee42

4 files changed

Lines changed: 119 additions & 0 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,7 @@ rules in templates can be disabled with eslint directives with mustache or html
245245
| [template-no-obsolete-elements](docs/rules/template-no-obsolete-elements.md) | disallow obsolete HTML elements | | | |
246246
| [template-no-outlet-outside-routes](docs/rules/template-no-outlet-outside-routes.md) | disallow {{outlet}} outside of route templates | | | |
247247
| [template-no-page-title-component](docs/rules/template-no-page-title-component.md) | disallow usage of ember-page-title component | | | |
248+
| [template-splat-attributes-only](docs/rules/template-splat-attributes-only.md) | disallow ...spread other than ...attributes | | | |
248249
| [template-style-concatenation](docs/rules/template-style-concatenation.md) | disallow string concatenation in inline styles | | | |
249250

250251
### Components
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# ember/template-splat-attributes-only
2+
3+
<!-- end auto-generated rule header -->
4+
5+
It is easy to introduce typos when typing out `...attributes` or to use e.g.
6+
`...arguments` instead. Unfortunately, that leads to a cryptic runtime error,
7+
but does not fail the build.
8+
9+
This rule warns you when you use an attribute starting with `...` that is **not**
10+
`...attributes`.
11+
12+
## Examples
13+
14+
This rule **forbids** the following:
15+
16+
```gjs
17+
<template><div ...atributes></div></template>
18+
```
19+
20+
```gjs
21+
<template><div ...arguments></div></template>
22+
```
23+
24+
This rule **allows** the following:
25+
26+
```gjs
27+
<template><div ...attributes></div></template>
28+
```
29+
30+
## References
31+
32+
- [Ember 3.11 release](https://blog.emberjs.com/2019/07/15/ember-3-11-released.html)
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/** @type {import('eslint').Rule.RuleModule} */
2+
module.exports = {
3+
meta: {
4+
type: 'problem',
5+
docs: {
6+
description: 'disallow ...spread other than ...attributes',
7+
category: 'Best Practices',
8+
url: 'https://github.com/ember-cli/eslint-plugin-ember/tree/master/docs/rules/template-splat-attributes-only.md',
9+
templateMode: 'both',
10+
},
11+
schema: [],
12+
messages: {
13+
onlyAttributes: 'Only `...attributes` can be applied to elements',
14+
},
15+
originallyFrom: {
16+
name: 'ember-template-lint',
17+
rule: 'lib/rules/splat-attributes-only.js',
18+
docs: 'docs/rule/splat-attributes-only.md',
19+
tests: 'test/unit/rules/splat-attributes-only-test.js',
20+
},
21+
},
22+
create(context) {
23+
return {
24+
GlimmerAttrNode(node) {
25+
if (node.name?.startsWith('...') && node.name !== '...attributes') {
26+
context.report({ node, messageId: 'onlyAttributes' });
27+
}
28+
},
29+
};
30+
},
31+
};
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
const rule = require('../../../lib/rules/template-splat-attributes-only');
2+
const RuleTester = require('eslint').RuleTester;
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-splat-attributes-only', rule, {
10+
valid: [
11+
'<template><div ...attributes></div></template>',
12+
'<template><MyComponent ...attributes /></template>',
13+
14+
'<template><div attributes></div></template>',
15+
'<template><div arguments></div></template>',
16+
'<template><div><div ...attributes></div></div></template>',
17+
],
18+
invalid: [
19+
{
20+
code: '<template><div ...props></div></template>',
21+
output: null,
22+
errors: [{ messageId: 'onlyAttributes' }],
23+
},
24+
25+
{
26+
code: '<template><div ...arguments></div></template>',
27+
output: null,
28+
errors: [{ messageId: 'onlyAttributes' }],
29+
},
30+
],
31+
});
32+
33+
const hbsRuleTester = new RuleTester({
34+
parser: require.resolve('ember-eslint-parser/hbs'),
35+
parserOptions: {
36+
ecmaVersion: 2022,
37+
sourceType: 'module',
38+
},
39+
});
40+
41+
hbsRuleTester.run('template-splat-attributes-only', rule, {
42+
valid: [
43+
'<div ...attributes></div>',
44+
'<div attributes></div>',
45+
'<div arguments></div>',
46+
'<div><div ...attributes></div></div>',
47+
],
48+
invalid: [
49+
{
50+
code: '<div ...arguments></div>',
51+
output: null,
52+
errors: [{ message: 'Only `...attributes` can be applied to elements' }],
53+
},
54+
],
55+
});

0 commit comments

Comments
 (0)