magi-code 0.61.0

Repository-aware CLI coding agent for terminal work
Documentation
use super::*;

#[test]
fn grep_preserves_context_output() {
    let (temp, runtime) = runtime();
    fs::write(temp.path().join("a.txt"), "one\nmatch\nthree\n").unwrap();
    let result = runtime.dispatch(
        "grep",
        json!({"pattern":"match","path":".","limit":10,"context":1}),
    );
    assert!(result.content.contains("a.txt:1:one"));
    assert!(result.content.contains("a.txt:2:match"));
    assert!(result.content.contains("a.txt:3:three"));
}

#[test]
fn grep_stops_at_limit_without_scanning_all_matches() {
    let (temp, runtime) = runtime();
    fs::write(temp.path().join("a.txt"), "match\nmatch\nlater match\n").unwrap();
    let result = runtime.dispatch("grep", json!({"pattern":"match","path":".","limit":2}));
    assert_eq!(result.content.lines().count(), 2);
    assert_eq!(result.metadata["engine"], "native");
    assert_eq!(result.metadata["matches_returned"], 2);
    assert_eq!(result.metadata["truncated"], true);
    assert_eq!(result.metadata["timed_out"], false);
    assert_eq!(result.metadata["limit_reason"], "matches");
    assert!(result.metadata["files_scanned"].as_u64().unwrap() >= 1);
    assert!(result.metadata["bytes_scanned"].as_u64().unwrap() > 0);
    assert!(result.content.contains("a.txt:1:match"));
    assert!(result.content.contains("a.txt:2:match"));
}

#[test]
fn grep_skips_binary_files() {
    let (temp, runtime) = runtime();
    fs::write(temp.path().join("bin.dat"), b"early match\n\0hidden").unwrap();
    fs::write(temp.path().join("a.txt"), "visible match\n").unwrap();
    let result = runtime.dispatch("grep", json!({"pattern":"match","path":".","limit":10}));
    assert!(result.content.contains("visible match"));
    assert!(!result.content.contains("early match"));
    assert!(!result.content.contains("hidden"));
}

#[test]
fn grep_finds_matching_lines_with_native_engine() {
    let (temp, runtime) = runtime();
    fs::write(temp.path().join("a.txt"), "alpha\nbeta\n").unwrap();
    let result = runtime.dispatch("grep", json!({"pattern":"beta","path":".","limit":10}));
    assert!(result.success, "{}", result.content);
    assert!(result.content.contains("a.txt:2:beta"));
    assert_eq!(result.metadata["engine"], "native");
    assert!(result.metadata.get("exit_code").is_none());
}

#[test]
fn find_rejects_empty_query_and_invalid_limit() {
    let (_temp, runtime) = runtime();
    for args in [
        json!({"query":""}),
        json!({"query":"   "}),
        json!({"query":"lib", "limit":0}),
        json!({"query":"lib", "limit":crate::tools::args::FIND_MAX_LIMIT + 1}),
        json!({"query":"lib", "unknown":true}),
    ] {
        let result = runtime.dispatch("find", args);
        assert!(
            !result.success,
            "accepted invalid find args: {}",
            result.content
        );
    }
}

#[test]
fn find_returns_fuzzy_relative_file_paths() {
    let (temp, runtime) = runtime();
    fs::create_dir_all(temp.path().join("src")).unwrap();
    fs::create_dir_all(temp.path().join("docs")).unwrap();
    fs::write(temp.path().join("src/lib.rs"), "").unwrap();
    fs::write(temp.path().join("docs/readme.md"), "").unwrap();

    let result = runtime.dispatch("find", json!({"query":"lib", "limit":10}));

    assert!(result.success, "{}", result.content);
    assert!(
        result.content.lines().any(|line| line == "src/lib.rs"),
        "{}",
        result.content
    );
    assert!(
        !result
            .content
            .contains(temp.path().to_string_lossy().as_ref())
    );
    assert_eq!(result.metadata["engine"], "rust");
    assert_eq!(
        result.metadata["matches_returned"].as_u64().unwrap() as usize,
        result.content.lines().count()
    );
}

#[test]
fn find_directory_kind_returns_directory_paths_with_slash() {
    let (temp, runtime) = runtime();
    fs::create_dir_all(temp.path().join("src/components")).unwrap();
    fs::write(temp.path().join("src/components/button.rs"), "").unwrap();

    let result = runtime.dispatch(
        "find",
        json!({"query":"components", "kind":"directories", "limit":10}),
    );

    assert!(result.success, "{}", result.content);
    assert!(
        result.content.lines().any(|line| line == "src/components/"),
        "{}",
        result.content
    );
}

#[test]
fn find_mixed_kind_returns_files_and_directories() {
    let (temp, runtime) = runtime();
    fs::create_dir_all(temp.path().join("src/widget")).unwrap();
    fs::write(temp.path().join("src/widget.rs"), "").unwrap();
    fs::write(temp.path().join("src/widget/mod.rs"), "").unwrap();

    let result = runtime.dispatch(
        "find",
        json!({"query":"widget", "kind":"mixed", "limit":20}),
    );

    assert!(result.success, "{}", result.content);
    assert!(
        result.content.lines().any(|line| line == "src/widget.rs"),
        "{}",
        result.content
    );
    assert!(
        result.content.lines().any(|line| line == "src/widget/"),
        "{}",
        result.content
    );
}

#[test]
fn find_path_filter_scopes_results_to_directory() {
    let (temp, runtime) = runtime();
    fs::create_dir_all(temp.path().join("src")).unwrap();
    fs::create_dir_all(temp.path().join("docs")).unwrap();
    fs::write(temp.path().join("src/main.rs"), "").unwrap();
    fs::write(temp.path().join("docs/main.md"), "").unwrap();

    let result = runtime.dispatch("find", json!({"query":"main", "path":"src", "limit":20}));

    assert!(result.success, "{}", result.content);
    assert!(
        result.content.lines().any(|line| line == "src/main.rs"),
        "{}",
        result.content
    );
    assert!(
        !result.content.contains("docs/main.md"),
        "{}",
        result.content
    );
}

#[test]
fn find_path_filter_searches_filtered_universe_before_limit() {
    let (temp, runtime) = runtime();
    fs::create_dir_all(temp.path().join("scoped/deep/nested")).unwrap();
    for index in 0..25 {
        fs::write(temp.path().join(format!("needle_{index:02}.rs")), "").unwrap();
    }
    fs::write(temp.path().join("scoped/deep/nested/needle_target.rs"), "").unwrap();

    let result = runtime.dispatch(
        "find",
        json!({"query":"needle", "path":"scoped", "limit":1}),
    );

    assert!(result.success, "{}", result.content);
    assert_eq!(
        result.content.lines().collect::<Vec<_>>(),
        vec!["scoped/deep/nested/needle_target.rs"]
    );
    assert_eq!(result.metadata["matches_returned"], 1);
    assert_eq!(result.metadata["total_matched"], 1);
    assert_eq!(result.metadata["truncated"], false);
}

#[test]
fn find_path_filter_offset_pages_filtered_results() {
    let (temp, runtime) = runtime();
    fs::create_dir_all(temp.path().join("scoped")).unwrap();
    for index in 0..25 {
        fs::write(temp.path().join(format!("needle_{index:02}.rs")), "").unwrap();
    }
    for name in ["alpha", "beta", "gamma"] {
        fs::write(temp.path().join(format!("scoped/needle-{name}.rs")), "").unwrap();
    }

    let first_page = runtime.dispatch(
        "find",
        json!({"query":"needle", "path":"scoped", "limit":3}),
    );
    assert!(first_page.success, "{}", first_page.content);
    let first_page_paths = first_page.content.lines().collect::<Vec<_>>();
    assert_eq!(first_page_paths.len(), 3, "{}", first_page.content);
    assert_eq!(first_page.metadata["total_matched"], 3);

    let offset_page = runtime.dispatch(
        "find",
        json!({"query":"needle", "path":"scoped", "limit":1, "offset":1}),
    );

    assert!(offset_page.success, "{}", offset_page.content);
    assert_eq!(
        offset_page.content.lines().collect::<Vec<_>>(),
        vec![first_page_paths[1]]
    );
    assert_eq!(offset_page.metadata["matches_returned"], 1);
    assert_eq!(offset_page.metadata["total_matched"], 3);
    assert_eq!(offset_page.metadata["truncated"], true);
}

#[test]
fn find_rejects_file_path_and_outside_absolute_path_when_disabled() {
    let (temp, _runtime) = runtime();
    fs::write(temp.path().join("file.txt"), "").unwrap();
    let outside = TempDir::new().unwrap();
    fs::write(outside.path().join("outside.txt"), "").unwrap();
    let restricted = ToolRuntime::new_with_settings(
        temp.path(),
        ToolSettings {
            find: FindToolSettings {
                absolute_paths: false,
            },
            ..ToolSettings::default()
        },
    )
    .unwrap();

    let file_result = restricted.dispatch("find", json!({"query":"file", "path":"file.txt"}));
    assert!(!file_result.success);
    assert!(
        file_result
            .content
            .contains("find path must be a directory")
    );

    let outside_result =
        restricted.dispatch("find", json!({"query":"outside", "path": outside.path()}));
    assert!(!outside_result.success);
    assert!(
        outside_result.content.contains("escapes cwd"),
        "{}",
        outside_result.content
    );
}