#![cfg(feature = "scala-ast")]
use pmat::agents::registry::AgentRegistry;
use pmat::mcp_integration::scala_tools::ScalaAnalysisTool;
use pmat::mcp_integration::{McpError, McpTool};
use serde_json::{json, Value};
use std::fs;
use std::sync::Arc;
use tempfile::tempdir;
#[test]
fn test_scala_analysis_tool_metadata() {
let registry = Arc::new(AgentRegistry::new());
let tool = ScalaAnalysisTool::new(registry);
let metadata = tool.metadata();
assert_eq!(metadata.name, "analyze_scala");
assert!(!metadata.description.is_empty());
assert!(metadata.description.contains("Scala"));
assert!(metadata.input_schema["properties"]["path"].is_object());
assert!(metadata.input_schema["properties"]["max_depth"].is_object());
assert!(metadata.input_schema["properties"]["include_metrics"].is_object());
assert!(metadata.input_schema["properties"]["include_ast"].is_object());
assert_eq!(metadata.input_schema["required"], json!(["path"]));
}
#[test]
fn test_scala_tool_creation() {
let registry = Arc::new(AgentRegistry::new());
let _tool = ScalaAnalysisTool::new(registry);
}
#[tokio::test]
async fn test_scala_missing_path_parameter() {
let registry = Arc::new(AgentRegistry::new());
let tool = ScalaAnalysisTool::new(registry);
let params = json!({
"max_depth": 5
});
let result = tool.execute(params).await;
assert!(result.is_err());
let err = result.unwrap_err();
assert!(err.message.contains("path") || err.message.contains("Missing"));
}
#[tokio::test]
async fn test_scala_nonexistent_path() {
let registry = Arc::new(AgentRegistry::new());
let tool = ScalaAnalysisTool::new(registry);
let params = json!({
"path": "/nonexistent/path/to/scala/file.scala"
});
let result = tool.execute(params).await;
assert!(result.is_err());
let err = result.unwrap_err();
assert!(err.message.contains("exist") || err.message.contains("not found"));
}
#[tokio::test]
async fn test_scala_null_path() {
let registry = Arc::new(AgentRegistry::new());
let tool = ScalaAnalysisTool::new(registry);
let params = json!({
"path": null
});
let result = tool.execute(params).await;
assert!(result.is_err());
}
#[tokio::test]
async fn test_scala_empty_path() {
let registry = Arc::new(AgentRegistry::new());
let tool = ScalaAnalysisTool::new(registry);
let params = json!({
"path": ""
});
let result = tool.execute(params).await;
assert!(result.is_err());
}
#[tokio::test]
async fn test_scala_max_depth_parameter() {
let temp_dir = tempdir().unwrap();
let registry = Arc::new(AgentRegistry::new());
let tool = ScalaAnalysisTool::new(registry);
let params = json!({
"path": temp_dir.path().to_str().unwrap(),
"max_depth": 5
});
let result = tool.execute(params).await;
match result {
Ok(_) | Err(_) => {}
}
}
#[tokio::test]
async fn test_scala_default_max_depth() {
let temp_dir = tempdir().unwrap();
let registry = Arc::new(AgentRegistry::new());
let tool = ScalaAnalysisTool::new(registry);
let params = json!({
"path": temp_dir.path().to_str().unwrap()
});
let result = tool.execute(params).await;
match result {
Ok(_) | Err(_) => {}
}
}
#[tokio::test]
async fn test_scala_include_metrics_true() {
let temp_dir = tempdir().unwrap();
let registry = Arc::new(AgentRegistry::new());
let tool = ScalaAnalysisTool::new(registry);
let params = json!({
"path": temp_dir.path().to_str().unwrap(),
"include_metrics": true
});
let result = tool.execute(params).await;
if let Ok(output) = result {
assert!(output.is_object());
}
}
#[tokio::test]
async fn test_scala_include_metrics_false() {
let temp_dir = tempdir().unwrap();
let registry = Arc::new(AgentRegistry::new());
let tool = ScalaAnalysisTool::new(registry);
let params = json!({
"path": temp_dir.path().to_str().unwrap(),
"include_metrics": false
});
let result = tool.execute(params).await;
if let Ok(output) = result {
assert!(output.is_object());
}
}
#[tokio::test]
async fn test_scala_include_ast_true() {
let temp_dir = tempdir().unwrap();
let registry = Arc::new(AgentRegistry::new());
let tool = ScalaAnalysisTool::new(registry);
let params = json!({
"path": temp_dir.path().to_str().unwrap(),
"include_ast": true
});
let result = tool.execute(params).await;
if let Ok(output) = result {
assert!(output.is_object());
}
}
#[tokio::test]
async fn test_scala_include_ast_false() {
let temp_dir = tempdir().unwrap();
let registry = Arc::new(AgentRegistry::new());
let tool = ScalaAnalysisTool::new(registry);
let params = json!({
"path": temp_dir.path().to_str().unwrap(),
"include_ast": false
});
let result = tool.execute(params).await;
if let Ok(output) = result {
assert!(output.is_object());
}
}
#[tokio::test]
async fn test_scala_all_parameters_combined() {
let temp_dir = tempdir().unwrap();
let registry = Arc::new(AgentRegistry::new());
let tool = ScalaAnalysisTool::new(registry);
let params = json!({
"path": temp_dir.path().to_str().unwrap(),
"max_depth": 2,
"include_metrics": true,
"include_ast": true
});
let result = tool.execute(params).await;
match result {
Ok(_) | Err(_) => {}
}
}
#[tokio::test]
async fn test_scala_single_file_analysis() {
let temp_dir = tempdir().unwrap();
let scala_file = temp_dir.path().join("Test.scala");
fs::write(
&scala_file,
r#"
object Test {
def main(args: Array[String]): Unit = {
println("Hello, Scala!")
}
}
"#,
)
.unwrap();
let registry = Arc::new(AgentRegistry::new());
let tool = ScalaAnalysisTool::new(registry);
let params = json!({
"path": scala_file.to_str().unwrap()
});
let result = tool.execute(params).await;
if let Ok(output) = result {
assert!(output.is_object());
}
}
#[tokio::test]
async fn test_scala_directory_analysis() {
let temp_dir = tempdir().unwrap();
let scala_file = temp_dir.path().join("Test.scala");
fs::write(&scala_file, "object Test {}").unwrap();
let registry = Arc::new(AgentRegistry::new());
let tool = ScalaAnalysisTool::new(registry);
let params = json!({
"path": temp_dir.path().to_str().unwrap()
});
let result = tool.execute(params).await;
if let Ok(output) = result {
assert!(output.is_object());
}
}
#[tokio::test]
async fn test_scala_empty_directory() {
let temp_dir = tempdir().unwrap();
let registry = Arc::new(AgentRegistry::new());
let tool = ScalaAnalysisTool::new(registry);
let params = json!({
"path": temp_dir.path().to_str().unwrap()
});
let result = tool.execute(params).await;
if let Ok(output) = result {
assert!(output.is_object());
}
}
#[tokio::test]
async fn test_scala_max_depth_zero() {
let temp_dir = tempdir().unwrap();
let registry = Arc::new(AgentRegistry::new());
let tool = ScalaAnalysisTool::new(registry);
let params = json!({
"path": temp_dir.path().to_str().unwrap(),
"max_depth": 0
});
let result = tool.execute(params).await;
match result {
Ok(_) | Err(_) => {}
}
}
#[tokio::test]
async fn test_scala_max_depth_negative() {
let temp_dir = tempdir().unwrap();
let registry = Arc::new(AgentRegistry::new());
let tool = ScalaAnalysisTool::new(registry);
let params = json!({
"path": temp_dir.path().to_str().unwrap(),
"max_depth": -1
});
let result = tool.execute(params).await;
match result {
Ok(_) | Err(_) => {}
}
}
#[tokio::test]
async fn test_scala_very_large_max_depth() {
let temp_dir = tempdir().unwrap();
let registry = Arc::new(AgentRegistry::new());
let tool = ScalaAnalysisTool::new(registry);
let params = json!({
"path": temp_dir.path().to_str().unwrap(),
"max_depth": 9999
});
let result = tool.execute(params).await;
match result {
Ok(_) | Err(_) => {}
}
}
#[tokio::test]
async fn test_scala_non_scala_file() {
let temp_dir = tempdir().unwrap();
let txt_file = temp_dir.path().join("test.txt");
fs::write(&txt_file, "not scala code").unwrap();
let registry = Arc::new(AgentRegistry::new());
let tool = ScalaAnalysisTool::new(registry);
let params = json!({
"path": txt_file.to_str().unwrap()
});
let result = tool.execute(params).await;
match result {
Ok(_) | Err(_) => {}
}
}
#[tokio::test]
async fn test_scala_simple_object() {
let temp_dir = tempdir().unwrap();
let scala_file = temp_dir.path().join("Simple.scala");
fs::write(
&scala_file,
r#"
object Simple {
val x = 42
}
"#,
)
.unwrap();
let registry = Arc::new(AgentRegistry::new());
let tool = ScalaAnalysisTool::new(registry);
let params = json!({
"path": scala_file.to_str().unwrap(),
"include_metrics": true
});
let result = tool.execute(params).await;
if let Ok(output) = result {
assert!(output.is_object());
}
}
#[tokio::test]
async fn test_scala_class_with_methods() {
let temp_dir = tempdir().unwrap();
let scala_file = temp_dir.path().join("Calculator.scala");
fs::write(
&scala_file,
r#"
class Calculator {
def add(a: Int, b: Int): Int = a + b
def subtract(a: Int, b: Int): Int = a - b
def multiply(a: Int, b: Int): Int = a * b
}
"#,
)
.unwrap();
let registry = Arc::new(AgentRegistry::new());
let tool = ScalaAnalysisTool::new(registry);
let params = json!({
"path": scala_file.to_str().unwrap(),
"include_metrics": true,
"include_ast": true
});
let result = tool.execute(params).await;
if let Ok(output) = result {
assert!(output.is_object());
}
}
#[tokio::test]
async fn test_scala_complex_code() {
let temp_dir = tempdir().unwrap();
let scala_file = temp_dir.path().join("Complex.scala");
fs::write(
&scala_file,
r#"
object Complex {
def fibonacci(n: Int): Int = n match {
case 0 => 0
case 1 => 1
case _ => fibonacci(n - 1) + fibonacci(n - 2)
}
def factorial(n: Int): Int = {
if (n <= 1) 1
else n * factorial(n - 1)
}
}
"#,
)
.unwrap();
let registry = Arc::new(AgentRegistry::new());
let tool = ScalaAnalysisTool::new(registry);
let params = json!({
"path": scala_file.to_str().unwrap(),
"include_metrics": true
});
let result = tool.execute(params).await;
if let Ok(output) = result {
assert!(output.is_object());
}
}
#[tokio::test]
async fn test_scala_concurrent_analysis() {
let temp_dir = tempdir().unwrap();
let scala_file = temp_dir.path().join("Test.scala");
fs::write(&scala_file, "object Test {}").unwrap();
let registry = Arc::new(AgentRegistry::new());
let mut handles = vec![];
for _ in 0..5 {
let tool = ScalaAnalysisTool::new(registry.clone());
let path = scala_file.to_str().unwrap().to_string();
let handle = tokio::spawn(async move {
let params = json!({
"path": path
});
tool.execute(params).await
});
handles.push(handle);
}
for handle in handles {
let _ = handle.await;
}
}