github.com/maeglindeveloper/gqlgen@v0.13.1-0.20210413081235-57808b12a0a0/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/99designs/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/99designs/gqlgen/example/chat", 177 "github.com/99designs/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/99designs/gqlgen/example/scalars/model.Banned", cfg.Models["Banned"].Model[0]) 190 require.Equal(t, "github.com/99designs/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 }