use anyhow::Result;
use probe_code::query::{perform_query, QueryOptions};
use std::fs;
use tempfile::tempdir;
#[test]
fn test_query_rust_function() -> Result<()> {
let temp_dir = tempdir()?;
let temp_path = temp_dir.path();
let rust_file_path = temp_path.join("test_function.rs");
let rust_content = r#"
fn hello_world() {
println!("Hello, world!");
}
fn add(a: i32, b: i32) -> i32 {
a + b
}
"#;
fs::write(&rust_file_path, rust_content)?;
let options = QueryOptions {
path: temp_path,
pattern: "fn $NAME($$$PARAMS) $$$BODY",
language: Some("rust"),
ignore: &[],
allow_tests: true,
max_results: None,
format: "plain",
};
let matches = perform_query(&options)?;
assert_eq!(matches.len(), 2);
let hello_match = matches
.iter()
.find(|m| m.matched_text.contains("hello_world"))
.unwrap();
assert!(hello_match.matched_text.contains("println!"));
let add_match = matches
.iter()
.find(|m| m.matched_text.contains("add"))
.unwrap();
assert!(add_match.matched_text.contains("a + b"));
Ok(())
}
#[test]
fn test_query_javascript_function() -> Result<()> {
let temp_dir = tempdir()?;
let temp_path = temp_dir.path();
let js_file_path = temp_path.join("test_function.js");
let js_content = r#"
function greet(name) {
return `Hello, ${name}!`;
}
const multiply = (a, b) => a * b;
"#;
fs::write(&js_file_path, js_content)?;
let options = QueryOptions {
path: temp_path,
pattern: "function $NAME($$$PARAMS) $$$BODY",
language: Some("javascript"),
ignore: &[],
allow_tests: true,
max_results: None,
format: "plain",
};
let matches = perform_query(&options)?;
assert_eq!(matches.len(), 1);
assert!(matches[0].matched_text.contains("greet"));
assert!(matches[0].matched_text.contains("return"));
let arrow_options = QueryOptions {
path: temp_path,
pattern: "const $NAME = ($$$PARAMS) => $$$BODY",
language: Some("javascript"),
ignore: &[],
allow_tests: true,
max_results: None,
format: "plain",
};
let arrow_matches = perform_query(&arrow_options)?;
assert_eq!(arrow_matches.len(), 1);
assert!(arrow_matches[0].matched_text.contains("multiply"));
assert!(arrow_matches[0].matched_text.contains("a * b"));
Ok(())
}
#[test]
fn test_query_with_max_results() -> Result<()> {
let temp_dir = tempdir()?;
let temp_path = temp_dir.path();
let rust_file_path = temp_path.join("test_multiple.rs");
let rust_content = r#"
fn func1() {}
fn func2() {}
fn func3() {}
fn func4() {}
fn func5() {}
"#;
fs::write(&rust_file_path, rust_content)?;
let options = QueryOptions {
path: temp_path,
pattern: "fn $NAME() {}",
language: Some("rust"),
ignore: &[],
allow_tests: true,
max_results: Some(3),
format: "plain",
};
let matches = perform_query(&options)?;
assert_eq!(matches.len(), 3);
Ok(())
}
#[test]
fn test_query_ignore_patterns() -> Result<()> {
let temp_dir = tempdir()?;
let temp_path = temp_dir.path();
let main_file_path = temp_path.join("main.rs");
fs::write(&main_file_path, "fn main() {}")?;
let test_dir_path = temp_path.join("test");
fs::create_dir(&test_dir_path)?;
let test_file_path = test_dir_path.join("test_file.rs");
fs::write(&test_file_path, "fn test_function() {}")?;
let options = QueryOptions {
path: temp_path,
pattern: "fn $NAME() {}",
language: Some("rust"),
ignore: &["test".to_string()],
allow_tests: false,
max_results: None,
format: "plain",
};
let matches = perform_query(&options)?;
assert_eq!(matches.len(), 1);
assert!(matches[0].matched_text.contains("main"));
assert!(!matches[0].matched_text.contains("test_function"));
Ok(())
}
#[test]
fn test_query_with_auto_detect_language() -> Result<()> {
let temp_dir = tempdir()?;
let temp_path = temp_dir.path();
let rust_file_path = temp_path.join("test_auto_detect.rs");
let rust_content = r#"
fn auto_detected_function() {
println!("This function should be found with auto-detection");
}
"#;
fs::write(&rust_file_path, rust_content)?;
let options = QueryOptions {
path: temp_path,
pattern: "fn $NAME($$$PARAMS) $$$BODY",
language: None, ignore: &[],
allow_tests: true,
max_results: None,
format: "plain",
};
let matches = perform_query(&options)?;
assert_eq!(matches.len(), 1);
assert!(matches[0].matched_text.contains("auto_detected_function"));
Ok(())
}