#[cfg(test)]
mod tests {
use crate::syntax::parser::{CodeChunk, SyntaxParser};
use crate::syntax::rust::RustParser;
use anyhow::Result;
fn create_parser() -> RustParser {
RustParser::new()
}
fn assert_chunk(
chunk: &CodeChunk,
expected_content: &str,
expected_start: usize,
expected_end: usize,
expected_element: &str,
) {
assert_eq!(chunk.content.trim(), expected_content.trim());
assert_eq!(chunk.start_line, expected_start);
assert_eq!(chunk.end_line, expected_end);
assert_eq!(chunk.language, "rust");
assert_eq!(chunk.element_type, expected_element);
assert!(!chunk.file_path.is_empty()); }
#[test]
fn test_parse_simple_function() -> Result<()> {
let code = r#"
fn main() {
println!("Hello, world!");
}
"#;
let mut parser = create_parser();
let chunks = parser.parse(code, "test.rs")?;
assert_eq!(chunks.len(), 2);
Ok(())
}
#[test]
fn test_parse_struct_and_impl() -> Result<()> {
let code = r#"
struct Point {
x: i32,
y: i32,
}
impl Point {
fn origin() -> Self {
Point { x: 0, y: 0 }
}
}
"#;
let mut parser = create_parser();
let chunks = parser.parse(code, "test.rs")?;
assert_eq!(chunks.len(), 3);
assert!(chunks.iter().any(|c| c.element_type == "struct"));
assert!(chunks.iter().any(|c| c.element_type == "impl"));
assert!(chunks.iter().any(|c| c.element_type == "function")); Ok(())
}
#[test]
fn test_parse_enum_and_trait() -> Result<()> {
let code = r#"
enum Color {
Red,
Green,
Blue,
}
trait Drawable {
fn draw(&self);
}
"#;
let mut parser = create_parser();
let chunks = parser.parse(code, "test.rs")?;
assert_eq!(chunks.len(), 2);
assert_chunk(
chunks.iter().find(|c| c.element_type == "enum").unwrap(),
"enum Color {\n Red,\n Green,\n Blue,\n }",
2,
6,
"enum",
);
assert_chunk(
chunks.iter().find(|c| c.element_type == "trait").unwrap(),
"trait Drawable {\n fn draw(&self);\n }",
8,
10,
"trait",
);
Ok(())
}
#[test]
fn test_parse_module() -> Result<()> {
let code = r#"
mod my_module {
const VALUE: i32 = 5;
fn internal_func() {}
}
"#;
let mut parser = create_parser();
let chunks = parser.parse(code, "test.rs")?;
assert_eq!(chunks.len(), 3);
assert!(chunks.iter().any(|c| c.element_type == "module"));
assert!(chunks.iter().any(|c| c.element_type == "const"));
assert!(chunks.iter().any(|c| c.element_type == "function"));
Ok(())
}
#[test]
fn test_parse_use_and_const() -> Result<()> {
let code = r#"
use std::collections::HashMap;
const MAX_SIZE: usize = 100;
"#;
let mut parser = create_parser();
let chunks = parser.parse(code, "test.rs")?;
assert_eq!(chunks.len(), 2);
assert_chunk(
chunks.iter().find(|c| c.element_type == "use").unwrap(),
"use std::collections::HashMap;",
2,
2,
"use",
);
assert_chunk(
chunks.iter().find(|c| c.element_type == "const").unwrap(),
"const MAX_SIZE: usize = 100;",
4,
4,
"const",
);
Ok(())
}
#[test]
fn test_parse_empty_input() -> Result<()> {
let code = "";
let mut parser = create_parser();
let chunks = parser.parse(code, "test.rs")?;
assert!(chunks.is_empty());
Ok(())
}
#[test]
fn test_parse_comments_only() -> Result<()> {
let code = "// This is a comment\n// So is this";
let mut parser = create_parser();
let chunks = parser.parse(code, "test.rs")?;
assert!(!chunks.is_empty(), "Fallback should produce at least one chunk");
assert_eq!(chunks[0].element_type, "file_chunk", "Chunk type should be file_chunk");
assert_eq!(chunks[0].language, "rust", "Language should be rust");
Ok(())
}
#[test]
fn test_parse_macros() -> Result<()> {
let code = r#"
macro_rules! my_macro {
() => { println!("Macro called"); };
}
my_macro!(); // Invocation
"#;
let mut parser = create_parser();
let chunks = parser.parse(code, "test.rs")?;
assert_eq!(chunks.len(), 2);
assert_chunk(
chunks.iter().find(|c| c.element_type == "macro_definition").unwrap(),
"macro_rules! my_macro {\n () => { println!(\"Macro called\"); };\n }",
2,
4,
"macro_definition",
);
assert_chunk(
chunks.iter().find(|c| c.element_type == "macro_invocation").unwrap(),
"my_macro!()",
6,
6,
"macro_invocation",
);
Ok(())
}
}