Classify remaining D&D producer diagnostics

This commit is contained in:
2026-08-27 16:04:32 +00:00
parent 6a1fd7bdb6
commit 480680b257
22 changed files with 202 additions and 182 deletions

View File

@@ -47,6 +47,33 @@ func Collect(findings []contracts.Warning, disposition contracts.DiagnosticDispo
return collector.Diagnostics(), nil
}
// NormalizationDiagnostics classifies deterministic normalization findings as
// observations, except for explicitly identified unresolved-quality findings.
func NormalizationDiagnostics(findings []contracts.Warning, advisoryReasonCodes ...string) ([]contracts.ProducerDiagnostic, error) {
advisoryReasons := make(map[string]struct{}, len(advisoryReasonCodes))
for _, reasonCode := range advisoryReasonCodes {
advisoryReasons[reasonCode] = struct{}{}
}
observations := make([]contracts.Warning, 0, len(findings))
advisories := make([]contracts.Warning, 0)
for _, finding := range findings {
if _, advisory := advisoryReasons[finding.ReasonCode]; advisory {
advisories = append(advisories, finding)
continue
}
observations = append(observations, finding)
}
diagnostics, err := Collect(observations, contracts.DiagnosticDispositionObservation, contracts.DiagnosticCategoryNormalization)
if err != nil {
return nil, err
}
qualityDiagnostics, err := Collect(advisories, contracts.DiagnosticDispositionAdvisory, contracts.DiagnosticCategoryDataQuality)
if err != nil {
return nil, err
}
return append(diagnostics, qualityDiagnostics...), nil
}
func Truncate(value string) string {
runes := []rune(value)
if len(runes) <= MaxDisplayedRunes {

View File

@@ -92,3 +92,21 @@ func TestCollectGroupsNormalizationFindingsWithBoundedSamples(t *testing.T) {
t.Fatalf("diagnostic = %#v", diagnostic)
}
}
func TestNormalizationDiagnosticsCombinesQualityAndCleanupWithoutWarnings(t *testing.T) {
groups, err := NormalizationDiagnostics([]contracts.Warning{
{Scope: "spell_casts[0]", ReasonCode: "spell_name_canonicalized", Message: "canonicalized spell name"},
{Scope: "spell_casts[1]", ReasonCode: "spell_name_unresolved", Message: "spell was not in the catalog"},
}, "spell_name_unresolved")
if err != nil {
t.Fatal(err)
}
if len(groups) != 2 || groups[0].Disposition != contracts.DiagnosticDispositionObservation || groups[1].Disposition != contracts.DiagnosticDispositionAdvisory {
t.Fatalf("groups = %#v, want cleanup observation and quality advisory", groups)
}
for _, group := range groups {
if group.Disposition == contracts.DiagnosticDispositionWarning {
t.Fatalf("groups = %#v, want zero warning groups", groups)
}
}
}