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