forked from ember-cli/eslint-plugin-ember
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtemplate-no-action.js
More file actions
157 lines (147 loc) · 5.11 KB
/
template-no-action.js
File metadata and controls
157 lines (147 loc) · 5.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
const rule = require('../../../lib/rules/template-no-action');
const RuleTester = require('eslint').RuleTester;
//------------------------------------------------------------------------------
// Tests
//------------------------------------------------------------------------------
const ruleTester = new RuleTester({
parser: require.resolve('ember-eslint-parser'),
parserOptions: { ecmaVersion: 2022, sourceType: 'module' },
});
ruleTester.run('template-no-action', rule, {
valid: [
`<template>
<button {{on "click" this.handleClick}}>Click</button>
</template>`,
`<template>
<button {{on "click" (fn this.save "arg")}}>Save</button>
</template>`,
`<template>
{{this.action}}
</template>`,
`<template>
{{@action}}
</template>`,
// GJS/GTS: a JS-scope binding shadows the ambient `action` keyword. The
// user has imported (or declared) their own `action`, so flagging would
// corrupt their reference.
{
filename: 'test.gjs',
code: "import action from './my-action';\n<template>{{action this.handleClick}}</template>",
},
{
filename: 'test.gjs',
code: "import action from './my-action';\n<template>{{(action this.handleClick)}}</template>",
},
{
filename: 'test.gjs',
code: "import action from './my-action';\n<template><button {{action this.handleClick}}>x</button></template>",
},
{
filename: 'test.gts',
code: "import action from './my-action';\n<template>{{action this.handleClick}}</template>",
},
{
filename: 'test.gjs',
code: 'const action = (h) => () => h();\n<template>{{action this.handleClick}}</template>',
},
// Template block-param shadowing — `action` is the iterator/let-bound
// value, not the ambient keyword.
'<template>{{#each items as |action|}}{{action this.x}}{{/each}}</template>',
'<template>{{#let (component "x") as |action|}}{{action this.x}}{{/let}}</template>',
'<template>{{#each items as |action|}}<button {{action this.x}}>x</button>{{/each}}</template>',
'<template><Foo as |action|>{{action this.x}}</Foo></template>',
],
invalid: [
{
code: `<template>
<button {{on "click" (action "save")}}>Save</button>
</template>`,
output: null,
errors: [
{
message:
'Do not use `action` as (action ...) — deprecated in Ember 5.9, removed in 6.0. Use the `fn` helper instead.',
type: 'GlimmerSubExpression',
},
],
},
{
code: `<template>
{{action "doSomething"}}
</template>`,
output: null,
errors: [
{
message:
'Do not use `action` in templates — deprecated in Ember 5.9, removed in 6.0. Use the `on` modifier and `fn` helper instead.',
type: 'GlimmerMustacheStatement',
},
],
},
{
code: `<template>
<button {{action "submit"}}>Submit</button>
</template>`,
output: null,
errors: [
{
message:
'Do not use `action` as an element modifier — deprecated in Ember 5.9, removed in 6.0. Use the `on` modifier instead.',
type: 'GlimmerElementModifierStatement',
},
],
},
{
code: `<template>
<input onclick={{action "foo"}}>
</template>`,
output: null,
errors: [
{
message:
'Do not use `action` in templates — deprecated in Ember 5.9, removed in 6.0. Use the `on` modifier and `fn` helper instead.',
type: 'GlimmerMustacheStatement',
},
],
},
// GJS/GTS: ambient `action` keyword usage with no shadowing import or
// block param. Still flagged.
{
filename: 'test.gjs',
code: '<template>{{action "save"}}</template>',
output: null,
errors: [{ messageId: 'mustache', type: 'GlimmerMustacheStatement' }],
},
{
filename: 'test.gjs',
code: '<template><button {{on "click" (action "save")}}>x</button></template>',
output: null,
errors: [{ messageId: 'subExpression', type: 'GlimmerSubExpression' }],
},
{
filename: 'test.gts',
code: '<template><button {{action "submit"}}>x</button></template>',
output: null,
errors: [{ messageId: 'modifier', type: 'GlimmerElementModifierStatement' }],
},
// Unrelated JS bindings do NOT mask the rule. Only a binding named
// `action` should be respected.
{
filename: 'test.gjs',
code: "import handler from './handler';\n<template>{{action this.x}}</template>",
output: null,
errors: [{ messageId: 'mustache' }],
},
// Ambient `action` outside a block-param scope is still flagged, even
// when an inner block legitimately shadows it.
{
filename: 'test.gjs',
code: '<template>{{#each items as |action|}}{{action this.x}}{{/each}}{{action this.y}}</template>',
output: null,
errors: [{ messageId: 'mustache' }],
},
],
});