code-system-graph 1.0.2

CLI, MCP, and HTTP delivery for local multi-repository code intelligence.
Documentation
//! End-to-end coverage for effective native discovery configuration.

use std::process::Command;

use code_system_graph::ConfigReport;
use code_system_graph_core::{ExecutionPolicy, ExtractionBudgets};

#[test]
fn config_show_should_report_defaults_and_selected_repository_rules() -> anyhow::Result<()> {
    let temporary = tempfile::tempdir()?;
    std::fs::create_dir_all(temporary.path().join("api"))?;
    std::fs::create_dir_all(temporary.path().join("worker"))?;
    std::fs::write(
        temporary.path().join("worker/.code-system-graph.yaml"),
        "version: 1\nexcludes:\n  - generated/**\n",
    )?;
    let manifest = temporary.path().join("code-system-graph.yaml");
    std::fs::write(
        &manifest,
        "version: 1\nname: configuration\nrepos:\n  api:\n    path: api\n    excludes:\n      - ./coverage//./**\n    includeDefaults:\n      - ./vendor//internal-sdk/./**\n  worker:\n    path: worker\n",
    )?;

    let output = Command::new(env!("CARGO_BIN_EXE_csgraph"))
        .args(["config", "show", "--config"])
        .arg(&manifest)
        .args(["--repo", "api"])
        .output()?;
    let report: ConfigReport = serde_json::from_slice(&output.stdout)?;

    assert!(
        output.status.success(),
        "stderr: {}",
        String::from_utf8_lossy(&output.stderr)
    );
    assert_eq!(report.schema_version, 1);
    assert_eq!(report.workspace, "configuration");
    assert_eq!(report.extraction_budgets, ExtractionBudgets::default());
    assert_eq!(report.execution_policy, ExecutionPolicy::default());
    assert_eq!(
        report.execution_policy_fingerprint,
        ExecutionPolicy::default().fingerprint()
    );
    assert_eq!(report.repositories.len(), 1);
    assert_eq!(report.repositories[0].alias, "api");
    assert_eq!(
        report.repositories[0]
            .ignore_policy
            .configured_excludes
            .patterns,
        vec!["coverage/**"]
    );
    assert_eq!(
        report.repositories[0]
            .ignore_policy
            .include_defaults
            .patterns,
        vec!["vendor/internal-sdk/**"]
    );
    assert!(
        report.repositories[0]
            .ignore_policy
            .default_excludes
            .iter()
            .any(|pattern| pattern.contains("node_modules"))
    );
    assert!(
        report.repositories[0]
            .ignore_policy
            .protected_excludes
            .iter()
            .any(|pattern| pattern.contains(".code-system-graph"))
    );
    Ok(())
}

#[test]
fn config_show_should_report_effective_execution_policy() -> anyhow::Result<()> {
    let temporary = tempfile::tempdir()?;
    std::fs::create_dir_all(temporary.path().join("api"))?;
    let manifest = temporary.path().join("code-system-graph.yaml");
    std::fs::write(
        &manifest,
        "version: 1\nname: configuration\nexecutionPolicy:\n  maxScanWallTimeMs: 28800000\n  maxNoProgressTimeMs: 600000\nrepos:\n  api:\n    path: api\n",
    )?;

    let output = Command::new(env!("CARGO_BIN_EXE_csgraph"))
        .args(["config", "show", "--config"])
        .arg(&manifest)
        .output()?;
    let report: ConfigReport = serde_json::from_slice(&output.stdout)?;

    assert!(output.status.success());
    assert_eq!(report.execution_policy.max_scan_wall_time_ms, 28_800_000);
    assert_eq!(report.execution_policy.max_no_progress_time_ms, 600_000);
    assert_eq!(
        report.execution_policy.max_worker_memory_bytes,
        ExecutionPolicy::default().max_worker_memory_bytes
    );
    assert_eq!(
        report.execution_policy_fingerprint,
        report.execution_policy.fingerprint()
    );
    Ok(())
}

#[test]
fn config_show_should_report_effective_budget_overrides() -> anyhow::Result<()> {
    let temporary = tempfile::tempdir()?;
    std::fs::create_dir_all(temporary.path().join("api"))?;
    let manifest = temporary.path().join("code-system-graph.yaml");
    std::fs::write(
        &manifest,
        "version: 1\nname: configuration\nextractionBudgets:\n  maxInputBytesPerArtifact: 1234\nrepos:\n  api:\n    path: api\n",
    )?;

    let output = Command::new(env!("CARGO_BIN_EXE_csgraph"))
        .args(["config", "show", "--config"])
        .arg(&manifest)
        .output()?;
    let report: ConfigReport = serde_json::from_slice(&output.stdout)?;

    assert!(output.status.success());
    assert_eq!(
        report.extraction_budgets.max_input_bytes_per_artifact,
        1_234
    );
    assert_eq!(
        report.extraction_budgets.max_ast_depth_per_artifact,
        ExtractionBudgets::default().max_ast_depth_per_artifact
    );
    Ok(())
}

#[test]
fn repository_local_config_should_reject_extraction_budget_overrides() -> anyhow::Result<()> {
    let temporary = tempfile::tempdir()?;
    std::fs::create_dir_all(temporary.path().join("api"))?;
    std::fs::write(
        temporary.path().join("api/.code-system-graph.yaml"),
        "version: 1\nextractionBudgets:\n  maxInputBytesPerArtifact: 999999999\n",
    )?;
    let manifest = temporary.path().join("code-system-graph.yaml");
    std::fs::write(
        &manifest,
        "version: 1\nname: configuration\nrepos:\n  api:\n    path: api\n",
    )?;

    let output = Command::new(env!("CARGO_BIN_EXE_csgraph"))
        .args(["config", "show", "--config"])
        .arg(&manifest)
        .output()?;

    assert!(!output.status.success());
    assert!(String::from_utf8_lossy(&output.stderr).contains("extractionBudgets"));
    Ok(())
}

#[test]
fn repository_local_config_should_reject_execution_policy_overrides() -> anyhow::Result<()> {
    let temporary = tempfile::tempdir()?;
    std::fs::create_dir_all(temporary.path().join("api"))?;
    std::fs::write(
        temporary.path().join("api/.code-system-graph.yaml"),
        "version: 1\nexecutionPolicy:\n  maxScanWallTimeMs: 999999999\n",
    )?;
    let manifest = temporary.path().join("code-system-graph.yaml");
    std::fs::write(
        &manifest,
        "version: 1\nname: configuration\nrepos:\n  api:\n    path: api\n",
    )?;

    let output = Command::new(env!("CARGO_BIN_EXE_csgraph"))
        .args(["config", "show", "--config"])
        .arg(&manifest)
        .output()?;

    assert!(!output.status.success());
    assert!(String::from_utf8_lossy(&output.stderr).contains("executionPolicy"));
    Ok(())
}

#[test]
fn analyzed_repository_should_not_control_advanced_global_policy() -> anyhow::Result<()> {
    let temporary = tempfile::tempdir()?;
    let repository = temporary.path().join("repository");
    std::fs::create_dir(&repository)?;
    let manifest = repository.join("code-system-graph.yaml");
    std::fs::write(
        &manifest,
        "version: 1\nname: untrusted-policy\nextractionBudgets:\n  maxInputBytesPerArtifact: 999999999\nexecutionPolicy:\n  maxScanWallTimeMs: 999999999\nrepos:\n  root:\n    path: .\n",
    )?;

    let output = Command::new(env!("CARGO_BIN_EXE_csgraph"))
        .args(["config", "show", "--config"])
        .arg(&manifest)
        .output()?;
    let stderr = String::from_utf8_lossy(&output.stderr);

    assert!(!output.status.success());
    assert!(stderr.contains("advanced global resource policy"));
    assert!(stderr.contains("move the workspace manifest outside every analyzed checkout"));
    Ok(())
}

#[test]
fn config_show_should_report_repository_local_rule_source() -> anyhow::Result<()> {
    let temporary = tempfile::tempdir()?;
    std::fs::create_dir_all(temporary.path().join("worker"))?;
    std::fs::write(
        temporary.path().join("worker/.code-system-graph.yaml"),
        "version: 1\nexcludes:\n  - generated/**\n",
    )?;
    let manifest = temporary.path().join("code-system-graph.yaml");
    std::fs::write(
        &manifest,
        "version: 1\nname: configuration\nrepos:\n  worker:\n    path: worker\n",
    )?;

    let output = Command::new(env!("CARGO_BIN_EXE_csgraph"))
        .args(["config", "show", "--config"])
        .arg(&manifest)
        .output()?;
    let report: ConfigReport = serde_json::from_slice(&output.stdout)?;

    assert!(matches!(
        report.repositories[0]
            .ignore_policy
            .configured_excludes
            .source,
        code_system_graph::ConfigSource::RepositoryLocal
    ));
    Ok(())
}

#[test]
fn config_show_should_reject_unknown_repository_alias() -> anyhow::Result<()> {
    let temporary = tempfile::tempdir()?;
    std::fs::create_dir_all(temporary.path().join("api"))?;
    let manifest = temporary.path().join("code-system-graph.yaml");
    std::fs::write(
        &manifest,
        "version: 1\nname: configuration\nrepos:\n  api:\n    path: api\n",
    )?;

    let output = Command::new(env!("CARGO_BIN_EXE_csgraph"))
        .args(["config", "show", "--config"])
        .arg(&manifest)
        .args(["--repo", "missing"])
        .output()?;

    assert!(!output.status.success());
    assert!(String::from_utf8_lossy(&output.stderr).contains("missing"));
    Ok(())
}

#[test]
fn config_show_should_reject_unsupported_glob_syntax() -> anyhow::Result<()> {
    let temporary = tempfile::tempdir()?;
    std::fs::create_dir_all(temporary.path().join("api"))?;
    let manifest = temporary.path().join("code-system-graph.yaml");
    std::fs::write(
        &manifest,
        "version: 1\nname: configuration\nrepos:\n  api:\n    path: api\n    excludes:\n      - \"src/[ab]/**\"\n",
    )?;

    let output = Command::new(env!("CARGO_BIN_EXE_csgraph"))
        .args(["config", "show", "--config"])
        .arg(&manifest)
        .output()?;

    assert!(!output.status.success());
    assert!(String::from_utf8_lossy(&output.stderr).contains("unsupported glob syntax"));
    Ok(())
}