test: encode eeschema kicad-cli ground truth (currently RED)

Update existing rotation/mirror assertions and add a kicad-cli-grounded
regression suite. eeschema's pin transform is verified against:
  - rotation: TRANSFORM(0,1,-1,0) for rot=90 — CCW in screen Y-down
  - mirror x: SYM_MIRROR_X = TRANSFORM(1,0,0,-1) — negates internal Y
  - mirror y: SYM_MIRROR_Y = TRANSFORM(-1,0,0,1) — negates internal X

Updated assertions:
  - test_pin_locator_y_flip: rotated cap pin 1 X 153.81 → 146.19
  - test_move_with_wire_preservation::test_resistor_rotated_90:
    pin 1 X 103.81 → 96.19
  - test_hierarchical_pad_net_map::test_90_degree_rotation:
    swapped UP_NET / DN_NET label coords

New file tests/test_pin_world_xy_eeschema_truth.py:
  - 4 parametrized diode tests via kicad-cli netlist (oracle = eeschema)
  - 2 parametrized resistor mirror tests via kicad-cli netlist
  - 3 pure-math pin_world_xy assertions for rot=90, mirror_x, mirror_y

Currently RED on rotation 90/270 (rotation direction) and mirror_x/y
(axis semantics swapped). Production fix in WireDragger.pin_world_xy
to follow.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Eugene Mikhantyev
2026-05-03 22:24:14 +01:00
parent 118318c2f3
commit f7660e15ad
4 changed files with 233 additions and 13 deletions

View File

@@ -222,13 +222,14 @@ class TestComputePinPositions:
assert abs(new2[1] - 23.81) < 1e-4
def test_resistor_rotated_90(self) -> None:
"""Device:R at (100, 100) rot=90. Pin 1 lib (0, +3.81) → y-flipped to
(0, -3.81) → rotated 90° → (3.81, 0) → world (103.81, 100)."""
"""Device:R at (100, 100) rot=90. Pin 1 lib (0, +3.81), Y-flip → (0, -3.81),
eeschema rot=90 TRANSFORM(0,1,-1,0): (0*0+1*-3.81, -1*0+0*-3.81) = (-3.81, 0).
World (96.19, 100). Verified vs kicad-cli netlist."""
sch = _make_sch_data([_make_symbol("R1", 100, 100, rotation=90)])
positions = WireDragger.compute_pin_positions(sch, "R1", 100, 100)
old1, _ = positions["1"]
old2, _ = positions["2"]
assert abs(old1[0] - 103.81) < 1e-3
assert abs(old1[0] - 96.19) < 1e-3
assert abs(old1[1] - 100) < 1e-3
def test_returns_empty_for_missing_component(self) -> None: