package iace import ( "strings" "testing" ) // TestManufacturerLibrary_HasTopManufacturers checks the curated baseline // (~50 entries across major mechanical/plant-engineering segments). The // expected manufacturers below are the ones that would be unsurprising to // find in any industrial risk-assessment context. func TestManufacturerLibrary_HasTopManufacturers(t *testing.T) { required := []string{ "FANUC", "KUKA", "ABB Robotics", "Yaskawa Motoman", "Universal Robots", "DMG MORI", "Mazak", "TRUMPF", "Heidenhain", "Festo", "SMC", "Bosch Rexroth", "PILZ", "SICK", "Schmersal", "Euchner", "Siemens", "Beckhoff", "Rockwell Automation", "Schuler", "Arburg", "KraussMaffei", } have := map[string]bool{} for _, mf := range GetManufacturerSafetyFeatures() { have[mf.Manufacturer] = true } for _, want := range required { if !have[want] { t.Errorf("manufacturer library missing %q", want) } } } // TestManufacturerLibrary_AllHaveNorms pins that every entry carries at // least one EN/ISO/IEC norm reference. A manufacturer entry without norm // anchor is just hearsay; with it, the operator has something verifiable. func TestManufacturerLibrary_AllHaveNorms(t *testing.T) { for _, mf := range GetManufacturerSafetyFeatures() { if len(mf.NormReferences) == 0 { t.Errorf("manufacturer %q (%s) missing NormReferences", mf.Manufacturer, mf.FeatureName) } if len(mf.Clarifications) == 0 { t.Errorf("manufacturer %q (%s) missing Clarifications", mf.Manufacturer, mf.FeatureName) } } } // TestLookupManufacturerFeaturesInText_FindsFANUC reproduces the GT-Bremse // scenario: a narrative mentioning "Robodrill" must surface the FANUC DCS // entry — that's how the operator gets the right clarification question // without us inventing commentary. func TestLookupManufacturerFeaturesInText_FindsFANUC(t *testing.T) { narrative := "Roboterzelle mit Fanuc Robodrill Werkzeugmaschine und KUKA-Roboter." hits := LookupManufacturerFeaturesInText(narrative) manufacturers := map[string]bool{} for _, h := range hits { manufacturers[h.Manufacturer] = true } if !manufacturers["FANUC"] { t.Errorf("expected FANUC hit for narrative %q, got %v", narrative, manufacturers) } if !manufacturers["KUKA"] { t.Errorf("expected KUKA hit for narrative %q, got %v", narrative, manufacturers) } } // TestLookupManufacturerFeaturesInText_HandlesUmlauts pins case + umlaut // robustness — "Stäubli" must match alias "staeubli". func TestLookupManufacturerFeaturesInText_HandlesUmlauts(t *testing.T) { hits := LookupManufacturerFeaturesInText("Stäubli TX2 Roboter und Schmersal Türverriegelung") manufacturers := map[string]bool{} for _, h := range hits { manufacturers[h.Manufacturer] = true } if !manufacturers["Stäubli Robotics"] { t.Errorf("expected Staeubli hit, got %v", manufacturers) } if !manufacturers["Schmersal"] { t.Errorf("expected Schmersal hit, got %v", manufacturers) } } // TestLookupManufacturerFeaturesInText_EmptyText handles missing narrative // gracefully — must not crash and must return nil/empty. func TestLookupManufacturerFeaturesInText_EmptyText(t *testing.T) { if hits := LookupManufacturerFeaturesInText(""); len(hits) > 0 { t.Errorf("expected no hits for empty narrative, got %d", len(hits)) } } // TestManufacturerLibrary_Has50OrMore checks the target count of the // curated set so a future regression that deletes many entries fails CI. func TestManufacturerLibrary_Has50OrMore(t *testing.T) { got := len(GetManufacturerSafetyFeatures()) if got < 50 { // Allow small undercount but keep the floor strict t.Errorf("manufacturer library has %d entries, expected >= 50", got) } } // TestNormalizeForMatch pins the umlaut/case folding behavior. func TestNormalizeForMatch(t *testing.T) { cases := []struct{ in, want string }{ {"Stäubli", "staeubli"}, {"FANUC", "fanuc"}, {"Schäffer", "schaeffer"}, {"Mößbauer", "moessbauer"}, } for _, c := range cases { if got := normalizeForMatch(c.in); got != c.want { t.Errorf("normalizeForMatch(%q) = %q, want %q", c.in, got, c.want) } } } // TestManufacturerLibrary_NormReferencesAreRealNorms scans for the standard // norm prefixes so a future "we just put a placeholder" regression fails. func TestManufacturerLibrary_NormReferencesAreRealNorms(t *testing.T) { for _, mf := range GetManufacturerSafetyFeatures() { ok := false for _, n := range mf.NormReferences { for _, prefix := range []string{"EN ", "IEC ", "ISO ", "DIN ", "EN ISO", "DIN EN", "VDE", "TRBS", "TRGS"} { if strings.HasPrefix(n, prefix) { ok = true break } } if ok { break } } if !ok { t.Errorf("manufacturer %q has no recognized norm prefix in %v", mf.Manufacturer, mf.NormReferences) } } }