Skip to content

Commit

Permalink
config: add test for struct tags
Browse files Browse the repository at this point in the history
This will fail a test if struct tags fall out of sync.

Signed-off-by: Hank Donnay <hdonnay@redhat.com>
  • Loading branch information
hdonnay committed Nov 4, 2021
1 parent 35c9c9f commit 6759ce5
Showing 1 changed file with 54 additions and 0 deletions.
54 changes: 54 additions & 0 deletions config/tags_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package config

import (
"reflect"
"testing"
)

// TestTags checks that exported types and fields used in the root Config struct
// have struct tags.
func TestTags(t *testing.T) {
t.Logf("checking for: %v", wanttags)
nt := reflect.TypeOf(Config{})
t.Run(nt.Name(), func(t *testing.T) { typecheck(t, nt) })
}

var wanttags = []string{`json`, `yaml`}

func typecheck(t *testing.T, typ reflect.Type) {
for i, lim := 0, typ.NumField(); i < lim; i++ {
f := typ.Field(i)
if f.PkgPath != "" {
// TODO(hank) Use the IsExported method once 1.16 support is
// dropped.
continue
}
// track the number of names for this field
vals := make(map[string]struct{})
// track which tag has which name
tagval := make(map[string]string)
for _, n := range wanttags {
if v, ok := f.Tag.Lookup(n); !ok {
t.Errorf("%s.%s: missing %q tag", typ.Name(), f.Name, n)
} else {
vals[v] = struct{}{}
tagval[n] = v
}
}
if len(vals) != 1 {
t.Errorf("different names for %q: %v", f.Name, tagval)
}
// Recurse on structs and pointers-to-structs.
switch nt := f.Type; nt.Kind() {
case reflect.Ptr:
pt := nt.Elem()
if pt.Kind() != reflect.Struct {
break
}
nt = nt.Elem()
fallthrough
case reflect.Struct:
t.Run(nt.Name(), func(t *testing.T) { typecheck(t, nt) })
}
}
}

0 comments on commit 6759ce5

Please sign in to comment.