#![cfg(feature = "agent-daemon")]
#[cfg(test)]
mod agent_tests {
use pmat::agent::{
AgentConfig, AgentDaemon, ClaudeCodeAgentMcpServer, DaemonConfig, ProjectState,
QualityThresholds, StatePersistence,
};
use pmat::services::quality_gate_service::{
QualityCheck, QualityGateInput, QualityGateService,
};
use pmat::services::service_base::Service;
use std::path::PathBuf;
use tempfile::TempDir;
use tokio::time::{sleep, Duration};
#[tokio::test]
#[ignore] async fn test_mcp_server_initialization() {
let config = AgentConfig::default();
let _server = ClaudeCodeAgentMcpServer::new(config);
}
#[tokio::test]
async fn test_daemon_lifecycle() {
let config = DaemonConfig::default();
let mut daemon = AgentDaemon::new(config);
let start_handle = tokio::spawn(async move { daemon.start().await });
sleep(Duration::from_millis(100)).await;
start_handle.abort();
}
#[tokio::test]
async fn test_state_persistence() {
let temp_dir = TempDir::new().unwrap();
let persistence = StatePersistence::new(temp_dir.path()).unwrap();
let project = ProjectState {
id: "test_project".to_string(),
path: PathBuf::from("/test/path"),
started_at: chrono::Utc::now(),
last_analyzed: None,
current_metrics: Default::default(),
watch_patterns: vec!["*.rs".to_string()],
thresholds: QualityThresholds::default(),
};
persistence.add_project(project.clone()).await.unwrap();
persistence.save().await.unwrap();
let persistence2 = StatePersistence::new(temp_dir.path()).unwrap();
let state = persistence2.get_state().await;
assert!(state.monitored_projects.contains_key("test_project"));
assert_eq!(
state.monitored_projects["test_project"].path,
PathBuf::from("/test/path")
);
}
#[tokio::test]
async fn test_quality_gate_integration() {
let service = QualityGateService::new();
let input = QualityGateInput {
path: PathBuf::from("."),
checks: vec![
QualityCheck::Complexity { max: 20 },
QualityCheck::Satd { tolerance: 0 },
],
strict: true,
};
let result = service.process(input).await.unwrap();
assert!(!result.results.is_empty());
assert!(result.summary.total_checks > 0);
}
#[tokio::test]
async fn test_metrics_update() {
let temp_dir = TempDir::new().unwrap();
let persistence = StatePersistence::new(temp_dir.path()).unwrap();
let project = ProjectState {
id: "metrics_test".to_string(),
path: PathBuf::from("/test"),
started_at: chrono::Utc::now(),
last_analyzed: None,
current_metrics: Default::default(),
watch_patterns: vec![],
thresholds: QualityThresholds::default(),
};
persistence.add_project(project).await.unwrap();
let metrics = pmat::agent::PersistentQualityMetrics {
avg_complexity: 5.5,
max_complexity: 15,
satd_count: 0,
dead_code_percentage: 2.5,
quality_score: 92.0,
files_analyzed: 100,
total_violations: 0,
};
persistence
.update_metrics("metrics_test", metrics)
.await
.unwrap();
let state = persistence.get_state().await;
assert_eq!(
state.monitored_projects["metrics_test"]
.current_metrics
.avg_complexity,
5.5
);
assert!(!state.quality_history.is_empty());
}
#[tokio::test]
async fn test_statistics_tracking() {
let temp_dir = TempDir::new().unwrap();
let persistence = StatePersistence::new(temp_dir.path()).unwrap();
persistence
.update_statistics(|stats| {
stats.sessions_count += 1;
stats.analyses_performed += 10;
stats.violations_detected += 5;
})
.await
.unwrap();
let state = persistence.get_state().await;
assert_eq!(state.statistics.sessions_count, 1);
assert_eq!(state.statistics.analyses_performed, 10);
assert_eq!(state.statistics.violations_detected, 5);
}
#[tokio::test]
async fn test_configuration_loading() {
let dev_config = r#"
[agent]
version = "1.0.0"
name = "test"
complexity_threshold = 20
watch_patterns = ["**/*.rs"]
update_interval = 30
max_projects = 10
[quality_monitor]
update_interval = { secs = 5, nanos = 0 }
complexity_threshold = 20
watch_patterns = ["**/*.rs"]
debounce_interval = { secs = 0, nanos = 500000000 }
max_batch_size = 50
[daemon]
working_directory = "/tmp"
health_check_interval = { secs = 30, nanos = 0 }
max_memory_mb = 500
auto_restart = true
shutdown_timeout = { secs = 10, nanos = 0 }
"#;
let config: DaemonConfig = toml::from_str(dev_config).unwrap();
assert_eq!(config.agent.complexity_threshold, 20);
}
}
#[cfg(test)]
mod mcp_protocol_tests {
use serde_json::json;
#[test]
fn test_mcp_request_format() {
let request = json!({
"jsonrpc": "2.0",
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"capabilities": {}
},
"id": 1
});
assert_eq!(request["jsonrpc"], "2.0");
assert_eq!(request["method"], "initialize");
assert!(request["id"].is_number());
}
#[test]
fn test_mcp_response_format() {
let response = json!({
"jsonrpc": "2.0",
"id": 1,
"result": {
"protocolVersion": "2024-11-05",
"serverInfo": {
"name": "pmat-agent",
"version": "1.0.0"
}
}
});
assert_eq!(response["jsonrpc"], "2.0");
assert!(response["result"].is_object());
assert!(response["result"]["serverInfo"].is_object());
}
#[test]
fn test_tool_call_format() {
let tool_call = json!({
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "run_quality_gates",
"arguments": {
"target_path": "./src"
}
},
"id": 42
});
assert_eq!(tool_call["method"], "tools/call");
assert_eq!(tool_call["params"]["name"], "run_quality_gates");
assert!(tool_call["params"]["arguments"].is_object());
}
}