repopilot 0.19.0

Local-first CLI for reviewing Git changes, security boundaries, and blast radius before merge.
Documentation
#[test]
fn classifies_rust_domain_file_role() {
    let file = facts(
        "src/domain/user.rs",
        Some("Rust"),
        "pub struct User { id: String }\n",
        false,
    );

    let context = classify_file(&file);

    assert_eq!(context.language, LanguageKind::Rust);
    assert!(context.has_role(FileRole::Domain));
    assert!(context.has_runtime(RuntimeKind::RustLibrary));
}


#[test]
fn classifies_rust_test_path() {
    let file = facts(
        "tests/parser_test.rs",
        Some("Rust"),
        "#[test]\nfn parses() {}\n",
        false,
    );

    let context = classify_file(&file);

    assert_eq!(context.language, LanguageKind::Rust);
    assert!(context.has_role(FileRole::Test));
    assert!(context.has_role(FileRole::RustTest));
    assert!(context.is_test);
}


#[test]
fn classifies_rust_iterator_pipeline_as_functional_without_marking_it_bad() {
    let file = facts(
        "src/domain/users.rs",
        Some("Rust"),
        "let names = users.iter().filter(|user| user.is_active).map(|user| user.name.clone()).collect::<Vec<_>>();\n",
        false,
    );

    let context = classify_file(&file);

    assert_eq!(context.language, LanguageKind::Rust);
    assert!(context.is_functional_code());
    assert!(!context.has_role(FileRole::Config));
}


#[test]
fn classifies_node_runtime_from_process_env_and_node_imports() {
    for content in [
        "const value = process.env.NODE_ENV;\n",
        "import fs from \"node:fs\";\n",
        "import path from 'node:path';\n",
    ] {
        let file = facts("src/server.ts", Some("TypeScript"), content, false);

        let context = classify_file(&file);

        assert!(context.has_framework(FrameworkKind::NodeJs));
        assert!(context.has_runtime(RuntimeKind::Node));
    }
}


#[test]
fn classifies_python_go_and_jvm_contexts() {
    let python = classify_file(&facts(
        "app/views.py",
        Some("Python"),
        "from fastapi import FastAPI\napp = FastAPI()\n",
        false,
    ));
    assert_eq!(python.language, LanguageKind::Python);
    assert!(python.has_framework(FrameworkKind::FastApi));
    assert!(python.has_runtime(RuntimeKind::Python));

    let go = classify_file(&facts(
        "cmd/server/main.go",
        Some("Go"),
        "package main\nimport \"github.com/gin-gonic/gin\"\nfunc main() {}\n",
        false,
    ));
    assert_eq!(go.language, LanguageKind::Go);
    assert!(go.has_framework(FrameworkKind::Gin));
    assert!(go.has_runtime(RuntimeKind::Go));
    assert!(go.has_role(FileRole::Script));

    let java = classify_file(&facts(
        "src/main/java/com/acme/UserService.java",
        Some("Java"),
        "import org.springframework.stereotype.Service;\npublic class UserService {}\n",
        false,
    ));
    assert_eq!(java.language, LanguageKind::Java);
    assert!(java.has_framework(FrameworkKind::Spring));
    assert!(java.has_paradigm(ProgrammingParadigm::ObjectOriented));
    assert!(java.has_runtime(RuntimeKind::Jvm));
}


#[test]
fn classifies_generated_files_as_non_production() {
    let file = facts(
        "src/generated/schema.rs",
        Some("Rust"),
        "// generated by schema tool\npub fn value() {}\n",
        false,
    );

    let context = classify_file(&file);

    assert!(context.has_role(FileRole::Generated));
    assert!(!context.is_production_code());
}


#[test]
fn classifies_emscripten_and_whole_file_disabled_bundles_as_generated() {
    // Emscripten/WASM glue and bundles that lead with a bare, whole-file
    // `/* eslint-disable */` are vendored output, not hand-maintained source.
    let emscripten = facts(
        "packages/app/src/woff2/woff2-bindings.ts",
        Some("TypeScript"),
        "// @ts-nocheck\nModule.inspect = function () { return \"[Emscripten Module object]\"; };\n",
        false,
    );
    let disabled = facts(
        "packages/app/src/vendor/bundle.js",
        Some("JavaScript"),
        "/* eslint-disable */\nfunction quit(status) { process.exit(status); }\n",
        false,
    );

    for file in [emscripten, disabled] {
        let context = classify_file(&file);
        assert!(
            context.has_role(FileRole::Generated),
            "vendored bundle should be Generated: {:?}",
            file.path
        );
    }
}

#[test]
fn hand_written_file_with_scoped_eslint_disable_is_not_generated() {
    // A scoped `eslint-disable` for specific rules (or one that is not the very
    // first line) is ordinary authored code and must keep its production role.
    let file = facts(
        "src/api/client.ts",
        Some("TypeScript"),
        "import x from \"./x\";\n/* eslint-disable no-console */\nexport function run() {}\n",
        false,
    );

    let context = classify_file(&file);

    assert!(!context.has_role(FileRole::Generated));
    assert!(context.is_production_code());
}


#[test]
fn classifies_config_file() {
    let file = facts(
        "tsconfig.json",
        None,
        "{ \"compilerOptions\": {} }\n",
        false,
    );

    let context = classify_file(&file);

    assert!(context.has_role(FileRole::Config));
    assert!(context.has_runtime(RuntimeKind::Unknown));
    assert!(!context.is_production_code());
}


#[test]
fn classifies_functional_language_context() {
    let file = facts(
        "src/Pipeline.hs",
        Some("Haskell"),
        "module Pipeline where\nrun xs = map (+1) xs\n",
        false,
    );

    let context = classify_file(&file);

    assert_eq!(context.language, LanguageKind::Haskell);
    assert!(context.has_paradigm(ProgrammingParadigm::Functional));
    assert!(context.is_functional_code());
}