github.com/inturn/pre-commit-gobuild@v1.0.12/internal/errchecker/embedded_walker_test.go (about)

     1  package errchecker
     2  
     3  import (
     4  	"go/ast"
     5  	"go/parser"
     6  	"go/token"
     7  	"go/types"
     8  	"testing"
     9  )
    10  
    11  const commonSrc = `
    12  package p
    13  
    14  type Inner struct {}
    15  func (Inner) Method()
    16  
    17  type Outer struct {Inner}
    18  type OuterP struct {*Inner}
    19  
    20  type InnerInterface interface {
    21  	Method()
    22  }
    23  
    24  type OuterInterface interface {InnerInterface}
    25  type MiddleInterfaceStruct struct {OuterInterface}
    26  type OuterInterfaceStruct struct {MiddleInterfaceStruct}
    27  
    28  var c = `
    29  
    30  type testCase struct {
    31  	selector   string
    32  	expectedOk bool
    33  	expected   []string
    34  }
    35  
    36  func TestWalkThroughEmbeddedInterfaces(t *testing.T) {
    37  	cases := []testCase{
    38  		testCase{"Inner{}.Method", false, nil},
    39  		testCase{"(&Inner{}).Method", false, nil},
    40  		testCase{"Outer{}.Method", false, nil},
    41  		testCase{"InnerInterface.Method", true, []string{"test.InnerInterface"}},
    42  		testCase{"OuterInterface.Method", true, []string{"test.OuterInterface", "test.InnerInterface"}},
    43  		testCase{"OuterInterfaceStruct.Method", true, []string{"test.OuterInterface", "test.InnerInterface"}},
    44  	}
    45  
    46  	for _, c := range cases {
    47  		fset := token.NewFileSet()
    48  		f, err := parser.ParseFile(fset, "test", commonSrc+c.selector, 0)
    49  		if err != nil {
    50  			t.Fatal(err)
    51  		}
    52  
    53  		conf := types.Config{}
    54  		info := types.Info{
    55  			Selections: make(map[*ast.SelectorExpr]*types.Selection),
    56  		}
    57  		_, err = conf.Check("test", fset, []*ast.File{f}, &info)
    58  		if err != nil {
    59  			t.Fatal(err)
    60  		}
    61  		ast.Inspect(f, func(n ast.Node) bool {
    62  			s, ok := n.(*ast.SelectorExpr)
    63  			if ok {
    64  				selection, ok := info.Selections[s]
    65  				if !ok {
    66  					t.Fatalf("no Selection!")
    67  				}
    68  				ts, ok := walkThroughEmbeddedInterfaces(selection)
    69  				if ok != c.expectedOk {
    70  					t.Errorf("expected ok %v got %v", c.expectedOk, ok)
    71  					return false
    72  				}
    73  				if !ok {
    74  					return false
    75  				}
    76  
    77  				if len(ts) != len(c.expected) {
    78  					t.Fatalf("expected %d types, got %d", len(c.expected), len(ts))
    79  				}
    80  
    81  				for i, e := range c.expected {
    82  					if e != ts[i].String() {
    83  						t.Errorf("mismatch at index %d: expected %s got %s", i, e, ts[i])
    84  					}
    85  				}
    86  			}
    87  
    88  			return true
    89  		})
    90  
    91  	}
    92  
    93  }