use super::*;
#[test]
fn basic_function() {
let code = r#"
fn hello() {
println!("Hello, world!");
}"#;
let result = extract_function(code, "hello");
let function = result.expect("Function not found");
assert_eq!(function, r#"println!("Hello, world!");"#);
}
#[test]
fn function_with_parameters() {
let code = r#"
fn add(a: i32, b: i32) -> i32 {
a + b
}"#;
let result = extract_function(code, "add");
let function = result.expect("Function not found");
assert_eq!(function, "a + b");
}
#[test]
fn function_with_generics() {
let code = r#"
fn process<T: Display>(item: T) -> String {
format!("Processed: {}", item)
}"#;
let result = extract_function(code, "process");
let function = result.expect("Function not found");
assert_eq!(function, "format!(\"Processed: {}\", item)");
}
#[test]
fn nested_braces() {
let code = r#"
fn complex() {
if true {
let x = {
let y = 5;
y * 2
};
println!("{}", x);
}
}"#;
let result = extract_function(code, "complex");
let function = result.expect("Function not found");
assert!(function.starts_with("if true {"));
}
#[test]
fn string_with_braces() {
let code = r##"
fn tricky_strings() {
println!("This is a { with a } inside a string");
let json = r#"{"key": "value"}"#;
}"##;
let result = extract_function(code, "tricky_strings");
let function = result.expect("Function not found");
assert!(function.starts_with("println!("));
assert!(function.contains("This is a { with a } inside a string"));
}
#[test]
fn comments() {
let code = r#"
fn commented() {
// This is a comment with { braces }
/* This is a block comment
with { nested } braces */
let x = 5; // Another comment
}"#;
let result = extract_function(code, "commented");
let function = result.expect("Function not found");
assert!(function.contains("let x = 5;"));
}
#[test]
fn public_function() {
let code = r#"
pub fn public_function() {
println!("I'm public!");
}"#;
let result = extract_function(code, "public_function");
let function = result.expect("Function not found");
assert!(function.contains("I'm public!"));
}
#[test]
fn function_with_attributes() {
let code = r#"
#[derive(Debug)]
#[inline]
pub fn attributed() {
println!("I have attributes!");
}"#;
let result = extract_function(code, "attributed");
let function = result.expect("Function not found");
assert!(function.contains("I have attributes!"));
}
#[test]
fn async_function() {
let code = r#"
async fn fetch_data() -> Result<String, Error> {
Ok("data".to_string())
}"#;
let result = extract_function(code, "fetch_data");
let function = result.expect("Function not found");
assert!(function.contains("Ok(\"data\".to_string())"));
}
#[test]
fn unsafe_function() {
let code = r#"
unsafe fn dangerous() {
let ptr = 0x12345 as *mut i32;
*ptr = 42;
}"#;
let result = extract_function(code, "dangerous");
let function = result.expect("Function not found");
assert!(function.contains("*ptr = 42;"));
}
#[test]
fn multiple_functions() {
let code = r#"
fn first() {
println!("First");
}
fn second() {
println!("Second");
}
fn third() {
println!("Third");
}"#;
let result = extract_function(code, "second");
let function = result.expect("Function not found");
assert!(function.contains("println!(\"Second\");"));
assert!(!function.contains("println!(\"First\");"));
assert!(!function.contains("println!(\"Third\");"));
}
#[test]
fn nested_functions() {
let code = r#"
fn outer() {
println!("Outer start");
fn inner() {
println!("Inner function");
}
inner();
println!("Outer end");
}"#;
let outer = extract_function(code, "outer");
assert!(outer.is_some());
let outer_fn = outer.unwrap();
assert!(outer_fn.contains("fn inner()"));
let inner = extract_function(code, "inner");
assert!(inner.is_some());
let inner_fn = inner.unwrap();
assert!(inner_fn.contains("Inner function"));
}
#[test]
fn impl_method() {
let code = r#"
struct Calculator;
impl Calculator {
pub fn new() -> Self {
Calculator
}
fn add(&self, a: i32, b: i32) -> i32 {
a + b
}
}"#;
let result = extract_function(code, "add");
let function = result.expect("Function not found");
assert!(function.contains("a + b"));
}
#[test]
fn function_with_where_clause() {
let code = r#"
fn complex_generic<T, U>(t: T, u: U) -> Vec<String>
where
T: Display + Clone,
U: AsRef<str>,
{
vec![format!("{}", t), u.as_ref().to_string()]
}"#;
let result = extract_function(code, "complex_generic");
let function = result.expect("Function not found");
assert_eq!(
function,
r#"vec![format!("{}", t), u.as_ref().to_string()]"#
);
}
#[test]
fn function_not_found() {
let code = r#"
fn hello() {
println!("Hello!");
}"#;
let result = extract_function(code, "goodbye");
assert!(result.is_none());
}
#[test]
fn closure_with_same_name_as_function() {
let code = r#"
fn process() {
println!("Real function");
}
fn main() {
let process = || {
println!("Closure");
};
process();
}"#;
let result = extract_function(code, "process");
let function = result.expect("Function not found");
assert_eq!(function, r#"println!("Real function");"#);
assert!(!function.contains("Closure"));
}