Skip to content
This repository has been archived by the owner on Aug 31, 2023. It is now read-only.

refactor(rome_js_analyze): update error messages for UseAltText diagnostics #4440

Merged
merged 3 commits into from
May 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 34 additions & 13 deletions crates/rome_js_analyze/src/analyzers/a11y/use_alt_text.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use rome_analyze::{context::RuleContext, declare_rule, Ast, Rule, RuleDiagnostic};
use rome_console::markup;
use rome_console::{fmt::Display, fmt::Formatter, markup};
use rome_js_syntax::{jsx_ext::AnyJsxElement, TextRange};
use rome_rowan::AstNode;

Expand Down Expand Up @@ -50,9 +50,25 @@ declare_rule! {
}
}

pub enum ValidatedElement {
Object,
Img,
Area,
Input,
}

impl Display for ValidatedElement {
fn fmt(&self, fmt: &mut Formatter) -> std::io::Result<()> {
match self {
ValidatedElement::Object => fmt.write_markup(markup!(<Emphasis>"title"</Emphasis>)),
_ => fmt.write_markup(markup!(<Emphasis>"alt"</Emphasis>)),
}
}
}

impl Rule for UseAltText {
type Query = Ast<AnyJsxElement>;
type State = TextRange;
type State = (ValidatedElement, TextRange);
type Signals = Option<Self::State>;
type Options = ();

Expand All @@ -74,18 +90,26 @@ impl Rule for UseAltText {
match element {
AnyJsxElement::JsxOpeningElement(opening_element) => {
if !opening_element.has_accessible_child() {
return Some(element.syntax().text_range());
return Some((
ValidatedElement::Object,
element.syntax().text_range(),
));
}
}
AnyJsxElement::JsxSelfClosingElement(_) => {
return Some(element.syntax().text_range());
return Some((ValidatedElement::Object, element.syntax().text_range()));
}
}
}
}
"img" | "area" => {
"img" => {
if !has_alt && !has_aria_label && !has_aria_labelledby {
return Some(element.syntax().text_range());
return Some((ValidatedElement::Img, element.syntax().text_range()));
}
}
"area" => {
if !has_alt && !has_aria_label && !has_aria_labelledby {
return Some((ValidatedElement::Area, element.syntax().text_range()));
}
}
"input" => {
Expand All @@ -94,7 +118,7 @@ impl Rule for UseAltText {
&& !has_aria_label
&& !has_aria_labelledby
{
return Some(element.syntax().text_range());
return Some((ValidatedElement::Input, element.syntax().text_range()));
}
}
_ => {}
Expand All @@ -104,15 +128,12 @@ impl Rule for UseAltText {
}

fn diagnostic(_ctx: &RuleContext<Self>, state: &Self::State) -> Option<RuleDiagnostic> {
if state.is_empty() {
return None;
}
let (validate_element, range) = state;
let message = markup!(
"Provide the attribute "<Emphasis>"alt"</Emphasis>" when using "<Emphasis>"img"</Emphasis>", "<Emphasis>"area"</Emphasis>" or "<Emphasis>"input type='image'"</Emphasis>""
"Provide a text alternative through the "{{validate_element}}", "<Emphasis>"aria-label"</Emphasis>" or "<Emphasis>"aria-labelledby"</Emphasis>" attribute"
).to_owned();

Some(
RuleDiagnostic::new(rule_category!(), state, message).note(markup! {
RuleDiagnostic::new(rule_category!(), range, message).note(markup! {
"Meaningful alternative text on elements helps users relying on screen readers to understand content's purpose within a page."
}),
)
Expand Down
18 changes: 9 additions & 9 deletions crates/rome_js_analyze/tests/specs/a11y/useAltText/area.jsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ expression: area.jsx
```
area.jsx:4:2 lint/a11y/useAltText ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

! Provide the attribute alt when using img, area or input type='image'
! Provide a text alternative through the alt, aria-label or aria-labelledby attribute

3 │ <>
> 4 │ <area />
Expand All @@ -51,7 +51,7 @@ area.jsx:4:2 lint/a11y/useAltText ━━━━━━━━━━━━━━━
```
area.jsx:5:3 lint/a11y/useAltText ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

! Provide the attribute alt when using img, area or input type='image'
! Provide a text alternative through the alt, aria-label or aria-labelledby attribute

3 │ <>
4 │ <area />
Expand All @@ -68,7 +68,7 @@ area.jsx:5:3 lint/a11y/useAltText ━━━━━━━━━━━━━━━
```
area.jsx:6:3 lint/a11y/useAltText ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

! Provide the attribute alt when using img, area or input type='image'
! Provide a text alternative through the alt, aria-label or aria-labelledby attribute

4 │ <area />
5 │ <area alt />
Expand All @@ -85,7 +85,7 @@ area.jsx:6:3 lint/a11y/useAltText ━━━━━━━━━━━━━━━
```
area.jsx:7:3 lint/a11y/useAltText ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

! Provide the attribute alt when using img, area or input type='image'
! Provide a text alternative through the alt, aria-label or aria-labelledby attribute

5 │ <area alt />
6 │ <area alt={undefined} />
Expand All @@ -102,7 +102,7 @@ area.jsx:7:3 lint/a11y/useAltText ━━━━━━━━━━━━━━━
```
area.jsx:8:3 lint/a11y/useAltText ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

! Provide the attribute alt when using img, area or input type='image'
! Provide a text alternative through the alt, aria-label or aria-labelledby attribute

6 │ <area alt={undefined} />
7 │ <area src="xyz" />
Expand All @@ -119,7 +119,7 @@ area.jsx:8:3 lint/a11y/useAltText ━━━━━━━━━━━━━━━
```
area.jsx:9:3 lint/a11y/useAltText ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

! Provide the attribute alt when using img, area or input type='image'
! Provide a text alternative through the alt, aria-label or aria-labelledby attribute

7 │ <area src="xyz" />
8 │ <area {...this.props} />
Expand All @@ -136,7 +136,7 @@ area.jsx:9:3 lint/a11y/useAltText ━━━━━━━━━━━━━━━
```
area.jsx:10:3 lint/a11y/useAltText ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

! Provide the attribute alt when using img, area or input type='image'
! Provide a text alternative through the alt, aria-label or aria-labelledby attribute

8 │ <area {...this.props} />
9 │ <area aria-label="" />
Expand All @@ -153,7 +153,7 @@ area.jsx:10:3 lint/a11y/useAltText ━━━━━━━━━━━━━━━
```
area.jsx:11:3 lint/a11y/useAltText ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

! Provide the attribute alt when using img, area or input type='image'
! Provide a text alternative through the alt, aria-label or aria-labelledby attribute

9 │ <area aria-label="" />
10 │ <area aria-label={undefined} />
Expand All @@ -170,7 +170,7 @@ area.jsx:11:3 lint/a11y/useAltText ━━━━━━━━━━━━━━━
```
area.jsx:12:3 lint/a11y/useAltText ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

! Provide the attribute alt when using img, area or input type='image'
! Provide a text alternative through the alt, aria-label or aria-labelledby attribute

10 │ <area aria-label={undefined} />
11 │ <area aria-labelledby="" />
Expand Down
28 changes: 14 additions & 14 deletions crates/rome_js_analyze/tests/specs/a11y/useAltText/img.jsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ expression: img.jsx
```
img.jsx:3:3 lint/a11y/useAltText ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

! Provide the attribute alt when using img, area or input type='image'
! Provide a text alternative through the alt, aria-label or aria-labelledby attribute

1 │ // invalid
2 │ <>
Expand All @@ -81,7 +81,7 @@ img.jsx:3:3 lint/a11y/useAltText ━━━━━━━━━━━━━━━
```
img.jsx:4:3 lint/a11y/useAltText ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

! Provide the attribute alt when using img, area or input type='image'
! Provide a text alternative through the alt, aria-label or aria-labelledby attribute

2 │ <>
3 │ <img />
Expand All @@ -98,7 +98,7 @@ img.jsx:4:3 lint/a11y/useAltText ━━━━━━━━━━━━━━━
```
img.jsx:5:3 lint/a11y/useAltText ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

! Provide the attribute alt when using img, area or input type='image'
! Provide a text alternative through the alt, aria-label or aria-labelledby attribute

3 │ <img />
4 │ <img alt />
Expand All @@ -115,7 +115,7 @@ img.jsx:5:3 lint/a11y/useAltText ━━━━━━━━━━━━━━━
```
img.jsx:6:3 lint/a11y/useAltText ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

! Provide the attribute alt when using img, area or input type='image'
! Provide a text alternative through the alt, aria-label or aria-labelledby attribute

4 │ <img alt />
5 │ <img alt={undefined} />
Expand All @@ -132,7 +132,7 @@ img.jsx:6:3 lint/a11y/useAltText ━━━━━━━━━━━━━━━
```
img.jsx:7:3 lint/a11y/useAltText ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

! Provide the attribute alt when using img, area or input type='image'
! Provide a text alternative through the alt, aria-label or aria-labelledby attribute

5 │ <img alt={undefined} />
6 │ <img src="xyz" />
Expand All @@ -149,7 +149,7 @@ img.jsx:7:3 lint/a11y/useAltText ━━━━━━━━━━━━━━━
```
img.jsx:8:3 lint/a11y/useAltText ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

! Provide the attribute alt when using img, area or input type='image'
! Provide a text alternative through the alt, aria-label or aria-labelledby attribute

6 │ <img src="xyz" />
7 │ <img role />
Expand All @@ -166,7 +166,7 @@ img.jsx:8:3 lint/a11y/useAltText ━━━━━━━━━━━━━━━
```
img.jsx:9:3 lint/a11y/useAltText ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

! Provide the attribute alt when using img, area or input type='image'
! Provide a text alternative through the alt, aria-label or aria-labelledby attribute

7 │ <img role />
8 │ <img {...this.props} />
Expand All @@ -183,7 +183,7 @@ img.jsx:9:3 lint/a11y/useAltText ━━━━━━━━━━━━━━━
```
img.jsx:10:3 lint/a11y/useAltText ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

! Provide the attribute alt when using img, area or input type='image'
! Provide a text alternative through the alt, aria-label or aria-labelledby attribute

8 │ <img {...this.props} />
9 │ <img alt={undefined} role="presentation" />
Expand All @@ -200,7 +200,7 @@ img.jsx:10:3 lint/a11y/useAltText ━━━━━━━━━━━━━━━
```
img.jsx:11:3 lint/a11y/useAltText ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

! Provide the attribute alt when using img, area or input type='image'
! Provide a text alternative through the alt, aria-label or aria-labelledby attribute

9 │ <img alt={undefined} role="presentation" />
10 │ <img alt role="presentation" />
Expand All @@ -217,7 +217,7 @@ img.jsx:11:3 lint/a11y/useAltText ━━━━━━━━━━━━━━━
```
img.jsx:12:3 lint/a11y/useAltText ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

! Provide the attribute alt when using img, area or input type='image'
! Provide a text alternative through the alt, aria-label or aria-labelledby attribute

10 │ <img alt role="presentation" />
11 │ <img role="presentation" />
Expand All @@ -234,7 +234,7 @@ img.jsx:12:3 lint/a11y/useAltText ━━━━━━━━━━━━━━━
```
img.jsx:13:3 lint/a11y/useAltText ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

! Provide the attribute alt when using img, area or input type='image'
! Provide a text alternative through the alt, aria-label or aria-labelledby attribute

11 │ <img role="presentation" />
12 │ <img role="none" />
Expand All @@ -251,7 +251,7 @@ img.jsx:13:3 lint/a11y/useAltText ━━━━━━━━━━━━━━━
```
img.jsx:14:3 lint/a11y/useAltText ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

! Provide the attribute alt when using img, area or input type='image'
! Provide a text alternative through the alt, aria-label or aria-labelledby attribute

12 │ <img role="none" />
13 │ <img aria-label={undefined} />
Expand All @@ -268,7 +268,7 @@ img.jsx:14:3 lint/a11y/useAltText ━━━━━━━━━━━━━━━
```
img.jsx:15:3 lint/a11y/useAltText ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

! Provide the attribute alt when using img, area or input type='image'
! Provide a text alternative through the alt, aria-label or aria-labelledby attribute

13 │ <img aria-label={undefined} />
14 │ <img aria-labelledby={undefined} />
Expand All @@ -285,7 +285,7 @@ img.jsx:15:3 lint/a11y/useAltText ━━━━━━━━━━━━━━━
```
img.jsx:16:3 lint/a11y/useAltText ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

! Provide the attribute alt when using img, area or input type='image'
! Provide a text alternative through the alt, aria-label or aria-labelledby attribute

14 │ <img aria-labelledby={undefined} />
15 │ <img aria-label="" />
Expand Down
Loading