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

nordisk/gunnar-ui

crates/gunnar-ui-recipe/tests/toml_parity.rs

//! **`.nornir/build-variants.toml` IS the code's emission — and this fails for
//! any reason it is not.**
//!
//! 1. the committed bytes are `emit`'s bytes (a row added to the code and not
//!    re-emitted, a hand edit, a comment typed into the output: all red);
//! 2. the emission reads back, through the ONE loader, to the declaration;
//! 3. the file is inert — an edit is visible to a reader and invisible to the code;
//! 4. the comparison can go red at all (a set differing by one field is unequal).

use gunnar_ui_recipe::{declared, emitted_toml, repo_root, GunnarUiBuildThing};
use nornir_build_thing::emit::first_difference;
use nornir_build_thing::plugin::{BuildThing, Role};
use nornir_build_thing::variant::{ArtifactKind, BuildVariantSet, Profile, ServiceShape};

fn committed() -> String {
    let path = BuildVariantSet::conventional_path(&repo_root());
    std::fs::read_to_string(&path).unwrap_or_else(|e| panic!("read {}: {e}", path.display()))
}

#[test]
fn the_committed_toml_is_the_codes_emission_byte_for_byte() {
    let emitted = emitted_toml().expect("the declaration emits");
    if let Some(diff) = first_difference(&committed(), &emitted) {
        panic!(
            ".nornir/build-variants.toml is not the code's emission — the code is the source. \
             Run `cargo run -p gunnar-ui-build-thing -- emit` and commit the result; never edit \
             the toml by hand. {diff}"
        );
    }
    let back = BuildVariantSet::from_toml_str(&emitted).expect("the emission parses back");
    assert_eq!(back, declared());
    back.validate_all().expect("and every variant validates");
    gunnar_ui_recipe::require_committed_is_emitted(&repo_root())
        .expect("the door's own check agrees");
}

#[test]
fn an_edited_toml_has_zero_effect_on_what_the_code_declares() {
    let before = declared();
    let edited = emitted_toml().unwrap().replace(
        "name = \"gunnar-ui-web\"",
        "name = \"gunnar-ui-web-edited\"",
    );
    let read = BuildVariantSet::from_toml_str(&edited).expect("still parses");
    assert_ne!(
        read, before,
        "the edit must be visible to a reader, else this proves nothing"
    );
    assert_eq!(
        GunnarUiBuildThing.variants(),
        before,
        "the code read the file — it must not"
    );
}

#[test]
fn the_comparison_reports_red_on_a_set_that_differs_by_one_field() {
    let set =
        BuildVariantSet::load_file(&BuildVariantSet::conventional_path(&repo_root())).unwrap();
    assert_eq!(set.variants.len(), 5, "5 [[build.variant]] rows (the product gunnar-ui first)");

    let mut p = set.clone();
    p.variants[2].features.clear();
    assert_ne!(p, set, "a variant losing its features must compare unequal");
    let mut p = set.clone();
    p.variants[1].target = None;
    assert_ne!(p, set, "a variant losing its target must compare unequal");
}

/// **Every row is a build this repository already performs**, held to the
/// values the doors that perform it use.
#[test]
fn the_rows_describe_the_builds_that_already_happen() {
    let set = declared();

    // The BFF: static musl, release, a skidbladnir service under `gunnar-ui`.
    // `deploy/deploy.sh`'s GUNNAR_UI_TRIPLE default and its ONE `cargo build`.
    for name in ["gunnar-ui-server", "gunnar-ui-server-metered"] {
        let v = set
            .get(name)
            .unwrap_or_else(|| panic!("{name} is declared"));
        assert_eq!(v.package.as_deref(), Some("gunnar-ui-server"));
        assert_eq!(v.bin.as_deref(), Some("gunnar-ui-server"));
        assert_eq!(v.target.as_deref(), Some("x86_64-unknown-linux-musl"));
        assert_eq!(v.profile, Profile::Release);
        assert_eq!(v.kind, ArtifactKind::Service);
        assert_eq!(v.member.as_deref(), Some("gunnar-ui"));
        assert_eq!(v.role, Some(Role::Server));
        assert_eq!(v.shape, ServiceShape::ThinStandalone);
        assert!(v.embeds.is_empty(), "nothing here compiles a sibling in");
        assert!(
            v.reaches.contains("gunnar"),
            "the BFF is useless without one"
        );
    }

    // The console: a wasm32 bundle, release, driven against the BFF.
    for name in ["gunnar-ui-web", "gunnar-ui-web-metered"] {
        let v = set
            .get(name)
            .unwrap_or_else(|| panic!("{name} is declared"));
        assert_eq!(v.package.as_deref(), Some("gunnar-ui-web"));
        assert_eq!(v.target.as_deref(), Some("wasm32-unknown-unknown"));
        assert_eq!(v.kind, ArtifactKind::Wasm);
        assert_eq!(
            v.role,
            Some(Role::Client),
            "a UI is a client, not a new role"
        );
        assert!(v.member.is_none(), "a browser bundle is no system service");
        assert!(
            v.reaches.contains("gunnar-ui"),
            "it reaches the BFF that serves it"
        );
    }

    // The metered/community split is the WHOLE feature universe, and it is
    // gunnar's word rather than one invented here.
    assert_eq!(
        set.offers.iter().map(String::as_str).collect::<Vec<_>>(),
        ["metered"]
    );
    assert!(set.get("gunnar-ui-server").unwrap().features.is_empty());
    assert_eq!(
        set.get("gunnar-ui-server-metered").unwrap().features,
        ["metered"]
    );
    assert!(set.get("gunnar-ui-web").unwrap().features.is_empty());
    assert_eq!(
        set.get("gunnar-ui-web-metered").unwrap().features,
        ["metered"]
    );

    // Exactly one normal case per role group, and no suite axis to confuse it.
    assert!(
        set.check_defaults().is_empty(),
        "{:?}",
        set.check_defaults()
    );
    assert!(
        set.get("gunnar-ui-server-metered").unwrap().is_default,
        "the deploy's default"
    );
    assert!(
        set.get("gunnar-ui-web").unwrap().is_default,
        "what bare `trunk build --release` makes"
    );
}

/// **NO `[[build.wasm]]` cell, and the absence is the declaration.**
///
/// The console's bundle is built by trunk, which runs the wasm row's cargo
/// build and then wasm-bindgen at the version `Trunk.toml` pins, `wasm-opt -Oz`
/// and the `index.html` asset pipeline — writing CONTENT-HASHED names
/// (`gunnar-ui-web-<hash>_bg.wasm`). `BindgenStage` DERIVES its outputs from the
/// package name, so a cell here would name `gunnar_ui_web_bg.wasm` and
/// `gunnar_ui_web.js`, two files trunk never writes, and anything chaining the
/// cell would be checked against a claim that is false.
///
/// This test exists so that adding a cell is a deliberate act that has to come
/// with the vocabulary to describe trunk, rather than a copy of facett's row.
#[test]
fn the_console_declares_no_wasm_cell_because_trunk_is_not_wasm_bindgen() {
    let set = declared();
    assert!(
        set.wasms.is_empty(),
        "a [[build.wasm]] cell would have to describe trunk, and BindgenStage cannot: \
         trunk's outputs are content-hashed and it also runs wasm-opt and the index.html \
         pipeline. See this test's doc comment."
    );
    let bundle = repo_root().join("crates/gunnar-ui-web/Trunk.toml");
    assert!(
        bundle.is_file(),
        "the bundler this repository actually uses: {}",
        bundle.display()
    );
}