use std::collections::HashMap;
use std::process::Command;
use std::time::Duration;
use tracing::Level;
use vibe_tests::EngineTests;
vibe_tests::engine_config! {
EngineTests::builder()
.compose_file("tests/fixtures/docker-compose.yml")
.mcp_host("http://localhost:9021/mcp/v1")
.ollama_host("http://localhost:11434")
.ollama_models(&["qwen2.5-coder:3b-instruct"])
.ollama_exclusive(true)
.on_start(|env| async move {
let app = "vibe-analyzer";
Command::new(&app)
.stdout(env.tee.clone())
.stderr(env.tee.clone())
.env("HOME", &env.home)
.args(["--config", "tests/fixtures/config.json5", "scan", "index"])
.status()
.expect("Failed to index");
let child = Command::new(&app)
.stdout(env.tee.clone())
.stderr(env.tee.clone())
.env("HOME", &env.home)
.args(["--config", "tests/fixtures/config.json5", "serve", "start"])
.spawn()
.expect("Failed to start MCP server");
Ok(Some(HashMap::from([
("pid".into(), child.id().to_string())
])))
})
.on_stop(|env| {
if let Some(data) = &env.data {
if let Some(pid) = data.get("pid") {
let _ = Command::new("kill").arg("-9").arg(pid).status();
}
}
let report_dir = std::path::PathBuf::from("tests/reports")
.join(chrono::Utc::now().format("%Y-%m-%d_%H-%M-%S").to_string());
std::fs::create_dir_all(&report_dir).ok();
std::fs::copy(&env.log_file, report_dir.join("test.log")).ok();
if let Ok(json) = serde_json::to_string_pretty(&env.report) {
std::fs::write(report_dir.join("report.json"), json).ok();
}
})
.on_log(|event| {
println!("{}", event.message)
})
.log_level(Level::ERROR)
.timeout(Duration::from_secs(60))
.build()
.expect("Failed to build engine")
}
#[tokio::test]
async fn test_admin_sync() {
let engine = vibe_tests::engine().await;
let result = engine.test("Обнови индекс").await;
assert!(result.success);
assert!(
result
.models
.iter()
.all(|m| m.tool.as_deref() == Some("admin_sync"))
);
}
#[tokio::test]
async fn test_search_docs_git() {
let engine = vibe_tests::engine().await;
let result = engine.test("Найди документацию по 'Git' воркфлоу").await;
assert!(result.success);
assert!(
result
.models
.iter()
.all(|m| m.tool.as_deref() == Some("search_documentation"))
);
}
#[tokio::test]
async fn test_show_tree_samples_error() {
let engine = vibe_tests::engine().await;
let result = engine.test("Call tool 'nonexistent_tool_xyz'").await;
assert!(!result.success, "Expected failure but got success");
}