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