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