github.com/anchore/syft@v1.4.2-0.20240516191711-1bec1fc5d397/syft/internal/sourcemetadata/completion_tester.go (about) 1 package sourcemetadata 2 3 import ( 4 "reflect" 5 "testing" 6 ) 7 8 type CompletionTester struct { 9 saw []any 10 valid []any 11 ignore []any 12 } 13 14 func NewCompletionTester(t testing.TB, ignore ...any) *CompletionTester { 15 tester := &CompletionTester{ 16 valid: AllTypes(), 17 ignore: ignore, 18 } 19 t.Cleanup(func() { 20 t.Helper() 21 tester.validate(t) 22 }) 23 return tester 24 } 25 26 func (tr *CompletionTester) Tested(t testing.TB, m any) { 27 t.Helper() 28 29 if m == nil { 30 return 31 } 32 if len(tr.valid) == 0 { 33 t.Fatal("no valid metadata types to test against") 34 } 35 ty := reflect.TypeOf(m) 36 for _, v := range tr.valid { 37 if reflect.TypeOf(v) == ty { 38 tr.saw = append(tr.saw, m) 39 return 40 } 41 } 42 43 t.Fatalf("tested metadata type is not valid: %s", ty.Name()) 44 } 45 46 func (tr *CompletionTester) validate(t testing.TB) { 47 t.Helper() 48 49 count := make(map[reflect.Type]int) 50 for _, m := range tr.saw { 51 count[reflect.TypeOf(m)]++ 52 } 53 54 validations: 55 for _, v := range tr.valid { 56 ty := reflect.TypeOf(v) 57 58 for _, ignore := range tr.ignore { 59 if ty == reflect.TypeOf(ignore) { 60 // skip ignored types 61 continue validations 62 } 63 } 64 65 if c, exists := count[ty]; c == 0 || !exists { 66 t.Errorf("metadata type %s is not covered by a test", ty.Name()) 67 } 68 } 69 }