Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/gunnar

xtask/tests/free_tree_run.rs

//! `cargo xtask free-tree` (`xtask/src/paid_guard.rs`): the verdict over what `cargo
//! tree` printed for the default-feature `gunnar-server`, driven here through stand-in
//! `cargo` programs, so each verdict is reached from a listing written down in the test.

use std::os::unix::fs::PermissionsExt;
use std::path::{Path, PathBuf};

use xtask::paid_guard::run;

struct Scratch(PathBuf);

impl Drop for Scratch {
    fn drop(&mut self) {
        let _ = std::fs::remove_dir_all(&self.0);
    }
}

/// A stand-in `cargo`: `tree … -i <name>` prints `chain`, any other `tree` prints
/// `listing`; `exit` is its exit code.
fn stand_in(dir: &Path, name: &str, listing: &str, chain: &str, exit: i32) -> String {
    let p = dir.join(name);
    std::fs::write(
        &p,
        format!(
            "#!/bin/sh\nfor a in \"$@\"; do if [ \"$a\" = -i ]; then cat <<'CHAIN'\n{chain}CHAIN\nexit 0; fi; done\n\
             [ {exit} -ne 0 ] && {{ echo 'error: no such package' >&2; exit {exit}; }}\ncat <<'TREE'\n{listing}TREE\n"
        ),
    )
    .unwrap();
    std::fs::set_permissions(&p, std::fs::Permissions::from_mode(0o755)).unwrap();
    p.display().to_string()
}

#[test]
fn the_free_server_passes_only_when_it_links_nothing_paid() {
    let base = std::env::temp_dir().join(format!("gunnar-free-tree-{}", std::process::id()));
    let _ = std::fs::remove_dir_all(&base);
    std::fs::create_dir_all(&base).unwrap();
    let _s = Scratch(base.clone());
    let root = base.join("gunnar");
    std::fs::create_dir_all(&root).unwrap();
    let free = format!(
        "gunnar-server v3.0.0 ({r}/crates/gunnar-server)\ngunnar-core v3.0.0 ({r}/crates/gunnar-core)\n\
         edda-admit v0.1.0 ({p}/edda/crates/admit)\nserde v1.0.200\nserde v1.0.200 (*)\n",
        r = root.display(),
        p = base.display()
    );
    assert!(
        run(&root, &stand_in(&base, "free", &free, "", 0)),
        "a free tree was refused"
    );

    let paid = format!("{free}monetize-impl-build-thing v0.4.0\ngunnar-ui-server v1.6.0 ({}/gunnar-ui/crates/gunnar-ui-server)\n", base.display());
    let chain = "monetize-impl-build-thing v0.4.0\n└── gunnar-server v3.0.0\n";
    assert!(
        !run(&root, &stand_in(&base, "paid", &paid, chain, 0)),
        "a paid crate passed the free tree"
    );

    let private = format!(
        "{free}vetra-thing v0.1.0 ({}/monetize-impl/crates/vetra-thing)\n",
        base.display()
    );
    assert!(
        !run(&root, &stand_in(&base, "private", &private, "", 0)),
        "a crate from a private checkout passed"
    );

    assert!(
        !run(&root, &stand_in(&base, "broken", "", "", 101)),
        "a tree cargo could not print passed"
    );
    assert!(
        !run(&root, &base.join("no-such-cargo").display().to_string()),
        "a cargo that is not there passed"
    );
}