use assert_cmd::Command;
use predicates::prelude::*;
use std::fs;
use tempfile::TempDir;
#[test]
fn test_search_includes_types_not_matching_search() {
let temp_dir = TempDir::new().unwrap();
fs::write(
temp_dir.path().join("auth.rs"),
r#"
use crate::models::Account;
pub fn login(account: Account) -> bool {
account.verify_credentials()
}
"#,
)
.unwrap();
fs::write(
temp_dir.path().join("models.rs"),
r#"
pub struct Account {
username: String,
password_hash: String,
}
impl Account {
pub fn verify_credentials(&self) -> bool {
// verification logic
true
}
}
"#,
)
.unwrap();
fs::write(
temp_dir.path().join("user.rs"),
r#"
use crate::models::Account;
pub fn create_user(name: &str) -> Account {
Account::new(name)
}
"#,
)
.unwrap();
let mut cmd = Command::cargo_bin("context-creator").unwrap();
cmd.arg("search")
.arg("login")
.arg(temp_dir.path())
.assert()
.success()
.stdout(predicate::str::contains("auth.rs")) .stdout(predicate::str::contains("models.rs")) .stdout(predicate::str::contains("Account")) .stdout(predicate::str::contains("verify_credentials")); }
#[test]
fn test_search_includes_imports_not_matching_search() {
let temp_dir = TempDir::new().unwrap();
fs::write(
temp_dir.path().join("payment.rs"),
r#"
pub fn process_payment(amount: f64) -> Result<(), Error> {
// payment logic
Ok(())
}
"#,
)
.unwrap();
fs::write(
temp_dir.path().join("checkout.rs"),
r#"
use crate::payment::process_payment;
pub fn checkout(items: Vec<Item>) -> Result<(), Error> {
let total = calculate_total(items);
process_payment(total)
}
"#,
)
.unwrap();
fs::write(
temp_dir.path().join("api.rs"),
r#"
use crate::checkout::checkout;
pub fn handle_checkout_request(request: Request) -> Response {
match checkout(request.items) {
Ok(_) => Response::success(),
Err(e) => Response::error(e),
}
}
"#,
)
.unwrap();
let mut cmd = Command::cargo_bin("context-creator").unwrap();
cmd.arg("search")
.arg("payment")
.arg(temp_dir.path())
.assert()
.success()
.stdout(predicate::str::contains("payment.rs")) .stdout(predicate::str::contains("checkout.rs")) .stdout(predicate::str::contains("api.rs")); }
#[test]
fn test_search_includes_callers_not_matching_search() {
let temp_dir = TempDir::new().unwrap();
fs::write(
temp_dir.path().join("validator.rs"),
r#"
pub fn validate_email(email: &str) -> bool {
email.contains('@') && email.contains('.')
}
"#,
)
.unwrap();
fs::write(
temp_dir.path().join("user_service.rs"),
r#"
use crate::validator::validate_email;
pub fn register_user(email: &str, password: &str) -> Result<User, Error> {
if !validate_email(email) {
return Err(Error::InvalidEmail);
}
// registration logic
Ok(User::new(email))
}
"#,
)
.unwrap();
fs::write(
temp_dir.path().join("admin.rs"),
r#"
use crate::validator::validate_email;
pub fn add_admin(email: &str) -> Result<Admin, Error> {
if !validate_email(email) {
return Err(Error::InvalidEmail);
}
Ok(Admin::new(email))
}
"#,
)
.unwrap();
let mut cmd = Command::cargo_bin("context-creator").unwrap();
cmd.arg("search")
.arg("validate_email")
.arg(temp_dir.path())
.assert()
.success()
.stdout(predicate::str::contains("validator.rs")) .stdout(predicate::str::contains("user_service.rs")) .stdout(predicate::str::contains("admin.rs")) .stdout(predicate::str::contains("register_user")) .stdout(predicate::str::contains("add_admin")); }
#[test]
fn test_search_with_no_semantic_only_includes_matches() {
let temp_dir = TempDir::new().unwrap();
fs::write(
temp_dir.path().join("auth.rs"),
r#"
use crate::models::User;
pub fn authenticate(user: User) -> bool {
user.is_valid()
}
"#,
)
.unwrap();
fs::write(
temp_dir.path().join("models.rs"),
r#"
pub struct User {
id: u64,
}
impl User {
pub fn is_valid(&self) -> bool {
self.id > 0
}
}
"#,
)
.unwrap();
let mut cmd = Command::cargo_bin("context-creator").unwrap();
cmd.arg("search")
.arg("authenticate")
.arg("--no-semantic")
.arg(temp_dir.path())
.assert()
.success()
.stdout(predicate::str::contains("auth.rs")) .stdout(predicate::str::contains("models.rs").not()); }
#[test]
fn test_search_semantic_follows_deep_chains() {
let temp_dir = TempDir::new().unwrap();
fs::write(
temp_dir.path().join("config.rs"),
r#"
pub struct Config {
pub api_key: String,
}
"#,
)
.unwrap();
fs::write(
temp_dir.path().join("client.rs"),
r#"
use crate::config::Config;
pub struct ApiClient {
config: Config,
}
impl ApiClient {
pub fn new(config: Config) -> Self {
Self { config }
}
}
"#,
)
.unwrap();
fs::write(
temp_dir.path().join("service.rs"),
r#"
use crate::client::ApiClient;
pub struct PaymentService {
client: ApiClient,
}
impl PaymentService {
pub fn process_payment(&self, amount: f64) -> Result<(), Error> {
// Uses client internally
Ok(())
}
}
"#,
)
.unwrap();
let mut cmd = Command::cargo_bin("context-creator").unwrap();
cmd.arg("search")
.arg("process_payment")
.arg(temp_dir.path())
.assert()
.success()
.stdout(predicate::str::contains("service.rs")) .stdout(predicate::str::contains("client.rs")) .stdout(predicate::str::contains("config.rs")) .stdout(predicate::str::contains("ApiClient")) .stdout(predicate::str::contains("Config")); }