package iace import ( "encoding/json" "os" "path/filepath" "testing" ) func TestVerifyPins(t *testing.T) { pins := []AcceptedPin{ {Pattern: "HPa", MustFire: true}, {Pattern: "HPb", MustFire: false}, } res := VerifyPins(pins, []string{"HPa", "HPb"}) if !res[0].OK { t.Errorf("HPa must_fire=true and it fired -> should be OK") } if res[1].OK { t.Errorf("HPb must_fire=false but it fired -> should be VIOLATED") } res2 := VerifyPins(pins, []string{}) if res2[0].OK || !res2[1].OK { t.Errorf("expected HPa violated + HPb ok, got %+v", res2) } } func TestGenerateDedupPin(t *testing.T) { pin := GenerateDedupPin(DedupCandidate{KeepPattern: "HP144", DropPattern: "HP013", Category: "electrical_hazard"}) if pin.Pattern != "HP013" || pin.MustFire { t.Fatalf("want pin {HP013, must_fire=false}, got %+v", pin) } } // TestWarewashing_AcceptedPins re-checks every accepted P1 supersession against the // live warewashing engine output. A future change that un-suppresses HP013/016/018 // or drops HP2201/HP144 breaks a pin here — the gate compounds, not erodes. func TestWarewashing_AcceptedPins(t *testing.T) { raw, err := os.ReadFile(filepath.Join("testdata", "accepted_pins_warewashing.json")) if err != nil { t.Fatalf("read pins: %v", err) } var ps PinSet if err := json.Unmarshal(raw, &ps); err != nil { t.Fatalf("parse pins: %v", err) } _, _, kept := warewashingEngineOutput() firedIDs := make([]string, 0, len(kept)) for _, pm := range kept { firedIDs = append(firedIDs, pm.PatternID) } ok := 0 for _, r := range VerifyPins(ps.Pins, firedIDs) { if r.OK { ok++ continue } t.Errorf("PIN VIOLATED: %s (must_fire=%v) — %s [%s]", r.Pin.Pattern, r.Pin.MustFire, r.Detail, r.Pin.Reason) } t.Logf("accepted pins for %q: %d/%d hold", ps.Machine, ok, len(ps.Pins)) }