pmat 3.26.0

PMAT - Zero-config AI context generation and code quality toolkit (CLI, MCP, HTTP)
// Tests for quality gate handlers
// This file is included by quality_handlers.rs via include!()
// NO `use` imports or `#!` inner attributes allowed

#[cfg_attr(coverage_nightly, coverage(off))]
#[cfg(test)]
mod tests {
    use super::*;
    use serde_json::json;
    use tokio_util::sync::CancellationToken;

    fn test_extra() -> RequestHandlerExtra {
        RequestHandlerExtra::new("test-request".to_string(), CancellationToken::new())
    }

    // === QualityGateTool Tests ===

    #[test]
    fn test_quality_gate_tool_new() {
        let tool = QualityGateTool::new();
        // Verify creation succeeds
        let _ = tool;
    }

    #[test]
    fn test_quality_gate_tool_default() {
        let tool = QualityGateTool;
        let _ = tool;
    }

    #[tokio::test]
    async fn test_quality_gate_tool_invalid_args() {
        let tool = QualityGateTool::new();
        let args = json!({"invalid": "args"});
        let result = tool.handle(args, test_extra()).await;
        assert!(result.is_err());
        let err = result.unwrap_err();
        assert!(err.to_string().contains("Invalid arguments"));
    }

    #[tokio::test]
    async fn test_quality_gate_tool_missing_paths() {
        let tool = QualityGateTool::new();
        let args = json!({});
        let result = tool.handle(args, test_extra()).await;
        assert!(result.is_err());
    }

    #[tokio::test]
    async fn test_quality_gate_tool_empty_paths() {
        let tool = QualityGateTool::new();
        let args = json!({"paths": []});
        let result = tool.handle(args, test_extra()).await;
        // Empty paths should return error from tool_functions
        assert!(result.is_err());
    }

    #[tokio::test]
    async fn test_quality_gate_tool_with_strict() {
        let tool = QualityGateTool::new();
        let args = json!({
            "paths": ["/nonexistent/path"],
            "strict": true
        });
        let result = tool.handle(args, test_extra()).await;
        // Should succeed (graceful handling of nonexistent paths)
        assert!(result.is_ok());
    }

    #[tokio::test]
    async fn test_quality_gate_tool_with_file() {
        let tool = QualityGateTool::new();
        let args = json!({
            "paths": ["."],
            "file": "/nonexistent/specific/file.rs"
        });
        let result = tool.handle(args, test_extra()).await;
        // Should fail because file doesn't exist
        assert!(result.is_err());
    }

    #[tokio::test]
    async fn test_quality_gate_tool_strict_false() {
        let tool = QualityGateTool::new();
        let args = json!({
            "paths": ["/nonexistent/path"],
            "strict": false
        });
        let result = tool.handle(args, test_extra()).await;
        assert!(result.is_ok());
    }

    // === QualityGateSummaryTool Tests ===

    #[test]
    fn test_quality_gate_summary_tool_new() {
        let tool = QualityGateSummaryTool::new();
        let _ = tool;
    }

    #[test]
    fn test_quality_gate_summary_tool_default() {
        let tool = QualityGateSummaryTool;
        let _ = tool;
    }

    #[tokio::test]
    async fn test_quality_gate_summary_tool_invalid_args() {
        let tool = QualityGateSummaryTool::new();
        let args = json!({"invalid": "args"});
        let result = tool.handle(args, test_extra()).await;
        assert!(result.is_err());
        let err = result.unwrap_err();
        assert!(err.to_string().contains("Invalid arguments"));
    }

    #[tokio::test]
    async fn test_quality_gate_summary_tool_missing_paths() {
        let tool = QualityGateSummaryTool::new();
        let args = json!({});
        let result = tool.handle(args, test_extra()).await;
        assert!(result.is_err());
    }

    #[tokio::test]
    async fn test_quality_gate_summary_tool_empty_paths() {
        let tool = QualityGateSummaryTool::new();
        let args = json!({"paths": []});
        let result = tool.handle(args, test_extra()).await;
        assert!(result.is_err());
    }

    #[tokio::test]
    async fn test_quality_gate_summary_tool_json_format() {
        let tool = QualityGateSummaryTool::new();
        let args = json!({
            "paths": ["/nonexistent/path"],
            "format": "json"
        });
        let result = tool.handle(args, test_extra()).await;
        assert!(result.is_ok());
    }

    #[tokio::test]
    async fn test_quality_gate_summary_tool_markdown_format() {
        let tool = QualityGateSummaryTool::new();
        let args = json!({
            "paths": ["/nonexistent/path"],
            "format": "markdown"
        });
        let result = tool.handle(args, test_extra()).await;
        assert!(result.is_ok());
        let value = result.unwrap();
        assert!(value.get("markdown").is_some());
    }

    #[tokio::test]
    async fn test_quality_gate_summary_tool_unsupported_format() {
        let tool = QualityGateSummaryTool::new();
        let args = json!({
            "paths": ["/nonexistent/path"],
            "format": "xml"
        });
        let result = tool.handle(args, test_extra()).await;
        assert!(result.is_err());
        let err = result.unwrap_err();
        assert!(err.to_string().contains("Unsupported format"));
    }

    #[tokio::test]
    async fn test_quality_gate_summary_tool_default_format() {
        let tool = QualityGateSummaryTool::new();
        let args = json!({
            "paths": ["/nonexistent/path"]
        });
        let result = tool.handle(args, test_extra()).await;
        // Default format (json) should work
        assert!(result.is_ok());
    }

    // === QualityGateBaselineTool Tests ===

    #[test]
    fn test_quality_gate_baseline_tool_new() {
        let tool = QualityGateBaselineTool::new();
        let _ = tool;
    }

    #[test]
    fn test_quality_gate_baseline_tool_default() {
        let tool = QualityGateBaselineTool;
        let _ = tool;
    }

    #[tokio::test]
    async fn test_quality_gate_baseline_tool_invalid_args() {
        let tool = QualityGateBaselineTool::new();
        let args = json!({"invalid": "args"});
        let result = tool.handle(args, test_extra()).await;
        assert!(result.is_err());
        let err = result.unwrap_err();
        assert!(err.to_string().contains("Invalid arguments"));
    }

    #[tokio::test]
    async fn test_quality_gate_baseline_tool_missing_paths() {
        let tool = QualityGateBaselineTool::new();
        let args = json!({});
        let result = tool.handle(args, test_extra()).await;
        assert!(result.is_err());
    }

    #[tokio::test]
    async fn test_quality_gate_baseline_tool_empty_paths() {
        let tool = QualityGateBaselineTool::new();
        let args = json!({"paths": []});
        let result = tool.handle(args, test_extra()).await;
        assert!(result.is_err());
    }

    #[tokio::test]
    async fn test_quality_gate_baseline_tool_with_output() {
        let tool = QualityGateBaselineTool::new();
        let args = json!({
            "paths": ["/nonexistent/path"],
            "output": "/tmp/baseline.json"
        });
        let result = tool.handle(args, test_extra()).await;
        // Should succeed and create baseline
        assert!(result.is_ok());
    }

    #[tokio::test]
    async fn test_quality_gate_baseline_tool_without_output() {
        let tool = QualityGateBaselineTool::new();
        let args = json!({
            "paths": ["/nonexistent/path"]
        });
        let result = tool.handle(args, test_extra()).await;
        assert!(result.is_ok());
    }

    // === QualityGateCompareTool Tests ===

    #[test]
    fn test_quality_gate_compare_tool_new() {
        let tool = QualityGateCompareTool::new();
        let _ = tool;
    }

    #[test]
    fn test_quality_gate_compare_tool_default() {
        let tool = QualityGateCompareTool;
        let _ = tool;
    }

    #[tokio::test]
    async fn test_quality_gate_compare_tool_invalid_args() {
        let tool = QualityGateCompareTool::new();
        let args = json!({"invalid": "args"});
        let result = tool.handle(args, test_extra()).await;
        assert!(result.is_err());
        let err = result.unwrap_err();
        assert!(err.to_string().contains("Invalid arguments"));
    }

    #[tokio::test]
    async fn test_quality_gate_compare_tool_missing_baseline() {
        let tool = QualityGateCompareTool::new();
        let args = json!({"paths": ["."]});
        let result = tool.handle(args, test_extra()).await;
        assert!(result.is_err());
    }

    #[tokio::test]
    async fn test_quality_gate_compare_tool_missing_paths() {
        let tool = QualityGateCompareTool::new();
        let args = json!({"baseline": "/tmp/baseline.json"});
        let result = tool.handle(args, test_extra()).await;
        assert!(result.is_err());
    }

    #[tokio::test]
    async fn test_quality_gate_compare_tool_empty_paths() {
        let tool = QualityGateCompareTool::new();
        let args = json!({
            "baseline": "/tmp/baseline.json",
            "paths": []
        });
        let result = tool.handle(args, test_extra()).await;
        assert!(result.is_err());
    }

    #[tokio::test]
    async fn test_quality_gate_compare_tool_nonexistent_baseline() {
        let tool = QualityGateCompareTool::new();
        let args = json!({
            "baseline": "/nonexistent/baseline.json",
            "paths": ["."]
        });
        let result = tool.handle(args, test_extra()).await;
        // Should fail because baseline doesn't exist
        assert!(result.is_err());
    }

    // === QualityGateArgs Deserialization Tests ===

    #[test]
    fn test_quality_gate_args_deserialize_minimal() {
        let json = json!({"paths": ["/path/to/project"]});
        let args: QualityGateArgs = serde_json::from_value(json).unwrap();
        assert_eq!(args.paths, vec!["/path/to/project"]);
        assert!(!args.strict);
        assert!(args.file.is_none());
    }

    #[test]
    fn test_quality_gate_args_deserialize_full() {
        let json = json!({
            "paths": ["/path1", "/path2"],
            "strict": true,
            "file": "/specific/file.rs"
        });
        let args: QualityGateArgs = serde_json::from_value(json).unwrap();
        assert_eq!(args.paths, vec!["/path1", "/path2"]);
        assert!(args.strict);
        assert_eq!(args.file, Some("/specific/file.rs".to_string()));
    }

    // === QualityGateSummaryArgs Deserialization Tests ===

    #[test]
    fn test_quality_gate_summary_args_deserialize_minimal() {
        let json = json!({"paths": ["/path"]});
        let args: QualityGateSummaryArgs = serde_json::from_value(json).unwrap();
        assert_eq!(args.paths, vec!["/path"]);
        assert!(args.format.is_none());
    }

    #[test]
    fn test_quality_gate_summary_args_deserialize_full() {
        let json = json!({
            "paths": ["/path1", "/path2"],
            "format": "markdown"
        });
        let args: QualityGateSummaryArgs = serde_json::from_value(json).unwrap();
        assert_eq!(args.paths, vec!["/path1", "/path2"]);
        assert_eq!(args.format, Some("markdown".to_string()));
    }

    // === QualityGateBaselineArgs Deserialization Tests ===

    #[test]
    fn test_quality_gate_baseline_args_deserialize_minimal() {
        let json = json!({"paths": ["/path"]});
        let args: QualityGateBaselineArgs = serde_json::from_value(json).unwrap();
        assert_eq!(args.paths, vec!["/path"]);
        assert!(args.output.is_none());
    }

    #[test]
    fn test_quality_gate_baseline_args_deserialize_full() {
        let json = json!({
            "paths": ["/path"],
            "output": "/output/baseline.json"
        });
        let args: QualityGateBaselineArgs = serde_json::from_value(json).unwrap();
        assert_eq!(args.paths, vec!["/path"]);
        assert_eq!(args.output, Some("/output/baseline.json".to_string()));
    }

    // === QualityGateCompareArgs Deserialization Tests ===

    #[test]
    fn test_quality_gate_compare_args_deserialize() {
        let json = json!({
            "baseline": "/path/to/baseline.json",
            "paths": ["/path1", "/path2"]
        });
        let args: QualityGateCompareArgs = serde_json::from_value(json).unwrap();
        assert_eq!(args.baseline, "/path/to/baseline.json");
        assert_eq!(args.paths, vec!["/path1", "/path2"]);
    }

    #[test]
    fn test_quality_gate_compare_args_deserialize_missing_baseline() {
        let json = json!({"paths": ["/path"]});
        let result: std::result::Result<QualityGateCompareArgs, serde_json::Error> =
            serde_json::from_value(json);
        assert!(result.is_err());
    }

    #[test]
    fn test_quality_gate_compare_args_deserialize_missing_paths() {
        let json = json!({"baseline": "/baseline.json"});
        let result: std::result::Result<QualityGateCompareArgs, serde_json::Error> =
            serde_json::from_value(json);
        assert!(result.is_err());
    }
}