1
2
3
4
5 package cryptotest
6
7 import (
8 "fmt"
9 "reflect"
10 "slices"
11 "testing"
12 )
13
14
15
16
17
18
19
20
21
22 func NoExtraMethods(t *testing.T, ms interface{}, allowed ...string) {
23 t.Helper()
24 extraMethods, err := extraMethods(ms)
25 if err != nil {
26 t.Fatal(err)
27 }
28 for _, m := range extraMethods {
29 if slices.Contains(allowed, m) {
30 continue
31 }
32 t.Errorf("unexpected method %q", m)
33 }
34 }
35
36 func extraMethods(ip interface{}) ([]string, error) {
37 v := reflect.ValueOf(ip)
38 if v.Kind() != reflect.Ptr || v.Elem().Kind() != reflect.Interface || v.Elem().IsNil() {
39 return nil, fmt.Errorf("argument must be a pointer to a non-nil interface")
40 }
41
42 interfaceType := v.Elem().Type()
43 concreteType := v.Elem().Elem().Type()
44
45 interfaceMethods := make(map[string]bool)
46 for i := range interfaceType.NumMethod() {
47 interfaceMethods[interfaceType.Method(i).Name] = true
48 }
49
50 var extraMethods []string
51 for i := range concreteType.NumMethod() {
52 m := concreteType.Method(i)
53 if !m.IsExported() {
54 continue
55 }
56 if !interfaceMethods[m.Name] {
57 extraMethods = append(extraMethods, m.Name)
58 }
59 }
60
61 return extraMethods, nil
62 }
63
View as plain text