github.com/go-swagger/go-swagger@v0.31.0/generator/pointer_test.go (about) 1 package generator 2 3 import ( 4 "fmt" 5 "testing" 6 7 "github.com/go-openapi/loads" 8 "github.com/go-openapi/spec" 9 "github.com/go-openapi/swag" 10 "github.com/stretchr/testify/assert" 11 "github.com/stretchr/testify/require" 12 ) 13 14 func TestTypeResolver_NestedAliasedSlice(t *testing.T) { 15 specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml") 16 require.NoError(t, err) 17 18 definitions := specDoc.Spec().Definitions 19 k := "Statix" 20 schema := definitions[k] 21 22 tr := newTypeResolver("models", "", specDoc) 23 specDoc.Spec().Definitions["StatixItems0"] = *schema.Items.Schema.Items.Schema.Items.Schema 24 schema.Items.Schema.Items.Schema.Items.Schema = spec.RefProperty("#/definitions/StatixItems0") 25 tr.KnownDefs["StatixItems0"] = struct{}{} 26 tr.ModelName = k 27 rt, err := tr.ResolveSchema(&schema, false, false) 28 require.NoError(t, err) 29 30 assert.Equal(t, "[][][]*models.StatixItems0", rt.AliasedType) 31 } 32 33 func TestTypeResolver_PointerLifting(t *testing.T) { 34 _, resolver, err := basicTaskListResolver(t) 35 require.NoError(t, err) 36 37 testPointToPrimitives(t, *resolver, false /* not aliased */) 38 testPointToPrimitives(t, *resolver, true /* aliased */) 39 testPointToSliceElements(t, *resolver, false /* not aliased */) 40 testPointToSliceElements(t, *resolver, true /* aliased */) 41 testPointToAdditionalPropertiesElements(t, *resolver, false /* not aliased */) 42 testPointToAdditionalPropertiesElements(t, *resolver, true /* aliased */) 43 } 44 45 type builtinVal struct { 46 Type, Format, Expected, AliasedType string 47 48 Nullable, Aliased bool 49 50 Default interface{} 51 52 Extensions spec.Extensions 53 54 Required bool 55 ReadOnly bool 56 Maximum *float64 57 ExclusiveMaximum bool 58 Minimum *float64 59 ExclusiveMinimum bool 60 MaxLength *int64 61 MinLength *int64 62 Pattern string 63 MaxItems *int64 64 MinItems *int64 65 UniqueItems bool 66 MultipleOf *float64 67 Enum []interface{} 68 } 69 70 func nullableExt() spec.Extensions { 71 return spec.Extensions{"x-nullable": true} 72 } 73 74 func isNullableExt() spec.Extensions { 75 return spec.Extensions{"x-isnullable": true} 76 } 77 78 func notNullableExt() spec.Extensions { 79 return spec.Extensions{"x-nullable": false} 80 } 81 82 func isNotNullableExt() spec.Extensions { 83 return spec.Extensions{"x-isnullable": false} 84 } 85 86 var boolPointerVals = []builtinVal{ 87 {Type: "boolean", Format: "", Expected: "bool", Nullable: true, Default: true, Required: false, ReadOnly: false}, 88 {Type: "boolean", Format: "", Expected: "bool", Nullable: true, Default: nil, Required: true, ReadOnly: false}, 89 {Type: "boolean", Format: "", Expected: "bool", Nullable: false, Default: nil, Required: false, ReadOnly: false}, 90 {Type: "boolean", Format: "", Expected: "bool", Nullable: false, Default: nil, Required: true, ReadOnly: true}, 91 {Type: "boolean", Format: "", Expected: "bool", Nullable: false, Default: true, Required: true, ReadOnly: true}, 92 {Type: "boolean", Format: "", Expected: "bool", Nullable: true, Default: true, Required: false, ReadOnly: false, Extensions: nullableExt()}, 93 {Type: "boolean", Format: "", Expected: "bool", Nullable: true, Default: nil, Required: true, ReadOnly: false, Extensions: nullableExt()}, 94 {Type: "boolean", Format: "", Expected: "bool", Nullable: true, Default: nil, Required: false, ReadOnly: false, Extensions: nullableExt()}, 95 {Type: "boolean", Format: "", Expected: "bool", Nullable: true, Default: nil, Required: true, ReadOnly: true, Extensions: nullableExt()}, 96 {Type: "boolean", Format: "", Expected: "bool", Nullable: true, Default: true, Required: true, ReadOnly: true, Extensions: nullableExt()}, 97 {Type: "boolean", Format: "", Expected: "bool", Nullable: true, Default: true, Required: false, ReadOnly: false, Extensions: isNullableExt()}, 98 {Type: "boolean", Format: "", Expected: "bool", Nullable: true, Default: nil, Required: true, ReadOnly: false, Extensions: isNullableExt()}, 99 {Type: "boolean", Format: "", Expected: "bool", Nullable: true, Default: nil, Required: false, ReadOnly: false, Extensions: isNullableExt()}, 100 {Type: "boolean", Format: "", Expected: "bool", Nullable: true, Default: nil, Required: true, ReadOnly: true, Extensions: isNullableExt()}, 101 {Type: "boolean", Format: "", Expected: "bool", Nullable: true, Default: true, Required: true, ReadOnly: true, Extensions: isNullableExt()}, 102 {Type: "boolean", Format: "", Expected: "bool", Nullable: false, Default: true, Required: false, ReadOnly: false, Extensions: notNullableExt()}, 103 {Type: "boolean", Format: "", Expected: "bool", Nullable: false, Default: nil, Required: true, ReadOnly: false, Extensions: notNullableExt()}, 104 {Type: "boolean", Format: "", Expected: "bool", Nullable: false, Default: nil, Required: false, ReadOnly: false, Extensions: notNullableExt()}, 105 {Type: "boolean", Format: "", Expected: "bool", Nullable: false, Default: nil, Required: true, ReadOnly: true, Extensions: notNullableExt()}, 106 {Type: "boolean", Format: "", Expected: "bool", Nullable: false, Default: true, Required: true, ReadOnly: true, Extensions: notNullableExt()}, 107 {Type: "boolean", Format: "", Expected: "bool", Nullable: false, Default: true, Required: false, ReadOnly: false, Extensions: isNotNullableExt()}, 108 {Type: "boolean", Format: "", Expected: "bool", Nullable: false, Default: nil, Required: true, ReadOnly: false, Extensions: isNotNullableExt()}, 109 {Type: "boolean", Format: "", Expected: "bool", Nullable: false, Default: nil, Required: false, ReadOnly: false, Extensions: isNotNullableExt()}, 110 {Type: "boolean", Format: "", Expected: "bool", Nullable: false, Default: nil, Required: true, ReadOnly: true, Extensions: isNotNullableExt()}, 111 {Type: "boolean", Format: "", Expected: "bool", Nullable: false, Default: true, Required: true, ReadOnly: true, Extensions: isNotNullableExt()}, 112 } 113 114 func generateNumberPointerVals(t, v string) (result []builtinVal) { 115 vv := v 116 if vv == "" || vv == "int" { 117 if t == "integer" { 118 vv = "int64" 119 } else { 120 vv = "float64" 121 } 122 } 123 if vv == "uint" && t == "integer" { 124 vv = "uint64" 125 } 126 if t == "number" { 127 if v == "float" { 128 vv = "float32" 129 } else { 130 vv = "float64" 131 } 132 } 133 return []builtinVal{ 134 // plain vanilla 135 {Type: t, Format: v, Expected: vv}, 136 {Type: t, Format: v, Expected: vv, Nullable: true, Extensions: nullableExt()}, 137 {Type: t, Format: v, Expected: vv, Nullable: true, Extensions: isNullableExt()}, // 2 138 139 // plain vanilla readonly and defaults 140 {Type: t, Format: v, Expected: vv, Nullable: false, ReadOnly: true}, 141 {Type: t, Format: v, Expected: vv, Nullable: true, ReadOnly: true, Extensions: nullableExt()}, 142 {Type: t, Format: v, Expected: vv, Nullable: true, ReadOnly: true, Extensions: isNullableExt()}, 143 {Type: t, Format: v, Expected: vv, Nullable: true, Default: 3}, 144 {Type: t, Format: v, Expected: vv, Nullable: false, Default: 3, ReadOnly: true}, 145 {Type: t, Format: v, Expected: vv, Nullable: true, Default: 3, ReadOnly: true, Extensions: nullableExt()}, 146 {Type: t, Format: v, Expected: vv, Nullable: true, Default: 3, ReadOnly: true, Extensions: isNullableExt()}, // 9 147 148 // required 149 {Type: t, Format: v, Expected: vv, Nullable: true, Required: true}, 150 {Type: t, Format: v, Expected: vv, Nullable: true, Required: true, Extensions: nullableExt()}, 151 {Type: t, Format: v, Expected: vv, Nullable: true, Required: true, Extensions: isNullableExt()}, // 12 152 153 // required, readonly and defaults 154 {Type: t, Format: v, Expected: vv, Nullable: false, Required: true, ReadOnly: true}, 155 {Type: t, Format: v, Expected: vv, Nullable: true, Required: true, ReadOnly: true, Extensions: nullableExt()}, 156 {Type: t, Format: v, Expected: vv, Nullable: true, Required: true, ReadOnly: true, Extensions: isNullableExt()}, 157 {Type: t, Format: v, Expected: vv, Nullable: true, Required: true, Default: 3}, 158 {Type: t, Format: v, Expected: vv, Nullable: false, Required: true, Default: 3, ReadOnly: true}, 159 {Type: t, Format: v, Expected: vv, Nullable: true, Required: true, Default: 3, ReadOnly: true, Extensions: nullableExt()}, 160 {Type: t, Format: v, Expected: vv, Nullable: true, Required: true, Default: 3, ReadOnly: true, Extensions: isNullableExt()}, // 19 161 162 // minimum validation 163 {Type: t, Format: v, Expected: vv, Minimum: swag.Float64(2)}, 164 {Type: t, Format: v, Expected: vv, Nullable: true, Minimum: swag.Float64(0)}, 165 {Type: t, Format: v, Expected: vv, Nullable: true, Minimum: swag.Float64(2), Extensions: nullableExt()}, 166 {Type: t, Format: v, Expected: vv, Nullable: true, Minimum: swag.Float64(2), Extensions: isNullableExt()}, // 23 167 168 // minimum validation, readonly and defaults 169 {Type: t, Format: v, Expected: vv, Nullable: false, ReadOnly: true, Minimum: swag.Float64(2)}, 170 {Type: t, Format: v, Expected: vv, Nullable: false, ReadOnly: true, Minimum: swag.Float64(0)}, 171 {Type: t, Format: v, Expected: vv, Nullable: true, ReadOnly: true, Minimum: swag.Float64(2), Extensions: nullableExt()}, 172 {Type: t, Format: v, Expected: vv, Nullable: true, ReadOnly: true, Minimum: swag.Float64(2), Extensions: isNullableExt()}, 173 {Type: t, Format: v, Expected: vv, Nullable: false, Default: 3, Minimum: swag.Float64(2)}, 174 {Type: t, Format: v, Expected: vv, Nullable: false, Default: 3, ReadOnly: true, Minimum: swag.Float64(2)}, 175 {Type: t, Format: v, Expected: vv, Nullable: true, Default: 3, ReadOnly: true, Minimum: swag.Float64(2), Extensions: nullableExt()}, 176 {Type: t, Format: v, Expected: vv, Nullable: true, Default: 3, ReadOnly: true, Minimum: swag.Float64(2), Extensions: isNullableExt()}, // 31 177 178 // required, minimum validation 179 {Type: t, Format: v, Expected: vv, Nullable: true, Required: true, Minimum: swag.Float64(2)}, 180 {Type: t, Format: v, Expected: vv, Nullable: true, Required: true, Minimum: swag.Float64(0)}, 181 {Type: t, Format: v, Expected: vv, Nullable: true, Required: true, Minimum: swag.Float64(2), Extensions: nullableExt()}, 182 {Type: t, Format: v, Expected: vv, Nullable: true, Required: true, Minimum: swag.Float64(2), Extensions: isNullableExt()}, // 35 183 184 // required, minimum validation, readonly and defaults 185 {Type: t, Format: v, Expected: vv, Nullable: false, Required: true, Minimum: swag.Float64(2), ReadOnly: true}, 186 {Type: t, Format: v, Expected: vv, Nullable: true, Required: true, Minimum: swag.Float64(2), ReadOnly: true, Extensions: nullableExt()}, 187 {Type: t, Format: v, Expected: vv, Nullable: true, Required: true, Minimum: swag.Float64(2), ReadOnly: true, Extensions: isNullableExt()}, 188 {Type: t, Format: v, Expected: vv, Nullable: true, Required: true, Minimum: swag.Float64(2), Default: 3}, 189 {Type: t, Format: v, Expected: vv, Nullable: false, Required: true, Minimum: swag.Float64(2), Default: 3, ReadOnly: true}, 190 {Type: t, Format: v, Expected: vv, Nullable: true, Required: true, Minimum: swag.Float64(2), Default: 3, ReadOnly: true, Extensions: nullableExt()}, 191 {Type: t, Format: v, Expected: vv, Nullable: true, Required: true, Minimum: swag.Float64(2), Default: 3, ReadOnly: true, Extensions: isNullableExt()}, // 42 192 193 // maximum validation 194 {Type: t, Format: v, Expected: vv, Maximum: swag.Float64(2)}, 195 {Type: t, Format: v, Expected: vv, Nullable: true, Maximum: swag.Float64(0)}, 196 {Type: t, Format: v, Expected: vv, Nullable: true, Maximum: swag.Float64(2), Extensions: nullableExt()}, 197 {Type: t, Format: v, Expected: vv, Nullable: true, Maximum: swag.Float64(2), Extensions: isNullableExt()}, // 46 198 199 // maximum validation, readonly and defaults 200 {Type: t, Format: v, Expected: vv, Nullable: false, ReadOnly: true, Maximum: swag.Float64(2)}, 201 {Type: t, Format: v, Expected: vv, Nullable: false, ReadOnly: true, Maximum: swag.Float64(0)}, 202 {Type: t, Format: v, Expected: vv, Nullable: true, ReadOnly: true, Maximum: swag.Float64(2), Extensions: nullableExt()}, 203 {Type: t, Format: v, Expected: vv, Nullable: true, ReadOnly: true, Maximum: swag.Float64(2), Extensions: isNullableExt()}, 204 {Type: t, Format: v, Expected: vv, Nullable: false, Default: 3, Maximum: swag.Float64(2)}, 205 {Type: t, Format: v, Expected: vv, Nullable: false, Default: 3, ReadOnly: true, Maximum: swag.Float64(2)}, 206 {Type: t, Format: v, Expected: vv, Nullable: true, Default: 3, ReadOnly: true, Maximum: swag.Float64(2), Extensions: nullableExt()}, 207 {Type: t, Format: v, Expected: vv, Nullable: true, Default: 3, ReadOnly: true, Maximum: swag.Float64(2), Extensions: isNullableExt()}, // 54 208 209 // required, maximum validation 210 {Type: t, Format: v, Expected: vv, Nullable: true, Required: true, Maximum: swag.Float64(2)}, 211 {Type: t, Format: v, Expected: vv, Nullable: true, Required: true, Maximum: swag.Float64(0)}, 212 {Type: t, Format: v, Expected: vv, Nullable: true, Required: true, Maximum: swag.Float64(2), Extensions: nullableExt()}, 213 {Type: t, Format: v, Expected: vv, Nullable: true, Required: true, Maximum: swag.Float64(2), Extensions: isNullableExt()}, // 58 214 215 // required, maximum validation, readonly and defaults 216 {Type: t, Format: v, Expected: vv, Nullable: false, Required: true, Maximum: swag.Float64(2), ReadOnly: true}, 217 {Type: t, Format: v, Expected: vv, Nullable: true, Required: true, Maximum: swag.Float64(2), ReadOnly: true, Extensions: nullableExt()}, 218 {Type: t, Format: v, Expected: vv, Nullable: true, Required: true, Maximum: swag.Float64(2), ReadOnly: true, Extensions: isNullableExt()}, 219 {Type: t, Format: v, Expected: vv, Nullable: true, Required: true, Maximum: swag.Float64(2), Default: 3}, 220 {Type: t, Format: v, Expected: vv, Nullable: false, Required: true, Maximum: swag.Float64(2), Default: 3, ReadOnly: true}, 221 {Type: t, Format: v, Expected: vv, Nullable: true, Required: true, Maximum: swag.Float64(2), Default: 3, ReadOnly: true, Extensions: nullableExt()}, 222 {Type: t, Format: v, Expected: vv, Nullable: true, Required: true, Maximum: swag.Float64(2), Default: 3, ReadOnly: true, Extensions: isNullableExt()}, // 65 223 224 // minimum and maximum validation 225 {Type: t, Format: v, Expected: vv, Minimum: swag.Float64(2), Maximum: swag.Float64(5)}, 226 {Type: t, Format: v, Expected: vv, Nullable: true, Minimum: swag.Float64(-1), Maximum: swag.Float64(1)}, 227 {Type: t, Format: v, Expected: vv, Nullable: true, Minimum: swag.Float64(0), Maximum: swag.Float64(1)}, 228 {Type: t, Format: v, Expected: vv, Nullable: true, Minimum: swag.Float64(-1), Maximum: swag.Float64(0)}, 229 {Type: t, Format: v, Expected: vv, Nullable: true, Minimum: swag.Float64(2), Maximum: swag.Float64(6), Extensions: nullableExt()}, 230 {Type: t, Format: v, Expected: vv, Nullable: true, Minimum: swag.Float64(2), Maximum: swag.Float64(6), Extensions: isNullableExt()}, // 72 231 232 // minimum and maximum validation, readonly and defaults 233 {Type: t, Format: v, Expected: vv, Nullable: false, ReadOnly: true, Minimum: swag.Float64(-1), Maximum: swag.Float64(2)}, 234 {Type: t, Format: v, Expected: vv, Nullable: false, ReadOnly: true, Minimum: swag.Float64(0), Maximum: swag.Float64(3)}, 235 {Type: t, Format: v, Expected: vv, Nullable: false, ReadOnly: true, Minimum: swag.Float64(-1), Maximum: swag.Float64(0)}, 236 {Type: t, Format: v, Expected: vv, Nullable: false, Default: 3, Minimum: swag.Float64(-1), ReadOnly: true, Maximum: swag.Float64(2)}, 237 {Type: t, Format: v, Expected: vv, Nullable: true, ReadOnly: true, Maximum: swag.Float64(2), Extensions: nullableExt()}, 238 {Type: t, Format: v, Expected: vv, Nullable: true, ReadOnly: true, Maximum: swag.Float64(2), Extensions: isNullableExt()}, 239 {Type: t, Format: v, Expected: vv, Nullable: true, Default: 3, Minimum: swag.Float64(-1), Maximum: swag.Float64(6)}, 240 {Type: t, Format: v, Expected: vv, Nullable: false, Default: 3, Minimum: swag.Float64(1), Maximum: swag.Float64(6)}, 241 {Type: t, Format: v, Expected: vv, Nullable: false, Default: 3, Minimum: swag.Float64(-6), Maximum: swag.Float64(-1)}, 242 {Type: t, Format: v, Expected: vv, Nullable: true, Default: 3, ReadOnly: true, Minimum: swag.Float64(-1), Maximum: swag.Float64(2), Extensions: nullableExt()}, 243 {Type: t, Format: v, Expected: vv, Nullable: true, Default: 3, ReadOnly: true, Minimum: swag.Float64(-1), Maximum: swag.Float64(2), Extensions: isNullableExt()}, // 83 244 245 // required, minimum and maximum validation 246 {Type: t, Format: v, Expected: vv, Nullable: true, Required: true, Minimum: swag.Float64(2), Maximum: swag.Float64(5)}, 247 {Type: t, Format: v, Expected: vv, Nullable: true, Required: true, Minimum: swag.Float64(-1), Maximum: swag.Float64(1)}, 248 {Type: t, Format: v, Expected: vv, Nullable: true, Required: true, Minimum: swag.Float64(0), Maximum: swag.Float64(1)}, 249 {Type: t, Format: v, Expected: vv, Nullable: true, Required: true, Minimum: swag.Float64(-1), Maximum: swag.Float64(0)}, 250 {Type: t, Format: v, Expected: vv, Nullable: true, Required: true, Minimum: swag.Float64(2), Maximum: swag.Float64(6), Extensions: nullableExt()}, 251 {Type: t, Format: v, Expected: vv, Nullable: true, Required: true, Minimum: swag.Float64(2), Maximum: swag.Float64(6), Extensions: isNullableExt()}, // 89 252 253 // required, minimum and maximum validation, readonly and defaults 254 {Type: t, Format: v, Expected: vv, Nullable: false, Required: true, ReadOnly: true, Minimum: swag.Float64(-1), Maximum: swag.Float64(2)}, 255 {Type: t, Format: v, Expected: vv, Nullable: false, Required: true, ReadOnly: true, Minimum: swag.Float64(0), Maximum: swag.Float64(3)}, 256 {Type: t, Format: v, Expected: vv, Nullable: false, Required: true, ReadOnly: true, Minimum: swag.Float64(-1), Maximum: swag.Float64(0)}, 257 {Type: t, Format: v, Expected: vv, Nullable: false, Required: true, Default: 3, Minimum: swag.Float64(-1), ReadOnly: true, Maximum: swag.Float64(2)}, 258 {Type: t, Format: v, Expected: vv, Nullable: true, Required: true, ReadOnly: true, Maximum: swag.Float64(2), Extensions: nullableExt()}, 259 {Type: t, Format: v, Expected: vv, Nullable: true, Required: true, ReadOnly: true, Maximum: swag.Float64(2), Extensions: isNullableExt()}, 260 {Type: t, Format: v, Expected: vv, Nullable: true, Required: true, Default: 3, Minimum: swag.Float64(-1), Maximum: swag.Float64(6)}, 261 {Type: t, Format: v, Expected: vv, Nullable: true, Required: true, Default: 3, Minimum: swag.Float64(1), Maximum: swag.Float64(6)}, 262 {Type: t, Format: v, Expected: vv, Nullable: true, Required: true, Default: 3, Minimum: swag.Float64(-6), Maximum: swag.Float64(-1)}, 263 {Type: t, Format: v, Expected: vv, Nullable: true, Required: true, Default: 3, ReadOnly: true, Minimum: swag.Float64(-1), Maximum: swag.Float64(2), Extensions: nullableExt()}, 264 {Type: t, Format: v, Expected: vv, Nullable: true, Required: true, Default: 3, ReadOnly: true, Minimum: swag.Float64(-1), Maximum: swag.Float64(2), Extensions: isNullableExt()}, // 99 265 } 266 } 267 268 var stringPointerVals = []builtinVal{ 269 {Type: "string", Format: "", Expected: "string", Nullable: false}, 270 {Type: "string", Format: "", Expected: "string", Nullable: true, Extensions: nullableExt()}, 271 {Type: "string", Format: "", Expected: "string", Nullable: true, Extensions: isNullableExt()}, // 2 272 273 // plain vanilla readonly and defaults 274 {Type: "string", Format: "", Expected: "string", Nullable: false, ReadOnly: true}, 275 {Type: "string", Format: "", Expected: "string", Nullable: true, ReadOnly: true, Extensions: nullableExt()}, 276 {Type: "string", Format: "", Expected: "string", Nullable: true, ReadOnly: true, Extensions: isNullableExt()}, 277 {Type: "string", Format: "", Expected: "string", Nullable: true, Default: 3}, 278 {Type: "string", Format: "", Expected: "string", Nullable: false, Default: 3, ReadOnly: true}, 279 {Type: "string", Format: "", Expected: "string", Nullable: true, Default: 3, ReadOnly: true, Extensions: nullableExt()}, 280 {Type: "string", Format: "", Expected: "string", Nullable: true, Default: 3, ReadOnly: true, Extensions: isNullableExt()}, // 9 281 282 // required 283 {Type: "string", Format: "", Expected: "string", Nullable: true, Required: true}, 284 {Type: "string", Format: "", Expected: "string", Nullable: true, Required: true, Extensions: nullableExt()}, 285 {Type: "string", Format: "", Expected: "string", Nullable: true, Required: true, Extensions: isNullableExt()}, // 12 286 287 // required, readonly and defaults 288 {Type: "string", Format: "", Expected: "string", Nullable: false, Required: true, ReadOnly: true}, 289 {Type: "string", Format: "", Expected: "string", Nullable: true, Required: true, ReadOnly: true, Extensions: nullableExt()}, 290 {Type: "string", Format: "", Expected: "string", Nullable: true, Required: true, ReadOnly: true, Extensions: isNullableExt()}, 291 {Type: "string", Format: "", Expected: "string", Nullable: true, Required: true, Default: 3}, 292 {Type: "string", Format: "", Expected: "string", Nullable: false, Required: true, Default: 3, ReadOnly: true}, 293 {Type: "string", Format: "", Expected: "string", Nullable: true, Required: true, Default: 3, ReadOnly: true, Extensions: nullableExt()}, 294 {Type: "string", Format: "", Expected: "string", Nullable: true, Required: true, Default: 3, ReadOnly: true, Extensions: isNullableExt()}, // 19 295 296 // minLength validation 297 {Type: "string", Format: "", Expected: "string", Nullable: false, MinLength: swag.Int64(2)}, 298 {Type: "string", Format: "", Expected: "string", Nullable: true, MinLength: swag.Int64(0)}, 299 {Type: "string", Format: "", Expected: "string", Nullable: true, MinLength: swag.Int64(2), Extensions: nullableExt()}, 300 {Type: "string", Format: "", Expected: "string", Nullable: true, MinLength: swag.Int64(2), Extensions: isNullableExt()}, // 23 301 302 // minLength validation, readonly and defaults 303 {Type: "string", Format: "", Expected: "string", Nullable: false, ReadOnly: true, MinLength: swag.Int64(2)}, 304 {Type: "string", Format: "", Expected: "string", Nullable: false, ReadOnly: true, MinLength: swag.Int64(0)}, 305 {Type: "string", Format: "", Expected: "string", Nullable: true, ReadOnly: true, MinLength: swag.Int64(2), Extensions: nullableExt()}, 306 {Type: "string", Format: "", Expected: "string", Nullable: true, ReadOnly: true, MinLength: swag.Int64(2), Extensions: isNullableExt()}, 307 {Type: "string", Format: "", Expected: "string", Nullable: false, Default: 3, MinLength: swag.Int64(2)}, 308 {Type: "string", Format: "", Expected: "string", Nullable: false, Default: 3, ReadOnly: true, MinLength: swag.Int64(2)}, 309 {Type: "string", Format: "", Expected: "string", Nullable: true, Default: 3, ReadOnly: true, MinLength: swag.Int64(2), Extensions: nullableExt()}, 310 {Type: "string", Format: "", Expected: "string", Nullable: true, Default: 3, ReadOnly: true, MinLength: swag.Int64(2), Extensions: isNullableExt()}, // 31 311 312 // required, minLength validation 313 {Type: "string", Format: "", Expected: "string", Nullable: true, Required: true, MinLength: swag.Int64(2)}, 314 {Type: "string", Format: "", Expected: "string", Nullable: true, Required: true, MinLength: swag.Int64(0)}, 315 {Type: "string", Format: "", Expected: "string", Nullable: true, Required: true, MinLength: swag.Int64(2), Extensions: nullableExt()}, 316 {Type: "string", Format: "", Expected: "string", Nullable: true, Required: true, MinLength: swag.Int64(2), Extensions: isNullableExt()}, // 35 317 318 // required, minLength validation, readonly and defaults 319 {Type: "string", Format: "", Expected: "string", Nullable: false, Required: true, MinLength: swag.Int64(2), ReadOnly: true}, 320 {Type: "string", Format: "", Expected: "string", Nullable: true, Required: true, MinLength: swag.Int64(2), ReadOnly: true, Extensions: nullableExt()}, 321 {Type: "string", Format: "", Expected: "string", Nullable: true, Required: true, MinLength: swag.Int64(2), ReadOnly: true, Extensions: isNullableExt()}, 322 {Type: "string", Format: "", Expected: "string", Nullable: true, Required: true, MinLength: swag.Int64(2), Default: 3}, 323 {Type: "string", Format: "", Expected: "string", Nullable: false, Required: true, MinLength: swag.Int64(2), Default: 3, ReadOnly: true}, 324 {Type: "string", Format: "", Expected: "string", Nullable: true, Required: true, MinLength: swag.Int64(2), Default: 3, ReadOnly: true, Extensions: nullableExt()}, 325 {Type: "string", Format: "", Expected: "string", Nullable: true, Required: true, MinLength: swag.Int64(2), Default: 3, ReadOnly: true, Extensions: isNullableExt()}, // 42 326 } 327 328 var strfmtValues = []builtinVal{ 329 {Type: "string", Format: "password", Expected: "strfmt.Password", Nullable: false}, 330 {Type: "string", Format: "password", Expected: "strfmt.Password", Nullable: true, Extensions: nullableExt()}, 331 {Type: "string", Format: "password", Expected: "strfmt.Password", Nullable: true, Extensions: isNullableExt()}, // 2 332 333 // plain vanilla readonly and defaults 334 {Type: "string", Format: "password", Expected: "strfmt.Password", Nullable: false, ReadOnly: true}, 335 {Type: "string", Format: "password", Expected: "strfmt.Password", Nullable: true, ReadOnly: true, Extensions: nullableExt()}, 336 {Type: "string", Format: "password", Expected: "strfmt.Password", Nullable: true, ReadOnly: true, Extensions: isNullableExt()}, 337 {Type: "string", Format: "password", Expected: "strfmt.Password", Nullable: true, Default: 3}, 338 {Type: "string", Format: "password", Expected: "strfmt.Password", Nullable: false, Default: 3, ReadOnly: true}, 339 {Type: "string", Format: "password", Expected: "strfmt.Password", Nullable: true, Default: 3, ReadOnly: true, Extensions: nullableExt()}, 340 {Type: "string", Format: "password", Expected: "strfmt.Password", Nullable: true, Default: 3, ReadOnly: true, Extensions: isNullableExt()}, // 9 341 342 // required 343 {Type: "string", Format: "password", Expected: "strfmt.Password", Nullable: true, Required: true}, 344 {Type: "string", Format: "password", Expected: "strfmt.Password", Nullable: true, Required: true, Extensions: nullableExt()}, 345 {Type: "string", Format: "password", Expected: "strfmt.Password", Nullable: true, Required: true, Extensions: isNullableExt()}, // 12 346 347 // required, readonly and defaults 348 {Type: "string", Format: "password", Expected: "strfmt.Password", Nullable: false, Required: true, ReadOnly: true}, 349 {Type: "string", Format: "password", Expected: "strfmt.Password", Nullable: true, Required: true, ReadOnly: true, Extensions: nullableExt()}, 350 {Type: "string", Format: "password", Expected: "strfmt.Password", Nullable: true, Required: true, ReadOnly: true, Extensions: isNullableExt()}, 351 {Type: "string", Format: "password", Expected: "strfmt.Password", Nullable: true, Required: true, Default: 3}, 352 {Type: "string", Format: "password", Expected: "strfmt.Password", Nullable: false, Required: true, Default: 3, ReadOnly: true}, 353 {Type: "string", Format: "password", Expected: "strfmt.Password", Nullable: true, Required: true, Default: 3, ReadOnly: true, Extensions: nullableExt()}, 354 {Type: "string", Format: "password", Expected: "strfmt.Password", Nullable: true, Required: true, Default: 3, ReadOnly: true, Extensions: isNullableExt()}, // 19 355 356 {Type: "string", Format: "binary", Expected: "io.ReadCloser", Nullable: false}, 357 {Type: "string", Format: "binary", Expected: "io.ReadCloser", Nullable: false, Extensions: nullableExt()}, 358 {Type: "string", Format: "binary", Expected: "io.ReadCloser", Nullable: false, Extensions: isNullableExt()}, // 22 359 360 // plain vanilla readonly and defaults 361 {Type: "string", Format: "binary", Expected: "io.ReadCloser", Nullable: false, ReadOnly: true}, 362 {Type: "string", Format: "binary", Expected: "io.ReadCloser", Nullable: false, ReadOnly: true, Extensions: nullableExt()}, 363 {Type: "string", Format: "binary", Expected: "io.ReadCloser", Nullable: false, ReadOnly: true, Extensions: isNullableExt()}, 364 {Type: "string", Format: "binary", Expected: "io.ReadCloser", Nullable: false, Default: 3}, 365 {Type: "string", Format: "binary", Expected: "io.ReadCloser", Nullable: false, Default: 3, ReadOnly: true}, 366 {Type: "string", Format: "binary", Expected: "io.ReadCloser", Nullable: false, Default: 3, ReadOnly: true, Extensions: nullableExt()}, 367 {Type: "string", Format: "binary", Expected: "io.ReadCloser", Nullable: false, Default: 3, ReadOnly: true, Extensions: isNullableExt()}, // 29 368 369 // required 370 {Type: "string", Format: "binary", Expected: "io.ReadCloser", Nullable: false, Required: true}, 371 {Type: "string", Format: "binary", Expected: "io.ReadCloser", Nullable: false, Required: true, Extensions: nullableExt()}, 372 {Type: "string", Format: "binary", Expected: "io.ReadCloser", Nullable: false, Required: true, Extensions: isNullableExt()}, // 32 373 374 // required, readonly and defaults 375 {Type: "string", Format: "binary", Expected: "io.ReadCloser", Nullable: false, Required: true, ReadOnly: true}, 376 {Type: "string", Format: "binary", Expected: "io.ReadCloser", Nullable: false, Required: true, ReadOnly: true, Extensions: nullableExt()}, 377 {Type: "string", Format: "binary", Expected: "io.ReadCloser", Nullable: false, Required: true, ReadOnly: true, Extensions: isNullableExt()}, 378 {Type: "string", Format: "binary", Expected: "io.ReadCloser", Nullable: false, Required: true, Default: 3}, 379 {Type: "string", Format: "binary", Expected: "io.ReadCloser", Nullable: false, Required: true, Default: 3, ReadOnly: true}, 380 {Type: "string", Format: "binary", Expected: "io.ReadCloser", Nullable: false, Required: true, Default: 3, ReadOnly: true, Extensions: nullableExt()}, 381 {Type: "string", Format: "binary", Expected: "io.ReadCloser", Nullable: false, Required: true, Default: 3, ReadOnly: true, Extensions: isNullableExt()}, // 39 382 } 383 384 func testPointToAdditionalPropertiesElements(t testing.TB, tr typeResolver, aliased bool) bool { 385 if aliased { 386 tr.ModelName = "MyAliasedThing" 387 } 388 resolver := &tr 389 for i, val := range boolPointerVals { 390 if !assertBuiltinAdditionalPropertiesElem(t, resolver, aliased, i, val) { 391 return false 392 } 393 } 394 for _, v := range []string{"", "int", "int8", "int16", "int32", "int64", "uint", "uint8", "uint16", "uint32", "uint64"} { 395 passed := true 396 for i, val := range generateNumberPointerVals("integer", v) { 397 if !assertBuiltinAdditionalPropertiesElem(t, resolver, aliased, i, val) { 398 passed = false 399 } 400 } 401 if !passed { 402 return false 403 } 404 } 405 for _, v := range []string{"", "float", "double"} { 406 passed := true 407 for i, val := range generateNumberPointerVals("number", v) { 408 if !assertBuiltinAdditionalPropertiesElem(t, resolver, aliased, i, val) { 409 passed = false 410 } 411 } 412 if !passed { 413 return false 414 } 415 } 416 for i, val := range stringPointerVals { 417 if !assertBuiltinAdditionalPropertiesElem(t, resolver, aliased, i, val) { 418 return false 419 } 420 } 421 for i, val := range strfmtValues { 422 if !assertBuiltinAdditionalPropertiesElem(t, resolver, aliased, i, val) { 423 return false 424 } 425 } 426 return true 427 } 428 429 func testPointToSliceElements(t testing.TB, tr typeResolver, aliased bool) bool { 430 if aliased { 431 tr.ModelName = "MyAliasedThing" 432 } 433 resolver := &tr 434 for i, val := range boolPointerVals { 435 if !assertBuiltinSliceElem(t, resolver, aliased, i, val) { 436 return false 437 } 438 } 439 for _, v := range []string{"", "int", "int8", "int16", "int32", "int64", "uint", "uint8", "uint16", "uint32", "uint64"} { 440 passed := true 441 for i, val := range generateNumberPointerVals("integer", v) { 442 if !assertBuiltinSliceElem(t, resolver, aliased, i, val) { 443 passed = false 444 } 445 } 446 if !passed { 447 return false 448 } 449 } 450 for _, v := range []string{"", "float", "double"} { 451 passed := true 452 for i, val := range generateNumberPointerVals("number", v) { 453 if !assertBuiltinSliceElem(t, resolver, aliased, i, val) { 454 passed = false 455 } 456 } 457 if !passed { 458 return false 459 } 460 } 461 for i, val := range stringPointerVals { 462 if !assertBuiltinSliceElem(t, resolver, aliased, i, val) { 463 return false 464 } 465 } 466 for i, val := range strfmtValues { 467 if !assertBuiltinSliceElem(t, resolver, aliased, i, val) { 468 return false 469 } 470 } 471 return true 472 } 473 474 func testPointToPrimitives(t testing.TB, tr typeResolver, aliased bool) bool { 475 if aliased { 476 tr.ModelName = "MyAliasedThing" 477 tr.KnownDefs[tr.ModelName] = struct{}{} 478 } 479 resolver := &tr 480 for i, val := range boolPointerVals { 481 if !assertBuiltinVal(t, resolver, aliased, i, val) { 482 return false 483 } 484 } 485 for _, v := range []string{"", "int", "int8", "int16", "int32", "int64", "uint", "uint8", "uint16", "uint32", "uint64"} { 486 passed := true 487 for i, val := range generateNumberPointerVals("integer", v) { 488 if !assertBuiltinVal(t, resolver, aliased, i, val) { 489 passed = false 490 } 491 } 492 if !passed { 493 return false 494 } 495 } 496 for _, v := range []string{"", "float", "double"} { 497 passed := true 498 for i, val := range generateNumberPointerVals("number", v) { 499 if !assertBuiltinVal(t, resolver, aliased, i, val) { 500 passed = false 501 } 502 } 503 if !passed { 504 return false 505 } 506 } 507 508 for i, val := range stringPointerVals { 509 if !assertBuiltinVal(t, resolver, aliased, i, val) { 510 return false 511 } 512 } 513 514 for i, val := range strfmtValues { 515 if !assertBuiltinVal(t, resolver, aliased, i, val) { 516 return false 517 } 518 } 519 return true 520 } 521 522 func assertBuiltinVal(t testing.TB, resolver *typeResolver, aliased bool, i int, val builtinVal) bool { 523 val.Aliased = aliased 524 if aliased { 525 val.AliasedType = val.Expected 526 val.Expected = "models.MyAliasedThing" 527 } 528 529 sch := new(spec.Schema) 530 sch.Typed(val.Type, val.Format) 531 sch.Default = val.Default 532 sch.ReadOnly = val.ReadOnly 533 sch.Extensions = val.Extensions 534 sch.Minimum = val.Minimum 535 sch.Maximum = val.Maximum 536 sch.MultipleOf = val.MultipleOf 537 sch.MinLength = val.MinLength 538 sch.MaxLength = val.MaxLength 539 540 rt, err := resolver.ResolveSchema(sch, !aliased, val.Required) 541 require.NoError(t, err) 542 if val.Nullable { 543 if !assert.True(t, rt.IsNullable, "expected nullable for item at: %d", i) { 544 // fmt.Println("isRequired:", val.Required) 545 // pretty.Println(sch) 546 return false 547 } 548 } else { 549 if !assert.False(t, rt.IsNullable, "expected not nullable for item at: %d", i) { 550 // fmt.Println("isRequired:", val.Required) 551 // pretty.Println(sch) 552 return false 553 } 554 } 555 if !assert.Equal(t, val.Aliased, rt.IsAliased, "expected (%q, %q) to be an aliased type", val.Type, val.Format) { 556 return false 557 } 558 if val.Aliased { 559 if !assert.Equal(t, val.AliasedType, rt.AliasedType, "expected %q (%q, %q) to be aliased as %q, but got %q", val.Expected, val.Type, val.Format, val.AliasedType, rt.AliasedType) { 560 return false 561 } 562 } 563 if !assertBuiltinResolve(t, val.Type, val.Format, val.Expected, rt, i) { 564 return false 565 } 566 return true 567 } 568 569 func assertBuiltinSliceElem(t testing.TB, resolver *typeResolver, aliased bool, i int, val builtinVal) bool { 570 val.Nullable = false 571 if nullableExtension(val.Extensions) != nil { 572 val.Nullable = *nullableExtension(val.Extensions) 573 } 574 sliceType := "[]" + val.Expected 575 if val.Nullable { 576 sliceType = "[]*" + val.Expected 577 } 578 val.Expected = sliceType 579 580 val.Aliased = aliased 581 if aliased { 582 val.AliasedType = val.Expected 583 val.Expected = "models.MyAliasedThing" 584 } 585 586 items := new(spec.Schema) 587 items.Typed(val.Type, val.Format) 588 items.Default = val.Default 589 items.ReadOnly = val.ReadOnly 590 items.Extensions = val.Extensions 591 items.Minimum = val.Minimum 592 items.Maximum = val.Maximum 593 items.MultipleOf = val.MultipleOf 594 items.MinLength = val.MinLength 595 items.MaxLength = val.MaxLength 596 597 sch := spec.ArrayProperty(items) 598 599 rt, err := resolver.ResolveSchema(sch, !aliased, val.Required) 600 require.NoError(t, err) 601 602 if val.Nullable { 603 if !assert.True(t, rt.ElemType.IsNullable, "expected nullable for item at: %d", i) { 604 return false 605 } 606 } else { 607 if !assert.False(t, rt.ElemType != nil && rt.ElemType.IsNullable, "expected not nullable for item at: %d", i) { 608 return false 609 } 610 } 611 612 if val.Aliased { 613 if !assert.Equal(t, val.Aliased, rt.IsAliased, "expected (%q, %q) to be an aliased type at: %d", val.Type, val.Format, i) { 614 return false 615 } 616 if !assert.Equal(t, val.AliasedType, rt.AliasedType, "expected %q (%q, %q) to be aliased as %q, but got %q at %d", val.Expected, val.Type, val.Format, val.AliasedType, rt.AliasedType, i) { 617 return false 618 } 619 } 620 621 if !assertBuiltinSliceElemnResolve(t, val.Type, val.Format, val.Expected, rt, i) { 622 return false 623 } 624 return true 625 } 626 627 func assertBuiltinAdditionalPropertiesElem(t testing.TB, resolver *typeResolver, aliased bool, i int, val builtinVal) bool { 628 val.Nullable = false 629 if nullableExtension(val.Extensions) != nil { 630 val.Nullable = *nullableExtension(val.Extensions) 631 } 632 sliceType := "map[string]" + val.Expected 633 if val.Nullable { 634 sliceType = "map[string]*" + val.Expected 635 } 636 val.Expected = sliceType 637 638 val.Aliased = aliased 639 if aliased { 640 val.AliasedType = val.Expected 641 val.Expected = "models.MyAliasedThing" 642 } 643 644 items := new(spec.Schema) 645 items.Typed(val.Type, val.Format) 646 items.Default = val.Default 647 items.ReadOnly = val.ReadOnly 648 items.Extensions = val.Extensions 649 items.Minimum = val.Minimum 650 items.Maximum = val.Maximum 651 items.MultipleOf = val.MultipleOf 652 items.MinLength = val.MinLength 653 items.MaxLength = val.MaxLength 654 655 sch := spec.MapProperty(items) 656 657 rt, err := resolver.ResolveSchema(sch, !aliased, val.Required) 658 require.NoError(t, err) 659 660 if val.Nullable { 661 if !assert.True(t, rt.ElemType.IsNullable, "expected nullable for item at: %d", i) { 662 return false 663 } 664 } else { 665 if !assert.False(t, rt.ElemType != nil && rt.ElemType.IsNullable, "expected not nullable for item at: %d", i) { 666 return false 667 } 668 } 669 670 if !assert.Equal(t, val.Aliased, rt.IsAliased, "expected (%q, %q) to be an aliased type at %d", val.Type, val.Format, i) { 671 return false 672 } 673 674 if val.Aliased { 675 if !assert.Equal(t, val.AliasedType, rt.AliasedType, "expected %q (%q, %q) to be aliased as %q, but got %q at %d", val.Expected, val.Type, val.Format, val.AliasedType, rt.AliasedType, i) { 676 return false 677 } 678 } 679 680 if !assertBuiltinSliceElemnResolve(t, val.Type, val.Format, val.Expected, rt, i) { 681 return false 682 } 683 return true 684 } 685 686 func assertBuiltinResolve(t testing.TB, tpe, tfmt, exp string, tr resolvedType, i int) bool { 687 return assert.Equal(t, tpe, tr.SwaggerType, fmt.Sprintf("expected %q (%q, %q) at %d for the swagger type but got %q", tpe, tfmt, exp, i, tr.SwaggerType)) && 688 assert.Equal(t, tfmt, tr.SwaggerFormat, fmt.Sprintf("expected %q (%q, %q) at %d for the swagger format but got %q", tfmt, tpe, exp, i, tr.SwaggerFormat)) && 689 assert.Equal(t, exp, tr.GoType, fmt.Sprintf("expected %q (%q, %q) at %d for the go type but got %q", exp, tpe, tfmt, i, tr.GoType)) 690 } 691 692 func assertBuiltinSliceElemnResolve(t testing.TB, tpe, tfmt, exp string, tr resolvedType, i int) bool { 693 return assert.Equal(t, tpe, tr.ElemType.SwaggerType, fmt.Sprintf("expected %q (%q, %q) at %d for the swagger type but got %q", tpe, tfmt, exp, i, tr.SwaggerType)) && 694 assert.Equal(t, tfmt, tr.ElemType.SwaggerFormat, fmt.Sprintf("expected %q (%q, %q) at %d for the swagger format but got %q", tfmt, tpe, exp, i, tr.SwaggerFormat)) && 695 assert.Equal(t, exp, tr.GoType, fmt.Sprintf("expected %q (%q, %q) at %d for the go type but got %q", exp, tpe, tfmt, i, tr.GoType)) 696 }