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