wsb 0.291.8591

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

/// What `omni lsp --capabilities` prints, in the shape it prints it.
fn initialize(revision: Option<u64>, encoding: &str, server: &str) -> String {
    let mut caps = serde_json::json!({
        "positionEncoding": encoding,
        "completionProvider": { "triggerCharacters": [".", ":"] },
        "signatureHelpProvider": { "triggerCharacters": ["(", ","] },
        "semanticTokensProvider": { "legend": { "tokenTypes": ["namespace", "function", "class"], "tokenModifiers": ["declaration"] } },
    });
    if let Some(r) = revision {
        caps["experimental"] = serde_json::json!({ "omnicode": { "revision": r, "languages": {
            "rust": { "extensions": ["rs"], "features": ["diagnostics", "hover", "completion"] },
            "python": { "extensions": ["py", "pyi"], "features": ["diagnostics", "definition"] },
        }}});
    }
    serde_json::json!({ "capabilities": caps, "serverInfo": { "name": server, "version": "0.1.0" } }).to_string()
}

/// TEST20081: an `omni` is used for what it says it answers, and one that does not say, or
/// says it in a revision or an encoding this wsb does not speak, is refused by name.
///
/// Guessing what an older or foreign server answers would register editor features that
/// fail on every use with nothing saying why.
#[test]
fn test20081_omni_is_used_only_for_what_it_says_it_answers() {
    let path = Path::new("/opt/omni");
    let omni = parse(path, "omni 0.1.0", &initialize(Some(1), "utf-16", "omnicode")).expect("a usable omni");
    assert_eq!(omni.revision, 1);
    assert_eq!(omni.legend.token_types, ["namespace", "function", "class"]);
    assert_eq!(omni.completion_triggers, [".", ":"]);
    assert_eq!(omni.language_of(Path::new("/w/src/a.pyi")).map(|(id, _)| id), Some("python"));
    assert_eq!(omni.language_of(Path::new("/w/notes.txt")), None);

    let refused = |text: String| match parse(path, "omni 0.1.0", &text) {
        Err(Unavailable::Incompatible { detail, .. }) => detail,
        other => panic!("accepted or misread: {other:?}"),
    };
    assert!(refused(initialize(None, "utf-16", "omnicode")).contains("does not say what it answers for"));
    assert!(refused(initialize(Some(0), "utf-16", "omnicode")).contains("revision 0"));
    assert!(refused(initialize(Some(1), "utf-8", "omnicode")).contains("utf-16"));
    assert!(refused(initialize(Some(1), "utf-16", "rust-analyzer")).contains("not omnicode"));
    assert!(matches!(parse(path, "", "not json"), Err(Unavailable::Broken { .. })));
}

/// TEST20082: a missing `omni` says where it was looked for, and what a service needs.
#[test]
fn test20082_a_missing_omni_says_where_it_was_looked_for() {
    let said = Unavailable::NotInstalled { searched: vec!["/usr/bin".into(), "/home/op/.local/bin".into()] }.to_string();
    assert!(said.contains("/usr/bin, /home/op/.local/bin"), "{said}");
    assert!(said.contains("wsb daemon install"), "it does not say a service needs reinstalling: {said}");
}

/// TEST20083: a real `omni` describes itself (needs WSB_OMNI, an omni binary).
#[test]
#[ignore = "needs WSB_OMNI: the path of an omni binary"]
fn test20083_a_real_omni_describes_itself() {
    let path = std::env::var_os("WSB_OMNI").expect("WSB_OMNI must name an omni binary for this test");
    let omni = describe(Path::new(&path)).expect("the omni describes itself");
    assert!(omni.revision >= REQUIRED_REVISION);
    assert!(omni.languages["rust"].features.iter().any(|f| f == "completion"), "{omni:?}");
    assert!(omni.languages["python"].features.iter().any(|f| f == "definition"), "{omni:?}");
    assert!(omni.version.starts_with("omni "), "{}", omni.version);
}