github.com/matiasanaya/gqlgen@v0.6.0/codegen/util_test.go (about)

     1  package codegen
     2  
     3  import (
     4  	"go/ast"
     5  	"go/importer"
     6  	"go/parser"
     7  	"go/token"
     8  	"go/types"
     9  	"testing"
    10  
    11  	"github.com/stretchr/testify/require"
    12  )
    13  
    14  func TestNormalizeVendor(t *testing.T) {
    15  	require.Equal(t, "bar/baz", normalizeVendor("foo/vendor/bar/baz"))
    16  	require.Equal(t, "[]bar/baz", normalizeVendor("[]foo/vendor/bar/baz"))
    17  	require.Equal(t, "*bar/baz", normalizeVendor("*foo/vendor/bar/baz"))
    18  	require.Equal(t, "*[]*bar/baz", normalizeVendor("*[]*foo/vendor/bar/baz"))
    19  }
    20  
    21  func TestFindField(t *testing.T) {
    22  	input := `
    23  package test
    24  
    25  type Std struct {
    26  	Name string
    27  	Value int
    28  }
    29  type Anon struct {
    30  	Name string
    31  	Tags
    32  }
    33  type Tags struct {
    34  	Bar string ` + "`" + `gqlgen:"foo"` + "`" + `
    35  	Foo int    ` + "`" + `gqlgen:"bar"` + "`" + `
    36  }
    37  type Amb struct {
    38  	Bar string ` + "`" + `gqlgen:"foo"` + "`" + `
    39  	Foo int    ` + "`" + `gqlgen:"foo"` + "`" + `
    40  }
    41  type Embed struct {
    42  	Std
    43  	Test string
    44  }
    45  `
    46  	scope, err := parseScope(input, "test")
    47  	require.NoError(t, err)
    48  
    49  	std := scope.Lookup("Std").Type().Underlying().(*types.Struct)
    50  	anon := scope.Lookup("Anon").Type().Underlying().(*types.Struct)
    51  	tags := scope.Lookup("Tags").Type().Underlying().(*types.Struct)
    52  	amb := scope.Lookup("Amb").Type().Underlying().(*types.Struct)
    53  	embed := scope.Lookup("Embed").Type().Underlying().(*types.Struct)
    54  
    55  	tests := []struct {
    56  		Name        string
    57  		Struct      *types.Struct
    58  		Field       string
    59  		Tag         string
    60  		Expected    string
    61  		ShouldError bool
    62  	}{
    63  		{"Finds a field by name with no tag", std, "name", "", "Name", false},
    64  		{"Finds a field by name when passed tag but tag not used", std, "name", "gqlgen", "Name", false},
    65  		{"Ignores tags when not passed a tag", tags, "foo", "", "Foo", false},
    66  		{"Picks field with tag over field name when passed a tag", tags, "foo", "gqlgen", "Bar", false},
    67  		{"Errors when ambigious", amb, "foo", "gqlgen", "", true},
    68  		{"Finds a field that is in embedded struct", anon, "bar", "", "Bar", false},
    69  		{"Finds field that is not in embedded struct", embed, "test", "", "Test", false},
    70  	}
    71  
    72  	for _, tt := range tests {
    73  		tt := tt
    74  		field, err := findField(tt.Struct, tt.Field, tt.Tag)
    75  		if tt.ShouldError {
    76  			require.Nil(t, field, tt.Name)
    77  			require.Error(t, err, tt.Name)
    78  		} else {
    79  			require.NoError(t, err, tt.Name)
    80  			require.Equal(t, tt.Expected, field.Name(), tt.Name)
    81  		}
    82  	}
    83  }
    84  
    85  func parseScope(input interface{}, packageName string) (*types.Scope, error) {
    86  	// test setup to parse the types
    87  	fset := token.NewFileSet()
    88  	f, err := parser.ParseFile(fset, "test.go", input, 0)
    89  	if err != nil {
    90  		return nil, err
    91  	}
    92  
    93  	conf := types.Config{Importer: importer.Default()}
    94  	pkg, err := conf.Check(packageName, fset, []*ast.File{f}, nil)
    95  	if err != nil {
    96  		return nil, err
    97  	}
    98  
    99  	return pkg.Scope(), nil
   100  }