pmat 3.16.0

PMAT - Zero-config AI context generation and code quality toolkit (CLI, MCP, HTTP)
// TDD: Bonus Detector Tests
// Tests Bonus Points Detection (+10 maximum)
// All tests should FAIL until BonusDetector is implemented

#[cfg_attr(coverage_nightly, coverage(off))]
#[cfg(test)]
mod bonus_detector_tests {
    use crate::tests::repo_score::test_utils::*;

    #[tokio::test]
    #[ignore] // RED: Will fail until BonusDetector is implemented
    async fn test_bonus_property_tests_detected() {
        // ARRANGE
        let temp_dir = create_temp_repo();
        let repo_path = temp_dir.path();
        init_git_repo(repo_path);

        // Create property test indicators
        std::fs::create_dir_all(repo_path.join(".github/workflows")).unwrap();
        std::fs::write(
            repo_path.join(".github/workflows/property-tests.yml"),
            "name: Property Tests\non: [push]\njobs:\n  test:\n    steps:\n      - run: cargo test --test proptest",
        )
        .unwrap();

        // use crate::services::repo_score::bonus::BonusDetector;
        // let detector = BonusDetector::new();
        // let bonus = detector.detect_all(repo_path).await.unwrap();

        // ASSERT
        // assert!(bonus.property_tests.detected);
        // assert_eq!(bonus.property_tests.points, 3.0);
        // assert!(bonus.property_tests.evidence.contains(&".github/workflows/property-tests.yml".to_string()));

        panic!("BonusDetector not implemented yet");
    }

    #[tokio::test]
    #[ignore] // RED: Will fail until BonusDetector is implemented
    async fn test_bonus_fuzzing_detected() {
        // ARRANGE
        let temp_dir = create_temp_repo();
        let repo_path = temp_dir.path();
        init_git_repo(repo_path);

        // Create fuzzing directory and targets
        std::fs::create_dir_all(repo_path.join("fuzz/fuzz_targets")).unwrap();
        std::fs::write(
            repo_path.join("fuzz/Cargo.toml"),
            "[package]\nname = \"fuzz\"\n",
        )
        .unwrap();
        std::fs::write(
            repo_path.join("fuzz/fuzz_targets/target1.rs"),
            "// Fuzz target\n",
        )
        .unwrap();

        // use crate::services::repo_score::bonus::BonusDetector;
        // let detector = BonusDetector::new();
        // let bonus = detector.detect_all(repo_path).await.unwrap();

        // ASSERT
        // assert!(bonus.fuzzing.detected);
        // assert_eq!(bonus.fuzzing.points, 2.0);
        // assert!(bonus.fuzzing.evidence.iter().any(|e| e.contains("fuzz")));

        panic!("BonusDetector not implemented yet");
    }

    #[tokio::test]
    #[ignore] // RED: Will fail until BonusDetector is implemented
    async fn test_bonus_mutation_testing_detected() {
        // ARRANGE
        let temp_dir = create_temp_repo();
        let repo_path = temp_dir.path();
        init_git_repo(repo_path);

        // Create mutants.toml configuration
        let mutants_config = r#"
[[mutants]]
name = "main"
path = "src"

[config]
timeout_multiplier = 5.0
"#;
        std::fs::write(repo_path.join("mutants.toml"), mutants_config).unwrap();

        // use crate::services::repo_score::bonus::BonusDetector;
        // let detector = BonusDetector::new();
        // let bonus = detector.detect_all(repo_path).await.unwrap();

        // ASSERT
        // assert!(bonus.mutation_testing.detected);
        // assert_eq!(bonus.mutation_testing.points, 2.0);
        // assert!(bonus.mutation_testing.evidence.contains(&"mutants.toml".to_string()));

        panic!("BonusDetector not implemented yet");
    }

    #[tokio::test]
    #[ignore] // RED: Will fail until BonusDetector is implemented
    async fn test_bonus_living_docs_detected() {
        // ARRANGE
        let temp_dir = create_temp_repo();
        let repo_path = temp_dir.path();
        init_git_repo(repo_path);

        // Create mdBook structure
        std::fs::create_dir_all(repo_path.join("docs/book/src")).unwrap();
        std::fs::write(
            repo_path.join("docs/book/book.toml"),
            "[book]\ntitle = \"Test Book\"\n",
        )
        .unwrap();
        std::fs::write(
            repo_path.join("docs/book/src/SUMMARY.md"),
            "# Summary\n\n- [Chapter 1](./chapter_1.md)\n",
        )
        .unwrap();

        // use crate::services::repo_score::bonus::BonusDetector;
        // let detector = BonusDetector::new();
        // let bonus = detector.detect_all(repo_path).await.unwrap();

        // ASSERT
        // assert!(bonus.living_docs.detected);
        // assert_eq!(bonus.living_docs.points, 3.0);
        // assert!(bonus.living_docs.evidence.iter().any(|e| e.contains("book.toml")));

        panic!("BonusDetector not implemented yet");
    }

    #[tokio::test]
    #[ignore] // RED: Will fail until BonusDetector is implemented
    async fn test_bonus_all_detected_maximum_points() {
        // ARRANGE
        let temp_dir = create_temp_repo();
        let repo_path = temp_dir.path();
        init_git_repo(repo_path);

        // Create ALL bonus indicators
        // Property tests
        std::fs::create_dir_all(repo_path.join(".github/workflows")).unwrap();
        std::fs::write(
            repo_path.join(".github/workflows/property-tests.yml"),
            "name: Property Tests",
        )
        .unwrap();

        // Fuzzing
        std::fs::create_dir_all(repo_path.join("fuzz/fuzz_targets")).unwrap();
        std::fs::write(repo_path.join("fuzz/Cargo.toml"), "[package]").unwrap();

        // Mutation testing
        std::fs::write(repo_path.join("mutants.toml"), "[[mutants]]").unwrap();

        // Living docs
        std::fs::create_dir_all(repo_path.join("docs/book")).unwrap();
        std::fs::write(repo_path.join("docs/book/book.toml"), "[book]").unwrap();

        // use crate::services::repo_score::bonus::BonusDetector;
        // let detector = BonusDetector::new();
        // let bonus = detector.detect_all(repo_path).await.unwrap();

        // ASSERT
        // All bonuses detected = 10 points total
        // assert_eq!(bonus.total(), 10.0);
        // assert!(bonus.property_tests.detected);
        // assert!(bonus.fuzzing.detected);
        // assert!(bonus.mutation_testing.detected);
        // assert!(bonus.living_docs.detected);

        panic!("BonusDetector not implemented yet");
    }

    #[tokio::test]
    #[ignore] // RED: Will fail until BonusDetector is implemented
    async fn test_bonus_none_detected() {
        // ARRANGE
        let temp_dir = create_temp_repo();
        let repo_path = temp_dir.path();
        init_git_repo(repo_path);
        // Minimal repo with no bonus features

        // use crate::services::repo_score::bonus::BonusDetector;
        // let detector = BonusDetector::new();
        // let bonus = detector.detect_all(repo_path).await.unwrap();

        // ASSERT
        // assert_eq!(bonus.total(), 0.0);
        // assert!(!bonus.property_tests.detected);
        // assert!(!bonus.fuzzing.detected);
        // assert!(!bonus.mutation_testing.detected);
        // assert!(!bonus.living_docs.detected);

        panic!("BonusDetector not implemented yet");
    }

    #[tokio::test]
    #[ignore] // RED: Will fail until BonusDetector is implemented
    async fn test_bonus_partial_detection() {
        // ARRANGE
        let temp_dir = create_temp_repo();
        let repo_path = temp_dir.path();
        init_git_repo(repo_path);

        // Only property tests and living docs
        std::fs::create_dir_all(repo_path.join(".github/workflows")).unwrap();
        std::fs::write(
            repo_path.join(".github/workflows/property-tests.yml"),
            "property tests",
        )
        .unwrap();
        std::fs::create_dir_all(repo_path.join("docs/book")).unwrap();
        std::fs::write(repo_path.join("docs/book/book.toml"), "[book]").unwrap();

        // use crate::services::repo_score::bonus::BonusDetector;
        // let detector = BonusDetector::new();
        // let bonus = detector.detect_all(repo_path).await.unwrap();

        // ASSERT
        // 3 + 3 = 6 points
        // assert_eq!(bonus.total(), 6.0);
        // assert!(bonus.property_tests.detected);
        // assert!(bonus.living_docs.detected);
        // assert!(!bonus.fuzzing.detected);
        // assert!(!bonus.mutation_testing.detected);

        panic!("BonusDetector not implemented yet");
    }

    #[tokio::test]
    #[ignore] // RED: Will fail until BonusDetector is implemented
    async fn test_bonus_cargo_mutants_alternative() {
        // Test that cargo-mutants (alternative to mutants.toml) is also detected
        let temp_dir = create_temp_repo();
        let repo_path = temp_dir.path();
        init_git_repo(repo_path);

        // Create .cargo-mutants.toml instead
        std::fs::write(
            repo_path.join(".cargo-mutants.toml"),
            "timeout_multiplier = 5.0",
        )
        .unwrap();

        // use crate::services::repo_score::bonus::BonusDetector;
        // let detector = BonusDetector::new();
        // let bonus = detector.detect_all(repo_path).await.unwrap();

        // ASSERT
        // assert!(bonus.mutation_testing.detected);
        // assert_eq!(bonus.mutation_testing.points, 2.0);

        panic!("BonusDetector not implemented yet");
    }

    #[tokio::test]
    #[ignore] // RED: Will fail until BonusDetector is implemented
    async fn test_bonus_jupyter_book_alternative() {
        // Test that Jupyter Book is also recognized as living docs
        let temp_dir = create_temp_repo();
        let repo_path = temp_dir.path();
        init_git_repo(repo_path);

        // Create Jupyter Book structure
        std::fs::create_dir_all(repo_path.join("docs")).unwrap();
        std::fs::write(
            repo_path.join("docs/_config.yml"),
            "title: Test Book\n",
        )
        .unwrap();
        std::fs::write(
            repo_path.join("docs/_toc.yml"),
            "format: jb-book\n",
        )
        .unwrap();

        // use crate::services::repo_score::bonus::BonusDetector;
        // let detector = BonusDetector::new();
        // let bonus = detector.detect_all(repo_path).await.unwrap();

        // ASSERT
        // assert!(bonus.living_docs.detected);
        // assert!(bonus.living_docs.evidence.iter().any(|e| e.contains("_config.yml")));

        panic!("BonusDetector not implemented yet");
    }
}