Extract rule: template-require-valid-alt-text#2614
Conversation
NullVoxPopuli-ai-agent
left a comment
There was a problem hiding this comment.
Review: template-require-valid-alt-text (PR #2614)
Comparison with ember-template-lint source
General correctness:
-
Error message differences (minor): Several messages have slightly different punctuation:
- ETL:
"All <img> tags must have an alt attribute"→ ESLint: adds period at end - ETL:
"The alt text must not be the same as the image source"→ ESLint: adds period - ETL:
"A number is not valid alt text"→ ESLint: adds period - ETL:
"The alt attribute should be empty if <img> has role of none or presentation"→ ESLint: wraps in backticks and quotes differently
These are cosmetic but will cause test failures if anyone is matching exact messages from the original.
- ETL:
-
imgRedundantreported onaltAttrnode, notnode: In the ESLint version, the redundant words error reports onaltAttr(the attribute node) instead ofnode(the element node). The original ETL always reports on the elementnode. This is actually a nice improvement for editor UX (highlights just the attribute), but it's a behavioral difference. -
img role=presentation check order: The ESLint version checks
altAttr && roleAttrfirst, then checks!altAttr. The original checks role+alt validation AFTER the main alt presence check. But in the ESLint version, if bothaltAttrandroleAttrexist and it's role=presentation with non-empty alt, it reportsimgRolePresentationbut does NOT return — it continues to also check for redundant words, numeric alt, etc. The original also does this (the role check is before theif (!hasAltAttribute)check and doesn't return). So both can report multiple errors for the same element, which matches. -
hasAccessibleChildfor<object>: The original ETL usesAstNodeInfo.hasChildren(node)which likely checks for any child nodes (including text nodes with content). The ESLint version'shasChildren()function filters text nodes bychars.trim().length > 0, which is equivalent. -
Missing
<object>title attribute behavior: The original checksroleValuedirectly against['presentation', 'none']— androleValuecould be a MustacheStatement node object if dynamic, in which caseincludes()would return false. The ESLint version usesgetTextValue(roleAttr)which returnsundefinedfor non-TextNode types, and'presentation' || 'none'].includes(undefined)is false. This matches.
Scope analysis (gjs/gts):
Not applicable. This rule only checks HTML element tags (img, input, object, area) and their attributes. No helper/component name resolution is involved.
Tests: Comprehensive test coverage matching the original ETL test cases. Both gjs and hbs modes tested. Good.
Summary: Solid migration with good fidelity to the original. Minor message punctuation differences. No blocking issues.
🤖 Automated review comparing with ember-template-lint source
3512c6f to
c34ec5d
Compare
Split from #2371.