weavatrix-rust 2.1.1

Protocol-independent Rust repository intelligence: typed evidence graphs for impact, architecture, APIs, Git, search, and memory
Documentation
use super::rules::finding_id;
use super::runtime_findings;

#[test]
fn finding_identity_survives_line_shifts_and_reindentation() {
    let original = "    for (const item of items) { await save(item); }";
    let shifted = "        for (const item of items) {  await save(item); }";
    assert_eq!(
        finding_id("runtime.await_in_loop", "src/a.js", original),
        finding_id("runtime.await_in_loop", "src/a.js", shifted),
        "indentation and inner spacing must not change a finding identity"
    );
    assert_ne!(
        finding_id("runtime.await_in_loop", "src/a.js", original),
        finding_id("runtime.await_in_loop", "src/b.js", original),
        "the same code in another file is another finding"
    );
}

#[test]
fn runtime_rules_report_stable_findings_for_moved_code() {
    let body = "const items = [];\nfor (const item of items) { await save(item); }\n";
    let moved = format!("// header\n// header\n{body}");
    let (first, scanned, truncated) = runtime_findings(
        [(
            "src/a.js".to_owned(),
            "javascript".to_owned(),
            body.to_owned(),
        )],
        10,
    );
    let (second, _, _) = runtime_findings(
        [("src/a.js".to_owned(), "javascript".to_owned(), moved)],
        10,
    );
    assert_eq!(scanned, 1);
    assert!(!truncated);
    assert_eq!(first.len(), 1, "await inside a loop is reported once");
    assert_eq!(
        first[0]["id"], second[0]["id"],
        "moving code down the file keeps its identity so debt stays comparable"
    );
    assert_ne!(first[0]["line"], second[0]["line"]);
}

#[test]
fn runtime_rules_ignore_rust_code_compiled_only_for_tests() {
    let source = r#"
pub fn production() {
    risky().unwrap();
}

#[cfg(test)]
mod tests {
    const JSON: &str = "{ braces in strings do not close the module }";

    #[test]
    fn smoke() {
        risky().expect("tests may assert");
    }
}
"#;
    let (findings, scanned, truncated) = runtime_findings(
        [(
            "src/lib.rs".to_owned(),
            "rust".to_owned(),
            source.to_owned(),
        )],
        10,
    );
    assert_eq!(scanned, 1);
    assert!(!truncated);
    assert_eq!(findings.len(), 1);
    assert_eq!(findings[0]["line"], 3);
}

#[test]
fn blocking_calls_are_reported_only_inside_async_contexts() {
    let rust = r"
fn background_worker() {
    std::thread::sleep(std::time::Duration::from_millis(10));
}

async fn request_handler() {
    std::thread::sleep(std::time::Duration::from_millis(10));
}
";
    let python = r"
def background_worker():
    time.sleep(1)

async def request_handler():
    time.sleep(1)
";
    let javascript = r#"
function backgroundWorker() {
    readFileSync("state.json");
}

async function requestHandler() {
    readFileSync("state.json");
}
"#;
    let (findings, scanned, truncated) = runtime_findings(
        [
            ("src/lib.rs".to_owned(), "rust".to_owned(), rust.to_owned()),
            (
                "worker.py".to_owned(),
                "python".to_owned(),
                python.to_owned(),
            ),
            (
                "worker.js".to_owned(),
                "javascript".to_owned(),
                javascript.to_owned(),
            ),
        ],
        10,
    );
    assert_eq!(scanned, 3);
    assert!(!truncated);
    assert_eq!(findings.len(), 3);
    assert!(findings.iter().all(|finding| {
        let expected = if finding["file"] == "worker.py" { 6 } else { 7 };
        finding["line"] == expected
    }));
}