From 0696cc32282d53a7b5a460924e5fe2bfccf7c679 Mon Sep 17 00:00:00 2001 From: Kalven Schraut Date: Sat, 6 Apr 2024 19:38:22 -0500 Subject: [PATCH] fix(linter): handle self closing script tags in astro partial loader (#2017) --- crates/oxc_linter/src/partial_loader/astro.rs | 94 ++++++++++++++++++- 1 file changed, 91 insertions(+), 3 deletions(-) diff --git a/crates/oxc_linter/src/partial_loader/astro.rs b/crates/oxc_linter/src/partial_loader/astro.rs index 2fbb6b5ee5aa..3510aceef622 100644 --- a/crates/oxc_linter/src/partial_loader/astro.rs +++ b/crates/oxc_linter/src/partial_loader/astro.rs @@ -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> { let split_finder = Finder::new(ASTRO_SPLIT); @@ -72,8 +72,13 @@ impl<'a> AstroPartialLoader<'a> { } else { break; }; - // find "" - 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 "" 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> { + AstroPartialLoader::new(source_text).parse() + } + + #[test] + fn test_parse_astro() { + let source_text = r#" +

Welcome, world!

+ + + "#; + + 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; + --- + +

Welcome, world!

+ + + "#; + + 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#" +

Welcome, world!

+ + + + + "#; + + 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#" +

Welcome, world!

+ + + "#; + + 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");"#); + } +}