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 2 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
45 changes: 31 additions & 14 deletions crates/rome_js_analyze/src/analyzers/a11y/use_alt_text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,16 @@ declare_rule! {
}
}

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

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 +81,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((ValidatedElement::Img, element.syntax().text_range()));
}
}
"area" => {
if !has_alt && !has_aria_label && !has_aria_labelledby {
return Some(element.syntax().text_range());
return Some((ValidatedElement::Area, element.syntax().text_range()));
}
}
"input" => {
Expand All @@ -94,7 +109,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 +119,17 @@ impl Rule for UseAltText {
}

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

let (validate_element, range) = state;
let message = match validate_element {
ValidatedElement::Object => markup!(
"Provide a text alternative through the "<Emphasis>"title"</Emphasis>", "<Emphasis>"aria-label"</Emphasis>" or "<Emphasis>"aria-labelledby"</Emphasis>" attribute"
).to_owned(),
_ => markup!(
"Provide a text alternative through the "<Emphasis>"alt"</Emphasis>", "<Emphasis>"aria-label"</Emphasis>" or "<Emphasis>"aria-labelledby"</Emphasis>" attribute"
).to_owned(),
Copy link
Contributor

@ematipico ematipico May 8, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's a suggestion, you could DRY this code like this:

First, we apply rome_console::fmt::Display to ValidatedElement:

impl rome_console::fmt::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>))
        }
    }
}

And then we just need to display it here:

let message = markup!(
"Provide a text alternative through the "{{validate_element}}", "<Emphasis>"aria-label"</Emphasis>" or "<Emphasis>"aria-labelledby"</Emphasis>" attribute"
).to_owned();

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! I updated in 33e8927

};
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