package iace import "testing" // Helper-level: operates on already-normalised (lowercase, umlaut-folded) text. func TestHasUnnegatedOccurrence(t *testing.T) { neg := "keine pneumatischen oder hydraulischen schnittstellen. hubantrieb ueber kette (kettenspannung zyklisch zu pruefen)." tests := []struct { name string text string kw string want bool }{ {"negated hydraulik", neg, "hydraulisch", false}, {"negated pneumatik", neg, "pneumatisch", false}, {"positive kette after period", neg, "kette", true}, {"ohne negates", "ohne hydraulik vorhanden", "hydraulik", false}, {"mit ends scope", "ohne hydraulik, mit pneumatikzylinder", "pneumatik", true}, {"plain positive", "die maschine hat eine hydraulikpumpe", "hydraulik", true}, {"weder/contrast", "weder pneumatik noch hydraulik verbaut", "pneumatik", false}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if got := hasUnnegatedOccurrence(tt.text, tt.kw); got != tt.want { t.Errorf("hasUnnegatedOccurrence(%q,%q)=%v, want %v", tt.text, tt.kw, got, tt.want) } }) } } // Integration: the Kistenhub interface sentence SURFACES the hydraulic (C041) // and pneumatic (C051) components flagged as negated (for expert review), keeps // the chain drive (C010) as present, and crucially leaks NO pneumatic/hydraulic // tags into the matching set (so no phantom hazards). func TestParseNarrative_NegatedInterfacesFlagged(t *testing.T) { text := "Keine pneumatischen oder hydraulischen Schnittstellen. " + "Hubantrieb über Kette (Kettenspannung zyklisch zu prüfen)." res := ParseNarrative(text) status := func(id string) (found, negated bool) { for _, c := range res.Components { if c.LibraryID == id { return true, c.Negated } } return false, false } if f, n := status("C041"); !f || !n { t.Errorf("C041 (Hydraulikpumpe) should be surfaced & negated; found=%v negated=%v", f, n) } if f, n := status("C051"); !f || !n { t.Errorf("C051 (Pneumatikzylinder) should be surfaced & negated; found=%v negated=%v", f, n) } if f, n := status("C010"); !f || n { t.Errorf("C010 (Kettenantrieb) should be present & not negated; found=%v negated=%v", f, n) } for _, tag := range res.CustomTags { if tag == "pneumatic_part" || tag == "hydraulic_part" { t.Errorf("negated component leaked tag %q into the matching set", tag) } } }