package standards import ( "go/ast" "go/parser" "go/token" "os" "strconv" "strings" "testing" ) func TestDocumentedEventSchemas(t *testing.T) { raw, err := os.ReadFile("../docs/integrations/events.md") if err != nil { t.Fatalf("ReadFile(events.md) error = %v", err) } doc := string(raw) for _, schema := range schemaConstants(t, false) { if !strings.Contains(doc, schema) { t.Fatalf("docs/integrations/events.md missing schema %q", schema) } } } func TestDocumentedConsumerStandardsConstants(t *testing.T) { raw, err := os.ReadFile("../docs/consumers/pkg-standards.md") if err != nil { t.Fatalf("ReadFile(pkg-standards.md) error = %v", err) } doc := string(raw) for _, schema := range schemaConstants(t, true) { if !strings.Contains(doc, schema) { t.Fatalf("docs/consumers/pkg-standards.md missing schema %q", schema) } } for _, kind := range kindConstants(t) { if !strings.Contains(doc, kind) { t.Fatalf("docs/consumers/pkg-standards.md missing kind %q", kind) } } } func schemaConstants(t *testing.T, includeNonCurrent bool) []string { t.Helper() return stringConstantsFromFile(t, "schema.go", "Schema", func(name string) bool { return !includeNonCurrent && schemaConstantNotInCurrentContract(name) }) } func kindConstants(t *testing.T) []string { t.Helper() return stringConstantsFromFile(t, "kind.go", "Kind", nil) } func stringConstantsFromFile(t *testing.T, path string, prefix string, skip func(string) bool) []string { t.Helper() file, err := parser.ParseFile(token.NewFileSet(), path, nil, 0) if err != nil { t.Fatalf("ParseFile(%s) error = %v", path, err) } var out []string ast.Inspect(file, func(n ast.Node) bool { valueSpec, ok := n.(*ast.ValueSpec) if !ok { return true } for i, name := range valueSpec.Names { if !strings.HasPrefix(name.Name, prefix) || (skip != nil && skip(name.Name)) { continue } if i >= len(valueSpec.Values) { t.Fatalf("constant %s has no explicit value", name.Name) } lit, ok := valueSpec.Values[i].(*ast.BasicLit) if !ok || lit.Kind != token.STRING { t.Fatalf("constant %s is not a string literal", name.Name) } value, err := strconv.Unquote(lit.Value) if err != nil { t.Fatalf("constant %s value is not a quoted string: %v", name.Name, err) } out = append(out, value) } return true }) if len(out) == 0 { t.Fatalf("no %s constants found in %s", prefix, path) } return out } func schemaConstantNotInCurrentContract(name string) bool { return name == "SchemaRawOpenWeatherHourlyForecastV1" }