relay-knowledge 1.1.16

Graph-database-based knowledge graph project.
Documentation
use super::super::{SourceGrepKind, SourceGrepRequest, materialization::TempSourceTree};
use super::*;
use crate::{code::source_line_defines_identity, domain::RepositoryCodeRange};

#[test]
fn internal_scanner_filters_definition_lines_before_enforcing_limit() {
    let mut tree = TempSourceTree::create().expect("temp tree should be created");
    tree.write("src/lib.c", b"return target();\nint target(void);\n")
        .expect("source path should be written");
    let request = SourceGrepRequest {
        query: "target".to_owned(),
        paths: vec!["src/lib.c".to_owned()],
        path_filters: Vec::new(),
        language_filters: Vec::new(),
        limit: 1,
        kind: SourceGrepKind::Definition,
        exclude_generated: false,
    };

    let matches = internal_source_grep_matches(&tree.root, &request.paths, &request, |matched| {
        source_line_defines_identity(&matched.excerpt, "target")
    })
    .expect("internal scanner should apply definition acceptance");

    assert_eq!(matches.len(), 1);
    assert_eq!(matches[0].line_range.start, 2);
    assert_eq!(matches[0].excerpt, "int target(void);");
}

#[test]
fn definition_scanner_prefers_modified_type_declarations_over_docs_and_constructors() {
    let mut tree = TempSourceTree::create().expect("temp tree should be created");
    tree.write(
        "src/Widget.java",
        b"/** @see #Widget(Value) */\npublic final class Widget {\n  public Widget(Value value) {}\n}\n",
    )
    .expect("source path should be written");
    let request = SourceGrepRequest {
        query: "Widget".to_owned(),
        paths: vec!["src/Widget.java".to_owned()],
        path_filters: Vec::new(),
        language_filters: vec!["java".to_owned()],
        limit: 1,
        kind: SourceGrepKind::Definition,
        exclude_generated: false,
    };

    let matches = internal_source_grep_matches(&tree.root, &request.paths, &request, |matched| {
        source_line_defines_identity(&matched.excerpt, "Widget")
    })
    .expect("definition scan should remain bounded after shape filtering");

    assert_eq!(matches.len(), 1);
    assert_eq!(matches[0].line_range.start, 2);
    assert_eq!(matches[0].excerpt, "public final class Widget {");
}

#[test]
fn internal_scanner_includes_template_preamble_for_declaration_lines() {
    let mut tree = TempSourceTree::create().expect("temp tree should be created");
    tree.write(
        "include/cache.h",
        b"template <typename InstanceType>\nclass NoDestructor {};\n",
    )
    .expect("source path should be written");
    let request = SourceGrepRequest {
        query: "NoDestructor".to_owned(),
        paths: vec!["include/cache.h".to_owned()],
        path_filters: Vec::new(),
        language_filters: Vec::new(),
        limit: 1,
        kind: SourceGrepKind::Definition,
        exclude_generated: false,
    };

    let matches = internal_source_grep_matches(&tree.root, &request.paths, &request, |matched| {
        matched
            .excerpt
            .lines()
            .map(str::trim)
            .any(|line| source_line_defines_identity(line, "NoDestructor"))
    })
    .expect("internal scanner should include template context");

    assert_eq!(matches.len(), 1);
    assert_eq!(
        matches[0].line_range,
        RepositoryCodeRange { start: 1, end: 2 }
    );
    assert!(
        matches[0]
            .excerpt
            .contains("template <typename InstanceType>")
    );
    assert!(matches[0].excerpt.contains("class NoDestructor"));
}

#[test]
fn hybrid_scanner_tokenizes_query_and_keeps_initializer_header() {
    let mut tree = TempSourceTree::create().expect("temp tree should be created");
    tree.write(
        "src/generated_table.c",
        b"static const struct rk_table_row rk_rows[] = {\n  [RK_STAGE_READ] = {\n    .name = \"read\",\n    .read = rk_driver_read,\n  },\n};\n",
    )
    .expect("source path should be written");
    let request = SourceGrepRequest {
        query: "compound initializer table row read function pointer".to_owned(),
        paths: vec!["src/generated_table.c".to_owned()],
        path_filters: vec!["src/generated_table.c".to_owned()],
        language_filters: vec!["c".to_owned()],
        limit: 5,
        kind: SourceGrepKind::Hybrid,
        exclude_generated: false,
    };

    let matches = internal_source_grep_matches(&tree.root, &request.paths, &request, |_| true)
        .expect("hybrid scanner should search query terms");

    assert!(matches.iter().any(|matched| {
        matched.excerpt.contains("[RK_STAGE_READ]")
            && matched.excerpt.contains(".read = rk_driver_read")
    }));
}

#[test]
fn internal_scanner_searches_materialized_paths_without_ripgrep() {
    let mut tree = TempSourceTree::create().expect("temp tree should be created");
    tree.write(
        ".github/workflows/ci.yml",
        b"# RK_INTERNAL_SCANNER_REFERENCE\nname: ci\n",
    )
    .expect("hidden path should be written");
    let request = SourceGrepRequest {
        query: "RK_INTERNAL_SCANNER_REFERENCE".to_owned(),
        paths: vec![".github/workflows/ci.yml".to_owned()],
        path_filters: Vec::new(),
        language_filters: Vec::new(),
        limit: 5,
        kind: SourceGrepKind::References,
        exclude_generated: false,
    };

    let matches = internal_source_grep_matches(&tree.root, &request.paths, &request, |_| true)
        .expect("internal scanner should read materialized files");

    assert_eq!(matches.len(), 1);
    assert_eq!(matches[0].path, ".github/workflows/ci.yml");
    assert_eq!(matches[0].line_range.start, 1);
    assert_eq!(matches[0].byte_range.start, 2);
    assert!(matches[0].excerpt.contains("RK_INTERNAL_SCANNER_REFERENCE"));
}

#[test]
fn internal_scanner_returns_bounded_excerpts_for_long_non_definition_lines() {
    let mut tree = TempSourceTree::create().expect("temp tree should be created");
    let prefix = "x".repeat(MAX_GREP_LINE_BYTES + 64);
    let suffix = "y".repeat(MAX_GREP_LINE_BYTES + 64);
    let source = format!("{prefix}RK_LONG_REFERENCE{suffix}\n");
    tree.write("dist/bundle.js", source.as_bytes())
        .expect("long source path should be written");
    let request = SourceGrepRequest {
        query: "RK_LONG_REFERENCE".to_owned(),
        paths: vec!["dist/bundle.js".to_owned()],
        path_filters: Vec::new(),
        language_filters: Vec::new(),
        limit: 5,
        kind: SourceGrepKind::References,
        exclude_generated: false,
    };

    let matches = internal_source_grep_matches(&tree.root, &request.paths, &request, |_| true)
        .expect("internal scanner should return long-line matches");

    assert_eq!(matches.len(), 1);
    assert_eq!(matches[0].line_range.start, 1);
    assert_eq!(matches[0].byte_range.start, prefix.len() as u32);
    assert!(matches[0].excerpt.contains("RK_LONG_REFERENCE"));
    assert!(matches[0].excerpt.len() <= MAX_GREP_LINE_BYTES);
}

#[test]
fn internal_scanner_skips_binary_blobs() {
    let mut tree = TempSourceTree::create().expect("temp tree should be created");
    tree.write("assets/blob.bin", b"prefix RK_BINARY_REFERENCE\0suffix\n")
        .expect("binary path should be written");
    let request = SourceGrepRequest {
        query: "RK_BINARY_REFERENCE".to_owned(),
        paths: vec!["assets/blob.bin".to_owned()],
        path_filters: Vec::new(),
        language_filters: Vec::new(),
        limit: 5,
        kind: SourceGrepKind::References,
        exclude_generated: false,
    };

    let matches = internal_source_grep_matches(&tree.root, &request.paths, &request, |_| true)
        .expect("internal scanner should skip binary blobs without failing");

    assert!(matches.is_empty());
}

#[test]
fn internal_scanner_excludes_generated_files_when_requested() {
    let mut tree = TempSourceTree::create().expect("temp tree should be created");
    tree.write(
        "src/client.ts",
        b"// @generated by fixture\nexport const RK_GENERATED_REFERENCE = true;\n",
    )
    .expect("generated source path should be written");
    let request = SourceGrepRequest {
        query: "RK_GENERATED_REFERENCE".to_owned(),
        paths: vec!["src/client.ts".to_owned()],
        path_filters: Vec::new(),
        language_filters: Vec::new(),
        limit: 5,
        kind: SourceGrepKind::References,
        exclude_generated: true,
    };

    let matches = internal_source_grep_matches(&tree.root, &request.paths, &request, |_| true)
        .expect("internal scanner should skip generated files");

    assert!(matches.is_empty());
}

#[test]
fn internal_scanner_marks_generated_matches_when_allowed() {
    let mut tree = TempSourceTree::create().expect("temp tree should be created");
    tree.write(
        "src/client.ts",
        b"// @generated by fixture\nexport const RK_GENERATED_REFERENCE = true;\n",
    )
    .expect("generated source path should be written");
    let request = SourceGrepRequest {
        query: "RK_GENERATED_REFERENCE".to_owned(),
        paths: vec!["src/client.ts".to_owned()],
        path_filters: Vec::new(),
        language_filters: Vec::new(),
        limit: 5,
        kind: SourceGrepKind::References,
        exclude_generated: false,
    };

    let matches = internal_source_grep_matches(&tree.root, &request.paths, &request, |_| true)
        .expect("internal scanner should retain generated files when allowed");

    assert_eq!(matches.len(), 1);
    assert!(matches[0].is_generated);
}

#[test]
fn internal_scanner_prefers_handwritten_matches_before_limit() {
    let mut tree = TempSourceTree::create().expect("temp tree should be created");
    tree.write(
        "generated/api.ts",
        b"// @generated by fixture\nexport const RK_TARGET = 1;\n",
    )
    .expect("generated source should be written");
    tree.write("src/api.ts", b"export const RK_TARGET = 2;\n")
        .expect("handwritten source should be written");
    let request = SourceGrepRequest {
        query: "RK_TARGET".to_owned(),
        paths: vec!["generated/api.ts".to_owned(), "src/api.ts".to_owned()],
        path_filters: Vec::new(),
        language_filters: Vec::new(),
        limit: 1,
        kind: SourceGrepKind::Hybrid,
        exclude_generated: false,
    };

    let matches = internal_source_grep_matches(&tree.root, &request.paths, &request, |_| true)
        .expect("internal scanner should prefer handwritten matches");

    assert_eq!(matches.len(), 1);
    assert_eq!(matches[0].path, "src/api.ts");
    assert!(!matches[0].is_generated);
}

#[test]
fn internal_scanner_distributes_candidate_pool_across_paths_before_reuse() {
    let mut tree = TempSourceTree::create().expect("temp tree should be created");
    tree.write("src/a.java", b"Target.a();\nTarget.a2();\n")
        .expect("first source should be written");
    tree.write(
        "src/b.java",
        b"import example.Target;\nTarget.expectedUsage();\n",
    )
    .expect("second source should be written");
    tree.write("src/c.java", b"Target.c();\nTarget.c2();\n")
        .expect("third source should be written");
    let request = SourceGrepRequest {
        query: "Target".to_owned(),
        paths: vec![
            "src/a.java".to_owned(),
            "src/b.java".to_owned(),
            "src/c.java".to_owned(),
        ],
        path_filters: Vec::new(),
        language_filters: vec!["java".to_owned()],
        limit: 6,
        kind: SourceGrepKind::References,
        exclude_generated: false,
    };

    let matches = internal_source_grep_matches(&tree.root, &request.paths, &request, |_| true)
        .expect("reference candidates should be distributed fairly");

    assert_eq!(matches.len(), 6);
    assert_eq!(
        matches
            .iter()
            .map(|matched| matched.path.as_str())
            .collect::<Vec<_>>(),
        [
            "src/a.java",
            "src/b.java",
            "src/c.java",
            "src/a.java",
            "src/b.java",
            "src/c.java",
        ]
    );
    assert_eq!(matches[1].line_range.start, 2);
    assert_eq!(matches[4].line_range.start, 1);
}

#[test]
fn reference_scanner_keeps_code_usage_before_comments_and_imports_within_path() {
    let mut tree = TempSourceTree::create().expect("temp tree should be created");
    tree.write(
        "src/Session.swift",
        b"/// Target handles callbacks.\nimport ExampleTarget\npublic let delegate: Target\nTarget.run()\n",
    )
    .expect("source should be written");
    let request = SourceGrepRequest {
        query: "Target".to_owned(),
        paths: vec!["src/Session.swift".to_owned()],
        path_filters: Vec::new(),
        language_filters: vec!["swift".to_owned()],
        limit: 2,
        kind: SourceGrepKind::References,
        exclude_generated: false,
    };

    let matches = internal_source_grep_matches(&tree.root, &request.paths, &request, |_| true)
        .expect("reference scanner should retain bounded code usages");

    assert_eq!(matches.len(), 2);
    assert_eq!(matches[0].excerpt, "public let delegate: Target");
    assert_eq!(matches[1].excerpt, "Target.run()");
}