use pmat::mcp_server::{McpServer, StateManager};
use pmat::models::refactor::RefactorConfig;
use serde_json::json;
use std::path::PathBuf;
use std::sync::Arc;
use tokio::sync::Mutex;
#[tokio::test]
async fn test_state_manager_lifecycle() {
use tempfile::tempdir;
let temp_dir = tempdir().unwrap();
let mut manager = StateManager::with_temp_dir(temp_dir.path());
assert!(
manager.get_state().is_err(),
"Should not have state initially"
);
let targets = vec![PathBuf::from("test.rs")];
let config = RefactorConfig::default();
manager
.start_session(targets.clone(), config.clone())
.unwrap();
let state = manager.get_state().unwrap();
assert_eq!(state.targets.len(), 1);
assert_eq!(state.targets[0], PathBuf::from("test.rs"));
assert_eq!(state.config.target_complexity, config.target_complexity);
manager.advance().unwrap();
let state_after_advance = manager.get_state().unwrap();
assert_eq!(state_after_advance.targets.len(), 1);
manager.stop_session().unwrap();
assert!(
manager.get_state().is_err(),
"Should not have state after stop"
);
}
#[tokio::test]
async fn test_state_manager_multiple_sessions() {
use tempfile::tempdir;
let temp_dir = tempdir().unwrap();
let mut manager = StateManager::with_temp_dir(temp_dir.path());
let targets1 = vec![PathBuf::from("file1.rs")];
manager
.start_session(targets1, RefactorConfig::default())
.unwrap();
let state1 = manager.get_state().unwrap();
assert_eq!(state1.targets[0], PathBuf::from("file1.rs"));
manager.stop_session().unwrap();
let targets2 = vec![PathBuf::from("file2.rs"), PathBuf::from("file3.rs")];
manager
.start_session(targets2, RefactorConfig::default())
.unwrap();
let state2 = manager.get_state().unwrap();
assert_eq!(state2.targets.len(), 2);
assert_eq!(state2.targets[0], PathBuf::from("file2.rs"));
assert_eq!(state2.targets[1], PathBuf::from("file3.rs"));
manager.stop_session().unwrap();
}
#[tokio::test]
async fn test_state_manager_error_conditions() {
use tempfile::tempdir;
let temp_dir = tempdir().unwrap();
let mut manager = StateManager::with_temp_dir(temp_dir.path());
assert!(
manager.advance().is_err(),
"Should fail to advance without session"
);
assert!(
manager.stop_session().is_err(),
"Should fail to stop without session"
);
let targets = vec![PathBuf::from("test.rs")];
manager
.start_session(targets.clone(), RefactorConfig::default())
.unwrap();
let result = manager.start_session(targets, RefactorConfig::default());
assert!(result.is_err(), "Should fail to start session twice");
manager.stop_session().unwrap();
}
#[tokio::test]
async fn test_mcp_server_creation() {
let _server = McpServer::new();
}
#[ignore = "requires MCP server setup"]
#[tokio::test]
async fn test_handler_parameter_parsing() {
use pmat::mcp_server::handlers::{
handle_refactor_get_state, handle_refactor_start, handle_refactor_stop,
};
let state_manager = Arc::new(Mutex::new(StateManager::new()));
let start_params = json!({
"targets": ["src/main.rs", "src/lib.rs"],
"config": {
"target_complexity": 10,
"remove_satd": true,
"max_function_lines": 50
}
});
let start_result = handle_refactor_start(&state_manager, start_params).await;
assert!(start_result.is_ok(), "Should handle valid start parameters");
let state_result = handle_refactor_get_state(&state_manager).await;
assert!(state_result.is_ok(), "Should return current state");
let stop_result = handle_refactor_stop(&state_manager).await;
assert!(stop_result.is_ok(), "Should stop session successfully");
}
#[tokio::test]
async fn test_handler_invalid_parameters() {
use pmat::mcp_server::handlers::handle_refactor_start;
let state_manager = Arc::new(Mutex::new(StateManager::new()));
let invalid_params = json!({
"config": {
"target_complexity": 10
}
});
let result = handle_refactor_start(&state_manager, invalid_params).await;
assert!(result.is_err(), "Should fail with missing targets");
let invalid_targets = json!({
"targets": "not_an_array"
});
let result = handle_refactor_start(&state_manager, invalid_targets).await;
assert!(result.is_err(), "Should fail with invalid targets format");
let empty_targets = json!({
"targets": []
});
let _result = handle_refactor_start(&state_manager, empty_targets).await;
}
#[tokio::test]
async fn test_snapshot_persistence() {
use pmat::mcp_server::snapshots::SnapshotManager;
use pmat::models::refactor::RefactorStateMachine;
use tempfile::tempdir;
let temp_dir = tempdir().unwrap();
let _snapshot_path = temp_dir.path().join("test-snapshot.bin");
let snapshot_manager = SnapshotManager::with_path(temp_dir.path());
let config = RefactorConfig {
target_complexity: 15,
remove_satd: true,
max_function_lines: 100,
parallel_workers: 4,
memory_limit_mb: 512,
batch_size: 10,
..Default::default()
};
let state = RefactorStateMachine::new(
vec![PathBuf::from("test1.rs"), PathBuf::from("test2.rs")],
config,
);
snapshot_manager.save_snapshot(&state).unwrap();
let loaded_state = snapshot_manager.load_snapshot().unwrap();
assert_eq!(loaded_state.targets.len(), state.targets.len());
assert_eq!(loaded_state.targets[0], state.targets[0]);
assert_eq!(loaded_state.targets[1], state.targets[1]);
assert_eq!(
loaded_state.config.target_complexity,
state.config.target_complexity
);
assert_eq!(loaded_state.config.remove_satd, state.config.remove_satd);
assert_eq!(
loaded_state.config.max_function_lines,
state.config.max_function_lines
);
snapshot_manager.remove_snapshot().unwrap();
let load_result = snapshot_manager.load_snapshot();
assert!(load_result.is_err(), "Should fail to load after removal");
}
#[tokio::test]
async fn test_serialization_format() {
use pmat::mcp_server::capnp_conversion::{get_serialization_format, is_capnp_available};
let format = get_serialization_format();
let is_available = is_capnp_available();
assert_eq!(format, "JSON");
assert!(!is_available);
}
#[tokio::test]
#[ignore] async fn test_complete_workflow() {
let state_manager = Arc::new(Mutex::new(StateManager::new()));
use pmat::mcp_server::handlers::handle_refactor_start;
let start_params = json!({
"targets": ["src/main.rs"],
"config": {
"target_complexity": 20,
"remove_satd": false
}
});
let start_result = handle_refactor_start(&state_manager, start_params)
.await
.unwrap();
assert!(start_result.get("session_id").is_some());
assert!(start_result.get("state").is_some());
use pmat::mcp_server::handlers::handle_refactor_get_state;
let state_result = handle_refactor_get_state(&state_manager).await.unwrap();
assert!(state_result.is_object());
use pmat::mcp_server::handlers::handle_refactor_next_iteration;
let next_result = handle_refactor_next_iteration(&state_manager)
.await
.unwrap();
assert!(next_result.is_object());
use pmat::mcp_server::handlers::handle_refactor_stop;
let stop_result = handle_refactor_stop(&state_manager).await.unwrap();
assert_eq!(
stop_result["message"],
"Refactoring session stopped successfully"
);
let final_state_result = handle_refactor_get_state(&state_manager).await;
assert!(
final_state_result.is_err(),
"Should have no state after stop"
);
}
#[tokio::test]
async fn test_concurrent_access() {
use tempfile::tempdir;
let temp_dir = tempdir().unwrap();
let state_manager = Arc::new(Mutex::new(StateManager::with_temp_dir(temp_dir.path())));
let start_params = json!({
"targets": ["test.rs"],
"config": {}
});
use pmat::mcp_server::handlers::{handle_refactor_get_state, handle_refactor_start};
handle_refactor_start(&state_manager, start_params)
.await
.unwrap();
let mut handles = Vec::new();
for _ in 0..5 {
let manager_clone = Arc::clone(&state_manager);
let handle =
tokio::spawn(async move { handle_refactor_get_state(&manager_clone).await.unwrap() });
handles.push(handle);
}
for handle in handles {
let result = handle.await.unwrap();
assert!(result.is_object());
}
use pmat::mcp_server::handlers::handle_refactor_stop;
handle_refactor_stop(&state_manager).await.unwrap();
}