From 74b43ed5af9ea302c91cb70c053715674a12f726 Mon Sep 17 00:00:00 2001 From: sjat Date: Wed, 24 Jun 2026 14:05:56 +0200 Subject: [PATCH] test(rack): guard empty rack value and cover 0U/both/multi-rack rendering Co-Authored-By: Claude Sonnet 4.6 --- scripts/gen_rack.py | 3 +++ tests/test_gen_rack.py | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/scripts/gen_rack.py b/scripts/gen_rack.py index a627a23..9bf9b46 100644 --- a/scripts/gen_rack.py +++ b/scripts/gen_rack.py @@ -73,6 +73,9 @@ def load_rack_items(hardware_dir: Path) -> list[dict]: def validate_item(fm: dict) -> None: name = fm.get("hostname") or fm.get("_path", "?") + rack = fm.get("rack") + if not isinstance(rack, str) or not rack: + raise SchemaError(f"{name}: rack must be a non-empty string") face = fm.get("rack_face") if face not in FACES: raise SchemaError(f"{name}: rack_face={face!r} not in {sorted(FACES)}") diff --git a/tests/test_gen_rack.py b/tests/test_gen_rack.py index cdd44f1..c056d2e 100644 --- a/tests/test_gen_rack.py +++ b/tests/test_gen_rack.py @@ -42,6 +42,11 @@ def test_validate_rejects_missing_units_on_faced_item(): gen_rack.validate_item(item(rack_face="front")) +def test_validate_rejects_empty_rack(): + with pytest.raises(gen_rack.SchemaError): + gen_rack.validate_item(item(rack=None, rack_u=1, u_height=1, rack_face="front")) + + def test_overlaps_detects_same_face_overlap(): items = [ item(hostname="a", rack_u=1, u_height=2, rack_face="front"), @@ -135,6 +140,42 @@ def test_generate_writes_artifacts(tmp_path): assert "mf00" in (out / "rack01-elevation.svg").read_text() +def test_render_svg_draws_zero_u_rail(): + items = [item(hostname="pdu01", kind="pdu", rack_face="left")] + svg = gen_rack.render_svg("rack01", items) + assert "pdu01" in svg + assert "rotate(-90" in svg + + +def test_render_svg_both_face_draws_in_both_columns(): + items = [item(hostname="dev", rack_u=10, u_height=1, rack_face="both")] + svg = gen_rack.render_svg("rack01", items) + assert svg.count("dev (U10)") == 2 + + +def test_generate_writes_one_pair_per_rack(tmp_path): + hw = tmp_path / "hardware" + out = tmp_path / "out" + hw.mkdir() + _write_item( + hw, + "a", + "---\nhostname: a\nkind: server\nstatus: in-use\n" + "rack: rack01\nrack_u: 1\nu_height: 1\nrack_face: front\n---\n", + ) + _write_item( + hw, + "b", + "---\nhostname: b\nkind: server\nstatus: in-use\n" + "rack: rack02\nrack_u: 1\nu_height: 1\nrack_face: front\n---\n", + ) + rc = gen_rack.generate(hw, out) + assert rc == 0 + assert (out / "rack01.md").exists() and (out / "rack02.md").exists() + assert (out / "rack01-elevation.svg").exists() + assert (out / "rack02-elevation.svg").exists() + + def test_generate_returns_1_on_overlap(tmp_path): hw = tmp_path / "hardware" out = tmp_path / "out"