Skip to content

Commit aa9e027

Browse files
committed
Add HBS rule tests for various accessibility and template linting rules
1 parent 177e7d0 commit aa9e027

8 files changed

Lines changed: 429 additions & 0 deletions

tests/lib/rules/template-no-accesskey-attribute.js

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,3 +98,54 @@ ruleTester.run('template-no-accesskey-attribute', rule, {
9898
},
9999
],
100100
});
101+
102+
const hbsRuleTester = new RuleTester({
103+
parser: require.resolve('ember-eslint-parser/hbs'),
104+
parserOptions: { ecmaVersion: 2022, sourceType: 'module' },
105+
});
106+
107+
hbsRuleTester.run('template-no-accesskey-attribute (hbs)', rule, {
108+
valid: ['<div></div>'],
109+
invalid: [
110+
{
111+
code: '<button accesskey="n"></button>',
112+
output: '<button></button>',
113+
errors: [
114+
{
115+
message:
116+
'No access key attribute allowed. Inconsistencies between keyboard shortcuts and keyboard commands used by screenreader and keyboard only users create accessibility complications.',
117+
},
118+
],
119+
},
120+
{
121+
code: '<button accesskey></button>',
122+
output: '<button></button>',
123+
errors: [
124+
{
125+
message:
126+
'No access key attribute allowed. Inconsistencies between keyboard shortcuts and keyboard commands used by screenreader and keyboard only users create accessibility complications.',
127+
},
128+
],
129+
},
130+
{
131+
code: '<button accesskey={{some-key}}></button>',
132+
output: '<button></button>',
133+
errors: [
134+
{
135+
message:
136+
'No access key attribute allowed. Inconsistencies between keyboard shortcuts and keyboard commands used by screenreader and keyboard only users create accessibility complications.',
137+
},
138+
],
139+
},
140+
{
141+
code: '<button accesskey="{{some-key}}"></button>',
142+
output: '<button></button>',
143+
errors: [
144+
{
145+
message:
146+
'No access key attribute allowed. Inconsistencies between keyboard shortcuts and keyboard commands used by screenreader and keyboard only users create accessibility complications.',
147+
},
148+
],
149+
},
150+
],
151+
});

tests/lib/rules/template-no-aria-hidden-body.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,28 @@ ruleTester.run('template-no-aria-hidden-body', rule, {
2626
},
2727
],
2828
});
29+
30+
const hbsRuleTester = new RuleTester({
31+
parser: require.resolve('ember-eslint-parser/hbs'),
32+
parserOptions: { ecmaVersion: 2022, sourceType: 'module' },
33+
});
34+
35+
hbsRuleTester.run('template-no-aria-hidden-body (hbs)', rule, {
36+
valid: [
37+
'<body></body>',
38+
'<body><h1>Hello world</h1></body>',
39+
'<body><p aria-hidden="true">Some things are better left unsaid</p></body>',
40+
],
41+
invalid: [
42+
{
43+
code: '<body aria-hidden="true"></body>',
44+
output: '<body></body>',
45+
errors: [{ messageId: 'noAriaHiddenBody' }],
46+
},
47+
{
48+
code: '<body aria-hidden></body>',
49+
output: '<body></body>',
50+
errors: [{ messageId: 'noAriaHiddenBody' }],
51+
},
52+
],
53+
});

tests/lib/rules/template-no-debugger.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,3 +82,24 @@ ruleTester.run('template-no-debugger', rule, {
8282
},
8383
],
8484
});
85+
86+
const hbsRuleTester = new RuleTester({
87+
parser: require.resolve('ember-eslint-parser/hbs'),
88+
parserOptions: { ecmaVersion: 2022, sourceType: 'module' },
89+
});
90+
91+
hbsRuleTester.run('template-no-debugger (hbs)', rule, {
92+
valid: ['{{foo}}', '{{button}}'],
93+
invalid: [
94+
{
95+
code: '{{debugger}}',
96+
output: null,
97+
errors: [{ message: 'Unexpected debugger statement in template.' }],
98+
},
99+
{
100+
code: '{{#debugger}}Invalid!{{/debugger}}',
101+
output: null,
102+
errors: [{ message: 'Unexpected debugger statement in template.' }],
103+
},
104+
],
105+
});

tests/lib/rules/template-no-empty-headings.js

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,3 +129,121 @@ ruleTester.run('template-no-empty-headings', rule, {
129129
},
130130
],
131131
});
132+
133+
const hbsRuleTester = new RuleTester({
134+
parser: require.resolve('ember-eslint-parser/hbs'),
135+
parserOptions: { ecmaVersion: 2022, sourceType: 'module' },
136+
});
137+
138+
hbsRuleTester.run('template-no-empty-headings (hbs)', rule, {
139+
valid: [
140+
'<h1>Accessible Heading</h1>',
141+
'<h1>Accessible&nbsp;Heading</h1>',
142+
'<h1 aria-hidden="true">Valid Heading</h1>',
143+
'<h1 aria-hidden="true"><span>Valid Heading</span></h1>',
144+
'<h1 aria-hidden="false">Accessible Heading</h1>',
145+
'<h1 hidden>Valid Heading</h1>',
146+
'<h1 hidden><span>Valid Heading</span></h1>',
147+
'<h1><span aria-hidden="true">Hidden text</span><span>Visible text</span></h1>',
148+
'<h1><span aria-hidden="true">Hidden text</span>Visible text</h1>',
149+
'<div role="heading" aria-level="1">Accessible Text</div>',
150+
'<div role="heading" aria-level="1"><span>Accessible Text</span></div>',
151+
'<div role="heading" aria-level="1"><span aria-hidden="true">Hidden text</span><span>Visible text</span></div>',
152+
'<div role="heading" aria-level="1"><span aria-hidden="true">Hidden text</span>Visible text</div>',
153+
'<div></div>',
154+
'<p></p>',
155+
'<span></span>',
156+
'<header></header>',
157+
'<h2><CustomComponent /></h2>',
158+
'<h2>{{@title}}</h2>',
159+
'<h2>{{#component}}{{/component}}</h2>',
160+
'<h2><span>{{@title}}</span></h2>',
161+
'<h2><div><CustomComponent /></div></h2>',
162+
'<h2><div></div><CustomComponent /></h2>',
163+
'<h2><div><span>{{@title}}</span></div></h2>',
164+
'<h2><span>Some text{{@title}}</span></h2>',
165+
'<h2><span><div></div>{{@title}}</span></h2>',
166+
],
167+
invalid: [
168+
{
169+
code: '<h1></h1>',
170+
output: null,
171+
errors: [{ messageId: 'emptyHeading' }],
172+
},
173+
{
174+
code: '<h1> \n &nbsp;</h1>',
175+
output: null,
176+
errors: [{ messageId: 'emptyHeading' }],
177+
},
178+
{
179+
code: '<h1><span></span></h1>',
180+
output: null,
181+
errors: [{ messageId: 'emptyHeading' }],
182+
},
183+
{
184+
code: '<h1><span> \n &nbsp;</span></h1>',
185+
output: null,
186+
errors: [{ messageId: 'emptyHeading' }],
187+
},
188+
{
189+
code: '<h1><div><span></span></div></h1>',
190+
output: null,
191+
errors: [{ messageId: 'emptyHeading' }],
192+
},
193+
{
194+
code: '<h1><span></span><span></span></h1>',
195+
output: null,
196+
errors: [{ messageId: 'emptyHeading' }],
197+
},
198+
{
199+
code: '<h1> &nbsp; <div aria-hidden="true">Some hidden text</div></h1>',
200+
output: null,
201+
errors: [{ messageId: 'emptyHeading' }],
202+
},
203+
{
204+
code: '<h1><span aria-hidden="true">Inaccessible text</span></h1>',
205+
output: null,
206+
errors: [{ messageId: 'emptyHeading' }],
207+
},
208+
{
209+
code: '<h1><span hidden>Inaccessible text</span></h1>',
210+
output: null,
211+
errors: [{ messageId: 'emptyHeading' }],
212+
},
213+
{
214+
code: '<h1><span hidden>{{@title}}</span></h1>',
215+
output: null,
216+
errors: [{ messageId: 'emptyHeading' }],
217+
},
218+
{
219+
code: '<h1><span hidden>{{#component}}Inaccessible text{{/component}}</span></h1>',
220+
output: null,
221+
errors: [{ messageId: 'emptyHeading' }],
222+
},
223+
{
224+
code: '<h1><span hidden><CustomComponent>Inaccessible text</CustomComponent></span></h1>',
225+
output: null,
226+
errors: [{ messageId: 'emptyHeading' }],
227+
},
228+
{
229+
code: '<h1><span aria-hidden="true">Hidden text</span><span aria-hidden="true">Hidden text</span></h1>',
230+
output: null,
231+
errors: [{ messageId: 'emptyHeading' }],
232+
},
233+
{
234+
code: '<div role="heading" aria-level="1"></div>',
235+
output: null,
236+
errors: [{ messageId: 'emptyHeading' }],
237+
},
238+
{
239+
code: '<div role="heading" aria-level="1"><span aria-hidden="true">Inaccessible text</span></div>',
240+
output: null,
241+
errors: [{ messageId: 'emptyHeading' }],
242+
},
243+
{
244+
code: '<div role="heading" aria-level="1"><span hidden>Inaccessible text</span></div>',
245+
output: null,
246+
errors: [{ messageId: 'emptyHeading' }],
247+
},
248+
],
249+
});

tests/lib/rules/template-no-log.js

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,3 +117,57 @@ ruleTester.run('template-no-log', rule, {
117117
},
118118
],
119119
});
120+
121+
const hbsRuleTester = new RuleTester({
122+
parser: require.resolve('ember-eslint-parser/hbs'),
123+
parserOptions: { ecmaVersion: 2022, sourceType: 'module' },
124+
});
125+
126+
hbsRuleTester.run('template-no-log (hbs)', rule, {
127+
valid: [
128+
'{{foo}}',
129+
'{{button}}',
130+
'{{#each this.logs as |log|}}{{log}}{{/each}}',
131+
'{{#let this.log as |log|}}{{log}}{{/let}}',
132+
'{{#let (component "my-log-component") as |log|}}{{#log}}message{{/log}}{{/let}}',
133+
'<Logs @logs={{this.logs}} as |log|>{{log}}</Logs>',
134+
'<Logs @logs={{this.logs}} as |log|><Log>{{log}}</Log></Logs>',
135+
],
136+
invalid: [
137+
{
138+
code: '{{log}}',
139+
output: null,
140+
errors: [{ message: 'Unexpected log statement in template.' }],
141+
},
142+
{
143+
code: '{{log "Logs are best for debugging!"}}',
144+
output: null,
145+
errors: [{ message: 'Unexpected log statement in template.' }],
146+
},
147+
{
148+
code: '{{#log}}Arrgh!{{/log}}',
149+
output: null,
150+
errors: [{ message: 'Unexpected log statement in template.' }],
151+
},
152+
{
153+
code: '{{#log "Foo"}}{{/log}}',
154+
output: null,
155+
errors: [{ message: 'Unexpected log statement in template.' }],
156+
},
157+
{
158+
code: '{{#each this.messages as |message|}}{{log message}}{{/each}}',
159+
output: null,
160+
errors: [{ message: 'Unexpected log statement in template.' }],
161+
},
162+
{
163+
code: '{{#let this.message as |message|}}{{log message}}{{/let}}',
164+
output: null,
165+
errors: [{ message: 'Unexpected log statement in template.' }],
166+
},
167+
{
168+
code: '<Messages @messages={{this.messages}} as |message|>{{#log}}{{message}}{{/log}}</Messages>',
169+
output: null,
170+
errors: [{ message: 'Unexpected log statement in template.' }],
171+
},
172+
],
173+
});

tests/lib/rules/template-no-positive-tabindex.js

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,3 +143,87 @@ ruleTester.run('template-no-positive-tabindex', rule, {
143143
},
144144
],
145145
});
146+
147+
const hbsRuleTester = new RuleTester({
148+
parser: require.resolve('ember-eslint-parser/hbs'),
149+
parserOptions: { ecmaVersion: 2022, sourceType: 'module' },
150+
});
151+
152+
hbsRuleTester.run('template-no-positive-tabindex (hbs)', rule, {
153+
valid: [
154+
'<button tabindex="0"></button>',
155+
'<button tabindex="-1"></button>',
156+
'<button tabindex={{-1}}>baz</button>',
157+
'<button tabindex={{"-1"}}>baz</button>',
158+
'<button tabindex="{{-1}}">baz</button>',
159+
'<button tabindex="{{"-1"}}">baz</button>',
160+
'<button tabindex="{{if this.show -1}}">baz</button>',
161+
'<button tabindex="{{if this.show "-1" "0"}}">baz</button>',
162+
'<button tabindex="{{if (not this.show) "-1" "0"}}">baz</button>',
163+
'<button tabindex={{if this.show -1}}>baz</button>',
164+
'<button tabindex={{if this.show "-1" "0"}}>baz</button>',
165+
'<button tabindex={{if (not this.show) "-1" "0"}}>baz</button>',
166+
],
167+
invalid: [
168+
{
169+
code: '<button tabindex={{someProperty}}></button>',
170+
output: null,
171+
errors: [{ message: 'Avoid positive integer values for tabindex.' }],
172+
},
173+
{
174+
code: '<button tabindex="1"></button>',
175+
output: null,
176+
errors: [{ message: 'Avoid positive integer values for tabindex.' }],
177+
},
178+
{
179+
code: '<button tabindex="text"></button>',
180+
output: null,
181+
errors: [{ message: 'Avoid positive integer values for tabindex.' }],
182+
},
183+
{
184+
code: '<button tabindex={{true}}></button>',
185+
output: null,
186+
errors: [{ message: 'Avoid positive integer values for tabindex.' }],
187+
},
188+
{
189+
code: '<button tabindex="{{false}}"></button>',
190+
output: null,
191+
errors: [{ message: 'Avoid positive integer values for tabindex.' }],
192+
},
193+
{
194+
code: '<button tabindex="{{5}}"></button>',
195+
output: null,
196+
errors: [{ message: 'Avoid positive integer values for tabindex.' }],
197+
},
198+
{
199+
code: '<button tabindex="{{if a 1 -1}}"></button>',
200+
output: null,
201+
errors: [{ message: 'Avoid positive integer values for tabindex.' }],
202+
},
203+
{
204+
code: '<button tabindex="{{if a -1 1}}"></button>',
205+
output: null,
206+
errors: [{ message: 'Avoid positive integer values for tabindex.' }],
207+
},
208+
{
209+
code: '<button tabindex="{{if a 1}}"></button>',
210+
output: null,
211+
errors: [{ message: 'Avoid positive integer values for tabindex.' }],
212+
},
213+
{
214+
code: '<button tabindex="{{if (not a) 1}}"></button>',
215+
output: null,
216+
errors: [{ message: 'Avoid positive integer values for tabindex.' }],
217+
},
218+
{
219+
code: '<button tabindex="{{unless a 1}}"></button>',
220+
output: null,
221+
errors: [{ message: 'Avoid positive integer values for tabindex.' }],
222+
},
223+
{
224+
code: '<button tabindex="{{unless a -1 1}}"></button>',
225+
output: null,
226+
errors: [{ message: 'Avoid positive integer values for tabindex.' }],
227+
},
228+
],
229+
});

0 commit comments

Comments
 (0)