github.com/emreu/go-swagger@v0.22.1/generator/client_test.go (about) 1 // Copyright 2015 go-swagger maintainers 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package generator 16 17 import ( 18 "io/ioutil" 19 "log" 20 "os" 21 "path/filepath" 22 "strings" 23 "testing" 24 25 "github.com/stretchr/testify/assert" 26 ) 27 28 const ( 29 defaultAPIPackage = "operations" 30 defaultClientPackage = "client" 31 defaultModelPackage = "models" 32 defaultServerPackage = "restapi" 33 34 basicFixture = "../fixtures/petstores/petstore.json" 35 ) 36 37 func testClientGenOpts() (g GenOpts) { 38 g.Target = "." 39 g.APIPackage = defaultAPIPackage 40 g.ModelPackage = defaultModelPackage 41 g.ServerPackage = defaultServerPackage 42 g.ClientPackage = defaultClientPackage 43 g.Principal = "" 44 g.DefaultScheme = "http" 45 g.IncludeModel = true 46 g.IncludeValidator = true 47 g.IncludeHandler = true 48 g.IncludeParameters = true 49 g.IncludeResponses = true 50 g.IncludeSupport = true 51 g.TemplateDir = "" 52 g.DumpData = false 53 g.IsClient = true 54 _ = g.EnsureDefaults() 55 return 56 } 57 58 func Test_GenerateClient(t *testing.T) { 59 log.SetOutput(ioutil.Discard) 60 61 // exercise safeguards 62 err := GenerateClient("test", []string{"model1"}, []string{"op1", "op2"}, nil) 63 assert.Error(t, err) 64 65 opts := testClientGenOpts() 66 opts.TemplateDir = "dir/nowhere" 67 err = GenerateClient("test", []string{"model1"}, []string{"op1", "op2"}, &opts) 68 assert.Error(t, err) 69 70 opts = testClientGenOpts() 71 opts.TemplateDir = "http://nowhere.com" 72 err = GenerateClient("test", []string{"model1"}, []string{"op1", "op2"}, &opts) 73 assert.Error(t, err) 74 75 opts = testClientGenOpts() 76 opts.Spec = "dir/nowhere.yaml" 77 err = GenerateClient("test", []string{"model1"}, []string{"op1", "op2"}, &opts) 78 assert.Error(t, err) 79 80 opts = testClientGenOpts() 81 opts.Spec = basicFixture 82 err = GenerateClient("test", []string{"model1"}, []string{}, &opts) 83 assert.Error(t, err) 84 85 opts = testClientGenOpts() 86 // bad content in spec (HTML...) 87 opts.Spec = "https://github.com/OAI/OpenAPI-Specification/blob/master/examples/v2.0/json/petstore.json" 88 err = GenerateClient("test", []string{}, []string{}, &opts) 89 assert.Error(t, err) 90 91 opts = testClientGenOpts() 92 // generate remote spec 93 opts.Spec = "https://raw.githubusercontent.com/OAI/OpenAPI-Specification/master/examples/v2.0/yaml/petstore.yaml" 94 cwd, _ := os.Getwd() 95 tft, _ := ioutil.TempDir(cwd, "generated") 96 defer func() { 97 _ = os.RemoveAll(tft) 98 }() 99 opts.Target = tft 100 opts.IsClient = true 101 DefaultSectionOpts(&opts) 102 103 defer func() { 104 _ = os.RemoveAll(opts.Target) 105 }() 106 err = GenerateClient("test", []string{}, []string{}, &opts) 107 assert.NoError(t, err) 108 109 // just checks this does not fail 110 origStdout := os.Stdout 111 defer func() { 112 os.Stdout = origStdout 113 }() 114 tgt, _ := ioutil.TempDir(cwd, "dumped") 115 defer func() { 116 _ = os.RemoveAll(tgt) 117 }() 118 os.Stdout, _ = os.Create(filepath.Join(tgt, "stdout")) 119 opts.DumpData = true 120 err = GenerateClient("test", []string{}, []string{}, &opts) 121 assert.NoError(t, err) 122 _, err = os.Stat(filepath.Join(tgt, "stdout")) 123 assert.NoError(t, err) 124 } 125 126 func TestClient(t *testing.T) { 127 targetdir, err := ioutil.TempDir(os.TempDir(), "swagger_nogo") 128 if err != nil { 129 t.Fatalf("Failed to create a test target directory: %v", err) 130 } 131 log.SetOutput(ioutil.Discard) 132 defer func() { 133 _ = os.RemoveAll(targetdir) 134 log.SetOutput(os.Stdout) 135 }() 136 137 tests := []struct { 138 name string 139 template string 140 wantError bool 141 prepare func(opts *GenOpts) 142 }{ 143 { 144 name: "InvalidSpec", 145 wantError: true, 146 prepare: func(opts *GenOpts) { 147 opts.Spec = invalidSpecExample 148 opts.ValidateSpec = true 149 }, 150 }, 151 { 152 name: "BaseImportDisabled", 153 wantError: false, 154 }, 155 { 156 name: "Non_existing_contributor_template", 157 template: "NonExistingContributorTemplate", 158 wantError: true, 159 }, 160 { 161 name: "Existing_contributor", 162 template: "stratoscale", 163 wantError: false, 164 }, 165 } 166 167 for _, tt := range tests { 168 t.Run(tt.name, func(t *testing.T) { 169 opts := testClientGenOpts() 170 opts.Target = targetdir 171 opts.Spec = basicFixture 172 opts.LanguageOpts.BaseImportFunc = nil 173 opts.Template = tt.template 174 175 if tt.prepare != nil { 176 tt.prepare(&opts) 177 } 178 179 err := GenerateClient("foo", nil, nil, &opts) 180 if tt.wantError { 181 assert.Error(t, err) 182 } else { 183 assert.NoError(t, err) 184 } 185 }) 186 } 187 } 188 189 func TestGenClient_1518(t *testing.T) { 190 // test client response handling when unexpected success response kicks in 191 log.SetOutput(ioutil.Discard) 192 defer func() { 193 log.SetOutput(os.Stdout) 194 }() 195 196 opts := testClientGenOpts() 197 opts.Spec = filepath.Join("..", "fixtures", "bugs", "1518", "fixture-1518.yaml") 198 199 cwd, _ := os.Getwd() 200 tft, _ := ioutil.TempDir(cwd, "generated") 201 opts.Target = tft 202 203 defer func() { 204 _ = os.RemoveAll(opts.Target) 205 }() 206 err := GenerateClient("client", []string{}, []string{}, &opts) 207 if !assert.NoError(t, err) { 208 t.FailNow() 209 } 210 211 fixtureConfig := map[string][]string{ 212 "client/operations/operations_client.go": { // generated file 213 // expected code lines 214 `success, ok := result.(*GetRecords1OK)`, 215 `if ok {`, 216 `return success, nil`, 217 `msg := fmt.Sprintf(`, 218 `panic(msg)`, 219 // expected code lines 220 `success, ok := result.(*GetRecords2OK)`, 221 `if ok {`, 222 `return success, nil`, 223 `unexpectedSuccess := result.(*GetRecords2Default)`, 224 `return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code())`, 225 // expected code lines 226 `switch value := result.(type) {`, 227 `case *GetRecords3OK:`, 228 `return value, nil, nil`, 229 `case *GetRecords3Created:`, 230 `return nil, value, nil`, 231 `msg := fmt.Sprintf(`, 232 `panic(msg)`, 233 // expected code lines 234 `switch value := result.(type) {`, 235 `case *GetRecords4OK:`, 236 `return value, nil, nil`, 237 `case *GetRecords4Created:`, 238 `return nil, value, nil`, 239 `unexpectedSuccess := result.(*GetRecords4Default)`, 240 `return nil, nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code())`, 241 }, 242 } 243 244 for fileToInspect, expectedCode := range fixtureConfig { 245 code, err := ioutil.ReadFile(filepath.Join(opts.Target, filepath.FromSlash(fileToInspect))) 246 if assert.NoError(t, err) { 247 for line, codeLine := range expectedCode { 248 if !assertInCode(t, strings.TrimSpace(codeLine), string(code)) { 249 t.Logf("Code expected did not match in codegenfile %s for expected line %d: %q", fileToInspect, line, expectedCode[line]) 250 } 251 } 252 } 253 } 254 }