github.com/josephspurrier/go-swagger@v0.2.1-0.20221129144919-1f672a142a00/scan/schema_test.go (about) 1 //go:build !go1.11 2 // +build !go1.11 3 4 // Copyright 2015 go-swagger maintainers 5 // 6 // Licensed under the Apache License, Version 2.0 (the "License"); 7 // you may not use this file except in compliance with the License. 8 // You may obtain a copy of the License at 9 // 10 // http://www.apache.org/licenses/LICENSE-2.0 11 // 12 // Unless required by applicable law or agreed to in writing, software 13 // distributed under the License is distributed on an "AS IS" BASIS, 14 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 // See the License for the specific language governing permissions and 16 // limitations under the License. 17 18 package scan 19 20 import ( 21 "os" 22 "path/filepath" 23 "testing" 24 25 "github.com/go-openapi/spec" 26 "github.com/stretchr/testify/assert" 27 ) 28 29 func TestSchemaParser(t *testing.T) { 30 _ = classificationProg 31 schema := noModelDefs["NoModel"] 32 33 assert.Equal(t, spec.StringOrArray([]string{"object"}), schema.Type) 34 assert.Equal(t, "NoModel is a struct without an annotation.", schema.Title) 35 assert.Equal(t, "NoModel exists in a package\nbut is not annotated with the swagger model annotations\nso it should now show up in a test.", schema.Description) 36 assert.Len(t, schema.Required, 3) 37 assert.Len(t, schema.Properties, 11) 38 39 assertProperty(t, &schema, "integer", "id", "int64", "ID") 40 prop, ok := schema.Properties["id"] 41 assert.Equal(t, "ID of this no model instance.\nids in this application start at 11 and are smaller than 1000", prop.Description) 42 assert.True(t, ok, "should have had an 'id' property") 43 assert.EqualValues(t, 1000, *prop.Maximum) 44 assert.True(t, prop.ExclusiveMaximum, "'id' should have had an exclusive maximum") 45 assert.NotNil(t, prop.Minimum) 46 assert.EqualValues(t, 10, *prop.Minimum) 47 assert.True(t, prop.ExclusiveMinimum, "'id' should have had an exclusive minimum") 48 assert.Equal(t, 11, prop.Default, "ID default value is incorrect") 49 50 assertProperty(t, &schema, "string", "NoNameOmitEmpty", "", "") 51 prop, ok = schema.Properties["NoNameOmitEmpty"] 52 assert.Equal(t, "A field which has omitempty set but no name", prop.Description) 53 assert.True(t, ok, "should have had an 'NoNameOmitEmpty' property") 54 55 assertProperty(t, &schema, "integer", "score", "int32", "Score") 56 prop, ok = schema.Properties["score"] 57 assert.Equal(t, "The Score of this model", prop.Description) 58 assert.True(t, ok, "should have had a 'score' property") 59 assert.EqualValues(t, 45, *prop.Maximum) 60 assert.False(t, prop.ExclusiveMaximum, "'score' should not have had an exclusive maximum") 61 assert.NotNil(t, prop.Minimum) 62 assert.EqualValues(t, 3, *prop.Minimum) 63 assert.False(t, prop.ExclusiveMinimum, "'score' should not have had an exclusive minimum") 64 assert.Equal(t, 27, prop.Example) 65 66 expectedNameExtensions := spec.Extensions{ 67 "x-go-name": "Name", 68 "x-property-array": []interface{}{ 69 "value1", 70 "value2", 71 }, 72 "x-property-array-obj": []interface{}{ 73 map[string]interface{}{ 74 "name": "obj", 75 "value": "field", 76 }, 77 }, 78 "x-property-value": "value", 79 } 80 81 assertProperty(t, &schema, "string", "name", "", "Name") 82 prop, ok = schema.Properties["name"] 83 assert.True(t, ok) 84 assert.Equal(t, "Name of this no model instance", prop.Description) 85 assert.EqualValues(t, 4, *prop.MinLength) 86 assert.EqualValues(t, 50, *prop.MaxLength) 87 assert.Equal(t, "[A-Za-z0-9-.]*", prop.Pattern) 88 assert.EqualValues(t, expectedNameExtensions, prop.Extensions) 89 90 assertProperty(t, &schema, "string", "created", "date-time", "Created") 91 prop, ok = schema.Properties["created"] 92 assert.Equal(t, "Created holds the time when this entry was created", prop.Description) 93 assert.True(t, ok, "should have a 'created' property") 94 assert.True(t, prop.ReadOnly, "'created' should be read only") 95 96 assertProperty(t, &schema, "string", "gocreated", "date-time", "GoTimeCreated") 97 prop, ok = schema.Properties["gocreated"] 98 assert.Equal(t, "GoTimeCreated holds the time when this entry was created in go time.Time", prop.Description) 99 assert.True(t, ok, "should have a 'gocreated' property") 100 101 assertArrayProperty(t, &schema, "string", "foo_slice", "", "FooSlice") 102 prop, ok = schema.Properties["foo_slice"] 103 assert.Equal(t, "a FooSlice has foos which are strings", prop.Description) 104 assert.True(t, ok, "should have a 'foo_slice' property") 105 assert.NotNil(t, prop.Items, "foo_slice should have had an items property") 106 assert.NotNil(t, prop.Items.Schema, "foo_slice.items should have had a schema property") 107 assert.True(t, prop.UniqueItems, "'foo_slice' should have unique items") 108 assert.EqualValues(t, 3, *prop.MinItems, "'foo_slice' should have had 3 min items") 109 assert.EqualValues(t, 10, *prop.MaxItems, "'foo_slice' should have had 10 max items") 110 itprop := prop.Items.Schema 111 assert.EqualValues(t, 3, *itprop.MinLength, "'foo_slice.items.minLength' should have been 3") 112 assert.EqualValues(t, 10, *itprop.MaxLength, "'foo_slice.items.maxLength' should have been 10") 113 assert.EqualValues(t, "\\w+", itprop.Pattern, "'foo_slice.items.pattern' should have \\w+") 114 115 assertArrayProperty(t, &schema, "string", "time_slice", "date-time", "TimeSlice") 116 prop, ok = schema.Properties["time_slice"] 117 assert.Equal(t, "a TimeSlice is a slice of times", prop.Description) 118 assert.True(t, ok, "should have a 'time_slice' property") 119 assert.NotNil(t, prop.Items, "time_slice should have had an items property") 120 assert.NotNil(t, prop.Items.Schema, "time_slice.items should have had a schema property") 121 assert.True(t, prop.UniqueItems, "'time_slice' should have unique items") 122 assert.EqualValues(t, 3, *prop.MinItems, "'time_slice' should have had 3 min items") 123 assert.EqualValues(t, 10, *prop.MaxItems, "'time_slice' should have had 10 max items") 124 125 assertArrayProperty(t, &schema, "array", "bar_slice", "", "BarSlice") 126 prop, ok = schema.Properties["bar_slice"] 127 assert.Equal(t, "a BarSlice has bars which are strings", prop.Description) 128 assert.True(t, ok, "should have a 'bar_slice' property") 129 assert.NotNil(t, prop.Items, "bar_slice should have had an items property") 130 assert.NotNil(t, prop.Items.Schema, "bar_slice.items should have had a schema property") 131 assert.True(t, prop.UniqueItems, "'bar_slice' should have unique items") 132 assert.EqualValues(t, 3, *prop.MinItems, "'bar_slice' should have had 3 min items") 133 assert.EqualValues(t, 10, *prop.MaxItems, "'bar_slice' should have had 10 max items") 134 itprop = prop.Items.Schema 135 if assert.NotNil(t, itprop) { 136 assert.EqualValues(t, 4, *itprop.MinItems, "'bar_slice.items.minItems' should have been 4") 137 assert.EqualValues(t, 9, *itprop.MaxItems, "'bar_slice.items.maxItems' should have been 9") 138 itprop2 := itprop.Items.Schema 139 if assert.NotNil(t, itprop2) { 140 assert.EqualValues(t, 5, *itprop2.MinItems, "'bar_slice.items.items.minItems' should have been 5") 141 assert.EqualValues(t, 8, *itprop2.MaxItems, "'bar_slice.items.items.maxItems' should have been 8") 142 itprop3 := itprop2.Items.Schema 143 if assert.NotNil(t, itprop3) { 144 assert.EqualValues(t, 3, *itprop3.MinLength, "'bar_slice.items.items.items.minLength' should have been 3") 145 assert.EqualValues(t, 10, *itprop3.MaxLength, "'bar_slice.items.items.items.maxLength' should have been 10") 146 assert.EqualValues(t, "\\w+", itprop3.Pattern, "'bar_slice.items.items.items.pattern' should have \\w+") 147 } 148 } 149 } 150 151 assertArrayProperty(t, &schema, "array", "deep_time_slice", "", "DeepTimeSlice") 152 prop, ok = schema.Properties["deep_time_slice"] 153 assert.Equal(t, "a DeepSlice has bars which are time", prop.Description) 154 assert.True(t, ok, "should have a 'deep_time_slice' property") 155 assert.NotNil(t, prop.Items, "deep_time_slice should have had an items property") 156 assert.NotNil(t, prop.Items.Schema, "deep_time_slice.items should have had a schema property") 157 assert.True(t, prop.UniqueItems, "'deep_time_slice' should have unique items") 158 assert.EqualValues(t, 3, *prop.MinItems, "'deep_time_slice' should have had 3 min items") 159 assert.EqualValues(t, 10, *prop.MaxItems, "'deep_time_slice' should have had 10 max items") 160 itprop = prop.Items.Schema 161 if assert.NotNil(t, itprop) { 162 assert.EqualValues(t, 4, *itprop.MinItems, "'deep_time_slice.items.minItems' should have been 4") 163 assert.EqualValues(t, 9, *itprop.MaxItems, "'deep_time_slice.items.maxItems' should have been 9") 164 itprop2 := itprop.Items.Schema 165 if assert.NotNil(t, itprop2) { 166 assert.EqualValues(t, 5, *itprop2.MinItems, "'deep_time_slice.items.items.minItems' should have been 5") 167 assert.EqualValues(t, 8, *itprop2.MaxItems, "'deep_time_slice.items.items.maxItems' should have been 8") 168 itprop3 := itprop2.Items.Schema 169 assert.NotNil(t, itprop3) 170 } 171 } 172 173 assertArrayProperty(t, &schema, "object", "items", "", "Items") 174 prop, ok = schema.Properties["items"] 175 assert.True(t, ok, "should have an 'items' slice") 176 assert.NotNil(t, prop.Items, "items should have had an items property") 177 assert.NotNil(t, prop.Items.Schema, "items.items should have had a schema property") 178 itprop = prop.Items.Schema 179 assert.Len(t, itprop.Properties, 5) 180 assert.Len(t, itprop.Required, 4) 181 assertProperty(t, itprop, "integer", "id", "int32", "ID") 182 iprop, ok := itprop.Properties["id"] 183 assert.True(t, ok) 184 assert.Equal(t, "ID of this no model instance.\nids in this application start at 11 and are smaller than 1000", iprop.Description) 185 assert.EqualValues(t, 1000, *iprop.Maximum) 186 assert.True(t, iprop.ExclusiveMaximum, "'id' should have had an exclusive maximum") 187 assert.NotNil(t, iprop.Minimum) 188 assert.EqualValues(t, 10, *iprop.Minimum) 189 assert.True(t, iprop.ExclusiveMinimum, "'id' should have had an exclusive minimum") 190 assert.Equal(t, 11, iprop.Default, "ID default value is incorrect") 191 192 assertRef(t, itprop, "pet", "Pet", "#/definitions/pet") 193 iprop, ok = itprop.Properties["pet"] 194 assert.True(t, ok) 195 if itprop.Ref.String() != "" { 196 assert.Equal(t, "The Pet to add to this NoModel items bucket.\nPets can appear more than once in the bucket", iprop.Description) 197 } 198 199 assertProperty(t, itprop, "integer", "quantity", "int16", "Quantity") 200 iprop, ok = itprop.Properties["quantity"] 201 assert.True(t, ok) 202 assert.Equal(t, "The amount of pets to add to this bucket.", iprop.Description) 203 assert.EqualValues(t, 1, *iprop.Minimum) 204 assert.EqualValues(t, 10, *iprop.Maximum) 205 206 assertProperty(t, itprop, "string", "expiration", "date-time", "Expiration") 207 iprop, ok = itprop.Properties["expiration"] 208 assert.True(t, ok) 209 assert.Equal(t, "A dummy expiration date.", iprop.Description) 210 211 assertProperty(t, itprop, "string", "notes", "", "Notes") 212 iprop, ok = itprop.Properties["notes"] 213 assert.True(t, ok) 214 assert.Equal(t, "Notes to add to this item.\nThis can be used to add special instructions.", iprop.Description) 215 216 definitions := make(map[string]spec.Schema) 217 sp := newSchemaParser(classificationProg) 218 pn := "github.com/go-swagger/go-swagger/fixtures/goparsing/classification/models" 219 // pnr := "../fixtures/goparsing/classification/models" 220 pkg := classificationProg.Package(pn) 221 if assert.NotNil(t, pkg) { 222 223 fnd := false 224 for _, fil := range pkg.Files { 225 nm := filepath.Base(classificationProg.Fset.File(fil.Pos()).Name()) 226 if nm == "order.go" { 227 fnd = true 228 err := sp.Parse(fil, definitions) 229 assert.NoError(t, err) 230 break 231 } 232 } 233 assert.True(t, fnd) 234 msch, ok := definitions["order"] 235 assert.True(t, ok) 236 assert.Equal(t, pn, msch.Extensions["x-go-package"]) 237 assert.Equal(t, "StoreOrder", msch.Extensions["x-go-name"]) 238 } 239 } 240 241 func TestEmbeddedTypes(t *testing.T) { 242 schema := noModelDefs["ComplexerOne"] 243 assertProperty(t, &schema, "integer", "age", "int32", "Age") 244 assertProperty(t, &schema, "integer", "id", "int64", "ID") 245 assertProperty(t, &schema, "string", "createdAt", "date-time", "CreatedAt") 246 assertProperty(t, &schema, "string", "extra", "", "Extra") 247 assertProperty(t, &schema, "string", "name", "", "Name") 248 assertProperty(t, &schema, "string", "notes", "", "Notes") 249 } 250 251 func TestArrayOfPointers(t *testing.T) { 252 schema := noModelDefs["cars"] 253 assertProperty(t, &schema, "array", "cars", "", "Cars") 254 } 255 256 func TestEmbeddedAllOf(t *testing.T) { 257 schema := noModelDefs["AllOfModel"] 258 259 assert.Len(t, schema.AllOf, 3) 260 asch := schema.AllOf[0] 261 assertProperty(t, &asch, "integer", "age", "int32", "Age") 262 assertProperty(t, &asch, "integer", "id", "int64", "ID") 263 assertProperty(t, &asch, "string", "name", "", "Name") 264 265 asch = schema.AllOf[1] 266 assert.Equal(t, "#/definitions/withNotes", asch.Ref.String()) 267 268 asch = schema.AllOf[2] 269 assertProperty(t, &asch, "string", "createdAt", "date-time", "CreatedAt") 270 assertProperty(t, &asch, "integer", "did", "int64", "DID") 271 assertProperty(t, &asch, "string", "cat", "", "Cat") 272 } 273 274 func TestEmbeddedStarExpr(t *testing.T) { 275 schema := noModelDefs["EmbeddedStarExpr"] 276 277 assertProperty(t, &schema, "integer", "embeddedMember", "int64", "EmbeddedMember") 278 assertProperty(t, &schema, "integer", "notEmbedded", "int64", "NotEmbedded") 279 } 280 281 func TestOverridingOneIgnore(t *testing.T) { 282 schema := noModelDefs["OverridingOneIgnore"] 283 284 assertProperty(t, &schema, "integer", "id", "int64", "ID") 285 assertProperty(t, &schema, "string", "name", "", "Name") 286 assert.Len(t, schema.Properties, 2) 287 } 288 289 func TestAliasedTypes(t *testing.T) { 290 schema := noModelDefs["OtherTypes"] 291 assertRef(t, &schema, "named", "Named", "#/definitions/SomeStringType") 292 assertRef(t, &schema, "numbered", "Numbered", "#/definitions/SomeIntType") 293 assertProperty(t, &schema, "string", "dated", "date-time", "Dated") 294 assertRef(t, &schema, "timed", "Timed", "#/definitions/SomeTimedType") 295 assertRef(t, &schema, "petted", "Petted", "#/definitions/SomePettedType") 296 assertRef(t, &schema, "somethinged", "Somethinged", "#/definitions/SomethingType") 297 assertRef(t, &schema, "strMap", "StrMap", "#/definitions/SomeStringMap") 298 assertRef(t, &schema, "strArrMap", "StrArrMap", "#/definitions/SomeArrayStringMap") 299 300 assertRef(t, &schema, "manyNamed", "ManyNamed", "#/definitions/SomeStringsType") 301 assertRef(t, &schema, "manyNumbered", "ManyNumbered", "#/definitions/SomeIntsType") 302 assertArrayProperty(t, &schema, "string", "manyDated", "date-time", "ManyDated") 303 assertRef(t, &schema, "manyTimed", "ManyTimed", "#/definitions/SomeTimedsType") 304 assertRef(t, &schema, "manyPetted", "ManyPetted", "#/definitions/SomePettedsType") 305 assertRef(t, &schema, "manySomethinged", "ManySomethinged", "#/definitions/SomethingsType") 306 307 assertArrayRef(t, &schema, "nameds", "Nameds", "#/definitions/SomeStringType") 308 assertArrayRef(t, &schema, "numbereds", "Numbereds", "#/definitions/SomeIntType") 309 assertArrayProperty(t, &schema, "string", "dateds", "date-time", "Dateds") 310 assertArrayRef(t, &schema, "timeds", "Timeds", "#/definitions/SomeTimedType") 311 assertArrayRef(t, &schema, "petteds", "Petteds", "#/definitions/SomePettedType") 312 assertArrayRef(t, &schema, "somethingeds", "Somethingeds", "#/definitions/SomethingType") 313 314 assertRef(t, &schema, "modsNamed", "ModsNamed", "#/definitions/modsSomeStringType") 315 assertRef(t, &schema, "modsNumbered", "ModsNumbered", "#/definitions/modsSomeIntType") 316 assertProperty(t, &schema, "string", "modsDated", "date-time", "ModsDated") 317 assertRef(t, &schema, "modsTimed", "ModsTimed", "#/definitions/modsSomeTimedType") 318 assertRef(t, &schema, "modsPetted", "ModsPetted", "#/definitions/modsSomePettedType") 319 320 assertArrayRef(t, &schema, "modsNameds", "ModsNameds", "#/definitions/modsSomeStringType") 321 assertArrayRef(t, &schema, "modsNumbereds", "ModsNumbereds", "#/definitions/modsSomeIntType") 322 assertArrayProperty(t, &schema, "string", "modsDateds", "date-time", "ModsDateds") 323 assertArrayRef(t, &schema, "modsTimeds", "ModsTimeds", "#/definitions/modsSomeTimedType") 324 assertArrayRef(t, &schema, "modsPetteds", "ModsPetteds", "#/definitions/modsSomePettedType") 325 326 assertRef(t, &schema, "manyModsNamed", "ManyModsNamed", "#/definitions/modsSomeStringsType") 327 assertRef(t, &schema, "manyModsNumbered", "ManyModsNumbered", "#/definitions/modsSomeIntsType") 328 assertArrayProperty(t, &schema, "string", "manyModsDated", "date-time", "ManyModsDated") 329 assertRef(t, &schema, "manyModsTimed", "ManyModsTimed", "#/definitions/modsSomeTimedsType") 330 assertRef(t, &schema, "manyModsPetted", "ManyModsPetted", "#/definitions/modsSomePettedsType") 331 assertRef(t, &schema, "manyModsPettedPtr", "ManyModsPettedPtr", "#/definitions/modsSomePettedsPtrType") 332 333 assertProperty(t, &schema, "string", "namedAlias", "", "NamedAlias") 334 assertProperty(t, &schema, "integer", "numberedAlias", "int64", "NumberedAlias") 335 assertArrayProperty(t, &schema, "string", "namedsAlias", "", "NamedsAlias") 336 assertArrayProperty(t, &schema, "integer", "numberedsAlias", "int64", "NumberedsAlias") 337 } 338 339 func TestParsePrimitiveSchemaProperty(t *testing.T) { 340 schema := noModelDefs["PrimateModel"] 341 assertProperty(t, &schema, "boolean", "a", "", "A") 342 assertProperty(t, &schema, "integer", "b", "int32", "B") 343 assertProperty(t, &schema, "string", "c", "", "C") 344 assertProperty(t, &schema, "integer", "d", "int64", "D") 345 assertProperty(t, &schema, "integer", "e", "int8", "E") 346 assertProperty(t, &schema, "integer", "f", "int16", "F") 347 assertProperty(t, &schema, "integer", "g", "int32", "G") 348 assertProperty(t, &schema, "integer", "h", "int64", "H") 349 assertProperty(t, &schema, "integer", "i", "uint64", "I") 350 assertProperty(t, &schema, "integer", "j", "uint8", "J") 351 assertProperty(t, &schema, "integer", "k", "uint16", "K") 352 assertProperty(t, &schema, "integer", "l", "uint32", "L") 353 assertProperty(t, &schema, "integer", "m", "uint64", "M") 354 assertProperty(t, &schema, "number", "n", "float", "N") 355 assertProperty(t, &schema, "number", "o", "double", "O") 356 assertProperty(t, &schema, "integer", "p", "uint8", "P") 357 assertProperty(t, &schema, "integer", "q", "uint64", "Q") 358 } 359 360 func TestParseStringFormatSchemaProperty(t *testing.T) { 361 schema := noModelDefs["FormattedModel"] 362 assertProperty(t, &schema, "string", "a", "byte", "A") 363 assertProperty(t, &schema, "string", "b", "creditcard", "B") 364 assertProperty(t, &schema, "string", "c", "date", "C") 365 assertProperty(t, &schema, "string", "d", "date-time", "D") 366 assertProperty(t, &schema, "string", "e", "duration", "E") 367 assertProperty(t, &schema, "string", "f", "email", "F") 368 assertProperty(t, &schema, "string", "g", "hexcolor", "G") 369 assertProperty(t, &schema, "string", "h", "hostname", "H") 370 assertProperty(t, &schema, "string", "i", "ipv4", "I") 371 assertProperty(t, &schema, "string", "j", "ipv6", "J") 372 assertProperty(t, &schema, "string", "k", "isbn", "K") 373 assertProperty(t, &schema, "string", "l", "isbn10", "L") 374 assertProperty(t, &schema, "string", "m", "isbn13", "M") 375 assertProperty(t, &schema, "string", "n", "rgbcolor", "N") 376 assertProperty(t, &schema, "string", "o", "ssn", "O") 377 assertProperty(t, &schema, "string", "p", "uri", "P") 378 assertProperty(t, &schema, "string", "q", "uuid", "Q") 379 assertProperty(t, &schema, "string", "r", "uuid3", "R") 380 assertProperty(t, &schema, "string", "s", "uuid4", "S") 381 assertProperty(t, &schema, "string", "t", "uuid5", "T") 382 assertProperty(t, &schema, "string", "u", "mac", "U") 383 } 384 385 func assertProperty(t testing.TB, schema *spec.Schema, typeName, jsonName, format, goName string) { 386 if typeName == "" { 387 assert.Empty(t, schema.Properties[jsonName].Type) 388 } else { 389 if assert.NotEmpty(t, schema.Properties[jsonName].Type) { 390 assert.Equal(t, typeName, schema.Properties[jsonName].Type[0]) 391 } 392 } 393 if goName == "" { 394 assert.Equal(t, nil, schema.Properties[jsonName].Extensions["x-go-name"]) 395 } else { 396 assert.Equal(t, goName, schema.Properties[jsonName].Extensions["x-go-name"]) 397 } 398 assert.Equal(t, format, schema.Properties[jsonName].Format) 399 } 400 401 func assertRef(t testing.TB, schema *spec.Schema, jsonName, goName, fragment string) { 402 assert.Empty(t, schema.Properties[jsonName].Type) 403 psch := schema.Properties[jsonName] 404 assert.Equal(t, fragment, psch.Ref.String()) 405 } 406 407 func TestParseStructFields(t *testing.T) { 408 schema := noModelDefs["SimpleComplexModel"] 409 assertProperty(t, &schema, "object", "emb", "", "Emb") 410 eSchema := schema.Properties["emb"] 411 assertProperty(t, &eSchema, "integer", "cid", "int64", "CID") 412 assertProperty(t, &eSchema, "string", "baz", "", "Baz") 413 414 assertRef(t, &schema, "top", "Top", "#/definitions/Something") 415 assertRef(t, &schema, "notSel", "NotSel", "#/definitions/NotSelected") 416 } 417 418 func TestParsePointerFields(t *testing.T) { 419 schema := noModelDefs["Pointdexter"] 420 421 assertProperty(t, &schema, "integer", "id", "int64", "ID") 422 assertProperty(t, &schema, "string", "name", "", "Name") 423 assertProperty(t, &schema, "object", "emb", "", "Emb") 424 assertProperty(t, &schema, "string", "t", "uuid5", "T") 425 eSchema := schema.Properties["emb"] 426 assertProperty(t, &eSchema, "integer", "cid", "int64", "CID") 427 assertProperty(t, &eSchema, "string", "baz", "", "Baz") 428 429 assertRef(t, &schema, "top", "Top", "#/definitions/Something") 430 assertRef(t, &schema, "notSel", "NotSel", "#/definitions/NotSelected") 431 } 432 433 func assertArrayProperty(t testing.TB, schema *spec.Schema, typeName, jsonName, format, goName string) { 434 prop := schema.Properties[jsonName] 435 assert.NotEmpty(t, prop.Type) 436 assert.True(t, prop.Type.Contains("array")) 437 assert.NotNil(t, prop.Items) 438 if typeName != "" { 439 assert.Equal(t, typeName, prop.Items.Schema.Type[0]) 440 } 441 assert.Equal(t, goName, prop.Extensions["x-go-name"]) 442 assert.Equal(t, format, prop.Items.Schema.Format) 443 } 444 445 func assertArrayRef(t testing.TB, schema *spec.Schema, jsonName, goName, fragment string) { 446 assertArrayProperty(t, schema, "", jsonName, "", goName) 447 psch := schema.Properties[jsonName].Items.Schema 448 assert.Equal(t, fragment, psch.Ref.String()) 449 } 450 451 func TestParseSliceFields(t *testing.T) { 452 schema := noModelDefs["SliceAndDice"] 453 454 assertArrayProperty(t, &schema, "integer", "ids", "int64", "IDs") 455 assertArrayProperty(t, &schema, "string", "names", "", "Names") 456 assertArrayProperty(t, &schema, "string", "uuids", "uuid", "UUIDs") 457 assertArrayProperty(t, &schema, "object", "embs", "", "Embs") 458 eSchema := schema.Properties["embs"].Items.Schema 459 assertArrayProperty(t, eSchema, "integer", "cid", "int64", "CID") 460 assertArrayProperty(t, eSchema, "string", "baz", "", "Baz") 461 462 assertArrayRef(t, &schema, "tops", "Tops", "#/definitions/Something") 463 assertArrayRef(t, &schema, "notSels", "NotSels", "#/definitions/NotSelected") 464 465 assertArrayProperty(t, &schema, "integer", "ptrIds", "int64", "PtrIDs") 466 assertArrayProperty(t, &schema, "string", "ptrNames", "", "PtrNames") 467 assertArrayProperty(t, &schema, "string", "ptrUuids", "uuid", "PtrUUIDs") 468 assertArrayProperty(t, &schema, "object", "ptrEmbs", "", "PtrEmbs") 469 eSchema = schema.Properties["ptrEmbs"].Items.Schema 470 assertArrayProperty(t, eSchema, "integer", "ptrCid", "int64", "PtrCID") 471 assertArrayProperty(t, eSchema, "string", "ptrBaz", "", "PtrBaz") 472 473 assertArrayRef(t, &schema, "ptrTops", "PtrTops", "#/definitions/Something") 474 assertArrayRef(t, &schema, "ptrNotSels", "PtrNotSels", "#/definitions/NotSelected") 475 } 476 477 func assertMapProperty(t testing.TB, schema *spec.Schema, typeName, jsonName, format, goName string) { 478 prop := schema.Properties[jsonName] 479 assert.NotEmpty(t, prop.Type) 480 assert.True(t, prop.Type.Contains("object")) 481 assert.NotNil(t, prop.AdditionalProperties) 482 if typeName != "" { 483 assert.Equal(t, typeName, prop.AdditionalProperties.Schema.Type[0]) 484 } 485 assert.Equal(t, goName, prop.Extensions["x-go-name"]) 486 assert.Equal(t, format, prop.AdditionalProperties.Schema.Format) 487 } 488 489 func assertMapRef(t testing.TB, schema *spec.Schema, jsonName, goName, fragment string) { 490 assertMapProperty(t, schema, "", jsonName, "", goName) 491 psch := schema.Properties[jsonName].AdditionalProperties.Schema 492 assert.Equal(t, fragment, psch.Ref.String()) 493 } 494 495 func TestParseMapFields(t *testing.T) { 496 schema := noModelDefs["MapTastic"] 497 498 assertMapProperty(t, &schema, "integer", "ids", "int64", "IDs") 499 assertMapProperty(t, &schema, "string", "names", "", "Names") 500 assertMapProperty(t, &schema, "string", "uuids", "uuid", "UUIDs") 501 assertMapProperty(t, &schema, "object", "embs", "", "Embs") 502 eSchema := schema.Properties["embs"].AdditionalProperties.Schema 503 assertMapProperty(t, eSchema, "integer", "cid", "int64", "CID") 504 assertMapProperty(t, eSchema, "string", "baz", "", "Baz") 505 506 assertMapRef(t, &schema, "tops", "Tops", "#/definitions/Something") 507 assertMapRef(t, &schema, "notSels", "NotSels", "#/definitions/NotSelected") 508 509 assertMapProperty(t, &schema, "integer", "ptrIds", "int64", "PtrIDs") 510 assertMapProperty(t, &schema, "string", "ptrNames", "", "PtrNames") 511 assertMapProperty(t, &schema, "string", "ptrUuids", "uuid", "PtrUUIDs") 512 assertMapProperty(t, &schema, "object", "ptrEmbs", "", "PtrEmbs") 513 eSchema = schema.Properties["ptrEmbs"].AdditionalProperties.Schema 514 assertMapProperty(t, eSchema, "integer", "ptrCid", "int64", "PtrCID") 515 assertMapProperty(t, eSchema, "string", "ptrBaz", "", "PtrBaz") 516 517 assertMapRef(t, &schema, "ptrTops", "PtrTops", "#/definitions/Something") 518 assertMapRef(t, &schema, "ptrNotSels", "PtrNotSels", "#/definitions/NotSelected") 519 } 520 521 func TestInterfaceField(t *testing.T) { 522 523 _ = classificationProg 524 schema := noModelDefs["Interfaced"] 525 assertProperty(t, &schema, "object", "custom_data", "", "CustomData") 526 } 527 528 func TestStructDiscriminators(t *testing.T) { 529 _ = classificationProg 530 schema := noModelDefs["animal"] 531 532 assert.Equal(t, "BaseStruct", schema.Extensions["x-go-name"]) 533 assert.Equal(t, schema.Discriminator, "jsonClass") 534 535 sch := noModelDefs["gazelle"] 536 assert.Len(t, sch.AllOf, 2) 537 cl, _ := sch.Extensions.GetString("x-class") 538 assert.Equal(t, "a.b.c.d.E", cl) 539 cl, _ = sch.Extensions.GetString("x-go-name") 540 assert.Equal(t, "Gazelle", cl) 541 542 sch = noModelDefs["giraffe"] 543 assert.Len(t, sch.AllOf, 2) 544 cl, _ = sch.Extensions.GetString("x-class") 545 assert.Equal(t, "", cl) 546 cl, _ = sch.Extensions.GetString("x-go-name") 547 assert.Equal(t, "Giraffe", cl) 548 549 //sch = noModelDefs["lion"] 550 551 //b, _ := json.MarshalIndent(sch, "", " ") 552 //fmt.Println(string(b)) 553 554 } 555 556 func TestInterfaceDiscriminators(t *testing.T) { 557 _ = classificationProg 558 schema, ok := noModelDefs["fish"] 559 if assert.True(t, ok) && assert.Len(t, schema.AllOf, 5) { 560 sch := schema.AllOf[0] 561 assert.Len(t, sch.Properties, 1) 562 assertProperty(t, &sch, "integer", "id", "int64", "ID") 563 564 sch = schema.AllOf[1] 565 assert.Equal(t, "#/definitions/water", sch.Ref.String()) 566 sch = schema.AllOf[2] 567 assert.Equal(t, "#/definitions/extra", sch.Ref.String()) 568 569 sch = schema.AllOf[3] 570 assert.Len(t, sch.Properties, 1) 571 assertProperty(t, &sch, "string", "colorName", "", "ColorName") 572 573 sch = schema.AllOf[4] 574 assert.Len(t, sch.Properties, 2) 575 assertProperty(t, &sch, "string", "name", "", "Name") 576 assertProperty(t, &sch, "string", "jsonClass", "", "StructType") 577 assert.Equal(t, "jsonClass", sch.Discriminator) 578 } 579 580 schema, ok = noModelDefs["modelS"] 581 if assert.True(t, ok) { 582 assert.Len(t, schema.AllOf, 2) 583 cl, _ := schema.Extensions.GetString("x-class") 584 assert.Equal(t, "com.tesla.models.ModelS", cl) 585 cl, _ = schema.Extensions.GetString("x-go-name") 586 assert.Equal(t, "ModelS", cl) 587 588 sch := schema.AllOf[0] 589 assert.Equal(t, "#/definitions/TeslaCar", sch.Ref.String()) 590 sch = schema.AllOf[1] 591 assert.Len(t, sch.Properties, 1) 592 assertProperty(t, &sch, "string", "edition", "", "Edition") 593 } 594 595 schema, ok = noModelDefs["modelA"] 596 if assert.True(t, ok) { 597 598 cl, _ := schema.Extensions.GetString("x-go-name") 599 assert.Equal(t, "ModelA", cl) 600 601 sch, ok := schema.Properties["Tesla"] 602 if assert.True(t, ok) { 603 assert.Equal(t, "#/definitions/TeslaCar", sch.Ref.String()) 604 } 605 606 assertProperty(t, &schema, "integer", "doors", "int64", "Doors") 607 } 608 } 609 610 func TestStringStructTag(t *testing.T) { 611 _ = classificationProg 612 sch := noModelDefs["jsonString"] 613 assertProperty(t, &sch, "string", "someInt", "int64", "SomeInt") 614 assertProperty(t, &sch, "string", "someInt8", "int8", "SomeInt8") 615 assertProperty(t, &sch, "string", "someInt16", "int16", "SomeInt16") 616 assertProperty(t, &sch, "string", "someInt32", "int32", "SomeInt32") 617 assertProperty(t, &sch, "string", "someInt64", "int64", "SomeInt64") 618 assertProperty(t, &sch, "string", "someUint", "uint64", "SomeUint") 619 assertProperty(t, &sch, "string", "someUint8", "uint8", "SomeUint8") 620 assertProperty(t, &sch, "string", "someUint16", "uint16", "SomeUint16") 621 assertProperty(t, &sch, "string", "someUint32", "uint32", "SomeUint32") 622 assertProperty(t, &sch, "string", "someUint64", "uint64", "SomeUint64") 623 assertProperty(t, &sch, "string", "someFloat64", "double", "SomeFloat64") 624 assertProperty(t, &sch, "string", "someString", "", "SomeString") 625 assertProperty(t, &sch, "string", "someBool", "", "SomeBool") 626 627 prop, ok := sch.Properties["somethingElse"] 628 if assert.True(t, ok) { 629 assert.NotEqual(t, "string", prop.Type) 630 } 631 } 632 633 func TestPtrFieldStringStructTag(t *testing.T) { 634 _ = classificationProg 635 sch := noModelDefs["jsonPtrString"] 636 assertProperty(t, &sch, "string", "someInt", "int64", "SomeInt") 637 assertProperty(t, &sch, "string", "someInt8", "int8", "SomeInt8") 638 assertProperty(t, &sch, "string", "someInt16", "int16", "SomeInt16") 639 assertProperty(t, &sch, "string", "someInt32", "int32", "SomeInt32") 640 assertProperty(t, &sch, "string", "someInt64", "int64", "SomeInt64") 641 assertProperty(t, &sch, "string", "someUint", "uint64", "SomeUint") 642 assertProperty(t, &sch, "string", "someUint8", "uint8", "SomeUint8") 643 assertProperty(t, &sch, "string", "someUint16", "uint16", "SomeUint16") 644 assertProperty(t, &sch, "string", "someUint32", "uint32", "SomeUint32") 645 assertProperty(t, &sch, "string", "someUint64", "uint64", "SomeUint64") 646 assertProperty(t, &sch, "string", "someFloat64", "double", "SomeFloat64") 647 assertProperty(t, &sch, "string", "someString", "", "SomeString") 648 assertProperty(t, &sch, "string", "someBool", "", "SomeBool") 649 650 prop, ok := sch.Properties["somethingElse"] 651 if assert.True(t, ok) { 652 assert.NotEqual(t, "string", prop.Type) 653 } 654 } 655 656 func TestIgnoredStructField(t *testing.T) { 657 _ = classificationProg 658 sch := noModelDefs["ignoredFields"] 659 assertProperty(t, &sch, "string", "someIncludedField", "", "SomeIncludedField") 660 assertProperty(t, &sch, "string", "someErroneouslyIncludedField", "", "SomeErroneouslyIncludedField") 661 assert.Len(t, sch.Properties, 2) 662 } 663 664 func TestAliasedModels(t *testing.T) { 665 _, defs := extraModelsClassifier(t) 666 667 names := []string{ 668 "SomeStringType", 669 "SomeIntType", 670 "SomeTimeType", 671 "SomeTimedType", 672 "SomePettedType", 673 "SomethingType", 674 "SomeStringsType", 675 "SomeIntsType", 676 "SomeTimesType", 677 "SomeTimedsType", 678 "SomePettedsType", 679 "SomethingsType", 680 "SomeObject", 681 } 682 for k := range defs { 683 for i, b := range names { 684 if b == k { 685 names = append(names[:i], names[i+1:]...) 686 } 687 } 688 } 689 if assert.Empty(t, names) { 690 // single value types 691 assertDefinition(t, defs, "SomeStringType", "string", "", "") 692 assertDefinition(t, defs, "SomeIntType", "integer", "int64", "") 693 assertDefinition(t, defs, "SomeTimeType", "string", "date-time", "") 694 assertDefinition(t, defs, "SomeTimedType", "string", "date-time", "") 695 assertRefDefinition(t, defs, "SomePettedType", "#/definitions/pet", "") 696 assertRefDefinition(t, defs, "SomethingType", "#/definitions/Something", "") 697 698 // slice types 699 assertArrayDefinition(t, defs, "SomeStringsType", "string", "", "") 700 assertArrayDefinition(t, defs, "SomeIntsType", "integer", "int64", "") 701 assertArrayDefinition(t, defs, "SomeTimesType", "string", "date-time", "") 702 assertArrayDefinition(t, defs, "SomeTimedsType", "string", "date-time", "") 703 assertArrayWithRefDefinition(t, defs, "SomePettedsType", "#/definitions/pet", "") 704 assertArrayWithRefDefinition(t, defs, "SomethingsType", "#/definitions/Something", "") 705 706 // map types 707 assertMapDefinition(t, defs, "SomeObject", "object", "", "") 708 assertMapDefinition(t, defs, "SomeStringMap", "string", "", "") 709 assertMapDefinition(t, defs, "SomeIntMap", "integer", "int64", "") 710 assertMapDefinition(t, defs, "SomeTimeMap", "string", "date-time", "") 711 assertMapDefinition(t, defs, "SomeTimedMap", "string", "date-time", "") 712 assertMapWithRefDefinition(t, defs, "SomePettedMap", "#/definitions/pet", "") 713 assertMapWithRefDefinition(t, defs, "SomeSomethingMap", "#/definitions/Something", "") 714 } 715 } 716 717 func assertDefinition(t testing.TB, defs map[string]spec.Schema, defName, typeName, formatName, goName string) { 718 schema, ok := defs[defName] 719 if assert.True(t, ok) { 720 721 if assert.NotEmpty(t, schema.Type) { 722 assert.Equal(t, typeName, schema.Type[0]) 723 if goName != "" { 724 assert.Equal(t, goName, schema.Extensions["x-go-name"]) 725 } else { 726 assert.Nil(t, schema.Extensions["x-go-name"]) 727 } 728 assert.Equal(t, formatName, schema.Format) 729 } 730 } 731 } 732 733 func assertMapDefinition(t testing.TB, defs map[string]spec.Schema, defName, typeName, formatName, goName string) { 734 schema, ok := defs[defName] 735 if assert.True(t, ok) { 736 if assert.NotEmpty(t, schema.Type) { 737 assert.Equal(t, "object", schema.Type[0]) 738 adl := schema.AdditionalProperties 739 if assert.NotNil(t, adl) && assert.NotNil(t, adl.Schema) { 740 assert.Equal(t, typeName, adl.Schema.Type[0]) 741 assert.Equal(t, formatName, adl.Schema.Format) 742 } 743 if goName != "" { 744 assert.Equal(t, goName, schema.Extensions["x-go-name"]) 745 } else { 746 assert.Nil(t, schema.Extensions["x-go-name"]) 747 } 748 } 749 } 750 } 751 752 func assertMapWithRefDefinition(t testing.TB, defs map[string]spec.Schema, defName, refURL, goName string) { 753 schema, ok := defs[defName] 754 if assert.True(t, ok) { 755 if assert.NotEmpty(t, schema.Type) { 756 assert.Equal(t, "object", schema.Type[0]) 757 adl := schema.AdditionalProperties 758 if assert.NotNil(t, adl) && assert.NotNil(t, adl.Schema) { 759 if assert.NotZero(t, adl.Schema.Ref) { 760 assert.Equal(t, refURL, adl.Schema.Ref.String()) 761 } 762 } 763 if goName != "" { 764 assert.Equal(t, goName, schema.Extensions["x-go-name"]) 765 } else { 766 assert.Nil(t, schema.Extensions["x-go-name"]) 767 } 768 } 769 } 770 } 771 772 func assertArrayDefinition(t testing.TB, defs map[string]spec.Schema, defName, typeName, formatName, goName string) { 773 schema, ok := defs[defName] 774 if assert.True(t, ok) { 775 if assert.NotEmpty(t, schema.Type) { 776 assert.Equal(t, "array", schema.Type[0]) 777 adl := schema.Items 778 if assert.NotNil(t, adl) && assert.NotNil(t, adl.Schema) { 779 assert.Equal(t, typeName, adl.Schema.Type[0]) 780 assert.Equal(t, formatName, adl.Schema.Format) 781 } 782 if goName != "" { 783 assert.Equal(t, goName, schema.Extensions["x-go-name"]) 784 } else { 785 assert.Nil(t, schema.Extensions["x-go-name"]) 786 } 787 } 788 } 789 } 790 791 func assertArrayWithRefDefinition(t testing.TB, defs map[string]spec.Schema, defName, refURL, goName string) { 792 schema, ok := defs[defName] 793 if assert.True(t, ok) { 794 if assert.NotEmpty(t, schema.Type) { 795 assert.Equal(t, "array", schema.Type[0]) 796 adl := schema.Items 797 if assert.NotNil(t, adl) && assert.NotNil(t, adl.Schema) { 798 if assert.NotZero(t, adl.Schema.Ref) { 799 assert.Equal(t, refURL, adl.Schema.Ref.String()) 800 } 801 } 802 if goName != "" { 803 assert.Equal(t, goName, schema.Extensions["x-go-name"]) 804 } else { 805 assert.Nil(t, schema.Extensions["x-go-name"]) 806 } 807 } 808 } 809 } 810 811 func assertRefDefinition(t testing.TB, defs map[string]spec.Schema, defName, refURL, goName string) { 812 schema, ok := defs[defName] 813 if assert.True(t, ok) { 814 if assert.NotZero(t, schema.Ref) { 815 url := schema.Ref.String() 816 assert.Equal(t, refURL, url) 817 if goName != "" { 818 assert.Equal(t, goName, schema.Extensions["x-go-name"]) 819 } else { 820 assert.Nil(t, schema.Extensions["x-go-name"]) 821 } 822 } 823 } 824 } 825 826 func TestAddExtension(t *testing.T) { 827 ve := &spec.VendorExtensible{ 828 Extensions: make(spec.Extensions), 829 } 830 831 key := "x-go-name" 832 value := "Name" 833 addExtension(ve, key, value) 834 assert.Equal(t, value, ve.Extensions[key].(string)) 835 836 key2 := "x-go-package" 837 value2 := "schema" 838 os.Setenv("SWAGGER_GENERATE_EXTENSION", "true") 839 addExtension(ve, key2, value2) 840 assert.Equal(t, value2, ve.Extensions[key2].(string)) 841 842 key3 := "x-go-class" 843 value3 := "Spec" 844 os.Setenv("SWAGGER_GENERATE_EXTENSION", "false") 845 addExtension(ve, key3, value3) 846 assert.Equal(t, nil, ve.Extensions[key3]) 847 }