github.com/galaxy-book/gqlgen@v0.7.2/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  	require.Equal(t, "[]*bar/baz", normalizeVendor("[]*foo/vendor/bar/baz"))
    20  }
    21  
    22  func TestFindField(t *testing.T) {
    23  	input := `
    24  package test
    25  
    26  type Std struct {
    27  	Name string
    28  	Value int
    29  }
    30  type Anon struct {
    31  	Name string
    32  	Tags
    33  }
    34  type Tags struct {
    35  	Bar string ` + "`" + `gqlgen:"foo"` + "`" + `
    36  	Foo int    ` + "`" + `gqlgen:"bar"` + "`" + `
    37  }
    38  type Amb struct {
    39  	Bar string ` + "`" + `gqlgen:"foo"` + "`" + `
    40  	Foo int    ` + "`" + `gqlgen:"foo"` + "`" + `
    41  }
    42  type Embed struct {
    43  	Std
    44  	Test string
    45  }
    46  `
    47  	scope, err := parseScope(t, input, "test")
    48  	require.NoError(t, err)
    49  
    50  	std := scope.Lookup("Std").Type().Underlying().(*types.Struct)
    51  	anon := scope.Lookup("Anon").Type().Underlying().(*types.Struct)
    52  	tags := scope.Lookup("Tags").Type().Underlying().(*types.Struct)
    53  	amb := scope.Lookup("Amb").Type().Underlying().(*types.Struct)
    54  	embed := scope.Lookup("Embed").Type().Underlying().(*types.Struct)
    55  
    56  	tests := []struct {
    57  		Name        string
    58  		Struct      *types.Struct
    59  		Field       string
    60  		Tag         string
    61  		Expected    string
    62  		ShouldError bool
    63  	}{
    64  		{"Finds a field by name with no tag", std, "name", "", "Name", false},
    65  		{"Finds a field by name when passed tag but tag not used", std, "name", "gqlgen", "Name", false},
    66  		{"Ignores tags when not passed a tag", tags, "foo", "", "Foo", false},
    67  		{"Picks field with tag over field name when passed a tag", tags, "foo", "gqlgen", "Bar", false},
    68  		{"Errors when ambigious", amb, "foo", "gqlgen", "", true},
    69  		{"Finds a field that is in embedded struct", anon, "bar", "", "Bar", false},
    70  		{"Finds field that is not in embedded struct", embed, "test", "", "Test", false},
    71  	}
    72  
    73  	for _, tt := range tests {
    74  		tt := tt
    75  		field, err := findField(tt.Struct, tt.Field, tt.Tag)
    76  		if tt.ShouldError {
    77  			require.Nil(t, field, tt.Name)
    78  			require.Error(t, err, tt.Name)
    79  		} else {
    80  			require.NoError(t, err, tt.Name)
    81  			require.Equal(t, tt.Expected, field.Name(), tt.Name)
    82  		}
    83  	}
    84  }
    85  
    86  func parseScope(t *testing.T, input interface{}, packageName string) (*types.Scope, error) {
    87  	// test setup to parse the types
    88  	fset := token.NewFileSet()
    89  	f, err := parser.ParseFile(fset, "test.go", input, 0)
    90  	if err != nil {
    91  		return nil, err
    92  	}
    93  
    94  	conf := types.Config{Importer: importer.Default()}
    95  	pkg, err := conf.Check(packageName, fset, []*ast.File{f}, nil)
    96  	if err != nil {
    97  		return nil, err
    98  	}
    99  
   100  	return pkg.Scope(), nil
   101  }
   102  
   103  func TestEqualFieldName(t *testing.T) {
   104  	tt := []struct {
   105  		Name     string
   106  		Source   string
   107  		Target   string
   108  		Expected bool
   109  	}{
   110  		{Name: "words with same case", Source: "test", Target: "test", Expected: true},
   111  		{Name: "words different case", Source: "test", Target: "tEsT", Expected: true},
   112  		{Name: "different words", Source: "foo", Target: "bar", Expected: false},
   113  		{Name: "separated with underscore", Source: "the_test", Target: "TheTest", Expected: true},
   114  		{Name: "empty values", Source: "", Target: "", Expected: true},
   115  	}
   116  
   117  	for _, tc := range tt {
   118  		t.Run(tc.Name, func(t *testing.T) {
   119  			result := equalFieldName(tc.Source, tc.Target)
   120  			require.Equal(t, tc.Expected, result)
   121  		})
   122  	}
   123  }
   124  
   125  func TestEqualTypes(t *testing.T) {
   126  	tt := []struct {
   127  		Name     string
   128  		Source   string
   129  		Target   string
   130  		Expected bool
   131  	}{
   132  		{Name: "basic", Source: "bar/baz", Target: "bar/baz", Expected: true},
   133  		{Name: "basic slice", Source: "[]bar/baz", Target: "[]bar/baz", Expected: true},
   134  		{Name: "pointer", Source: "*bar/baz", Target: "bar/baz", Expected: true},
   135  		{Name: "pointer slice", Source: "[]*bar/baz", Target: "[]bar/baz", Expected: true},
   136  	}
   137  
   138  	for _, tc := range tt {
   139  		t.Run(tc.Name, func(t *testing.T) {
   140  			result := equalTypes(tc.Source, tc.Target)
   141  			require.Equal(t, tc.Expected, result)
   142  		})
   143  	}
   144  }