wsb 0.291.8591

Workspace tools for every project under $PRJ: git across submodules, template stamping, GitHub, and the workbench
Documentation
use super::*;
use crate::omnicode::roots::Fleet;

/// TEST20084: a position is shown only for the content it was found in.
///
/// A byte offset into a file that changed since it was analyzed points at the wrong place;
/// showing it as a line and column would send somebody there.
#[test]
fn test20084_positions_are_only_shown_for_unchanged_content() {
    use sha2::{Digest, Sha256};
    let dir = tempfile::tempdir().expect("a directory");
    let text = "a😀b\n漢字 helper\n";
    std::fs::write(dir.path().join("f.py"), text).expect("a file");
    let hash = format!("sha256:{:x}", Sha256::digest(text.as_bytes()));
    let offset = text.find("helper").expect("there");
    assert_eq!(position(dir.path(), "f.py", &hash, offset), Some((2, 4)), "columns are characters, from 1");
    std::fs::write(dir.path().join("f.py"), format!("# an edit above\n{text}")).expect("a change");
    assert_eq!(position(dir.path(), "f.py", &hash, offset), None);
    assert_eq!(position(dir.path(), "gone.py", &hash, 0), None);
}

/// TEST20085: every root of a worktree answers — or says it is not indexed, or that the
/// symbol is not in it — through a real `omni` (needs WSB_OMNI).
#[test]
#[ignore = "needs WSB_OMNI: the path of an omni binary"]
fn test20085_every_root_answers_or_says_why_not() {
    let omni_path = std::env::var_os("WSB_OMNI").expect("WSB_OMNI must name an omni binary for this test");
    let omni = crate::omnicode::locate::describe(Path::new(&omni_path)).expect("a usable omni");
    let state = tempfile::tempdir().expect("omni's state");
    // omni's state for this test alone: the omni children it starts inherit it.
    std::env::set_var("OMNI_STATE_DIR", state.path());
    let repo = tempfile::tempdir().expect("a repository");
    let root = crate::platform::canonicalize(repo.path()).expect("resolves");
    std::fs::write(root.join("util.py"), "def helper(x):\n    return x\n").expect("a file");
    std::fs::write(root.join("app.py"), "from util import helper\nhelper(1)\n").expect("a file");
    let fleet = Fleet::of(vec![root.clone()]).expect("one repository");
    let roots = fleet.analysis_roots(None).expect("its roots");

    let symbols = Question::Symbols { pattern: "help*".into(), kind: None };
    assert_eq!(ask(&omni, &roots, &symbols).expect("asked")[0].outcome, Outcome::NotIndexed);
    assert!(matches!(ask(&omni, &roots, &Question::Index).expect("indexed")[0].outcome, Outcome::Indexed(_)));
    match &ask(&omni, &roots, &symbols).expect("asked")[0].outcome {
        Outcome::Results { items, status, .. } => {
            assert_eq!(status, "complete");
            assert_eq!(items.len(), 1, "{items:?}");
            assert_eq!(items[0]["path"], "util.helper");
        }
        other => panic!("{other:?}"),
    }
    match &ask(&omni, &roots, &Question::Refs { target: "util.helper".into() }).expect("asked")[0].outcome {
        Outcome::Results { items, .. } => {
            let mut roles: Vec<(&str, &str)> =
                items.iter().map(|i| (i["span"]["path"].as_str().unwrap_or(""), i["role"].as_str().unwrap_or(""))).collect();
            roles.sort();
            assert_eq!(roles, [("app.py", "import"), ("app.py", "reference"), ("util.py", "definition")], "{items:?}");
        }
        other => panic!("{other:?}"),
    }
    assert!(matches!(
        &ask(&omni, &roots, &Question::Refs { target: "util.nothing".into() }).expect("asked")[0].outcome,
        Outcome::NoMatch { .. }
    ));
}