Skip to content
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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@ rules in templates can be disabled with eslint directives with mustache or html
| [template-no-obsolete-elements](docs/rules/template-no-obsolete-elements.md) | disallow obsolete HTML elements | | | |
| [template-no-outlet-outside-routes](docs/rules/template-no-outlet-outside-routes.md) | disallow {{outlet}} outside of route templates | | | |
| [template-no-page-title-component](docs/rules/template-no-page-title-component.md) | disallow usage of ember-page-title component | | | |
| [template-splat-attributes-only](docs/rules/template-splat-attributes-only.md) | disallow ...spread other than ...attributes | | | |
| [template-style-concatenation](docs/rules/template-style-concatenation.md) | disallow string concatenation in inline styles | | | |

### Components
Expand Down
32 changes: 32 additions & 0 deletions docs/rules/template-splat-attributes-only.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# ember/template-splat-attributes-only

<!-- end auto-generated rule header -->

It is easy to introduce typos when typing out `...attributes` or to use e.g.
`...arguments` instead. Unfortunately, that leads to a cryptic runtime error,
but does not fail the build.

This rule warns you when you use an attribute starting with `...` that is **not**
`...attributes`.

## Examples

This rule **forbids** the following:

```gjs
<template><div ...atributes></div></template>
```

```gjs
<template><div ...arguments></div></template>
```

This rule **allows** the following:

```gjs
<template><div ...attributes></div></template>
```

## References

- [Ember 3.11 release](https://blog.emberjs.com/2019/07/15/ember-3-11-released.html)
31 changes: 31 additions & 0 deletions lib/rules/template-splat-attributes-only.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/** @type {import('eslint').Rule.RuleModule} */
module.exports = {
meta: {
type: 'problem',
docs: {
description: 'disallow ...spread other than ...attributes',
category: 'Best Practices',
url: 'https://github.com/ember-cli/eslint-plugin-ember/tree/master/docs/rules/template-splat-attributes-only.md',
templateMode: 'both',
},
schema: [],
messages: {
onlyAttributes: 'Only `...attributes` can be applied to elements',
},
originallyFrom: {
name: 'ember-template-lint',
rule: 'lib/rules/splat-attributes-only.js',
docs: 'docs/rule/splat-attributes-only.md',
tests: 'test/unit/rules/splat-attributes-only-test.js',
},
},
create(context) {
return {
GlimmerAttrNode(node) {
if (node.name?.startsWith('...') && node.name !== '...attributes') {
context.report({ node, messageId: 'onlyAttributes' });
}
},
};
},
};
55 changes: 55 additions & 0 deletions tests/lib/rules/template-splat-attributes-only.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
const rule = require('../../../lib/rules/template-splat-attributes-only');
const RuleTester = require('eslint').RuleTester;

const ruleTester = new RuleTester({
parser: require.resolve('ember-eslint-parser'),
parserOptions: { ecmaVersion: 2022, sourceType: 'module' },
});

ruleTester.run('template-splat-attributes-only', rule, {
valid: [
'<template><div ...attributes></div></template>',
'<template><MyComponent ...attributes /></template>',

'<template><div attributes></div></template>',
'<template><div arguments></div></template>',
'<template><div><div ...attributes></div></div></template>',
],
invalid: [
{
code: '<template><div ...props></div></template>',
output: null,
errors: [{ messageId: 'onlyAttributes' }],
},

{
code: '<template><div ...arguments></div></template>',
output: null,
errors: [{ messageId: 'onlyAttributes' }],
},
],
});

const hbsRuleTester = new RuleTester({
parser: require.resolve('ember-eslint-parser/hbs'),
parserOptions: {
ecmaVersion: 2022,
sourceType: 'module',
},
});

hbsRuleTester.run('template-splat-attributes-only', rule, {
valid: [
'<div ...attributes></div>',
'<div attributes></div>',
'<div arguments></div>',
'<div><div ...attributes></div></div>',
],
invalid: [
{
code: '<div ...arguments></div>',
output: null,
errors: [{ message: 'Only `...attributes` can be applied to elements' }],
},
],
});
Loading