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

nordisk/facett

facett-map/tests/label_collision.rs

//! **The map's labels must not overplot into grey static.**
//!
//! THE DEFECT. `LabelLayer` had exactly one declutter — `lod_visible` — and
//! `view_lod_tier` saturates after three steps: past zoom 12 every `Lod::City` label
//! passes it. So every named street in the viewport painted its name at 12 pt on top of
//! every other one. MEASURED on the shipped `korp-ui` on a real 1900×1150 Xvfb window
//! over central Stockholm at zoom 12.1 against the live `korp-server` (80 000 served
//! ways, tile z12): the 2D pane was a field of overlapping grey text with the roads and
//! water unreadable underneath it. The LOD gate cannot cure this — there is no fourth
//! tier to promote a street into.
//!
//! THE ORACLE, and why it is not a count. `placed == 40` is equally consistent with 40
//! well-separated names and with 40 names stacked on one pixel — a count is a state
//! round-trip, and §LAW 2 says a guard that reads one has not seen the picture. The
//! claim "labels no longer overplot" is a claim about RECTANGLES, so this asserts on
//! `MapFacet::painted_label_boxes()` — the very boxes `paint_features` centred its text
//! in, written by the paint pass, never recomputed here.
//!
//! SEEN RED. With `paint_features` back on the old unconditional
//! `painter.text(to_px(at), …)` and the placer's verdict ignored, this file reports
//! **2 470 overlapping pairs of 210 placed labels** on the dense fixture below and
//! `placed == considered` (nothing was ever suppressed). With the pass wired it is
//! **0 overlaps**. The third case is the one that matters most and is the reason
//! `considered` is asserted at all: a `place_map_labels` that returned `None` for
//! everything would also report 0 overlaps — a perfectly blind green — so the sparse
//! test below pins the other end, and the dense test asserts the placer both RAN
//! (`considered` is the full candidate set) and BIT (`suppressed > 0`).

use facett_map::layer::{LabelLayer, LatLon, MapFacet, MapTheme, MapView};

/// One tagged label feature: `(id, position, OSM tags)`.
type TaggedLabel = (i64, LatLon, Vec<(String, String)>);

/// A pane the size korp's 2D canvas actually gets on a 1900×1150 window.
const PANE: (f32, f32) = (1258.0, 728.0);

/// Central Stockholm — the camera the defect was measured at.
const CLON: f64 = 18.0686;
const CLAT: f64 = 59.3293;

/// `n × n` named features spread over `span` degrees around Stockholm, each with a
/// street-length name — the shape of a real z12 viewport, where every one of them is
/// `Lod::City` and therefore passes the LOD gate.
fn street_grid(n: usize, span: f64) -> Vec<TaggedLabel> {
    let mut out = Vec::new();
    for i in 0..n {
        for j in 0..n {
            let f = |k: usize| (k as f64 / (n as f64 - 1.0)) - 0.5;
            out.push((
                (i * n + j) as i64 + 1,
                LatLon::new(CLAT + f(i) * span * 0.5, CLON + f(j) * span),
                vec![("highway".into(), "residential".into()), ("name".into(), format!("Björkvägen {i}-{j}"))],
            ));
        }
    }
    out
}

/// Mount the facet in a real egui harness at `zoom` and paint one frame. The harness is
/// what measures the galleys, so the boxes the placer reserves are the boxes the real
/// font produces — a placement computed against a guessed extent is a placement against
/// a different picture than the one that lands.
fn paint(labels: Vec<TaggedLabel>, zoom: f32) -> MapFacet {
    let cam = MapView::new(LatLon::new(CLAT, CLON), zoom, PANE);
    let mut facet = MapFacet::new("labels", cam, MapTheme::default());
    facet.push_layer(Box::new(LabelLayer::from_tagged("street-names", labels)));
    let mut h = egui_kittest::Harness::builder()
        .with_size(egui::Vec2::new(PANE.0, PANE.1))
        .build_ui_state(|ui, f: &mut MapFacet| f.ui(ui), facet);
    h.run();
    h.into_state()
}

/// **The defect, asserted on the applied output.** A dense city viewport places labels
/// that share no pixels, and the placer says out loud how much it dropped to get there.
#[test]
fn a_dense_city_viewport_paints_no_two_labels_on_the_same_pixels() {
    // 20×20 = 400 named streets across ~0.03° — roughly the density of central
    // Stockholm at z12, and every one of them Lod::City.
    let facet = paint(street_grid(20, 0.03), 12.5);
    let (placed, suppressed, considered) = facet.label_placement();
    let boxes = facet.painted_label_boxes();
    let overlaps = facet.label_overlaps();
    eprintln!(
        "dense z12.5: considered={considered} placed={placed} suppressed={suppressed} \
         boxes={} overlapping_pairs={overlaps}",
        boxes.len()
    );

    // (a) The pass RAN. Without this the two assertions below pass on a facet that
    //     never reached the placer at all — the blind green this whole file guards.
    assert!(
        considered >= 300,
        "the placer considered only {considered} of ~400 on-screen candidates — it did \
         not run over the real label set, so the overlap count below proves nothing"
    );
    // (b) It BIT. 400 street names cannot fit legibly in 1258×728; a placer that
    //     suppressed nothing is a placer that is not placing.
    assert!(
        suppressed > 0,
        "the placer suppressed 0 of {considered} candidates in a viewport that cannot \
         physically fit them — every label still drew, which is the defect verbatim"
    );
    // (c) The claim itself, on the boxes the painter used.
    assert_eq!(
        overlaps, 0,
        "{overlaps} pairs of the {} painted label boxes share pixels — the map is \
         painting text over text, which is exactly the grey static measured on korp-ui \
         over Stockholm at zoom 12.1",
        boxes.len()
    );
    // (d) The published numbers are the numbers, and they close.
    let js = facet.state_json();
    assert_eq!(js["labels"]["placed"].as_u64(), Some(placed as u64));
    assert_eq!(js["labels"]["suppressed"].as_u64(), Some(suppressed as u64));
    assert_eq!(
        placed + suppressed,
        considered,
        "placed + suppressed must exactly equal considered — a truncated candidate was \
         never considered, so a gap here means the accounting is lying"
    );
}

/// **The other end: the placer must not eat a map that fits.** Without this, a
/// `place_map_labels` that returned `None` for everything would sail through the dense
/// test above with 0 overlaps — a guard that can only ever report green.
#[test]
fn a_sparse_viewport_keeps_every_label_it_is_given() {
    let facet = paint(street_grid(3, 0.02), 13.0);
    let (placed, suppressed, considered) = facet.label_placement();
    eprintln!("sparse z13: considered={considered} placed={placed} suppressed={suppressed}");
    assert_eq!(considered, 9, "all 9 fixture labels should reach the placer");
    assert_eq!(
        suppressed, 0,
        "9 well-separated labels fit in 1258×728 with room to spare; suppressing {suppressed} \
         of them means the placer is dropping labels a human would have been able to read"
    );
    assert_eq!(placed, 9);
    assert_eq!(facet.label_overlaps(), 0);
}

/// **A regional camera still shows its place names.** The LOD gate and the collision
/// pass are different cures and must not be confused: `place=city` is `Lod::Region`, so
/// it needs zoom ≥ 6 to pass `lod_visible` at all — and once it is through that gate the
/// collision pass must not then eat it. Three cities on a 1258×728 pane collide with
/// nothing, so all three have to land.
#[test]
fn a_regional_camera_still_paints_the_place_names() {
    let feats = vec![
        (1, LatLon::new(59.3293, 18.0686), vec![("place".into(), "city".into()), ("name".into(), "Stockholm".into())]),
        (2, LatLon::new(59.6099, 17.8506), vec![("place".into(), "city".into()), ("name".into(), "Uppsala".into())]),
        (3, LatLon::new(59.1955, 17.6253), vec![("place".into(), "city".into()), ("name".into(), "Södertälje".into())]),
    ];
    let cam = MapView::new(LatLon::new(59.4, 17.9), 8.0, PANE);
    let mut facet = MapFacet::new("labels", cam, MapTheme::default());
    facet.push_layer(Box::new(LabelLayer::from_tagged("place-names", feats)));
    let mut h = egui_kittest::Harness::builder()
        .with_size(egui::Vec2::new(PANE.0, PANE.1))
        .build_ui_state(|ui, f: &mut MapFacet| f.ui(ui), facet);
    h.run();
    let facet = h.into_state();
    let (placed, _, considered) = facet.label_placement();
    eprintln!("regional z8: considered={considered} placed={placed}");
    assert_eq!(considered, 3, "all three city labels must clear the Lod::Region gate at zoom 8");
    assert_eq!(
        placed, 3,
        "a regional camera painted {placed} of 3 well-separated place names — the \
         collision pass has eaten the labels the LOD gate exists to keep"
    );
}

// ═════════════════════════════════════════════════════════════════════════════
// The three things a rect-vs-rect collision test cannot see
//
// The pass above WORKS: on the shipped korp-ui over central Stockholm at zoom 12.7
// against the live korp-server (80 000 ways, tile z12, Xvfb 1900×1150,
// `02-2d-z12.png`, 2026-08-03) it reported **255 placed of 3 756 considered and zero
// overlapping pairs** — one label per 3 591 px² — and the pane was still a field of
// text. Overlap is a claim about PAIRS. What the eye reacts to is the SURFACE, the
// REPETITION and the FIT, and none of the three is visible to `Rect::intersects`.
//
// The pane after all three rules, MEASURED on the same drive at camera 12.0 (same
// 80 000-way budget, 127 635 drawn features against the before run's 127 488):
// **64 placed, 0 repeats, ink 7.8 % of the canvas**.
// ═════════════════════════════════════════════════════════════════════════════

use facett_map::layer::WaysLayer;
use facett_map::style::MapPalette;
use facett_map::{mercator, unmercator, Way, WayKind};
use facett_map::style::{classify_with, Lod};

/// The zoom the defect was measured at.
const Z: f32 = 12.7;

/// The camera the fixtures are built against — the one the screenshot was taken with.
fn cam() -> MapView {
    MapView::new(LatLon::new(CLAT, CLON), Z, PANE)
}

/// `(lon, lat)` of a **pane pixel**, so a fixture can be written in the units the
/// declutter rules are stated in. Inverts `MapView::project` at bearing/tilt 0.
fn at_px(view: &MapView, x: f32, y: f32) -> (f64, f64) {
    let ws = view.world_px();
    let (cx, cy) = mercator(CLON, CLAT);
    unmercator(cx + (x - PANE.0 * 0.5) as f64 / ws, cy + (y - PANE.1 * 0.5) as f64 / ws)
}

/// A named, classified way running from pane pixel `a` to pane pixel `b`.
fn street(view: &MapView, id: i64, name: &str, highway: &str, a: (f32, f32), b: (f32, f32)) -> Way {
    let pts = vec![at_px(view, a.0, a.1), at_px(view, b.0, b.1)];
    let tags = vec![("highway".to_string(), highway.to_string())];
    let style = classify_with(&tags, &MapPalette::cartographic(true));
    let mut w = Way::line(id, "road", pts, style.color, style.width);
    w.style = style;
    w.name = name.to_string();
    w
}

/// Mount a `WaysLayer` + its `LabelLayer::from_ways` — korp's exact label path — and
/// paint one real frame.
fn paint_ways(ways: Vec<Way>) -> MapFacet {
    let mut facet = MapFacet::new("labels", cam(), MapTheme::cartographic(&facett_core::Theme::default(), true));
    facet.push_layer(Box::new(LabelLayer::from_ways("street-names", &ways)));
    facet.push_layer(Box::new(WaysLayer::new("streets", ways)));
    let mut h = egui_kittest::Harness::builder()
        .with_size(egui::Vec2::new(PANE.0, PANE.1))
        .build_ui_state(|ui, f: &mut MapFacet| f.ui(ui), facet);
    h.run();
    h.into_state()
}

/// A z12.7 city viewport the size of korp's canvas: 140 distinct street names, each
/// split into 6 ways the way OSM splits them, laid on a grid across the whole pane.
/// Six arterials, twelve primaries, the rest residential — the real class mix.
fn city_ways() -> Vec<Way> {
    let view = cam();
    let mut out = Vec::new();
    let mut id = 1i64;
    // A deterministic LCG, so the fixture is the same picture on every run.
    let mut seed = 0x5eed_u64;
    let mut rnd = || {
        seed = seed.wrapping_mul(6364136223846793005).wrapping_add(1442695040888963407);
        ((seed >> 33) as f64) / (u32::MAX as f64)
    };
    for s in 0..140 {
        let highway = match s {
            0..=5 => "motorway",
            6..=17 => "primary",
            18..=39 => "secondary",
            _ => "residential",
        };
        let name = format!("{}vägen", ["Björk", "Ek", "Lind", "Alm", "Asp", "Sälg", "Rönn"][s % 7]);
        let name = format!("{name} {s}");
        // A street runs across the pane in one of two directions, split into 6 ways.
        let horizontal = s % 2 == 0;
        let (x0, y0) = ((rnd() * 1.3 - 0.15) as f32 * PANE.0, (rnd() * 1.3 - 0.15) as f32 * PANE.1);
        let seg = 60.0 + (rnd() as f32) * 90.0;
        for k in 0..6 {
            let (a, b) = if horizontal {
                ((x0 + k as f32 * seg, y0), (x0 + (k + 1) as f32 * seg, y0))
            } else {
                ((x0, y0 + k as f32 * seg), (x0, y0 + (k + 1) as f32 * seg))
            };
            out.push(street(&view, id, &name, highway, a, b));
            id += 1;
        }
    }
    out
}

/// **The pane may not disappear under its own labels.**
///
/// SEEN RED. With `max_placed: 0` (no areal budget) and the repeat + fit rules removed
/// from `place_map_labels`, this fixture reports, verbatim:
///
/// ```text
/// z12.7 city pane: considered=674 placed=167 suppressed=507 · ink=251154 px (28.4 % of the pane) · distinct=60 repeats=107 · overlaps=0
/// thread 'a_z12_city_pane_does_not_disappear_under_its_own_labels' panicked at facett-map/tests/label_collision.rs:
///   167 labels reserved 28.4 % of a 1258x728 pane. Not one pair overlaps (0) — and the map
///   underneath is unreadable, which is the defect the collision pass could not see.
/// ```
///
/// `0 overlaps` in that red run is the whole point: the collision pass was perfect and
/// the picture was wrong.
#[test]
fn a_z12_city_pane_does_not_disappear_under_its_own_labels() {
    let facet = paint_ways(city_ways());
    let (placed, suppressed, considered) = facet.label_placement();
    let (distinct, repeats) = facet.label_repetition();
    let ink = facet.label_ink_frac();
    let overlaps = facet.label_overlaps();
    eprintln!(
        "z12.7 city pane: considered={considered} placed={placed} suppressed={suppressed} · \
         ink={} px ({:.1} % of the pane) · distinct={distinct} repeats={repeats} · overlaps={overlaps}",
        facet.state_json()["labels"]["ink_px"],
        ink * 100.0
    );

    // (a) The pass RAN over a real candidate set. The fixture offers 840 named ways;
    //     the repeat + fit rules cut that to `considered` BEFORE the placer (which is
    //     the point of them), so this floor is on what the placer itself walked.
    assert!(
        considered >= 100,
        "only {considered} of 840 named ways reached the placer; the fixture is not a city"
    );
    // (b) THE CLAIM: label ink is a minority of the pane, by a wide margin.
    assert!(
        ink <= 0.15,
        "{placed} labels reserved {:.1} % of a {}x{} pane. Not one pair overlaps ({overlaps}) — and \
         the map underneath is unreadable, which is the defect the collision pass could not see.",
        ink * 100.0,
        PANE.0 as i32,
        PANE.1 as i32
    );
    // (c) ANTI-BLIND-GREEN. A placer that drew nothing would score 0 % ink.
    assert!(
        placed >= 20,
        "only {placed} labels landed on a whole city pane — a blank map is not a calm map"
    );
    // (d) The budget is the thing that bit, and it is the one derived from THIS pane.
    let budget = facet.state_json()["labels"]["budget"].as_u64().unwrap() as usize;
    assert!(placed <= budget, "{placed} labels placed against a budget of {budget}");
    // (e) The accounting still closes.
    assert_eq!(placed + suppressed, considered, "placed + suppressed must equal considered");
    assert_eq!(overlaps, 0, "the collision pass must still hold");
}

/// **One street is one name, not one name per OSM way.**
///
/// OSM splits a street into many ways and `LabelLayer::from_ways` anchors a label at
/// each way's centroid, so a single road arrives at the placer once per fragment. Those
/// printings do not overlap — they are tens of px apart — so the collision pass keeps
/// every one of them and the reader gets the same word twelve times.
///
/// SEEN RED. With the `LABEL_REPEAT_PX` check removed from `place_map_labels`:
///
/// ```text
/// one street, twelve ways: placed=11 distinct=1 repeats=10
/// thread 'one_street_split_into_twelve_ways_is_printed_once' panicked at facett-map/tests/label_collision.rs:
///   "Ringvägen" was printed 11 times inside a 180x80 px anchor cluster — 11 times the
///   ink for one fact
/// ```
#[test]
fn one_street_split_into_twelve_ways_is_printed_once() {
    let view = cam();
    let mut ways = Vec::new();
    // 12 fragments of ONE street, each 110 px long (comfortably longer than the name,
    // so the FIT rule is not what drops them), with their anchors in a 180x80 px
    // cluster — every pair closer than `LABEL_REPEAT_PX` (250 px), so the correct
    // answer is exactly one printing.
    for r in 0..3 {
        for c in 0..4 {
            let x = 500.0 + c as f32 * 60.0;
            let y = 300.0 + r as f32 * 40.0;
            ways.push(street(&view, (r * 4 + c) as i64 + 1, "Ringvägen", "residential", (x, y), (x + 110.0, y)));
        }
    }
    let facet = paint_ways(ways);
    let (placed, ..) = facet.label_placement();
    let (distinct, repeats) = facet.label_repetition();
    eprintln!("one street, twelve ways: placed={placed} distinct={distinct} repeats={repeats}");

    assert_eq!(
        placed, 1,
        "\"Ringvägen\" was printed {placed} times inside a 180x80 px anchor cluster — {placed} \
         times the ink for one fact"
    );
    // ANTI-BLIND-GREEN: the name must still be SOMEWHERE. A repeat rule that dropped
    // every printing would satisfy an inequality but lose the street.
    assert_eq!(distinct, 1, "the street lost its name entirely");
    assert_eq!(repeats, 0);
}

/// **A name is not printed on a stub too short to carry it.**
///
/// A 12 px fragment of "Sankt Eriksgatan" labelled with its 100-odd px name says
/// nothing about where that street is; it is a word floating on the map. This is the
/// standard rule for line-placed symbols, and it is what makes the *remaining* labels
/// mean something — each one now marks a stretch you can actually follow.
///
/// SEEN RED. With the `merc_len * world_px < galley.width()` check removed:
///
/// ```text
/// fit rule: placed=2 considered=2
/// thread 'a_stub_shorter_than_its_own_name_is_not_labelled' panicked at facett-map/tests/label_collision.rs:
///   the stub must be dropped BEFORE the placer (it is not a collision), leaving 1
///   candidate; 2 reached it
/// ```
#[test]
fn a_stub_shorter_than_its_own_name_is_not_labelled() {
    let view = cam();
    let ways = vec![
        // 400 px of street — comfortably longer than its name.
        street(&view, 1, "Sankt Eriksgatan", "secondary", (200.0, 200.0), (600.0, 200.0)),
        // 12 px of a DIFFERENT street, far away so neither collision nor the repeat
        // rule can be what drops it.
        street(&view, 2, "Kungsbroplan", "residential", (900.0, 550.0), (912.0, 550.0)),
    ];
    let facet = paint_ways(ways);
    let (placed, _, considered) = facet.label_placement();
    eprintln!("fit rule: placed={placed} considered={considered}");

    assert_eq!(
        considered, 1,
        "the stub must be dropped BEFORE the placer (it is not a collision), leaving 1 candidate; \
         {considered} reached it"
    );
    assert_eq!(
        placed, 1,
        "both the 400 px street and the 12 px stub were labelled (placed={placed}) — a name on a \
         stub shorter than the name is a word floating on the map"
    );
    // ANTI-BLIND-GREEN: it is the STUB that was dropped, not the street.
    let boxes = facet.painted_label_boxes();
    assert_eq!(boxes.len(), 1, "exactly one box was painted");
    assert!(
        boxes[0].center().x < 700.0,
        "the surviving label sits at {:?} — the rule dropped the long street and kept the stub",
        boxes[0].center()
    );
}

/// **The label ink must be readable against the paper it is printed on.**
///
/// `MapTheme::cartographic` took its label colour from the HOST theme's `text`, with a
/// comment claiming that kept it "legible against the app's own chrome". korp's app
/// theme is dark, so the cartographic DAY map printed `#DCDCDC` on `#F2EFE9` paper.
///
/// SEEN RED. With `label: theme.text` restored in `MapTheme::cartographic`:
///
/// ```text
/// label contrast (day): ink #DC_DC_DC_FF on land #F2_EF_E9_FF = 1.18:1
/// thread 'the_day_map_prints_its_labels_at_readable_contrast' panicked at facett-map/tests/label_collision.rs:
///   the day map prints its labels at 1.18:1 against the paper. WCAG asks 4.5:1 for body
///   text; below that the text is not read, it is seen — as grain.
/// ```
///
/// MEASURED on the shipped korp-ui over Stockholm at z12.7: `#DCDCDC` covered 9 387 px,
/// 1.03 % of the map canvas, at that ratio.
#[test]
fn the_day_map_prints_its_labels_at_readable_contrast() {
    for (what, th) in [
        ("day", MapTheme::cartographic(&facett_core::Theme::default(), true)),
        ("night", MapTheme::cartographic(&facett_core::Theme::default(), false)),
    ] {
        let ratio = facett_map::style::contrast_ratio(th.label, th.land);
        eprintln!("label contrast ({what}): ink {:?} on land {:?} = {ratio:.2}:1", th.label, th.land);
        assert!(
            ratio >= 4.5,
            "the {what} map prints its labels at {ratio:.2}:1 against the paper. WCAG asks 4.5:1 \
             for body text; below that the text is not read, it is seen — as grain."
        );
        // The halo is the paper, so it can only ever HIDE text if it is used as ink.
        assert_eq!(th.label_halo, th.land, "the halo must be the paper colour");
    }
}

/// The `Lod` gate and the rank key are different declutter axes and must both be live:
/// an arterial and a cul-de-sac are the SAME tier at z12, so without a rank the tie
/// breaks to the tile decode order and the pane's few surviving names are chosen by
/// luck. This asserts the ordering the placer actually walks.
#[test]
fn an_arterial_outranks_a_cul_de_sac_at_the_same_lod_tier() {
    let pal = MapPalette::cartographic(true);
    let rank = |hw: &str| {
        facett_map::style::label_rank_of_style(&classify_with(
            &[("highway".to_string(), hw.to_string())],
            &pal,
        ))
    };
    let (m, p, s, r, f) = (rank("motorway"), rank("primary"), rank("secondary"), rank("residential"), rank("footway"));
    eprintln!("rank: motorway={m:.2} primary={p:.2} secondary={s:.2} residential={r:.2} footway={f:.2}");
    assert!(m > p && p > s && s > r && r > f, "the highway hierarchy must be strictly ordered: {m} {p} {s} {r} {f}");
    // Same TIER — which is exactly why the tier alone cannot order them.
    assert_eq!(
        classify_with(&[("highway", "motorway")], &pal).lod as u8 as i32,
        Lod::Country as i32,
        "sanity: the class table is the one being read"
    );
    // A named lake outranks a residential street but not an arterial.
    let lake = facett_map::style::label_rank_of_style(&classify_with(&[("natural", "water")], &pal));
    assert!(lake > r && lake < m, "a lake name sits between a street and an arterial (got {lake})");
    let _ = WayKind::Water;
}

/// **A five-digit county road number is not a motorway shield.**
///
/// Every `ref` used to resolve to `(Lod::Region, 0.90)`, above every street name in
/// the country and eligible from zoom 6. The first calm z12 render of Stockholm came
/// back labelled `35002 · 69013 · 10357 · 10060 · 10042 · 21001 · 10982 · 13506 ·
/// 40107` — the whole budget spent on Swedish secondary county numbers, because they
/// outranked "Sveavägen" by construction.
///
/// SEEN RED with the flat `(Lod::Region, 0.90)` restored:
/// ```text
/// ref ladder: E4=(Region,0.90) 73=(Region,0.90) 222=(Region,0.90) 10061=(Region,0.90) · Sveavägen=(City,0.27)
/// thread 'a_five_digit_county_number_does_not_outrank_a_street_name' panicked:
///   the county road number 10061 ranks 0.90 against a residential street's 0.27 — it
///   takes the pane's label budget from the streets a reader navigates by
/// ```
#[test]
fn a_five_digit_county_number_does_not_outrank_a_street_name() {
    let hw = |r: &str| {
        facett_map::style::classify_label(&[
            ("highway".to_string(), "secondary".to_string()),
            ("ref".to_string(), r.to_string()),
            ("name".to_string(), "Länsvägen".to_string()),
        ])
        .unwrap()
    };
    let (e4, riks, primar, sekundar) = (hw("E4"), hw("73"), hw("222"), hw("10061"));
    let street = facett_map::style::classify_label(&[
        ("highway".to_string(), "residential".to_string()),
        ("name".to_string(), "Sveavägen".to_string()),
    ])
    .unwrap();
    eprintln!(
        "ref ladder: E4=({:?},{:.2}) 73=({:?},{:.2}) 222=({:?},{:.2}) 10061=({:?},{:.2}) · Sveavägen=({:?},{:.2})",
        e4.lod, e4.rank, riks.lod, riks.rank, primar.lod, primar.rank, sekundar.lod, sekundar.rank, street.lod, street.rank
    );

    // The placer's key is (tier ASC, rank DESC), so a deeper tier loses outright.
    assert!(
        (sekundar.lod as u8, -sekundar.rank) > (street.lod as u8, -street.rank),
        "the county road number 10061 ranks {:.2} against a residential street's {:.2} — it takes          the pane's label budget from the streets a reader navigates by",
        sekundar.rank,
        street.rank
    );
    // ANTI-BLIND-GREEN: the ladder must still HAVE a top. Demoting every ref would
    // satisfy the line above and lose the E4 shield, which is the one number a driver
    // does navigate by.
    assert_eq!(e4.lod, Lod::Region, "an E-road shield must still read from a regional overview");
    assert!(e4.rank > riks.rank && riks.rank > primar.rank && primar.rank > sekundar.rank,
        "the ref ladder must be strictly ordered E4 > 73 > 222 > 10061");
    assert_eq!(riks.lod, Lod::Region, "a one/two-digit riksväg still reads regionally");
    assert_eq!(primar.lod, Lod::City, "a three-digit county road is a zoomed-in label");
}