Skip to content

Commit 8bce8c7

Browse files
committed
Fix template-no-attrs-in-components: align detection with upstream
The port flagged this.attrs.* (which is not a real Ember API) and ran on all templates. Upstream gates on file path (templates/components/, components/*/template, ui/components/, -components/) and flags bare attrs.* — the pre-Octane args-leakage pattern. Restore upstream's behavior.
1 parent 56f913d commit 8bce8c7

2 files changed

Lines changed: 94 additions & 29 deletions

File tree

lib/rules/template-no-attrs-in-components.js

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,42 @@
1+
const COMPONENT_TEMPLATE_REGEX = new RegExp(
2+
'templates/components|components/.*/template|ui/components|-components/'
3+
);
4+
15
/** @type {import('eslint').Rule.RuleModule} */
26
module.exports = {
37
meta: {
48
type: 'suggestion',
59
docs: {
610
description: 'disallow attrs in component templates',
711
category: 'Deprecations',
8-
912
url: 'https://github.com/ember-cli/eslint-plugin-ember/tree/master/docs/rules/template-no-attrs-in-components.md',
13+
templateMode: 'loose',
1014
},
1115
schema: [],
1216
messages: {
13-
noThisAttrs:
14-
'Component templates should not contain `this.attrs`. Use `@arg` syntax instead.',
17+
noAttrs: 'Component templates should not contain `attrs`.',
18+
},
19+
originallyFrom: {
20+
name: 'ember-template-lint',
21+
rule: 'lib/rules/no-attrs-in-components.js',
22+
docs: 'docs/rule/no-attrs-in-components.md',
23+
tests: 'test/unit/rules/no-attrs-in-components-test.js',
1524
},
1625
},
1726
create(context) {
27+
if (!COMPONENT_TEMPLATE_REGEX.test(context.filename)) {
28+
return {};
29+
}
1830
return {
1931
GlimmerPathExpression(node) {
20-
if (node.original?.startsWith('this.attrs.') || node.original === 'this.attrs') {
21-
context.report({ node, messageId: 'noThisAttrs' });
32+
const original = node.original;
33+
if (typeof original !== 'string') {
34+
return;
35+
}
36+
// Flag bare `attrs` or `attrs.<something>` (pre-Octane args-leakage).
37+
// Do NOT flag `this.attrs.*` — that is a different (non-existent) API.
38+
if (original === 'attrs' || original.startsWith('attrs.')) {
39+
context.report({ node, messageId: 'noAttrs' });
2240
}
2341
},
2442
};

tests/lib/rules/template-no-attrs-in-components.js

Lines changed: 71 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,40 +8,87 @@ const ruleTester = new RuleTester({
88

99
ruleTester.run('template-no-attrs-in-components', rule, {
1010
valid: [
11-
'<template>{{@value}}</template>',
12-
'<template>{{this.value}}</template>',
13-
// Class component with normal this access
14-
`import Component from '@glimmer/component';
15-
class MyComponent extends Component {
16-
<template>{{this.args.name}}</template>
17-
}`,
18-
// Bare attrs is not accessible without this, so it's allowed
19-
'<template>{{attrs.value}}</template>',
20-
'<template>{{attrs}}</template>',
21-
`import Component from '@glimmer/component';
22-
class MyComponent extends Component {
23-
<template>{{attrs.name}}</template>
24-
}`,
11+
// Not a component template path: nothing is flagged, regardless of content.
12+
{
13+
code: '<template>{{@value}}</template>',
14+
filename: 'app/templates/application.hbs',
15+
},
16+
{
17+
code: '<template>{{this.value}}</template>',
18+
filename: 'app/templates/application.hbs',
19+
},
20+
// `this.attrs.*` is not a real Ember API, but it is NOT what this rule
21+
// targets — upstream only flags bare `attrs.*`. So outside of a component
22+
// template, `this.attrs.*` should not be flagged.
23+
{
24+
code: '<template>{{this.attrs.foo}}</template>',
25+
filename: 'app/templates/application.hbs',
26+
},
27+
// Even `attrs.*` itself is only flagged inside component templates.
28+
{
29+
code: '<template>{{attrs.value}}</template>',
30+
filename: 'app/templates/application.hbs',
31+
},
32+
// Inside a component template, non-attrs paths are fine.
33+
{
34+
code: '<template>{{@value}}</template>',
35+
filename: 'app/templates/components/foo.hbs',
36+
},
37+
{
38+
code: '<template>{{this.value}}</template>',
39+
filename: 'app/templates/components/foo.hbs',
40+
},
41+
// Upstream does NOT flag `this.attrs.*`; only bare `attrs.*`.
42+
{
43+
code: '<template>{{this.attrs.foo}}</template>',
44+
filename: 'app/templates/components/foo.hbs',
45+
},
46+
// Pod-style components path matches the gate, but no `attrs` usage.
47+
{
48+
code: '<template>{{@value}}</template>',
49+
filename: 'app/components/foo/template.hbs',
50+
},
51+
// `-components/` path gate, no `attrs` usage.
52+
{
53+
code: '<template>{{@value}}</template>',
54+
filename: 'app/ui-components/foo.hbs',
55+
},
2556
],
2657
invalid: [
58+
// Bare `attrs.*` inside `templates/components/` — flagged.
59+
{
60+
code: '<template>{{attrs.foo}}</template>',
61+
filename: 'app/templates/components/foo.hbs',
62+
output: null,
63+
errors: [{ messageId: 'noAttrs' }],
64+
},
65+
// Bare `attrs` (no dotted tail) inside `templates/components/` — flagged.
66+
{
67+
code: '<template>{{attrs}}</template>',
68+
filename: 'app/templates/components/foo.hbs',
69+
output: null,
70+
errors: [{ messageId: 'noAttrs' }],
71+
},
72+
// Pod-style path `components/*/template` — flagged.
2773
{
28-
code: '<template>{{this.attrs.value}}</template>',
74+
code: '<template>{{attrs.name}}</template>',
75+
filename: 'app/components/foo/template.hbs',
2976
output: null,
30-
errors: [{ messageId: 'noThisAttrs' }],
77+
errors: [{ messageId: 'noAttrs' }],
3178
},
79+
// `ui/components` path — flagged.
3280
{
33-
code: '<template>{{this.attrs}}</template>',
81+
code: '<template>{{attrs.name}}</template>',
82+
filename: 'app/ui/components/foo.hbs',
3483
output: null,
35-
errors: [{ messageId: 'noThisAttrs' }],
84+
errors: [{ messageId: 'noAttrs' }],
3685
},
37-
// Class component using this.attrs
86+
// `-components/` path — flagged.
3887
{
39-
code: `import Component from '@glimmer/component';
40-
class MyComponent extends Component {
41-
<template>{{this.attrs.name}}</template>
42-
}`,
88+
code: '<template>{{attrs.name}}</template>',
89+
filename: 'app/ui-components/foo.hbs',
4390
output: null,
44-
errors: [{ messageId: 'noThisAttrs' }],
91+
errors: [{ messageId: 'noAttrs' }],
4592
},
4693
],
4794
});

0 commit comments

Comments
 (0)