From f29ff8a60aaede46de59228f5725f9f631111f1a Mon Sep 17 00:00:00 2001 From: Daniel Frederico Lins Leite Date: Tue, 8 Nov 2022 15:33:59 -0300 Subject: [PATCH 1/4] useValidAnchor considering all possible expressions --- .../src/analyzers/a11y/use_valid_anchor.rs | 85 +++--- .../tests/specs/a11y/useValidAnchor.jsx | 4 + .../specs/a11y/useValidAnchor.jsx.snap.new | 244 ++++++++++++++++++ 3 files changed, 300 insertions(+), 33 deletions(-) create mode 100644 crates/rome_js_analyze/tests/specs/a11y/useValidAnchor.jsx.snap.new diff --git a/crates/rome_js_analyze/src/analyzers/a11y/use_valid_anchor.rs b/crates/rome_js_analyze/src/analyzers/a11y/use_valid_anchor.rs index da1e8b2e2e3..7627dc367c1 100644 --- a/crates/rome_js_analyze/src/analyzers/a11y/use_valid_anchor.rs +++ b/crates/rome_js_analyze/src/analyzers/a11y/use_valid_anchor.rs @@ -268,47 +268,66 @@ fn is_invalid_anchor(anchor_attribute: &JsxAttribute) -> Option { let expression = attribute_value.expression().ok()?; - // href={null} - if let JsAnyExpression::JsAnyLiteralExpression( - JsAnyLiteralExpression::JsNullLiteralExpression(null), - ) = expression - { - return Some(UseValidAnchorState::IncorrectHref( - null.syntax().text_trimmed_range(), - )); - } else if let JsAnyExpression::JsIdentifierExpression(identifier) = expression { - let text = identifier.name().ok()?.value_token().ok()?; - // href={undefined} - if text.text_trimmed() == "undefined" { + + + match expression { + // href={null} + JsAnyExpression::JsAnyLiteralExpression( + JsAnyLiteralExpression::JsNullLiteralExpression(null), + ) => { return Some(UseValidAnchorState::IncorrectHref( - text.text_trimmed_range(), + null.syntax().text_trimmed_range(), )); } - } else if let JsAnyExpression::JsAnyLiteralExpression( - JsAnyLiteralExpression::JsStringLiteralExpression(string_literal), - ) = expression - { - let text = string_literal.inner_string_text().ok()?; - if text == "#" { - return Some(UseValidAnchorState::IncorrectHref( - string_literal.syntax().text_trimmed_range(), - )); + JsAnyExpression::JsIdentifierExpression(identifier) => { + let text = identifier.name().ok()?.value_token().ok()?; + // href={undefined} + if text.text_trimmed() == "undefined" { + return Some(UseValidAnchorState::IncorrectHref( + text.text_trimmed_range(), + )); + } } - } else if let JsAnyExpression::JsTemplate(template) = expression { - let mut iter = template.elements().iter(); - if let Some(JsAnyTemplateElement::JsTemplateChunkElement(element)) = iter.next() { - let template_token = element.template_chunk_token().ok()?; - let text = template_token.text_trimmed(); - if text == "#" || text.contains("javascript:") { + JsAnyExpression::JsAnyLiteralExpression( + JsAnyLiteralExpression::JsStringLiteralExpression(string_literal), + ) => { + let text = string_literal.inner_string_text().ok()?; + if text == "#" { return Some(UseValidAnchorState::IncorrectHref( - template_token.text_trimmed_range(), + string_literal.syntax().text_trimmed_range(), )); } } - } else { - return Some(UseValidAnchorState::IncorrectHref( - expression.syntax().text_trimmed_range(), - )); + JsAnyExpression::JsTemplate(template) => { + let mut iter = template.elements().iter(); + if let Some(JsAnyTemplateElement::JsTemplateChunkElement(element)) = iter.next() { + let template_token = element.template_chunk_token().ok()?; + let text = template_token.text_trimmed(); + if text == "#" || text.contains("javascript:") { + return Some(UseValidAnchorState::IncorrectHref( + template_token.text_trimmed_range(), + )); + } + } + } + JsAnyExpression::ImportMeta(_) | + JsAnyExpression::JsClassExpression(_) | + JsAnyExpression::JsComputedMemberExpression(_) | + JsAnyExpression::JsImportCallExpression(_) | + JsAnyExpression::JsLogicalExpression(_) | + JsAnyExpression::JsObjectExpression(_) | + JsAnyExpression::JsSuperExpression(_) | + JsAnyExpression::JsUnaryExpression(_) | + JsAnyExpression::JsUnknownExpression(_) | + JsAnyExpression::JsYieldExpression(_) | + JsAnyExpression::JsxTagExpression(_) | + JsAnyExpression::NewTarget(_) | + JsAnyExpression::TsNonNullAssertionExpression(_) => { + return Some(UseValidAnchorState::IncorrectHref( + expression.syntax().text_trimmed_range(), + )); + }, + _ => { } } } JsxAnyAttributeValue::JsxAnyTag(_) => {} diff --git a/crates/rome_js_analyze/tests/specs/a11y/useValidAnchor.jsx b/crates/rome_js_analyze/tests/specs/a11y/useValidAnchor.jsx index ed5a39f3eb9..ff0110df64e 100644 --- a/crates/rome_js_analyze/tests/specs/a11y/useValidAnchor.jsx +++ b/crates/rome_js_analyze/tests/specs/a11y/useValidAnchor.jsx @@ -17,4 +17,8 @@ + Download + Download + Download + Download \ No newline at end of file diff --git a/crates/rome_js_analyze/tests/specs/a11y/useValidAnchor.jsx.snap.new b/crates/rome_js_analyze/tests/specs/a11y/useValidAnchor.jsx.snap.new new file mode 100644 index 00000000000..3aebabd3cea --- /dev/null +++ b/crates/rome_js_analyze/tests/specs/a11y/useValidAnchor.jsx.snap.new @@ -0,0 +1,244 @@ +--- +source: crates/rome_js_analyze/tests/spec_tests.rs +assertion_line: 99 +expression: useValidAnchor.jsx +--- +# Input +```js +<> + {/* invalid */} + + + + + + + + + + + + + javascript:void(0)}/> + {/* valid */} + + + + Download + Download + Download + Download + +``` + +# Diagnostics +``` +useValidAnchor.jsx:3:5 lint/a11y/useValidAnchor ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Provide a href attribute for the a element. + + 1 │ <> + 2 │ {/* invalid */} + > 3 │ + │ ^^^^^ + 4 │ + 5 │ + + i An anchor element should always have a href + + i Check this thorough explanation to better understand the context. + + +``` + +``` +useValidAnchor.jsx:4:8 lint/a11y/useValidAnchor ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! The attribute href has to be assigned to a valid value. + + 2 │ {/* invalid */} + 3 │ + > 4 │ + │ ^^^^ + 5 │ + 6 │ + + i The href attribute should be a valid a URL + + i Check this thorough explanation to better understand the context. + + +``` + +``` +useValidAnchor.jsx:5:14 lint/a11y/useValidAnchor ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Provide a valid value for the attribute href. + + 3 │ + 4 │ + > 5 │ + │ ^^^^ + 6 │ + 7 │ + + i The href attribute should be a valid a URL + + i Check this thorough explanation to better understand the context. + + +``` + +``` +useValidAnchor.jsx:6:14 lint/a11y/useValidAnchor ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Provide a valid value for the attribute href. + + 4 │ + 5 │ + > 6 │ + │ ^^^^^^^^^ + 7 │ + 8 │ + + i The href attribute should be a valid a URL + + i Check this thorough explanation to better understand the context. + + +``` + +``` +useValidAnchor.jsx:8:14 lint/a11y/useValidAnchor ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Provide a valid value for the attribute href. + + 6 │ + 7 │ + > 8 │ + │ ^^^ + 9 │ + 10 │ + + i The href attribute should be a valid a URL + + i Check this thorough explanation to better understand the context. + + +``` + +``` +useValidAnchor.jsx:9:15 lint/a11y/useValidAnchor ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Provide a valid value for the attribute href. + + 7 │ + 8 │ + > 9 │ + │ ^ + 10 │ + 11 │ + + i The href attribute should be a valid a URL + + i Check this thorough explanation to better understand the context. + + +``` + +``` +useValidAnchor.jsx:10:13 lint/a11y/useValidAnchor ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Provide a valid value for the attribute href. + + 8 │ + 9 │ + > 10 │ + │ ^^^^^^^^^^^^^^^^^^^^ + 11 │ + 12 │ + + i The href attribute should be a valid a URL + + i Check this thorough explanation to better understand the context. + + +``` + +``` +useValidAnchor.jsx:12:15 lint/a11y/useValidAnchor ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Provide a valid value for the attribute href. + + 10 │ + 11 │ + > 12 │ + │ ^^^^^^^^^^^^^^^^^^ + 13 │ + 14 │ + + i The href attribute should be a valid a URL + + i Check this thorough explanation to better understand the context. + + +``` + +``` +useValidAnchor.jsx:13:8 lint/a11y/useValidAnchor ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use a button element instead of an a element. + + 11 │ + 12 │ + > 13 │ + │ ^^^^^^^^^^ + 14 │ + 15 │ javascript:void(0)}/> + + i Anchor elements should only be used for default sections or page navigation + + i Check this thorough explanation to better understand the context. + + +``` + +``` +useValidAnchor.jsx:14:5 lint/a11y/useValidAnchor ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use a button element instead of an a element. + + 12 │ + 13 │ + > 14 │ + │ ^^^^^^^^^^^^^^^^^^^^^^^ + 15 │ javascript:void(0)}/> + 16 │ {/* valid */} + + i Anchor elements should only be used for default sections or page navigation + + i Check this thorough explanation to better understand the context. + + +``` + +``` +useValidAnchor.jsx:15:14 lint/a11y/useValidAnchor ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Provide a valid value for the attribute href. + + 13 │ + 14 │ + > 15 │ javascript:void(0)}/> + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 16 │ {/* valid */} + 17 │ + + i The href attribute should be a valid a URL + + i Check this thorough explanation to better understand the context. + + +``` + + From d2fbe92aa9127273fb90760f507ade94c8df1b49 Mon Sep 17 00:00:00 2001 From: Daniel Frederico Lins Leite Date: Wed, 9 Nov 2022 07:56:15 -0300 Subject: [PATCH 2/4] fmt and clippy issues --- .../src/analyzers/a11y/use_valid_anchor.rs | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/crates/rome_js_analyze/src/analyzers/a11y/use_valid_anchor.rs b/crates/rome_js_analyze/src/analyzers/a11y/use_valid_anchor.rs index 7627dc367c1..6a8438ff502 100644 --- a/crates/rome_js_analyze/src/analyzers/a11y/use_valid_anchor.rs +++ b/crates/rome_js_analyze/src/analyzers/a11y/use_valid_anchor.rs @@ -269,11 +269,10 @@ fn is_invalid_anchor(anchor_attribute: &JsxAttribute) -> Option { let expression = attribute_value.expression().ok()?; - match expression { - // href={null} + // href={null} JsAnyExpression::JsAnyLiteralExpression( - JsAnyLiteralExpression::JsNullLiteralExpression(null), + JsAnyLiteralExpression::JsNullLiteralExpression(null), ) => { return Some(UseValidAnchorState::IncorrectHref( null.syntax().text_trimmed_range(), @@ -289,8 +288,8 @@ fn is_invalid_anchor(anchor_attribute: &JsxAttribute) -> Option { + JsAnyLiteralExpression::JsStringLiteralExpression(string_literal), + ) => { let text = string_literal.inner_string_text().ok()?; if text == "#" { return Some(UseValidAnchorState::IncorrectHref( @@ -300,7 +299,8 @@ fn is_invalid_anchor(anchor_attribute: &JsxAttribute) -> Option { let mut iter = template.elements().iter(); - if let Some(JsAnyTemplateElement::JsTemplateChunkElement(element)) = iter.next() { + if let Some(JsAnyTemplateElement::JsTemplateChunkElement(element)) = iter.next() + { let template_token = element.template_chunk_token().ok()?; let text = template_token.text_trimmed(); if text == "#" || text.contains("javascript:") { @@ -310,24 +310,24 @@ fn is_invalid_anchor(anchor_attribute: &JsxAttribute) -> Option { + JsAnyExpression::ImportMeta(_) + | JsAnyExpression::JsClassExpression(_) + | JsAnyExpression::JsComputedMemberExpression(_) + | JsAnyExpression::JsImportCallExpression(_) + | JsAnyExpression::JsLogicalExpression(_) + | JsAnyExpression::JsObjectExpression(_) + | JsAnyExpression::JsSuperExpression(_) + | JsAnyExpression::JsUnaryExpression(_) + | JsAnyExpression::JsUnknownExpression(_) + | JsAnyExpression::JsYieldExpression(_) + | JsAnyExpression::JsxTagExpression(_) + | JsAnyExpression::NewTarget(_) + | JsAnyExpression::TsNonNullAssertionExpression(_) => { return Some(UseValidAnchorState::IncorrectHref( expression.syntax().text_trimmed_range(), )); - }, - _ => { } + } + _ => {} } } JsxAnyAttributeValue::JsxAnyTag(_) => {} From eced59e29a386b865624e1bb26cb1108b47c857d Mon Sep 17 00:00:00 2001 From: Daniel Frederico Lins Leite Date: Wed, 9 Nov 2022 08:06:26 -0300 Subject: [PATCH 3/4] support for computed member expression --- .../src/analyzers/a11y/use_valid_anchor.rs | 1 - .../tests/specs/a11y/useValidAnchor.jsx | 3 +- .../tests/specs/a11y/useValidAnchor.jsx.snap | 5 + .../specs/a11y/useValidAnchor.jsx.snap.new | 244 ------------------ 4 files changed, 7 insertions(+), 246 deletions(-) delete mode 100644 crates/rome_js_analyze/tests/specs/a11y/useValidAnchor.jsx.snap.new diff --git a/crates/rome_js_analyze/src/analyzers/a11y/use_valid_anchor.rs b/crates/rome_js_analyze/src/analyzers/a11y/use_valid_anchor.rs index 6a8438ff502..bb15dbc0de4 100644 --- a/crates/rome_js_analyze/src/analyzers/a11y/use_valid_anchor.rs +++ b/crates/rome_js_analyze/src/analyzers/a11y/use_valid_anchor.rs @@ -312,7 +312,6 @@ fn is_invalid_anchor(anchor_attribute: &JsxAttribute) -> Option - Download + Download Download Download Download + Download \ No newline at end of file diff --git a/crates/rome_js_analyze/tests/specs/a11y/useValidAnchor.jsx.snap b/crates/rome_js_analyze/tests/specs/a11y/useValidAnchor.jsx.snap index a086044b69e..efaa73a2997 100644 --- a/crates/rome_js_analyze/tests/specs/a11y/useValidAnchor.jsx.snap +++ b/crates/rome_js_analyze/tests/specs/a11y/useValidAnchor.jsx.snap @@ -23,6 +23,11 @@ expression: useValidAnchor.jsx + Download + Download + Download + Download + Download ``` diff --git a/crates/rome_js_analyze/tests/specs/a11y/useValidAnchor.jsx.snap.new b/crates/rome_js_analyze/tests/specs/a11y/useValidAnchor.jsx.snap.new deleted file mode 100644 index 3aebabd3cea..00000000000 --- a/crates/rome_js_analyze/tests/specs/a11y/useValidAnchor.jsx.snap.new +++ /dev/null @@ -1,244 +0,0 @@ ---- -source: crates/rome_js_analyze/tests/spec_tests.rs -assertion_line: 99 -expression: useValidAnchor.jsx ---- -# Input -```js -<> - {/* invalid */} - - - - - - - - - - - - - javascript:void(0)}/> - {/* valid */} - - - - Download - Download - Download - Download - -``` - -# Diagnostics -``` -useValidAnchor.jsx:3:5 lint/a11y/useValidAnchor ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - - ! Provide a href attribute for the a element. - - 1 │ <> - 2 │ {/* invalid */} - > 3 │ - │ ^^^^^ - 4 │ - 5 │ - - i An anchor element should always have a href - - i Check this thorough explanation to better understand the context. - - -``` - -``` -useValidAnchor.jsx:4:8 lint/a11y/useValidAnchor ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - - ! The attribute href has to be assigned to a valid value. - - 2 │ {/* invalid */} - 3 │ - > 4 │ - │ ^^^^ - 5 │ - 6 │ - - i The href attribute should be a valid a URL - - i Check this thorough explanation to better understand the context. - - -``` - -``` -useValidAnchor.jsx:5:14 lint/a11y/useValidAnchor ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - - ! Provide a valid value for the attribute href. - - 3 │ - 4 │ - > 5 │ - │ ^^^^ - 6 │ - 7 │ - - i The href attribute should be a valid a URL - - i Check this thorough explanation to better understand the context. - - -``` - -``` -useValidAnchor.jsx:6:14 lint/a11y/useValidAnchor ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - - ! Provide a valid value for the attribute href. - - 4 │ - 5 │ - > 6 │ - │ ^^^^^^^^^ - 7 │ - 8 │ - - i The href attribute should be a valid a URL - - i Check this thorough explanation to better understand the context. - - -``` - -``` -useValidAnchor.jsx:8:14 lint/a11y/useValidAnchor ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - - ! Provide a valid value for the attribute href. - - 6 │ - 7 │ - > 8 │ - │ ^^^ - 9 │ - 10 │ - - i The href attribute should be a valid a URL - - i Check this thorough explanation to better understand the context. - - -``` - -``` -useValidAnchor.jsx:9:15 lint/a11y/useValidAnchor ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - - ! Provide a valid value for the attribute href. - - 7 │ - 8 │ - > 9 │ - │ ^ - 10 │ - 11 │ - - i The href attribute should be a valid a URL - - i Check this thorough explanation to better understand the context. - - -``` - -``` -useValidAnchor.jsx:10:13 lint/a11y/useValidAnchor ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - - ! Provide a valid value for the attribute href. - - 8 │ - 9 │ - > 10 │ - │ ^^^^^^^^^^^^^^^^^^^^ - 11 │ - 12 │ - - i The href attribute should be a valid a URL - - i Check this thorough explanation to better understand the context. - - -``` - -``` -useValidAnchor.jsx:12:15 lint/a11y/useValidAnchor ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - - ! Provide a valid value for the attribute href. - - 10 │ - 11 │ - > 12 │ - │ ^^^^^^^^^^^^^^^^^^ - 13 │ - 14 │ - - i The href attribute should be a valid a URL - - i Check this thorough explanation to better understand the context. - - -``` - -``` -useValidAnchor.jsx:13:8 lint/a11y/useValidAnchor ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - - ! Use a button element instead of an a element. - - 11 │ - 12 │ - > 13 │ - │ ^^^^^^^^^^ - 14 │ - 15 │ javascript:void(0)}/> - - i Anchor elements should only be used for default sections or page navigation - - i Check this thorough explanation to better understand the context. - - -``` - -``` -useValidAnchor.jsx:14:5 lint/a11y/useValidAnchor ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - - ! Use a button element instead of an a element. - - 12 │ - 13 │ - > 14 │ - │ ^^^^^^^^^^^^^^^^^^^^^^^ - 15 │ javascript:void(0)}/> - 16 │ {/* valid */} - - i Anchor elements should only be used for default sections or page navigation - - i Check this thorough explanation to better understand the context. - - -``` - -``` -useValidAnchor.jsx:15:14 lint/a11y/useValidAnchor ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - - ! Provide a valid value for the attribute href. - - 13 │ - 14 │ - > 15 │ javascript:void(0)}/> - │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - 16 │ {/* valid */} - 17 │ - - i The href attribute should be a valid a URL - - i Check this thorough explanation to better understand the context. - - -``` - - From f98920e46bad93db8668a244159a6cd4d7682248 Mon Sep 17 00:00:00 2001 From: Daniel Frederico Lins Leite Date: Wed, 9 Nov 2022 13:40:36 -0300 Subject: [PATCH 4/4] more examples of accepted expressions --- .../rome_js_analyze/src/analyzers/a11y/use_valid_anchor.rs | 6 +----- crates/rome_js_analyze/tests/specs/a11y/useValidAnchor.jsx | 1 + .../tests/specs/a11y/useValidAnchor.jsx.snap | 1 + 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/crates/rome_js_analyze/src/analyzers/a11y/use_valid_anchor.rs b/crates/rome_js_analyze/src/analyzers/a11y/use_valid_anchor.rs index bb15dbc0de4..b8d61d6b621 100644 --- a/crates/rome_js_analyze/src/analyzers/a11y/use_valid_anchor.rs +++ b/crates/rome_js_analyze/src/analyzers/a11y/use_valid_anchor.rs @@ -313,15 +313,11 @@ fn is_invalid_anchor(anchor_attribute: &JsxAttribute) -> Option { + | JsAnyExpression::NewTarget(_) => { return Some(UseValidAnchorState::IncorrectHref( expression.syntax().text_trimmed_range(), )); diff --git a/crates/rome_js_analyze/tests/specs/a11y/useValidAnchor.jsx b/crates/rome_js_analyze/tests/specs/a11y/useValidAnchor.jsx index 8caa45a8d2b..8bb127dcaf5 100644 --- a/crates/rome_js_analyze/tests/specs/a11y/useValidAnchor.jsx +++ b/crates/rome_js_analyze/tests/specs/a11y/useValidAnchor.jsx @@ -22,4 +22,5 @@ Download Download Download + Download \ No newline at end of file diff --git a/crates/rome_js_analyze/tests/specs/a11y/useValidAnchor.jsx.snap b/crates/rome_js_analyze/tests/specs/a11y/useValidAnchor.jsx.snap index efaa73a2997..550b0c7087b 100644 --- a/crates/rome_js_analyze/tests/specs/a11y/useValidAnchor.jsx.snap +++ b/crates/rome_js_analyze/tests/specs/a11y/useValidAnchor.jsx.snap @@ -28,6 +28,7 @@ expression: useValidAnchor.jsx Download Download Download + Download ```