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

nordisk/monetize

uitest/tests/copied_from_gunnar_ui.rs

//! **The drift alarm for the four copied client files.**
//!
//! `src/cdp.rs`, `src/http.rs`, `src/json.rs` and `src/ws.rs` each open with
//!
//! ```text
//! //! Copied from gunnar-ui/uitest/src/<f>.rs (one implementation: the same
//! //! zero-dependency client, not a rewrite). Keep the two in step by copying,
//! //! never by editing one alone.
//! ```
//!
//! Until this file existed that was a PROMISE, and a promise is not a guard.
//! `nornir mimir analyze duplicates` measured what the promise was worth on
//! 2026-09-10: 954 lines across the four files, with `http.rs`, `json.rs` and
//! `ws.rs` differing from gunnar-ui's by **exactly the one header line** and
//! `cdp.rs` by that header plus **one cited flag**. So the copies are in step
//! today — and nothing would have said so tomorrow. The failure mode is not a
//! build error: an edit on one side compiles perfectly on both, and the two
//! consoles then get tested by two different clients that look like one.
//!
//! # Why this is a guard and not a repoint
//!
//! The LAW's answer to a twin is one implementation, and the right home for
//! these four files is a std-only `nornir-cdp` leaf in edda — a CDP/websocket/
//! JSON/HTTP client is domain-free and both consoles want it as-is. That is NOT
//! done here, and the reason is a rule, not an oversight:
//! `gunnar-ui/uitest/Cargo.toml` declares ZERO dependencies **"on purpose"**, so
//! the harness "must build in seconds on an appliance with no crates.io". A
//! shared leaf — even a std-only one — is a dependency, and a path dependency to
//! `../../edda` makes the sibling checkout mandatory for a repository that is
//! the public product. Relaxing that rule is the owner's call, not this test's.
//!
//! Until it is relaxed, the copies stay and this file makes "keep the two in
//! step" a thing that FAILS rather than a thing that is said.
//!
//! # It cannot be satisfied by an absent sibling
//!
//! With no `gunnar-ui` beside this repository the test prints why and passes —
//! a clone of `monetize` alone must still be green. That step-aside is the known
//! hole (gunnar-ui's own `contract.rs` records the day it swallowed a real
//! drift), so it is narrow: `GUNNAR_UI_CHECKOUT` names the tree explicitly, and
//! when it is SET the test refuses instead of stepping aside.

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

/// The four files that are copies, not rewrites.
const COPIED: &[&str] = &["cdp.rs", "http.rs", "json.rs", "ws.rs"];

/// The header line each copy carries and its original does not. Compared as a
/// PREFIX, so the sentence may be reworded without breaking the guard, but a
/// copy that carries no attribution at all fails.
const HEADER: &str = "//! Copied from gunnar-ui/uitest/src/";

/// `cdp.rs` alone also carries this, because it is copied whole and the unused
/// half must not warn.
const ALLOW_DEAD: &str = "#![allow(dead_code)]";

/// The ONE sanctioned difference, and the marker that declares it. A divergence
/// that does not say this word is not a divergence; it is drift.
const DIVERGES: &str = "DIVERGES from the gunnar-ui copy";

/// gunnar-ui's `uitest/src`, or `None` when there is no such tree beside us.
fn gunnar_ui_src() -> Option<PathBuf> {
    if let Some(explicit) = std::env::var_os("GUNNAR_UI_CHECKOUT") {
        let p = Path::new(&explicit).join("uitest/src");
        assert!(
            p.is_dir(),
            "GUNNAR_UI_CHECKOUT is set but {} is not a directory — an explicit \
             pointer that misses is a typo, not a reason to skip",
            p.display()
        );
        return Some(p);
    }
    let sibling = Path::new(env!("CARGO_MANIFEST_DIR")).join("../../gunnar-ui/uitest/src");
    sibling.is_dir().then_some(sibling)
}

/// Drop the copy's own header: the attribution line(s) and, for `cdp.rs`, the
/// `allow(dead_code)`. Returns the remaining lines and how many header lines
/// were dropped, because ZERO is itself a failure — a copy with no attribution
/// is the state this whole file exists to make impossible.
fn strip_header(text: &str) -> (Vec<&str>, usize) {
    let mut lines = text.lines().peekable();
    let mut dropped = 0;
    while let Some(l) = lines.peek() {
        let t = l.trim_start();
        if t.starts_with(HEADER) || t.starts_with(ALLOW_DEAD) {
            dropped += 1;
            lines.next();
        } else {
            break;
        }
    }
    (lines.collect(), dropped)
}

/// Remove every sanctioned divergence: a run of `//` comment lines starting at
/// the [`DIVERGES`] marker, plus the ONE code line the run introduces. Returns
/// the remaining lines and the number of divergences removed, so a test can
/// assert the count against what the file is allowed.
fn take_divergences<'a>(lines: &[&'a str]) -> (Vec<&'a str>, usize) {
    let mut out = Vec::with_capacity(lines.len());
    let mut removed = 0;
    let mut i = 0;
    while i < lines.len() {
        if lines[i].contains(DIVERGES) {
            removed += 1;
            while i < lines.len() && lines[i].trim_start().starts_with("//") {
                i += 1;
            }
            // The single line the comment is ABOUT. A divergence that explains
            // itself and then changes nothing would silently pass; one that
            // changes two lines must say so twice.
            i += 1;
            continue;
        }
        out.push(lines[i]);
        i += 1;
    }
    (out, removed)
}

/// Every copied file is its gunnar-ui original plus a header, plus — for
/// `cdp.rs` — exactly one marked divergence.
#[test]
fn the_copied_clients_match_gunnar_uis_own() {
    let Some(theirs) = gunnar_ui_src() else {
        eprintln!(
            "gunnar-ui is not checked out beside this repository; the copied \
             clients' drift is NOT checked. Set GUNNAR_UI_CHECKOUT to refuse \
             instead of skipping."
        );
        return;
    };
    let ours = Path::new(env!("CARGO_MANIFEST_DIR")).join("src");

    // `cdp.rs` is the only file with a sanctioned divergence, and the count is
    // pinned: a second one has to be argued for in a diff, not slipped in.
    let allowed = |f: &str| if f == "cdp.rs" { 1 } else { 0 };

    for f in COPIED {
        let mine = std::fs::read_to_string(ours.join(f))
            .unwrap_or_else(|e| panic!("read {}: {e}", ours.join(f).display()));
        let theirs_text = std::fs::read_to_string(theirs.join(f))
            .unwrap_or_else(|e| panic!("read {}: {e}", theirs.join(f).display()));

        let (mine_lines, header) = strip_header(&mine);
        assert!(
            header > 0,
            "{f} carries no `{HEADER}…` attribution. A copy that does not say \
             what it is a copy of is the twin nobody finds."
        );

        let (mine_lines, diverged) = take_divergences(&mine_lines);
        assert_eq!(
            diverged,
            allowed(f),
            "{f}: {diverged} block(s) marked `{DIVERGES}`, {} allowed. A new \
             divergence is a decision and belongs in a diff someone read.",
            allowed(f)
        );

        let theirs_lines: Vec<&str> = theirs_text.lines().collect();
        assert_eq!(
            mine_lines.len(),
            theirs_lines.len(),
            "{f}: {} line(s) here against {} in gunnar-ui/uitest/src/{f}, after \
             the header and {diverged} sanctioned divergence(s). The two are \
             kept in step BY COPYING; copy it again.",
            mine_lines.len(),
            theirs_lines.len()
        );
        for (n, (a, b)) in mine_lines.iter().zip(theirs_lines.iter()).enumerate() {
            assert_eq!(
                a,
                b,
                "{f} line {} differs from gunnar-ui's:\n  here:      {a}\n  gunnar-ui: {b}\n\
                 Either copy gunnar-ui's file over this one, or mark the change \
                 with a `{DIVERGES}` comment saying what was measured.",
                n + 1
            );
        }
    }
}

#[cfg(test)]
mod unit {
    use super::*;

    /// The header stripper takes the attribution and the `allow`, and NOTHING
    /// else — a `//!` module doc that is not the attribution must survive, or
    /// the guard would compare two files it had silently truncated.
    #[test]
    fn strip_header_takes_only_the_attribution() {
        let text = "//! Copied from gunnar-ui/uitest/src/cdp.rs (one implementation)\n\
                    #![allow(dead_code)] // copied whole\n\
                    //! A real doc line.\n\
                    fn f() {}\n";
        let (lines, dropped) = strip_header(text);
        assert_eq!(dropped, 2);
        assert_eq!(lines, vec!["//! A real doc line.", "fn f() {}"]);

        let (lines, dropped) = strip_header("fn f() {}\n");
        assert_eq!(dropped, 0, "no attribution is 0, and the test asserts on it");
        assert_eq!(lines, vec!["fn f() {}"]);
    }

    /// A divergence eats its comment run and exactly one code line. RED when
    /// broken on both halves: eating zero code lines would let a marked comment
    /// hide a whole added block, and eating the rest of the file would let it
    /// hide everything after it.
    #[test]
    fn take_divergences_eats_the_comment_run_and_one_line() {
        let lines = vec![
            "    a,",
            "    // DIVERGES from the gunnar-ui copy, on a measurement:",
            "    // second comment line",
            "    \"--flag\",",
            "    b,",
        ];
        let (kept, n) = take_divergences(&lines);
        assert_eq!(n, 1);
        assert_eq!(kept, vec!["    a,", "    b,"]);

        let none = vec!["    a,", "    b,"];
        let (kept, n) = take_divergences(&none);
        assert_eq!(n, 0);
        assert_eq!(kept, none);
    }
}