xtask/tests/uitest_copies.rs
//! **RA4-24: monetize's copies of `uitest`'s client are held in step from THIS side too.**
//!
//! `uitest/src/{cdp,http,json,ws}.rs` are copied whole into monetize's `uitest/src/` (the
//! owner keeps the copy: `uitest` takes no dependency on purpose, CDP-SHARE). monetize's
//! `uitest/tests/copied_from_gunnar_ui.rs` fails when its copy drifts, but only in monetize's
//! CI: an edit made here alone (CRYPT-YUBI grew `cdp.rs` from 632 to 646 lines) stayed green
//! here and turned monetize red a day later. This test fails HERE, on the commit that edits
//! one side alone.
//!
//! monetize is always beside this repository (the workspace builds against its crates), so
//! there is no step-aside: a missing sibling is red. The copy's sanctioned differences are its
//! attribution header and blocks marked `DIVERGES from the gunnar-ui copy` (a comment run and
//! the one line it is about), pinned per file, the same rule monetize's guard holds.
use std::path::{Path, PathBuf};
/// The copied files, and how many marked divergences each copy may carry.
const COPIED: &[(&str, usize)] = &[("cdp.rs", 1), ("http.rs", 0), ("json.rs", 0), ("ws.rs", 0)];
const HEADER: &str = "//! Copied from gunnar-ui/uitest/src/";
const ALLOW_DEAD: &str = "#![allow(dead_code)]";
const DIVERGES: &str = "DIVERGES from the gunnar-ui copy";
fn root() -> PathBuf {
Path::new(env!("CARGO_MANIFEST_DIR")).parent().expect("xtask sits in the repo").to_path_buf()
}
/// The copy's lines with its header and marked divergences taken out, and the divergence count.
fn as_original(copy: &str) -> (Vec<&str>, usize, usize) {
let lines: Vec<&str> = copy.lines().collect();
let header = lines.iter().take_while(|l| l.trim_start().starts_with(HEADER) || l.trim_start().starts_with(ALLOW_DEAD)).count();
let (mut out, mut diverged, mut i) = (Vec::new(), 0, header);
while i < lines.len() {
if lines[i].contains(DIVERGES) {
diverged += 1;
while i < lines.len() && lines[i].trim_start().starts_with("//") {
i += 1;
}
i += 1;
continue;
}
out.push(lines[i]);
i += 1;
}
(out, header, diverged)
}
#[test]
fn monetizes_copies_of_the_uitest_client_are_this_repos_files() {
let ours = root().join("uitest/src");
let theirs = root().join("../monetize/uitest/src");
assert!(theirs.is_dir(), "monetize is not beside this repository ({}): the copies cannot be checked, and this workspace does not build without it either", theirs.display());
for (f, allowed) in COPIED {
let original = std::fs::read_to_string(ours.join(f)).unwrap_or_else(|e| panic!("read uitest/src/{f}: {e}"));
let copy = std::fs::read_to_string(theirs.join(f)).unwrap_or_else(|e| panic!("read monetize/uitest/src/{f}: {e}"));
let (copy, header, diverged) = as_original(©);
assert!(header > 0, "monetize's {f} says nowhere that it is a copy of this one");
assert_eq!(diverged, *allowed, "monetize's {f}: {diverged} marked divergence(s), {allowed} allowed");
let original: Vec<&str> = original.lines().collect();
let first = original.iter().zip(copy.iter()).position(|(a, b)| a != b);
assert!(
first.is_none() && original.len() == copy.len(),
"uitest/src/{f} and monetize's copy have drifted ({} lines here, {} there; first difference at line {}). \
Edit both: copy this file over monetize's uitest/src/{f} (keeping its header and marked divergences) in the same change.",
original.len(),
copy.len(),
first.map_or(original.len().min(copy.len()) + 1, |n| n + 1)
);
}
}
/// The rule itself: the header and a marked divergence (its comment run and one line) are all
/// a copy may add.
#[test]
fn a_copy_may_add_only_its_header_and_marked_divergences() {
let copy = "//! Copied from gunnar-ui/uitest/src/cdp.rs (one implementation)\n#![allow(dead_code)]\nfn a() {}\n // DIVERGES from the gunnar-ui copy, measured:\n // why\n \"--flag\",\nfn b() {}\n";
let (lines, header, diverged) = as_original(copy);
assert_eq!((header, diverged), (2, 1));
assert_eq!(lines, vec!["fn a() {}", "fn b() {}"]);
let (lines, header, _) = as_original("fn a() {}\n");
assert_eq!((lines, header), (vec!["fn a() {}"], 0));
}