fix(linter): handle self closing script tags in astro partial loader (#2017) (#2907)

Added tests to figure out what the problem from the issue was and
realize the self closing tag was not expected. Added code to handle this
case.

I am not that familiar with astro to know how common self closing script
tags are, their docs seem to use an opening and closing one for inline
scripts
https://docs.astro.build/en/guides/client-side-scripts/#load-external-scripts
This commit is contained in:
Kalven Schraut 2024-04-07 00:02:09 -05:00 committed by GitHub
parent 1cd5e7511b
commit 79e2c95e2d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -24,7 +24,7 @@ impl<'a> AstroPartialLoader<'a> {
results
}
/// Parse `---` front matter block
/// Parse `---` frontmatter block
#[allow(clippy::cast_possible_truncation)]
fn parse_frontmatter(&self) -> Option<JavaScriptSource<'a>> {
let split_finder = Finder::new(ASTRO_SPLIT);
@ -72,8 +72,13 @@ impl<'a> AstroPartialLoader<'a> {
} else {
break;
};
// find "</script>"
if let Some(offset) = script_end_finder.find(self.source_text[pointer..].as_bytes()) {
// check for the / of a self closing script tag
if let Some('/') = self.source_text.chars().nth(js_start - 2) {
js_end = pointer;
// find "</script>" if no self closing tag was found
} else if let Some(offset) =
script_end_finder.find(self.source_text[pointer..].as_bytes())
{
js_end = pointer + offset;
pointer += offset + SCRIPT_END.len();
} else {
@ -88,3 +93,86 @@ impl<'a> AstroPartialLoader<'a> {
results
}
}
#[cfg(test)]
mod test {
use super::{AstroPartialLoader, JavaScriptSource};
fn parse_astro(source_text: &str) -> Vec<JavaScriptSource<'_>> {
AstroPartialLoader::new(source_text).parse()
}
#[test]
fn test_parse_astro() {
let source_text = r#"
<h1>Welcome, world!</h1>
<script>
console.log("Hi");
</script>
"#;
let sources = parse_astro(source_text);
assert_eq!(sources.len(), 1);
assert_eq!(sources[0].source_text.trim(), r#"console.log("Hi");"#);
}
#[test]
fn test_parse_astro_with_fontmatter() {
let source_text = r#"
---
const { message = 'Welcome, world!' } = Astro.props;
---
<h1>Welcome, world!</h1>
<script>
console.log("Hi");
</script>
"#;
let sources = parse_astro(source_text);
assert_eq!(sources.len(), 2);
assert_eq!(
sources[0].source_text.trim(),
"const { message = 'Welcome, world!' } = Astro.props;"
);
assert_eq!(sources[1].source_text.trim(), r#"console.log("Hi");"#);
}
#[test]
fn test_parse_astro_with_inline_script() {
let source_text = r#"
<h1>Welcome, world!</h1>
<script is:inline src="https://my-analytics.com/script.js"></script>
<script>
console.log("Hi");
</script>
"#;
let sources = parse_astro(source_text);
assert_eq!(sources.len(), 2);
assert!(sources[0].source_text.is_empty());
assert_eq!(sources[1].source_text.trim(), r#"console.log("Hi");"#);
}
#[test]
fn test_parse_astro_with_inline_script_self_closing() {
let source_text = r#"
<h1>Welcome, world!</h1>
<script is:inline src="https://my-analytics.com/script.js" />
<script>
console.log("Hi");
</script>
"#;
let sources = parse_astro(source_text);
assert_eq!(sources.len(), 2);
assert!(sources[0].source_text.is_empty());
assert_eq!(sources[1].source_text.trim(), r#"console.log("Hi");"#);
}
}