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 }