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

nordisk/edda

crates/nornir-parquet-delta/tests/leaf_shape.rs

//! **This crate is a leaf and must stay one.** Same discipline as
//! `crates/gunnar-bitmap`'s `donation_shape.rs`, and for the same reason: a general
//! mechanism that grows a dependency on the first project to use it stops being general,
//! and nobody notices until the second project tries.
//!
//! The rule it enforces: `nornir-parquet-delta` depends on `parquet` (metadata + the
//! `ChunkReader` trait), `bytes` (that trait's payload type) and `thiserror`. Nothing
//! else, and in particular nothing from korp, facett or arrow.
//!
//! Proven red on 2026-09-02 by adding `korp = { path = "../../../korp" }` to the
//! manifest: `no_application_dependency` fired naming it.

use std::path::PathBuf;

fn manifest() -> String {
    let p = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("Cargo.toml");
    std::fs::read_to_string(&p).unwrap_or_else(|e| panic!("read {}: {e}", p.display()))
}

/// The `[dependencies]` section's crate names — the ones that ship. Dev-dependencies are
/// deliberately NOT checked: the tests build real parquet files, which needs arrow.
fn shipped_dependency_names() -> Vec<String> {
    let text = manifest();
    let mut in_deps = false;
    let mut out = Vec::new();
    for line in text.lines() {
        let t = line.trim();
        if t.starts_with('[') {
            in_deps = t == "[dependencies]";
            continue;
        }
        if !in_deps || t.is_empty() || t.starts_with('#') {
            continue;
        }
        if let Some((name, _)) = t.split_once('=') {
            out.push(name.trim().trim_matches('"').to_string());
        }
    }
    out
}

/// No application depends on this crate, so this crate depends on no application.
///
/// `cargo tree -p nornir-parquet-delta -i korp` must be empty; this is that check
/// without needing korp's checkout to be present.
#[test]
fn no_application_dependency() {
    let deps = shipped_dependency_names();
    assert!(!deps.is_empty(), "the manifest parser found no [dependencies] at all");
    for forbidden in ["korp", "facett", "nornir-service", "skade", "osm-katana", "gatling-forkjoin"] {
        assert!(
            !deps.iter().any(|d| d == forbidden || d.starts_with(&format!("{forbidden}-"))),
            "`{forbidden}` is not allowed in a leaf's shipped dependencies; found {deps:?}",
        );
    }
}

/// The shipped surface is three crates. Adding a fourth is a decision, not a slip — this
/// test is where it gets made.
#[test]
fn the_shipped_dependency_set_is_exactly_the_three_it_is_documented_to_be() {
    let mut deps = shipped_dependency_names();
    deps.sort();
    assert_eq!(
        deps,
        vec!["bytes".to_string(), "parquet".to_string(), "thiserror".to_string()],
        "the crate docs promise parquet + bytes + thiserror and nothing else",
    );
}

/// It reads footers and moves opaque bytes; it never decodes a page. So it must not ask
/// `parquet` for arrow or for a codec — the consumer's own feature set does that, and
/// cargo unifies them in a shared build.
#[test]
fn parquet_is_taken_without_arrow_and_without_a_codec() {
    let text = manifest();
    let line = text
        .lines()
        .find(|l| l.trim_start().starts_with("parquet =") && l.contains("default-features = false"))
        .expect("the [dependencies] parquet line must set default-features = false");
    // The dev-dependencies line DOES carry features; the shipped one must not.
    let shipped = text
        .split("[dev-dependencies]")
        .next()
        .expect("a manifest has a first half")
        .lines()
        .find(|l| l.trim_start().starts_with("parquet ="))
        .expect("a shipped parquet line");
    assert!(
        !shipped.contains("features = ["),
        "the shipped parquet dependency must take no features: {shipped}\n(the one found with \
         default-features=false was: {line})",
    );
}

/// Every source file is `#![deny(missing_docs)]`-clean by construction — the crate root
/// says so, and this test says the crate root still says so, because that attribute is
/// the only thing making the public API self-describing to a second consumer.
#[test]
fn the_crate_denies_undocumented_public_api() {
    let lib = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("src/lib.rs");
    let text = std::fs::read_to_string(lib).unwrap();
    assert!(text.contains("#![deny(missing_docs, rust_2018_idioms)]"));
}