github.com/6543-forks/go-swagger@v0.26.0/generator/typeresolver_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 generator
    16  
    17  import (
    18  	"fmt"
    19  	"testing"
    20  
    21  	"github.com/go-openapi/loads"
    22  	"github.com/go-openapi/spec"
    23  	"github.com/stretchr/testify/assert"
    24  	"github.com/stretchr/testify/require"
    25  )
    26  
    27  func schTypeVals() []struct{ Type, Format, Expected string } {
    28  	return []struct{ Type, Format, Expected string }{
    29  		{"boolean", "", "bool"},
    30  		{"string", "", "string"},
    31  		{"integer", "int8", "int8"},
    32  		{"integer", "int16", "int16"},
    33  		{"integer", "int32", "int32"},
    34  		{"integer", "int64", "int64"},
    35  		{"integer", "", "int64"},
    36  		{"integer", "uint8", "uint8"},
    37  		{"integer", "uint16", "uint16"},
    38  		{"integer", "uint32", "uint32"},
    39  		{"integer", "uint64", "uint64"},
    40  		{"number", "float", "float32"},
    41  		{"number", "double", "float64"},
    42  		{"number", "", "float64"},
    43  		{"string", "byte", "strfmt.Base64"},
    44  		{"string", "date", "strfmt.Date"},
    45  		{"string", "date-time", "strfmt.DateTime"},
    46  		{"string", "uri", "strfmt.URI"},
    47  		{"string", "email", "strfmt.Email"},
    48  		{"string", "hostname", "strfmt.Hostname"},
    49  		{"string", "ipv4", "strfmt.IPv4"},
    50  		{"string", "ipv6", "strfmt.IPv6"},
    51  		{"string", "mac", "strfmt.MAC"},
    52  		{"string", "uuid", "strfmt.UUID"},
    53  		{"string", "uuid3", "strfmt.UUID3"},
    54  		{"string", "uuid4", "strfmt.UUID4"},
    55  		{"string", "uuid5", "strfmt.UUID5"},
    56  		{"string", "isbn", "strfmt.ISBN"},
    57  		{"string", "isbn10", "strfmt.ISBN10"},
    58  		{"string", "isbn13", "strfmt.ISBN13"},
    59  		{"string", "creditcard", "strfmt.CreditCard"},
    60  		{"string", "ssn", "strfmt.SSN"},
    61  		{"string", "hexcolor", "strfmt.HexColor"},
    62  		{"string", "rgbcolor", "strfmt.RGBColor"},
    63  		{"string", "duration", "strfmt.Duration"},
    64  		{"string", "ObjectId", "strfmt.ObjectId"},
    65  		{"string", "password", "strfmt.Password"},
    66  		{"string", "uint8", "string"},
    67  		{"string", "uint16", "string"},
    68  		{"string", "uint32", "string"},
    69  		{"string", "uint64", "string"},
    70  		{"string", "int8", "string"},
    71  		{"string", "int16", "string"},
    72  		{"string", "int32", "string"},
    73  		{"string", "int64", "string"},
    74  		{"file", "", "io.ReadCloser"},
    75  	}
    76  }
    77  
    78  func schRefVals() []struct{ Type, GoType, Expected string } {
    79  	return []struct{ Type, GoType, Expected string }{
    80  		{"Comment", "", "models.Comment"},
    81  		{"UserCard", "UserItem", "models.UserItem"},
    82  	}
    83  }
    84  
    85  func TestTypeResolver_AdditionalItems(t *testing.T) {
    86  	_, resolver, e := basicTaskListResolver(t)
    87  	require.NoError(t, e)
    88  
    89  	tpe := spec.StringProperty()
    90  
    91  	// arrays of primitives and string formats with additional formats
    92  	for _, val := range schTypeVals() {
    93  		var sch spec.Schema
    94  		sch.Typed(val.Type, val.Format)
    95  		var coll spec.Schema
    96  		coll.Type = []string{"array"}
    97  		coll.Items = new(spec.SchemaOrArray)
    98  		coll.Items.Schema = tpe
    99  		coll.AdditionalItems = new(spec.SchemaOrBool)
   100  		coll.AdditionalItems.Schema = &sch
   101  
   102  		rt, err := resolver.ResolveSchema(&coll, true, true)
   103  		require.NoError(t, err)
   104  		require.True(t, rt.IsArray)
   105  
   106  		assert.True(t, rt.HasAdditionalItems)
   107  		assert.False(t, rt.IsNullable)
   108  	}
   109  }
   110  
   111  func TestTypeResolver_BasicTypes(t *testing.T) {
   112  
   113  	_, resolver, e := basicTaskListResolver(t)
   114  	require.NoError(t, e)
   115  
   116  	// primitives and string formats
   117  	for _, val := range schTypeVals() {
   118  		sch := new(spec.Schema)
   119  		sch.Typed(val.Type, val.Format)
   120  
   121  		rt, err := resolver.ResolveSchema(sch, true, false)
   122  		require.NoError(t, err)
   123  
   124  		assert.False(t, rt.IsNullable, "expected %s with format %q to not be nullable", val.Type, val.Format)
   125  		assertPrimitiveResolve(t, val.Type, val.Format, val.Expected, rt)
   126  	}
   127  
   128  	// arrays of primitives and string formats
   129  	for _, val := range schTypeVals() {
   130  		var sch spec.Schema
   131  		sch.Typed(val.Type, val.Format)
   132  		rt, err := resolver.ResolveSchema(new(spec.Schema).CollectionOf(sch), true, true)
   133  		require.NoError(t, err)
   134  
   135  		assert.True(t, rt.IsArray)
   136  		assert.False(t, rt.IsEmptyOmitted)
   137  
   138  		s := new(spec.Schema).CollectionOf(sch)
   139  		s.AddExtension(xOmitEmpty, false)
   140  		rt, err = resolver.ResolveSchema(s, true, true)
   141  		require.NoError(t, err)
   142  
   143  		assert.True(t, rt.IsArray)
   144  		assert.False(t, rt.IsEmptyOmitted)
   145  
   146  		s = new(spec.Schema).CollectionOf(sch)
   147  		s.AddExtension(xOmitEmpty, true)
   148  		rt, err = resolver.ResolveSchema(s, true, true)
   149  		require.NoError(t, err)
   150  
   151  		assert.True(t, rt.IsArray)
   152  		assert.True(t, rt.IsEmptyOmitted)
   153  	}
   154  
   155  	// primitives and string formats
   156  	for _, val := range schTypeVals() {
   157  		sch := new(spec.Schema)
   158  		sch.Typed(val.Type, val.Format)
   159  		sch.Extensions = make(spec.Extensions)
   160  		sch.Extensions[xIsNullable] = true
   161  
   162  		rt, err := resolver.ResolveSchema(sch, true, false)
   163  		require.NoError(t, err)
   164  
   165  		if val.Type == "file" {
   166  			assert.False(t, rt.IsNullable, "expected %q (%q) to not be nullable", val.Type, val.Format)
   167  		} else {
   168  			assert.True(t, rt.IsNullable, "expected %q (%q) to be nullable", val.Type, val.Format)
   169  		}
   170  		assertPrimitiveResolve(t, val.Type, val.Format, val.Expected, rt)
   171  
   172  		// Test x-nullable overrides x-isnullable
   173  		sch.Extensions[xIsNullable] = false
   174  		sch.Extensions[xNullable] = true
   175  		rt, err = resolver.ResolveSchema(sch, true, true)
   176  		require.NoError(t, err)
   177  
   178  		if val.Type == "file" {
   179  			assert.False(t, rt.IsNullable, "expected %q (%q) to not be nullable", val.Type, val.Format)
   180  		} else {
   181  			assert.True(t, rt.IsNullable, "expected %q (%q) to be nullable", val.Type, val.Format)
   182  		}
   183  		assertPrimitiveResolve(t, val.Type, val.Format, val.Expected, rt)
   184  
   185  		// Test x-nullable without x-isnullable
   186  		delete(sch.Extensions, xIsNullable)
   187  		sch.Extensions[xNullable] = true
   188  		rt, err = resolver.ResolveSchema(sch, true, true)
   189  		require.NoError(t, err)
   190  
   191  		if val.Type == "file" {
   192  			assert.False(t, rt.IsNullable, "expected %q (%q) to not be nullable", val.Type, val.Format)
   193  		} else {
   194  			assert.True(t, rt.IsNullable, "expected %q (%q) to be nullable", val.Type, val.Format)
   195  		}
   196  		assertPrimitiveResolve(t, val.Type, val.Format, val.Expected, rt)
   197  	}
   198  
   199  	// arrays of primitives and string formats
   200  	for _, val := range schTypeVals() {
   201  		var sch spec.Schema
   202  		sch.Typed(val.Type, val.Format)
   203  		sch.AddExtension(xIsNullable, true)
   204  
   205  		rt, err := resolver.ResolveSchema(new(spec.Schema).CollectionOf(sch), true, true)
   206  		require.NoError(t, err)
   207  
   208  		assert.True(t, rt.IsArray)
   209  	}
   210  }
   211  
   212  func TestTypeResolver_Refs(t *testing.T) {
   213  
   214  	_, resolver, e := basicTaskListResolver(t)
   215  	require.NoError(t, e)
   216  
   217  	// referenced objects
   218  	for _, val := range schRefVals() {
   219  		sch := new(spec.Schema)
   220  		sch.Ref, _ = spec.NewRef("#/definitions/" + val.Type)
   221  
   222  		rt, err := resolver.ResolveSchema(sch, true, true)
   223  		require.NoError(t, err)
   224  
   225  		assert.Equal(t, val.Expected, rt.GoType)
   226  		assert.False(t, rt.IsAnonymous)
   227  		assert.True(t, rt.IsNullable)
   228  		assert.Equal(t, "object", rt.SwaggerType)
   229  	}
   230  
   231  	// referenced array objects
   232  	for _, val := range schRefVals() {
   233  		sch := new(spec.Schema)
   234  		sch.Ref, _ = spec.NewRef("#/definitions/" + val.Type)
   235  
   236  		rt, err := resolver.ResolveSchema(new(spec.Schema).CollectionOf(*sch), true, true)
   237  		require.NoError(t, err)
   238  
   239  		assert.True(t, rt.IsArray)
   240  		assert.Equal(t, "[]"+val.Expected, rt.GoType)
   241  	}
   242  	// for named objects
   243  	// referenced objects
   244  	for _, val := range schRefVals() {
   245  		sch := new(spec.Schema)
   246  		sch.Ref, _ = spec.NewRef("#/definitions/" + val.Type)
   247  
   248  		rt, err := resolver.ResolveSchema(sch, false, true)
   249  		require.NoError(t, err)
   250  
   251  		assert.Equal(t, val.Expected, rt.GoType)
   252  		assert.False(t, rt.IsAnonymous)
   253  		assert.True(t, rt.IsNullable)
   254  		assert.Equal(t, "object", rt.SwaggerType)
   255  	}
   256  
   257  	// referenced array objects
   258  	for _, val := range schRefVals() {
   259  		sch := new(spec.Schema)
   260  		sch.Ref, _ = spec.NewRef("#/definitions/" + val.Type)
   261  
   262  		rt, err := resolver.ResolveSchema(new(spec.Schema).CollectionOf(*sch), false, true)
   263  		require.NoError(t, err)
   264  
   265  		assert.True(t, rt.IsArray)
   266  		assert.Equal(t, "[]"+val.Expected, rt.GoType)
   267  	}
   268  }
   269  
   270  func TestTypeResolver_AdditionalProperties(t *testing.T) {
   271  	_, resolver, err := basicTaskListResolver(t)
   272  	require.NoError(t, err)
   273  
   274  	// primitives as additional properties
   275  	for _, val := range schTypeVals() {
   276  		sch := new(spec.Schema)
   277  
   278  		sch.Typed(val.Type, val.Format)
   279  		parent := new(spec.Schema)
   280  		parent.AdditionalProperties = new(spec.SchemaOrBool)
   281  		parent.AdditionalProperties.Schema = sch
   282  
   283  		rt, err := resolver.ResolveSchema(parent, true, false)
   284  		require.NoError(t, err)
   285  
   286  		assert.True(t, rt.IsMap)
   287  		assert.False(t, rt.IsComplexObject)
   288  		assert.Equal(t, "map[string]"+val.Expected, rt.GoType)
   289  		assert.Equal(t, "object", rt.SwaggerType)
   290  	}
   291  
   292  	// array of primitives as additional properties
   293  	for _, val := range schTypeVals() {
   294  		sch := new(spec.Schema)
   295  
   296  		sch.Typed(val.Type, val.Format)
   297  		parent := new(spec.Schema)
   298  		parent.AdditionalProperties = new(spec.SchemaOrBool)
   299  		parent.AdditionalProperties.Schema = new(spec.Schema).CollectionOf(*sch)
   300  
   301  		rt, err := resolver.ResolveSchema(parent, true, false)
   302  		require.NoError(t, err)
   303  
   304  		assert.True(t, rt.IsMap)
   305  		assert.False(t, rt.IsComplexObject)
   306  		assert.Equal(t, "map[string][]"+val.Expected, rt.GoType)
   307  		assert.Equal(t, "object", rt.SwaggerType)
   308  	}
   309  
   310  	// refs as additional properties
   311  	for _, val := range schRefVals() {
   312  		sch := new(spec.Schema)
   313  		sch.Ref, _ = spec.NewRef("#/definitions/" + val.Type)
   314  		parent := new(spec.Schema)
   315  		parent.AdditionalProperties = new(spec.SchemaOrBool)
   316  		parent.AdditionalProperties.Schema = sch
   317  
   318  		rt, err := resolver.ResolveSchema(parent, true, true)
   319  		require.NoError(t, err)
   320  
   321  		assert.True(t, rt.IsMap)
   322  		assert.False(t, rt.IsComplexObject)
   323  		assert.Equal(t, "map[string]"+val.Expected, rt.GoType)
   324  		assert.Equal(t, "object", rt.SwaggerType)
   325  	}
   326  
   327  	// when additional properties and properties present, it's a complex object
   328  
   329  	// primitives as additional properties
   330  	for _, val := range schTypeVals() {
   331  		sch := new(spec.Schema)
   332  
   333  		sch.Typed(val.Type, val.Format)
   334  		parent := new(spec.Schema)
   335  		parent.Properties = make(map[string]spec.Schema)
   336  		parent.Properties["id"] = *spec.Int32Property()
   337  		parent.AdditionalProperties = new(spec.SchemaOrBool)
   338  		parent.AdditionalProperties.Schema = sch
   339  
   340  		rt, err := resolver.ResolveSchema(parent, true, true)
   341  		require.NoError(t, err)
   342  
   343  		assert.True(t, rt.IsComplexObject)
   344  		assert.False(t, rt.IsMap)
   345  		assert.Equal(t, "map[string]"+val.Expected, rt.GoType)
   346  		assert.Equal(t, "object", rt.SwaggerType)
   347  	}
   348  
   349  	// array of primitives as additional properties
   350  	for _, val := range schTypeVals() {
   351  		sch := new(spec.Schema)
   352  
   353  		sch.Typed(val.Type, val.Format)
   354  		parent := new(spec.Schema)
   355  		parent.Properties = make(map[string]spec.Schema)
   356  		parent.Properties["id"] = *spec.Int32Property()
   357  		parent.AdditionalProperties = new(spec.SchemaOrBool)
   358  		parent.AdditionalProperties.Schema = new(spec.Schema).CollectionOf(*sch)
   359  
   360  		rt, err := resolver.ResolveSchema(parent, true, true)
   361  		require.NoError(t, err)
   362  
   363  		assert.True(t, rt.IsComplexObject)
   364  		assert.False(t, rt.IsMap)
   365  		assert.Equal(t, "map[string][]"+val.Expected, rt.GoType)
   366  		assert.Equal(t, "object", rt.SwaggerType)
   367  	}
   368  
   369  	// refs as additional properties
   370  	for _, val := range schRefVals() {
   371  		sch := new(spec.Schema)
   372  		sch.Ref, _ = spec.NewRef("#/definitions/" + val.Type)
   373  		parent := new(spec.Schema)
   374  		parent.Properties = make(map[string]spec.Schema)
   375  		parent.Properties["id"] = *spec.Int32Property()
   376  		parent.AdditionalProperties = new(spec.SchemaOrBool)
   377  		parent.AdditionalProperties.Schema = sch
   378  
   379  		rt, err := resolver.ResolveSchema(parent, true, true)
   380  		require.NoError(t, err)
   381  
   382  		assert.True(t, rt.IsComplexObject)
   383  		assert.False(t, rt.IsMap)
   384  		assert.Equal(t, "map[string]"+val.Expected, rt.GoType)
   385  		assert.Equal(t, "object", rt.SwaggerType)
   386  	}
   387  }
   388  
   389  func TestTypeResolver_Notables(t *testing.T) {
   390  	doc, resolver, err := specResolver(t, "../fixtures/codegen/todolist.models.yml")
   391  	require.NoError(t, err)
   392  
   393  	def := doc.Spec().Definitions["Notables"]
   394  	rest, err := resolver.ResolveSchema(&def, false, true)
   395  	require.NoError(t, err)
   396  
   397  	assert.True(t, rest.IsArray)
   398  	assert.False(t, rest.IsAnonymous)
   399  	assert.False(t, rest.IsNullable)
   400  	assert.Equal(t, "[]models.Notable", rest.GoType)
   401  }
   402  
   403  func specResolver(t testing.TB, path string) (*loads.Document, *typeResolver, error) {
   404  	tlb, err := loads.Spec(path)
   405  	if err != nil {
   406  		return nil, nil, err
   407  	}
   408  	resolver := &typeResolver{
   409  		Doc:           tlb,
   410  		ModelsPackage: "models",
   411  	}
   412  	resolver.KnownDefs = make(map[string]struct{})
   413  	for k := range tlb.Spec().Definitions {
   414  		resolver.KnownDefs[k] = struct{}{}
   415  	}
   416  	return tlb, resolver, nil
   417  }
   418  
   419  func basicTaskListResolver(t testing.TB) (*loads.Document, *typeResolver, error) {
   420  	tlb, err := loads.Spec("../fixtures/codegen/tasklist.basic.yml")
   421  	if err != nil {
   422  		return nil, nil, err
   423  	}
   424  	swsp := tlb.Spec()
   425  	uc := swsp.Definitions["UserCard"]
   426  	uc.AddExtension(xGoName, "UserItem")
   427  	swsp.Definitions["UserCard"] = uc
   428  	resolver := &typeResolver{
   429  		Doc:           tlb,
   430  		ModelsPackage: "models",
   431  	}
   432  
   433  	resolver.KnownDefs = make(map[string]struct{})
   434  	for k, sch := range swsp.Definitions {
   435  		resolver.KnownDefs[k] = struct{}{}
   436  		if nm, ok := sch.Extensions[xGoName]; ok {
   437  			resolver.KnownDefs[nm.(string)] = struct{}{}
   438  		}
   439  	}
   440  	return tlb, resolver, nil
   441  }
   442  
   443  func TestTypeResolver_TupleTypes(t *testing.T) {
   444  	_, resolver, err := basicTaskListResolver(t)
   445  	require.NoError(t, err)
   446  
   447  	// tuple type (items with multiple schemas)
   448  	parent := new(spec.Schema)
   449  	parent.Typed("array", "")
   450  	parent.Items = new(spec.SchemaOrArray)
   451  	parent.Items.Schemas = append(
   452  		parent.Items.Schemas,
   453  		*spec.StringProperty(),
   454  		*spec.Int64Property(),
   455  		*spec.Float64Property(),
   456  		*spec.BoolProperty(),
   457  		*spec.ArrayProperty(spec.StringProperty()),
   458  		*spec.RefProperty("#/definitions/Comment"),
   459  	)
   460  
   461  	rt, err := resolver.ResolveSchema(parent, true, true)
   462  	require.NoError(t, err)
   463  
   464  	assert.False(t, rt.IsArray)
   465  	assert.True(t, rt.IsTuple)
   466  }
   467  
   468  func TestTypeResolver_AnonymousStructs(t *testing.T) {
   469  
   470  	_, resolver, err := basicTaskListResolver(t)
   471  	require.NoError(t, err)
   472  
   473  	// anonymous structs should be accounted for
   474  	parent := new(spec.Schema)
   475  	parent.Typed("object", "")
   476  	parent.Properties = make(map[string]spec.Schema)
   477  	parent.Properties["name"] = *spec.StringProperty()
   478  	parent.Properties["age"] = *spec.Int32Property()
   479  
   480  	rt, err := resolver.ResolveSchema(parent, true, true)
   481  	require.NoError(t, err)
   482  
   483  	assert.True(t, rt.IsNullable)
   484  	assert.True(t, rt.IsAnonymous)
   485  	assert.True(t, rt.IsComplexObject)
   486  
   487  	parent.Extensions = make(spec.Extensions)
   488  	parent.Extensions[xIsNullable] = true
   489  
   490  	rt, err = resolver.ResolveSchema(parent, true, true)
   491  	require.NoError(t, err)
   492  
   493  	assert.True(t, rt.IsNullable)
   494  	assert.True(t, rt.IsAnonymous)
   495  	assert.True(t, rt.IsComplexObject)
   496  
   497  	// Also test that it's nullable with just x-nullable
   498  	parent.Extensions[xIsNullable] = false
   499  	parent.Extensions[xNullable] = false
   500  
   501  	rt, err = resolver.ResolveSchema(parent, true, true)
   502  	require.NoError(t, err)
   503  
   504  	assert.False(t, rt.IsNullable)
   505  	assert.True(t, rt.IsAnonymous)
   506  	assert.True(t, rt.IsComplexObject)
   507  }
   508  
   509  func TestTypeResolver_ObjectType(t *testing.T) {
   510  	_, resolver, e := basicTaskListResolver(t)
   511  	require.NoError(t, e)
   512  
   513  	resolver.ModelName = "TheModel"
   514  	resolver.KnownDefs["TheModel"] = struct{}{}
   515  	defer func() { resolver.ModelName = "" }()
   516  
   517  	//very poor schema definitions (as in none)
   518  	types := []string{"object", ""}
   519  	for _, tpe := range types {
   520  		sch := new(spec.Schema)
   521  		sch.Typed(tpe, "")
   522  		rt, err := resolver.ResolveSchema(sch, true, true)
   523  		require.NoError(t, err)
   524  
   525  		assert.True(t, rt.IsMap)
   526  		assert.False(t, rt.IsComplexObject)
   527  		assert.Equal(t, "interface{}", rt.GoType)
   528  		assert.Equal(t, "object", rt.SwaggerType)
   529  
   530  		sch.Properties = make(map[string]spec.Schema)
   531  		var ss spec.Schema
   532  		sch.Properties["tags"] = *(&ss).CollectionOf(*spec.StringProperty())
   533  		rt, err = resolver.ResolveSchema(sch, false, true)
   534  		require.NoError(t, err)
   535  
   536  		assert.True(t, rt.IsComplexObject)
   537  		assert.False(t, rt.IsMap)
   538  		assert.Equal(t, "models.TheModel", rt.GoType)
   539  		assert.Equal(t, "object", rt.SwaggerType)
   540  
   541  		sch.Properties = nil
   542  		nsch := new(spec.Schema)
   543  		nsch.Typed(tpe, "")
   544  		nsch.AllOf = []spec.Schema{*sch}
   545  		rt, err = resolver.ResolveSchema(nsch, false, true)
   546  		require.NoError(t, err)
   547  
   548  		assert.True(t, rt.IsComplexObject)
   549  		assert.False(t, rt.IsMap)
   550  		assert.Equal(t, "models.TheModel", rt.GoType)
   551  		assert.Equal(t, "object", rt.SwaggerType)
   552  
   553  		sch = new(spec.Schema)
   554  		rt, err = resolver.ResolveSchema(sch, true, true)
   555  		require.NoError(t, err)
   556  
   557  		assert.True(t, rt.IsMap)
   558  		assert.False(t, rt.IsComplexObject)
   559  		assert.Equal(t, "interface{}", rt.GoType)
   560  		assert.Equal(t, "object", rt.SwaggerType)
   561  
   562  		sch = new(spec.Schema)
   563  		var sp spec.Schema
   564  		sp.Typed("object", "")
   565  		sch.AllOf = []spec.Schema{sp}
   566  		rt, err = resolver.ResolveSchema(sch, true, true)
   567  		require.NoError(t, err)
   568  
   569  		assert.True(t, rt.IsComplexObject)
   570  		assert.False(t, rt.IsMap)
   571  		assert.Equal(t, "models.TheModel", rt.GoType)
   572  		assert.Equal(t, "object", rt.SwaggerType)
   573  	}
   574  }
   575  
   576  func TestTypeResolver_AliasTypes(t *testing.T) {
   577  	doc, resolver, err := basicTaskListResolver(t)
   578  	require.NoError(t, err)
   579  
   580  	resolver.ModelsPackage = ""
   581  	resolver.ModelName = "Currency"
   582  	defer func() {
   583  		resolver.ModelName = ""
   584  		resolver.ModelsPackage = "models"
   585  	}()
   586  
   587  	defs := doc.Spec().Definitions[resolver.ModelName]
   588  	rt, err := resolver.ResolveSchema(&defs, false, true)
   589  	require.NoError(t, err)
   590  
   591  	assert.False(t, rt.IsAnonymous)
   592  	assert.True(t, rt.IsAliased)
   593  	assert.True(t, rt.IsPrimitive)
   594  	assert.Equal(t, "Currency", rt.GoType)
   595  	assert.Equal(t, "string", rt.AliasedType)
   596  }
   597  
   598  func assertPrimitiveResolve(t testing.TB, tpe, tfmt, exp string, tr resolvedType) {
   599  	assert.Equal(t, tpe, tr.SwaggerType, fmt.Sprintf("expected %q (%q, %q) to for the swagger type but got %q", tpe, tfmt, exp, tr.SwaggerType))
   600  	assert.Equal(t, tfmt, tr.SwaggerFormat, fmt.Sprintf("expected %q (%q, %q) to for the swagger format but got %q", tfmt, tpe, exp, tr.SwaggerFormat))
   601  	assert.Equal(t, exp, tr.GoType, fmt.Sprintf("expected %q (%q, %q) to for the go type but got %q", exp, tpe, tfmt, tr.GoType))
   602  }
   603  
   604  func TestTypeResolver_ExistingModel(t *testing.T) {
   605  	doc, err := loads.Spec("../fixtures/codegen/existing-model.yml")
   606  	resolver := newTypeResolver("model", doc)
   607  	require.NoError(t, err)
   608  
   609  	def := doc.Spec().Definitions["JsonWebKey"]
   610  	tpe, pkg, alias := knownDefGoType("JsonWebKey", def, nil)
   611  	assert.Equal(t, "jwk.Key", tpe)
   612  	assert.Equal(t, "github.com/user/package", pkg)
   613  	assert.Equal(t, "jwk", alias)
   614  	rest, err := resolver.ResolveSchema(&def, false, true)
   615  	require.NoError(t, err)
   616  
   617  	assert.False(t, rest.IsMap)
   618  	assert.False(t, rest.IsArray)
   619  	assert.False(t, rest.IsTuple)
   620  	assert.False(t, rest.IsStream)
   621  	assert.False(t, rest.IsAliased)
   622  	assert.False(t, rest.IsBaseType)
   623  	assert.False(t, rest.IsInterface)
   624  	assert.True(t, rest.IsNullable)
   625  	assert.False(t, rest.IsPrimitive)
   626  	assert.False(t, rest.IsAnonymous)
   627  	assert.True(t, rest.IsComplexObject)
   628  	assert.False(t, rest.IsCustomFormatter)
   629  	assert.Equal(t, "jwk.Key", rest.GoType)
   630  	assert.Equal(t, "github.com/user/package", rest.Pkg)
   631  	assert.Equal(t, "jwk", rest.PkgAlias)
   632  
   633  	def = doc.Spec().Definitions["JsonWebKeySet"].Properties["keys"]
   634  	rest, err = resolver.ResolveSchema(&def, false, true)
   635  	require.NoError(t, err)
   636  
   637  	assert.False(t, rest.IsMap)
   638  	assert.True(t, rest.IsArray)
   639  	assert.False(t, rest.IsTuple)
   640  	assert.False(t, rest.IsStream)
   641  	assert.False(t, rest.IsAliased)
   642  	assert.False(t, rest.IsBaseType)
   643  	assert.False(t, rest.IsInterface)
   644  	assert.False(t, rest.IsNullable)
   645  	assert.False(t, rest.IsPrimitive)
   646  	assert.False(t, rest.IsAnonymous)
   647  	assert.False(t, rest.IsComplexObject)
   648  	assert.False(t, rest.IsCustomFormatter)
   649  	assert.Equal(t, "[]jwk.Key", rest.GoType)
   650  	assert.Equal(t, "", rest.Pkg)
   651  	assert.Equal(t, "", rest.PkgAlias)
   652  }