Skip to content

Commit fef77af

Browse files
committed
docs(linter): Fix jsx-a11y/img-redundant-alt configuration option names. (#16552)
These were wrong previously due to the fields having different names in the config object than the actual configuration passed to the rule. The docs will now match the result we expect to see from the Also updated the tests to cover more cases, and found a few places where the current logic is problematic. Generated docs: ```md ## Configuration This rule accepts a configuration object with the following properties: ### components type: `string[]` default: `["img"]` JSX element types to validate (component names) where the rule applies. For example, `["img", "Image"]`. ### words type: `string[]` default: `["image", "photo", "picture"]` Words considered redundant in alt text that should trigger a warning. ```
1 parent c0766df commit fef77af

File tree

2 files changed

+82
-39
lines changed

2 files changed

+82
-39
lines changed

crates/oxc_linter/src/rules/jsx_a11y/img_redundant_alt.rs

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,10 @@ use crate::{
2020
},
2121
};
2222

23+
// TODO: Update this diagnostic message to actually include the custom words from the config.
2324
fn img_redundant_alt_diagnostic(span: Span) -> OxcDiagnostic {
2425
OxcDiagnostic::warn("Redundant `alt` attribute.")
25-
.with_help("Provide no redundant alt text for image. Screen-readers already announce `img` tags as an image. You don't need to use the words `image`, `photo,` or `picture` (or any specified custom words) in the `alt` prop.").with_label(span)
26+
.with_help("Provide no redundant alt text for image. Screen-readers already announce `img` tags as an image. You don't need to use the words `image`, `photo`, or `picture` (or any specified custom words) in the `alt` prop.").with_label(span)
2627
}
2728

2829
#[derive(Debug, Default, Clone)]
@@ -33,9 +34,9 @@ pub struct ImgRedundantAlt(Box<ImgRedundantAltConfig>);
3334
pub struct ImgRedundantAltConfig {
3435
/// JSX element types to validate (component names) where the rule applies.
3536
/// For example, `["img", "Image"]`.
36-
types_to_validate: Vec<CompactStr>,
37+
components: Vec<CompactStr>,
3738
/// Words considered redundant in alt text that should trigger a warning.
38-
redundant_words: Vec<Cow<'static, str>>,
39+
words: Vec<Cow<'static, str>>,
3940
}
4041

4142
impl std::ops::Deref for ImgRedundantAlt {
@@ -51,16 +52,17 @@ const REDUNDANT_WORDS: [&str; 3] = ["image", "photo", "picture"];
5152
impl Default for ImgRedundantAltConfig {
5253
fn default() -> Self {
5354
Self {
54-
types_to_validate: vec![CompactStr::new("img")],
55-
redundant_words: vec!["image".into(), "photo".into(), "picture".into()],
55+
components: vec![CompactStr::new("img")],
56+
words: vec!["image".into(), "photo".into(), "picture".into()],
5657
}
5758
}
5859
}
5960
impl ImgRedundantAltConfig {
60-
fn new(types_to_validate: Vec<&str>, redundant_words: &[&str]) -> Self {
61+
fn new(components: Vec<&str>, words: &[&str]) -> Self {
6162
Self {
62-
types_to_validate: types_to_validate.into_iter().map(Into::into).collect(),
63-
redundant_words: redundant_words
63+
components: components.into_iter().map(Into::into).collect(),
64+
// Using cow_to_ascii_lowercase means you cannot use non-ASCII characters (e.g. Japanese, Chinese, etc.). We should consider changing this?
65+
words: words
6466
.iter()
6567
.map(|w| Cow::Owned(w.cow_to_ascii_lowercase().to_string()))
6668
.collect::<Vec<_>>(),
@@ -131,7 +133,7 @@ impl Rule for ImgRedundantAlt {
131133

132134
let element_type = get_element_type(ctx, jsx_el);
133135

134-
if !self.types_to_validate.iter().any(|comp| comp == &element_type) {
136+
if !self.components.iter().any(|comp| comp == &element_type) {
135137
return;
136138
}
137139

@@ -193,7 +195,7 @@ impl ImgRedundantAlt {
193195
#[inline]
194196
fn is_redundant_alt_text(&self, alt_text: &str) -> bool {
195197
let alt_text = alt_text.cow_to_ascii_lowercase();
196-
for word in &self.redundant_words {
198+
for word in &self.words {
197199
if let Some(index) = alt_text.find(word.as_ref()) {
198200
// check if followed by space or is whole text
199201
if index + word.len() == alt_text.len()
@@ -211,7 +213,7 @@ impl ImgRedundantAlt {
211213
fn test() {
212214
use crate::tester::Tester;
213215

214-
fn array() -> serde_json::Value {
216+
fn config_array() -> serde_json::Value {
215217
serde_json::json!([{
216218
"components": ["Image"],
217219
"words": ["Word1", "Word2"]
@@ -268,6 +270,22 @@ fn test() {
268270
(r"<img alt='Photo of friend.' />;", None, None),
269271
(r"<img alt='Picture of friend.' />;", None, None),
270272
(r"<img alt='Image of friend.' />;", None, None),
273+
(
274+
r"<img alt='thing not to say' />;",
275+
Some(serde_json::json!([{ "words": ["not to say"] }])),
276+
None,
277+
),
278+
(
279+
r"<PicVersionThree alt='this is a photo' />;",
280+
Some(serde_json::json!([{ "components": ["PicVersionThree"] }])),
281+
None,
282+
),
283+
// TODO: if there is a period immediately after the banned word, it does not get recognized by the current logic.
284+
// (
285+
// r"<PicVersionThree alt='this is a photo.' />;",
286+
// Some(serde_json::json!([{ "components": ["PicVersionThree"] }])),
287+
// None,
288+
// ),
271289
(r"<img alt='PhOtO of friend.' />;", None, None),
272290
(r"<img alt={'photo'} />;", None, None),
273291
(r"<img alt='piCTUre of friend.' />;", None, None),
@@ -284,12 +302,16 @@ fn test() {
284302
(r"<img alt={`picture doing ${picture}`} {...this.props} />", None, None),
285303
(r"<img alt={`photo doing ${photo}`} {...this.props} />", None, None),
286304
(r"<img alt={`image doing ${image}`} {...this.props} />", None, None),
305+
(r"<Image alt='Photo of a friend' />", Some(config_array()), None),
287306
(r"<Image alt='Photo of a friend' />", None, Some(settings())),
288307
// TESTS FOR ARRAY OPTION TESTS
289-
(r"<img alt='Word1' />;", Some(array()), None),
290-
(r"<img alt='Word2' />;", Some(array()), None),
291-
(r"<Image alt='Word1' />;", Some(array()), None),
292-
(r"<Image alt='Word2' />;", Some(array()), None),
308+
(r"<img alt='Word1' />;", Some(config_array()), None),
309+
(r"<img alt='Word2' />;", Some(config_array()), None),
310+
(r"<Image alt='Word1' />;", Some(config_array()), None),
311+
(r"<Image alt='Word2' />;", Some(config_array()), None),
312+
// non-english tests, they need to be enabled after we fix the code.
313+
// (r"<img alt='イメージ' />", Some(serde_json::json!([{ "words": ["イメージ"] }])), None),
314+
// (r"<img alt='イメージです' />", Some(serde_json::json!([{ "words": ["イメージ"] }])), None),
293315
];
294316

295317
Tester::new(ImgRedundantAlt::NAME, ImgRedundantAlt::PLUGIN, pass, fail).test_and_snapshot();

0 commit comments

Comments
 (0)