github.com/apipluspower/gqlgen@v0.15.2/codegen/field_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/apipluspower/gqlgen/codegen/config"
    12  	"github.com/stretchr/testify/require"
    13  )
    14  
    15  func TestFindField(t *testing.T) {
    16  	input := `
    17  package test
    18  
    19  type Std struct {
    20  	Name string
    21  	Value int
    22  }
    23  type Anon struct {
    24  	Name string
    25  	Tags
    26  }
    27  type Tags struct {
    28  	Bar string ` + "`" + `gqlgen:"foo"` + "`" + `
    29  	Foo int    ` + "`" + `gqlgen:"bar"` + "`" + `
    30  }
    31  type Amb struct {
    32  	Bar string ` + "`" + `gqlgen:"foo"` + "`" + `
    33  	Foo int    ` + "`" + `gqlgen:"foo"` + "`" + `
    34  }
    35  type Embed struct {
    36  	Std
    37  	Test string
    38  }
    39  `
    40  	scope, err := parseScope(input, "test")
    41  	require.NoError(t, err)
    42  
    43  	std := scope.Lookup("Std").Type().(*types.Named)
    44  	anon := scope.Lookup("Anon").Type().(*types.Named)
    45  	tags := scope.Lookup("Tags").Type().(*types.Named)
    46  	amb := scope.Lookup("Amb").Type().(*types.Named)
    47  	embed := scope.Lookup("Embed").Type().(*types.Named)
    48  
    49  	tests := []struct {
    50  		Name        string
    51  		Named       *types.Named
    52  		Field       string
    53  		Tag         string
    54  		Expected    string
    55  		ShouldError bool
    56  	}{
    57  		{"Finds a field by name with no tag", std, "name", "", "Name", false},
    58  		{"Finds a field by name when passed tag but tag not used", std, "name", "gqlgen", "Name", false},
    59  		{"Ignores tags when not passed a tag", tags, "foo", "", "Foo", false},
    60  		{"Picks field with tag over field name when passed a tag", tags, "foo", "gqlgen", "Bar", false},
    61  		{"Errors when ambigious", amb, "foo", "gqlgen", "", true},
    62  		{"Finds a field that is in embedded struct", anon, "bar", "", "Bar", false},
    63  		{"Finds field that is not in embedded struct", embed, "test", "", "Test", false},
    64  	}
    65  
    66  	for _, tt := range tests {
    67  		b := builder{Config: &config.Config{StructTag: tt.Tag}}
    68  		target, err := b.findBindTarget(tt.Named, tt.Field)
    69  		if tt.ShouldError {
    70  			require.Nil(t, target, tt.Name)
    71  			require.Error(t, err, tt.Name)
    72  		} else {
    73  			require.NoError(t, err, tt.Name)
    74  			require.Equal(t, tt.Expected, target.Name(), tt.Name)
    75  		}
    76  	}
    77  }
    78  
    79  func parseScope(input interface{}, packageName string) (*types.Scope, error) {
    80  	// test setup to parse the types
    81  	fset := token.NewFileSet()
    82  	f, err := parser.ParseFile(fset, "test.go", input, 0)
    83  	if err != nil {
    84  		return nil, err
    85  	}
    86  
    87  	conf := types.Config{Importer: importer.Default()}
    88  	pkg, err := conf.Check(packageName, fset, []*ast.File{f}, nil)
    89  	if err != nil {
    90  		return nil, err
    91  	}
    92  
    93  	return pkg.Scope(), nil
    94  }
    95  
    96  func TestEqualFieldName(t *testing.T) {
    97  	tt := []struct {
    98  		Name     string
    99  		Source   string
   100  		Target   string
   101  		Expected bool
   102  	}{
   103  		{Name: "words with same case", Source: "test", Target: "test", Expected: true},
   104  		{Name: "words different case", Source: "test", Target: "tEsT", Expected: true},
   105  		{Name: "different words", Source: "foo", Target: "bar", Expected: false},
   106  		{Name: "separated with underscore", Source: "the_test", Target: "TheTest", Expected: true},
   107  		{Name: "empty values", Source: "", Target: "", Expected: true},
   108  	}
   109  
   110  	for _, tc := range tt {
   111  		t.Run(tc.Name, func(t *testing.T) {
   112  			result := equalFieldName(tc.Source, tc.Target)
   113  			require.Equal(t, tc.Expected, result)
   114  		})
   115  	}
   116  }