Skip to content

Commit 0227c9d

Browse files
committed
test: add missing tests from coverage audit; document gaps in coverage.md
- template-no-nested-interactive: add test for ignoreUsemapAttribute alias - template-no-curly-component-invocation: add test for requireDash:true behavior - coverage.md: document all 134 template rules with status
1 parent eb5b7d1 commit 0227c9d

3 files changed

Lines changed: 218 additions & 0 deletions

File tree

coverage.md

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
# Template-lint Rule Test Coverage
2+
3+
## Methodology
4+
5+
All 134 template rules were compared against the corresponding test files in
6+
[ember-template-lint](https://github.com/ember-template-lint/ember-template-lint)
7+
to identify configuration options, edge cases, or fixer behaviors exercised
8+
there but absent from our tests.
9+
10+
Line-ratio analysis (their test-file lines / our test-file lines) was used to
11+
prioritise which rules to read in depth. The 26 rules that lacked an
12+
`originallyFrom` marker were discovered in the process and are tracked in
13+
ember-cli/eslint-plugin-ember#2704.
14+
15+
Six rules have no ember-template-lint counterpart — they are original to this
16+
plugin.
17+
18+
---
19+
20+
## Gaps addressed in this PR
21+
22+
### `template-no-nested-interactive`
23+
24+
The rule schema accepts both `ignoreUsemap` and `ignoreUsemapAttribute` as
25+
equivalent option names (the implementation ORs them together). Only
26+
`ignoreUsemap` was tested. A test for the alias was added to both the GJS and
27+
HBS rule testers.
28+
29+
### `template-no-curly-component-invocation`
30+
31+
The `requireDash` option (default `false`) exists in the rule schema and is
32+
exercised inside `checkMustacheWithNamedArgs`, but was never explicitly tested.
33+
When `requireDash: true`, single-word names with named hash arguments
34+
(e.g. `{{foo bar=baz}}`) are skipped because they cannot be confidently
35+
identified as components. A test for this case was added to the HBS rule tester.
36+
37+
---
38+
39+
## Implementation gaps (no tests added)
40+
41+
These are behaviors present in ember-template-lint that our rule implementations
42+
do not support. Tests were not added because they would fail against the current
43+
implementation.
44+
45+
### `template-no-forbidden-elements`
46+
47+
ember-template-lint allows certain forbidden elements based on file path (e.g.
48+
`<meta>` is permitted in a `head.hbs` template). Our rule has no
49+
`context.getFilename()` call and does not implement path-based exceptions. The
50+
existing element-stack exception (`<meta>` inside a `<head>` element) is a
51+
separate, unrelated heuristic.
52+
53+
### `template-no-implicit-this`
54+
55+
ember-template-lint accepts regex patterns in the `allow` array (e.g.
56+
`allow: [/^data-test-.+/]`). Our schema constrains `allow` items to
57+
`type: 'string'`, so regex entries fail schema validation.
58+
59+
### `template-no-bare-strings`
60+
61+
ember-template-lint accepts `false` as the rule config to disable it entirely.
62+
Our schema only accepts an array or an object.
63+
64+
---
65+
66+
## Coverage summary
67+
68+
| Rule | Status |
69+
|------|--------|
70+
| template-attribute-indentation | complete |
71+
| template-attribute-order | complete |
72+
| template-block-indentation | complete |
73+
| template-builtin-component-arguments | complete |
74+
| template-deprecated-inline-view-helper | complete |
75+
| template-deprecated-render-helper | complete |
76+
| template-eol-last | complete |
77+
| template-linebreak-style | complete |
78+
| template-link-href-attributes | complete |
79+
| template-link-rel-noopener | complete |
80+
| template-modifier-name-case | complete |
81+
| template-no-abstract-roles | complete |
82+
| template-no-accesskey-attribute | complete |
83+
| template-no-action | complete |
84+
| template-no-action-modifiers | complete |
85+
| template-no-action-on-submit-button | complete |
86+
| template-no-args-paths | complete |
87+
| template-no-arguments-for-html-elements | complete |
88+
| template-no-aria-hidden-body | complete |
89+
| template-no-aria-unsupported-elements | complete |
90+
| template-no-array-prototype-extensions | complete |
91+
| template-no-at-ember-render-modifiers | complete |
92+
| template-no-attrs-in-components | complete |
93+
| template-no-autofocus-attribute | complete |
94+
| template-no-bare-strings | implementation gap (`config: false`) |
95+
| template-no-bare-yield | complete |
96+
| template-no-block-params-for-html-elements | complete |
97+
| template-no-builtin-form-components | complete |
98+
| template-no-capital-arguments | complete |
99+
| template-no-chained-this | complete |
100+
| template-no-class-bindings | complete |
101+
| template-no-curly-component-invocation | gap added (`requireDash`) |
102+
| template-no-debugger | complete |
103+
| template-no-deprecated | original rule |
104+
| template-no-duplicate-attributes | complete |
105+
| template-no-duplicate-id | complete |
106+
| template-no-duplicate-landmark-elements | complete |
107+
| template-no-dynamic-subexpression-invocations | complete |
108+
| template-no-element-event-actions | complete |
109+
| template-no-empty-headings | complete |
110+
| template-no-extra-mut-helper-argument | complete |
111+
| template-no-forbidden-elements | implementation gap (filePath config) |
112+
| template-no-heading-inside-button | complete |
113+
| template-no-html-comments | complete |
114+
| template-no-implicit-this | implementation gap (regex `allow`) |
115+
| template-no-index-component-invocation | complete |
116+
| template-no-inline-event-handlers | original rule |
117+
| template-no-inline-linkto | complete |
118+
| template-no-inline-styles | complete |
119+
| template-no-input-block | complete |
120+
| template-no-input-tagname | complete |
121+
| template-no-invalid-aria-attributes | complete |
122+
| template-no-invalid-interactive | complete |
123+
| template-no-invalid-link-text | complete |
124+
| template-no-invalid-link-title | complete |
125+
| template-no-invalid-meta | complete |
126+
| template-no-invalid-role | complete |
127+
| template-no-jsx-attributes | complete |
128+
| template-no-let-reference | original rule |
129+
| template-no-link-to-positional-params | complete |
130+
| template-no-link-to-tagname | complete |
131+
| template-no-log | complete |
132+
| template-no-model-argument-in-route-templates | complete |
133+
| template-no-multiple-empty-lines | complete |
134+
| template-no-mut-helper | complete |
135+
| template-no-negated-comparison | original rule |
136+
| template-no-nested-interactive | gap added (`ignoreUsemapAttribute` alias) |
137+
| template-no-nested-landmark | complete |
138+
| template-no-nested-splattributes | complete |
139+
| template-no-obscure-array-access | complete |
140+
| template-no-obsolete-elements | complete |
141+
| template-no-only-default-slot | complete |
142+
| template-no-outlet-outside-routes | complete |
143+
| template-no-page-title-component | original rule |
144+
| template-no-passed-in-event-handlers | complete |
145+
| template-no-pointer-down-event-binding | complete |
146+
| template-no-positional-data-test-selectors | complete |
147+
| template-no-positive-tabindex | complete |
148+
| template-no-potential-path-strings | complete |
149+
| template-no-quoteless-attributes | complete |
150+
| template-no-redundant-fn | complete |
151+
| template-no-redundant-role | complete |
152+
| template-no-restricted-invocations | complete |
153+
| template-no-route-action | complete |
154+
| template-no-scope-outside-table-headings | complete |
155+
| template-no-shadowed-elements | complete |
156+
| template-no-splattributes-with-class | complete |
157+
| template-no-this-in-template-only-components | complete |
158+
| template-no-trailing-spaces | complete |
159+
| template-no-triple-curlies | complete |
160+
| template-no-unavailable-this | original rule |
161+
| template-no-unbalanced-curlies | complete |
162+
| template-no-unbound | complete |
163+
| template-no-unknown-arguments-for-builtin-components | complete |
164+
| template-no-unnecessary-component-helper | complete |
165+
| template-no-unnecessary-concat | complete |
166+
| template-no-unnecessary-curly-parens | complete |
167+
| template-no-unnecessary-curly-strings | complete |
168+
| template-no-unsupported-role-attributes | complete |
169+
| template-no-unused-block-params | complete |
170+
| template-no-valueless-arguments | complete |
171+
| template-no-whitespace-for-layout | complete |
172+
| template-no-whitespace-within-word | complete |
173+
| template-no-with | complete |
174+
| template-no-yield-block-params-to-else-inverse | complete |
175+
| template-no-yield-only | complete |
176+
| template-no-yield-to-default | complete |
177+
| template-quotes | complete |
178+
| template-require-aria-activedescendant-tabindex | complete |
179+
| template-require-button-type | complete |
180+
| template-require-context-role | complete |
181+
| template-require-each-key | complete |
182+
| template-require-form-method | complete |
183+
| template-require-has-block-helper | complete |
184+
| template-require-iframe-src-attribute | complete |
185+
| template-require-iframe-title | complete |
186+
| template-require-input-label | complete |
187+
| template-require-lang-attribute | complete |
188+
| template-require-mandatory-role-attributes | complete |
189+
| template-require-media-caption | complete |
190+
| template-require-presentational-children | complete |
191+
| template-require-splattributes | complete |
192+
| template-require-strict-mode | complete |
193+
| template-require-valid-alt-text | complete |
194+
| template-require-valid-form-groups | complete |
195+
| template-require-valid-named-block-naming-format | complete |
196+
| template-self-closing-void-elements | complete |
197+
| template-simple-modifiers | complete |
198+
| template-simple-unless | complete |
199+
| template-sort-invocations | complete |
200+
| template-splat-attributes-only | complete |
201+
| template-style-concatenation | complete |
202+
| template-table-groups | complete |
203+
| template-template-length | complete |

tests/lib/rules/template-no-curly-component-invocation.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,11 @@ hbsRuleTester.run('template-no-curly-component-invocation', rule, {
277277
code: '{{#each items as |disallowed|}}{{disallowed}}{{/each}}',
278278
options: [{ disallow: ['disallowed'], noImplicitThis: false }],
279279
},
280+
// requireDash: true — single-word names with named args are not flagged (not obviously a component)
281+
{
282+
code: '{{foo bar=baz}}',
283+
options: [{ requireDash: true }],
284+
},
280285
],
281286
invalid: [
282287
{

tests/lib/rules/template-no-nested-interactive.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,11 @@ ruleTester.run('template-no-nested-interactive', rule, {
5454
'<template><div tabindex=-1><button>Click me!</button></div></template>',
5555
'<template><div tabindex="1"><button></button></div></template>',
5656
'<template><label><input></label></template>',
57+
// Config: ignoreUsemapAttribute (alias for ignoreUsemap)
58+
{
59+
code: '<template><button><img usemap=""></button></template>',
60+
options: [{ ignoreUsemapAttribute: true }],
61+
},
5762
'<template><details><summary>Details</summary>Something small enough to escape casual notice.</details></template>',
5863
'<template><details> <summary>Details</summary>Something small enough to escape casual notice.</details></template>',
5964
`<template>
@@ -293,6 +298,11 @@ hbsRuleTester.run('template-no-nested-interactive', rule, {
293298
code: '<button><img usemap=""></button>',
294299
options: [{ ignoreUsemap: true }],
295300
},
301+
// Config: ignoreUsemapAttribute (alias for ignoreUsemap)
302+
{
303+
code: '<button><img usemap=""></button>',
304+
options: [{ ignoreUsemapAttribute: true }],
305+
},
296306
],
297307
invalid: [
298308
{

0 commit comments

Comments
 (0)