github.com/animeshon/gqlgen@v0.13.1-0.20210304133704-3a770431bb6d/codegen/config/config_test.go (about)

     1  package config
     2  
     3  import (
     4  	"os"
     5  	"path/filepath"
     6  	"runtime"
     7  	"testing"
     8  
     9  	"github.com/pkg/errors"
    10  	"github.com/stretchr/testify/assert"
    11  	"github.com/stretchr/testify/require"
    12  	"github.com/vektah/gqlparser/v2"
    13  	"github.com/vektah/gqlparser/v2/ast"
    14  
    15  	"github.com/animeshon/gqlgen/internal/code"
    16  )
    17  
    18  func TestLoadConfig(t *testing.T) {
    19  	t.Run("config does not exist", func(t *testing.T) {
    20  		_, err := LoadConfig("doesnotexist.yml")
    21  		require.Error(t, err)
    22  	})
    23  
    24  	t.Run("malformed config", func(t *testing.T) {
    25  		_, err := LoadConfig("testdata/cfg/malformedconfig.yml")
    26  		require.EqualError(t, err, "unable to parse config: yaml: unmarshal errors:\n  line 1: cannot unmarshal !!str `asdf` into config.Config")
    27  	})
    28  
    29  	t.Run("unknown keys", func(t *testing.T) {
    30  		_, err := LoadConfig("testdata/cfg/unknownkeys.yml")
    31  		require.EqualError(t, err, "unable to parse config: yaml: unmarshal errors:\n  line 2: field unknown not found in type config.Config")
    32  	})
    33  
    34  	t.Run("globbed filenames", func(t *testing.T) {
    35  		c, err := LoadConfig("testdata/cfg/glob.yml")
    36  		require.NoError(t, err)
    37  
    38  		if runtime.GOOS == "windows" {
    39  			require.Equal(t, c.SchemaFilename[0], `testdata\cfg\glob\bar\bar with spaces.graphql`)
    40  			require.Equal(t, c.SchemaFilename[1], `testdata\cfg\glob\foo\foo.graphql`)
    41  		} else {
    42  			require.Equal(t, c.SchemaFilename[0], "testdata/cfg/glob/bar/bar with spaces.graphql")
    43  			require.Equal(t, c.SchemaFilename[1], "testdata/cfg/glob/foo/foo.graphql")
    44  		}
    45  	})
    46  
    47  	t.Run("unwalkable path", func(t *testing.T) {
    48  		_, err := LoadConfig("testdata/cfg/unwalkable.yml")
    49  		if runtime.GOOS == "windows" {
    50  			require.EqualError(t, err, "failed to walk schema at root not_walkable/: CreateFile not_walkable/: The system cannot find the file specified.")
    51  		} else {
    52  			require.EqualError(t, err, "failed to walk schema at root not_walkable/: lstat not_walkable/: no such file or directory")
    53  		}
    54  	})
    55  }
    56  
    57  func TestLoadConfigFromDefaultLocation(t *testing.T) {
    58  	testDir, err := os.Getwd()
    59  	require.NoError(t, err)
    60  	var cfg *Config
    61  
    62  	t.Run("will find closest match", func(t *testing.T) {
    63  		err = os.Chdir(filepath.Join(testDir, "testdata", "cfg", "subdir"))
    64  		require.NoError(t, err)
    65  
    66  		cfg, err = LoadConfigFromDefaultLocations()
    67  		require.NoError(t, err)
    68  		require.Equal(t, StringList{"inner"}, cfg.SchemaFilename)
    69  	})
    70  
    71  	t.Run("will find config in parent dirs", func(t *testing.T) {
    72  		err = os.Chdir(filepath.Join(testDir, "testdata", "cfg", "otherdir"))
    73  		require.NoError(t, err)
    74  
    75  		cfg, err = LoadConfigFromDefaultLocations()
    76  		require.NoError(t, err)
    77  		require.Equal(t, StringList{"outer"}, cfg.SchemaFilename)
    78  	})
    79  
    80  	t.Run("will return error if config doesn't exist", func(t *testing.T) {
    81  		err = os.Chdir(testDir)
    82  		require.NoError(t, err)
    83  
    84  		cfg, err = LoadConfigFromDefaultLocations()
    85  		require.True(t, os.IsNotExist(err))
    86  	})
    87  }
    88  
    89  func TestLoadDefaultConfig(t *testing.T) {
    90  	testDir, err := os.Getwd()
    91  	require.NoError(t, err)
    92  	var cfg *Config
    93  
    94  	t.Run("will find the schema", func(t *testing.T) {
    95  		err = os.Chdir(filepath.Join(testDir, "testdata", "defaultconfig"))
    96  		require.NoError(t, err)
    97  
    98  		cfg, err = LoadDefaultConfig()
    99  		require.NoError(t, err)
   100  		require.NotEmpty(t, cfg.Sources)
   101  	})
   102  
   103  	t.Run("will return error if schema doesn't exist", func(t *testing.T) {
   104  		err = os.Chdir(testDir)
   105  		require.NoError(t, err)
   106  
   107  		cfg, err = LoadDefaultConfig()
   108  		require.True(t, os.IsNotExist(errors.Cause(err)))
   109  	})
   110  }
   111  
   112  func TestReferencedPackages(t *testing.T) {
   113  	t.Run("valid", func(t *testing.T) {
   114  		tm := TypeMap{
   115  			"Foo": {Model: StringList{"github.com/test.Foo"}},
   116  			"Bar": {Model: StringList{"github.com/test.Bar"}},
   117  			"Baz": {Model: StringList{"github.com/otherpkg.Baz"}},
   118  			"Map": {Model: StringList{"map[string]interface{}"}},
   119  			"SkipResolver": {
   120  				Fields: map[string]TypeMapField{
   121  					"field": {Resolver: false},
   122  				},
   123  			},
   124  		}
   125  
   126  		pkgs := tm.ReferencedPackages()
   127  
   128  		assert.Equal(t, []string{"github.com/test", "github.com/otherpkg"}, pkgs)
   129  	})
   130  
   131  }
   132  
   133  func TestConfigCheck(t *testing.T) {
   134  	t.Run("invalid config format due to conflicting package names", func(t *testing.T) {
   135  		config := Config{
   136  			Exec:  PackageConfig{Filename: "generated/exec.go", Package: "graphql"},
   137  			Model: PackageConfig{Filename: "generated/models.go"},
   138  		}
   139  
   140  		require.EqualError(t, config.check(), "exec and model define the same import path (github.com/99designs/gqlgen/codegen/config/generated) with different package names (graphql vs generated)")
   141  	})
   142  
   143  	t.Run("federation must be in exec package", func(t *testing.T) {
   144  		config := Config{
   145  			Exec:       PackageConfig{Filename: "generated/exec.go"},
   146  			Federation: PackageConfig{Filename: "anotherpkg/federation.go"},
   147  		}
   148  
   149  		require.EqualError(t, config.check(), "federation and exec must be in the same package")
   150  	})
   151  
   152  	t.Run("federation must have same package name as exec", func(t *testing.T) {
   153  		config := Config{
   154  			Exec:       PackageConfig{Filename: "generated/exec.go"},
   155  			Federation: PackageConfig{Filename: "generated/federation.go", Package: "federation"},
   156  		}
   157  
   158  		require.EqualError(t, config.check(), "exec and federation define the same import path (github.com/99designs/gqlgen/codegen/config/generated) with different package names (generated vs federation)")
   159  	})
   160  
   161  	t.Run("deprecated federated flag raises an error", func(t *testing.T) {
   162  		config := Config{
   163  			Exec:      PackageConfig{Filename: "generated/exec.go"},
   164  			Federated: true,
   165  		}
   166  
   167  		require.EqualError(t, config.check(), "federated has been removed, instead use\nfederation:\n    filename: path/to/federated.go")
   168  	})
   169  }
   170  
   171  func TestAutobinding(t *testing.T) {
   172  	t.Run("valid paths", func(t *testing.T) {
   173  		cfg := Config{
   174  			Models: TypeMap{},
   175  			AutoBind: []string{
   176  				"github.com/animeshon/gqlgen/example/chat",
   177  				"github.com/animeshon/gqlgen/example/scalars/model",
   178  			},
   179  			Packages: &code.Packages{},
   180  		}
   181  
   182  		cfg.Schema = gqlparser.MustLoadSchema(&ast.Source{Name: "TestAutobinding.schema", Input: `
   183  			scalar Banned
   184  			type Message { id: ID }
   185  		`})
   186  
   187  		require.NoError(t, cfg.autobind())
   188  
   189  		require.Equal(t, "github.com/animeshon/gqlgen/example/scalars/model.Banned", cfg.Models["Banned"].Model[0])
   190  		require.Equal(t, "github.com/animeshon/gqlgen/example/chat.Message", cfg.Models["Message"].Model[0])
   191  	})
   192  
   193  	t.Run("with file path", func(t *testing.T) {
   194  		cfg := Config{
   195  			Models: TypeMap{},
   196  			AutoBind: []string{
   197  				"../chat",
   198  			},
   199  			Packages: &code.Packages{},
   200  		}
   201  
   202  		cfg.Schema = gqlparser.MustLoadSchema(&ast.Source{Name: "TestAutobinding.schema", Input: `
   203  			scalar Banned
   204  			type Message { id: ID }
   205  		`})
   206  
   207  		require.EqualError(t, cfg.autobind(), "unable to load ../chat - make sure you're using an import path to a package that exists")
   208  	})
   209  }