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