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

nordisk/edda

crates/appliance-grow/tests/one_monetize_embed_line.rs

//! RA2-13: appliance-grow takes ONE monetize-embed line, 0.3, in its dependency
//! AND its dev-dependency, and edda's lock holds exactly that one.
//!
//! Before: the dependency asked `>=0.1.3, <0.4`, a range across three semver-breaking
//! 0.x lines (crates.io's 0.2.0 is the old API, without the fleet forms), while the
//! dev-dependency pinned 0.1.3. So edda's own tests never built the 0.3 line the
//! published crate is meant for, against A3's "one line" rule (monetize
//! `xtask/tests/the_published_line.rs`).
//!
//! The reader is a small line scanner, as in monetize's guard: no TOML crate is added
//! for one test.

use std::path::{Path, PathBuf};

/// The ONE monetize-embed line (A3: monetize's crates.io line is 0.3.0).
const LINE: &str = "0.3";

fn manifest_dir() -> PathBuf {
    PathBuf::from(env!("CARGO_MANIFEST_DIR"))
}

fn read(p: &Path) -> String {
    std::fs::read_to_string(p).unwrap_or_else(|e| panic!("read {}: {e}", p.display()))
}

/// The `monetize-embed = …` line under the `[section]` header, if any.
fn entry<'a>(manifest: &'a str, section: &str) -> Option<&'a str> {
    let mut inside = false;
    for line in manifest.lines() {
        let t = line.trim();
        if t.starts_with('[') {
            inside = t == format!("[{section}]");
            continue;
        }
        if inside && t.starts_with("monetize-embed") && t["monetize-embed".len()..].trim_start().starts_with('=') {
            return Some(t);
        }
    }
    None
}

/// The requirement an entry asks: the bare string, or `version = "…"` in a table.
fn requirement(entry: &str) -> String {
    let rhs = entry.split_once('=').map(|(_, r)| r.trim()).unwrap_or_default();
    let quoted = |s: &str| s.split('"').nth(1).map(str::to_owned);
    if rhs.starts_with('"') {
        return quoted(rhs).unwrap_or_default();
    }
    let at = rhs.find("version").unwrap_or_else(|| panic!("no version in `{entry}`"));
    quoted(&rhs[at..]).unwrap_or_default()
}

/// Every `version` of a `[[package]] name = "monetize-embed"` in a lock.
fn locked_versions(lock: &str) -> Vec<String> {
    let mut out = Vec::new();
    let mut lines = lock.lines().peekable();
    while let Some(l) = lines.next() {
        if l.trim() == "name = \"monetize-embed\"" {
            if let Some(v) = lines.peek().and_then(|v| v.trim().strip_prefix("version = \"")) {
                out.push(v.trim_end_matches('"').to_owned());
            }
        }
    }
    out
}

#[test]
fn the_dependency_and_the_dev_dependency_ask_the_same_one_line() {
    let m = read(&manifest_dir().join("Cargo.toml"));
    let dep = entry(&m, "dependencies").expect("appliance-grow names monetize-embed under [dependencies]");
    let dev = entry(&m, "dev-dependencies").expect("appliance-grow names monetize-embed under [dev-dependencies]");
    let (dep, dev) = (requirement(dep), requirement(dev));
    assert_eq!(dep, LINE, "the dependency must ask exactly the {LINE} line, not a range across 0.x lines");
    assert_eq!(dev, dep, "the dev-dependency must ask the same line the published crate asks");
}

#[test]
fn eddas_lock_holds_one_monetize_embed_on_that_line() {
    let lock = read(&manifest_dir().join("../../Cargo.lock"));
    let got = locked_versions(&lock);
    assert_eq!(got.len(), 1, "edda's Cargo.lock must hold ONE monetize-embed, holds {got:?}");
    assert!(
        got[0].starts_with(&format!("{LINE}.")),
        "edda's Cargo.lock has monetize-embed {}, not on the {LINE} line",
        got[0]
    );
}

#[test]
fn the_scanner_reads_both_entry_forms_and_the_lock() {
    let m = "[dependencies]\nmonetize-embed = { version = \">=0.1.3, <0.4\", optional = true }\n\
             [dev-dependencies]\nmonetize-embed = \"0.1.3\"\nmonetize-embedx = \"9\"\n";
    assert_eq!(requirement(entry(m, "dependencies").unwrap()), ">=0.1.3, <0.4");
    assert_eq!(requirement(entry(m, "dev-dependencies").unwrap()), "0.1.3");
    assert_eq!(entry(m, "build-dependencies"), None);
    let lock = "[[package]]\nname = \"monetize-embed\"\nversion = \"0.1.3\"\n\n[[package]]\nname = \"monetize-embed\"\nversion = \"0.3.0\"\n";
    assert_eq!(locked_versions(lock), ["0.1.3", "0.3.0"]);
}