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