github.com/AngusLu/go-swagger@v0.28.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  		// now this behavior has moved down to the type resolver:
   241  		// * it used to be hidden to the type resolver, but rendered like that eventually
   242  		assert.Equal(t, "[]*"+val.Expected, rt.GoType)
   243  	}
   244  	// for named objects
   245  	// referenced objects
   246  	for _, val := range schRefVals() {
   247  		sch := new(spec.Schema)
   248  		sch.Ref, _ = spec.NewRef("#/definitions/" + val.Type)
   249  
   250  		rt, err := resolver.ResolveSchema(sch, false, true)
   251  		require.NoError(t, err)
   252  
   253  		assert.Equal(t, val.Expected, rt.GoType)
   254  		assert.False(t, rt.IsAnonymous)
   255  		assert.True(t, rt.IsNullable)
   256  		assert.Equal(t, "object", rt.SwaggerType)
   257  	}
   258  
   259  	// referenced array objects
   260  	for _, val := range schRefVals() {
   261  		sch := new(spec.Schema)
   262  		sch.Ref, _ = spec.NewRef("#/definitions/" + val.Type)
   263  
   264  		rt, err := resolver.ResolveSchema(new(spec.Schema).CollectionOf(*sch), false, true)
   265  		require.NoError(t, err)
   266  
   267  		assert.True(t, rt.IsArray)
   268  		// now this behavior has moved down to the type resolver:
   269  		// * it used to be hidden to the type resolver, but rendered like that eventually
   270  		assert.Equal(t, "[]*"+val.Expected, rt.GoType)
   271  	}
   272  }
   273  
   274  func TestTypeResolver_AdditionalProperties(t *testing.T) {
   275  	_, resolver, err := basicTaskListResolver(t)
   276  	require.NoError(t, err)
   277  
   278  	// primitives as additional properties
   279  	for _, val := range schTypeVals() {
   280  		sch := new(spec.Schema)
   281  
   282  		sch.Typed(val.Type, val.Format)
   283  		parent := new(spec.Schema)
   284  		parent.AdditionalProperties = new(spec.SchemaOrBool)
   285  		parent.AdditionalProperties.Schema = sch
   286  
   287  		rt, err := resolver.ResolveSchema(parent, true, false)
   288  		require.NoError(t, err)
   289  
   290  		assert.True(t, rt.IsMap)
   291  		assert.False(t, rt.IsComplexObject)
   292  		assert.Equal(t, "map[string]"+val.Expected, rt.GoType)
   293  		assert.Equal(t, "object", rt.SwaggerType)
   294  	}
   295  
   296  	// array of primitives as additional properties
   297  	for _, val := range schTypeVals() {
   298  		sch := new(spec.Schema)
   299  
   300  		sch.Typed(val.Type, val.Format)
   301  		parent := new(spec.Schema)
   302  		parent.AdditionalProperties = new(spec.SchemaOrBool)
   303  		parent.AdditionalProperties.Schema = new(spec.Schema).CollectionOf(*sch)
   304  
   305  		rt, err := resolver.ResolveSchema(parent, true, false)
   306  		require.NoError(t, err)
   307  
   308  		assert.True(t, rt.IsMap)
   309  		assert.False(t, rt.IsComplexObject)
   310  		assert.Equal(t, "map[string][]"+val.Expected, rt.GoType)
   311  		assert.Equal(t, "object", rt.SwaggerType)
   312  	}
   313  
   314  	// refs as additional properties
   315  	for _, val := range schRefVals() {
   316  		sch := new(spec.Schema)
   317  		sch.Ref, _ = spec.NewRef("#/definitions/" + val.Type)
   318  		parent := new(spec.Schema)
   319  		parent.AdditionalProperties = new(spec.SchemaOrBool)
   320  		parent.AdditionalProperties.Schema = sch
   321  
   322  		rt, err := resolver.ResolveSchema(parent, true, true)
   323  		require.NoError(t, err)
   324  
   325  		assert.True(t, rt.IsMap)
   326  		assert.False(t, rt.IsComplexObject)
   327  		assert.Equal(t, "map[string]"+val.Expected, rt.GoType)
   328  		assert.Equal(t, "object", rt.SwaggerType)
   329  	}
   330  
   331  	// when additional properties and properties present, it's a complex object
   332  
   333  	// primitives as additional properties
   334  	for _, val := range schTypeVals() {
   335  		sch := new(spec.Schema)
   336  
   337  		sch.Typed(val.Type, val.Format)
   338  		parent := new(spec.Schema)
   339  		parent.Properties = make(map[string]spec.Schema)
   340  		parent.Properties["id"] = *spec.Int32Property()
   341  		parent.AdditionalProperties = new(spec.SchemaOrBool)
   342  		parent.AdditionalProperties.Schema = sch
   343  
   344  		rt, err := resolver.ResolveSchema(parent, true, true)
   345  		require.NoError(t, err)
   346  
   347  		assert.True(t, rt.IsComplexObject)
   348  		assert.False(t, rt.IsMap)
   349  		assert.Equal(t, "map[string]"+val.Expected, rt.GoType)
   350  		assert.Equal(t, "object", rt.SwaggerType)
   351  	}
   352  
   353  	// array of primitives as additional properties
   354  	for _, val := range schTypeVals() {
   355  		sch := new(spec.Schema)
   356  
   357  		sch.Typed(val.Type, val.Format)
   358  		parent := new(spec.Schema)
   359  		parent.Properties = make(map[string]spec.Schema)
   360  		parent.Properties["id"] = *spec.Int32Property()
   361  		parent.AdditionalProperties = new(spec.SchemaOrBool)
   362  		parent.AdditionalProperties.Schema = new(spec.Schema).CollectionOf(*sch)
   363  
   364  		rt, err := resolver.ResolveSchema(parent, true, true)
   365  		require.NoError(t, err)
   366  
   367  		assert.True(t, rt.IsComplexObject)
   368  		assert.False(t, rt.IsMap)
   369  		assert.Equal(t, "map[string][]"+val.Expected, rt.GoType)
   370  		assert.Equal(t, "object", rt.SwaggerType)
   371  	}
   372  
   373  	// refs as additional properties
   374  	for _, val := range schRefVals() {
   375  		sch := new(spec.Schema)
   376  		sch.Ref, _ = spec.NewRef("#/definitions/" + val.Type)
   377  		parent := new(spec.Schema)
   378  		parent.Properties = make(map[string]spec.Schema)
   379  		parent.Properties["id"] = *spec.Int32Property()
   380  		parent.AdditionalProperties = new(spec.SchemaOrBool)
   381  		parent.AdditionalProperties.Schema = sch
   382  
   383  		rt, err := resolver.ResolveSchema(parent, true, true)
   384  		require.NoError(t, err)
   385  
   386  		assert.True(t, rt.IsComplexObject)
   387  		assert.False(t, rt.IsMap)
   388  		assert.Equal(t, "map[string]"+val.Expected, rt.GoType)
   389  		assert.Equal(t, "object", rt.SwaggerType)
   390  	}
   391  }
   392  
   393  func TestTypeResolver_Notables(t *testing.T) {
   394  	doc, resolver, err := specResolver(t, "../fixtures/codegen/todolist.models.yml")
   395  	require.NoError(t, err)
   396  
   397  	def := doc.Spec().Definitions["Notables"]
   398  	rest, err := resolver.ResolveSchema(&def, false, true)
   399  	require.NoError(t, err)
   400  
   401  	assert.True(t, rest.IsArray)
   402  	assert.False(t, rest.IsAnonymous)
   403  	assert.False(t, rest.IsNullable)
   404  	assert.Equal(t, "[]*models.Notable", rest.GoType)
   405  }
   406  
   407  func specResolver(t testing.TB, path string) (*loads.Document, *typeResolver, error) {
   408  	tlb, err := loads.Spec(path)
   409  	if err != nil {
   410  		return nil, nil, err
   411  	}
   412  	resolver := &typeResolver{
   413  		Doc:           tlb,
   414  		ModelsPackage: "models",
   415  	}
   416  	resolver.KnownDefs = make(map[string]struct{})
   417  	for k := range tlb.Spec().Definitions {
   418  		resolver.KnownDefs[k] = struct{}{}
   419  	}
   420  	return tlb, resolver, nil
   421  }
   422  
   423  func basicTaskListResolver(t testing.TB) (*loads.Document, *typeResolver, error) {
   424  	tlb, err := loads.Spec("../fixtures/codegen/tasklist.basic.yml")
   425  	if err != nil {
   426  		return nil, nil, err
   427  	}
   428  	swsp := tlb.Spec()
   429  	uc := swsp.Definitions["UserCard"]
   430  	uc.AddExtension(xGoName, "UserItem")
   431  	swsp.Definitions["UserCard"] = uc
   432  	resolver := &typeResolver{
   433  		Doc:           tlb,
   434  		ModelsPackage: "models",
   435  	}
   436  
   437  	resolver.KnownDefs = make(map[string]struct{})
   438  	for k, sch := range swsp.Definitions {
   439  		resolver.KnownDefs[k] = struct{}{}
   440  		if nm, ok := sch.Extensions[xGoName]; ok {
   441  			resolver.KnownDefs[nm.(string)] = struct{}{}
   442  		}
   443  	}
   444  	return tlb, resolver, nil
   445  }
   446  
   447  func TestTypeResolver_TupleTypes(t *testing.T) {
   448  	_, resolver, err := basicTaskListResolver(t)
   449  	require.NoError(t, err)
   450  
   451  	// tuple type (items with multiple schemas)
   452  	parent := new(spec.Schema)
   453  	parent.Typed("array", "")
   454  	parent.Items = new(spec.SchemaOrArray)
   455  	parent.Items.Schemas = append(
   456  		parent.Items.Schemas,
   457  		*spec.StringProperty(),
   458  		*spec.Int64Property(),
   459  		*spec.Float64Property(),
   460  		*spec.BoolProperty(),
   461  		*spec.ArrayProperty(spec.StringProperty()),
   462  		*spec.RefProperty("#/definitions/Comment"),
   463  	)
   464  
   465  	rt, err := resolver.ResolveSchema(parent, true, true)
   466  	require.NoError(t, err)
   467  
   468  	assert.False(t, rt.IsArray)
   469  	assert.True(t, rt.IsTuple)
   470  }
   471  
   472  func TestTypeResolver_AnonymousStructs(t *testing.T) {
   473  
   474  	_, resolver, err := basicTaskListResolver(t)
   475  	require.NoError(t, err)
   476  
   477  	// anonymous structs should be accounted for
   478  	parent := new(spec.Schema)
   479  	parent.Typed("object", "")
   480  	parent.Properties = make(map[string]spec.Schema)
   481  	parent.Properties["name"] = *spec.StringProperty()
   482  	parent.Properties["age"] = *spec.Int32Property()
   483  
   484  	rt, err := resolver.ResolveSchema(parent, true, true)
   485  	require.NoError(t, err)
   486  
   487  	assert.True(t, rt.IsNullable)
   488  	assert.True(t, rt.IsAnonymous)
   489  	assert.True(t, rt.IsComplexObject)
   490  
   491  	parent.Extensions = make(spec.Extensions)
   492  	parent.Extensions[xIsNullable] = true
   493  
   494  	rt, err = resolver.ResolveSchema(parent, true, true)
   495  	require.NoError(t, err)
   496  
   497  	assert.True(t, rt.IsNullable)
   498  	assert.True(t, rt.IsAnonymous)
   499  	assert.True(t, rt.IsComplexObject)
   500  
   501  	// Also test that it's nullable with just x-nullable
   502  	parent.Extensions[xIsNullable] = false
   503  	parent.Extensions[xNullable] = false
   504  
   505  	rt, err = resolver.ResolveSchema(parent, true, true)
   506  	require.NoError(t, err)
   507  
   508  	assert.False(t, rt.IsNullable)
   509  	assert.True(t, rt.IsAnonymous)
   510  	assert.True(t, rt.IsComplexObject)
   511  }
   512  
   513  func TestTypeResolver_ObjectType(t *testing.T) {
   514  	_, resolver, e := basicTaskListResolver(t)
   515  	require.NoError(t, e)
   516  
   517  	resolver.ModelName = "TheModel"
   518  	resolver.KnownDefs["TheModel"] = struct{}{}
   519  	defer func() { resolver.ModelName = "" }()
   520  
   521  	// very poor schema definitions (as in none)
   522  	types := []string{"object", ""}
   523  	for _, tpe := range types {
   524  		sch := new(spec.Schema)
   525  		sch.Typed(tpe, "")
   526  		rt, err := resolver.ResolveSchema(sch, true, true)
   527  		require.NoError(t, err)
   528  
   529  		assert.True(t, rt.IsMap)
   530  		assert.False(t, rt.IsComplexObject)
   531  		assert.Equal(t, "interface{}", rt.GoType)
   532  		assert.Equal(t, "object", rt.SwaggerType)
   533  
   534  		sch.Properties = make(map[string]spec.Schema)
   535  		var ss spec.Schema
   536  		sch.Properties["tags"] = *(&ss).CollectionOf(*spec.StringProperty())
   537  		rt, err = resolver.ResolveSchema(sch, false, true)
   538  		require.NoError(t, err)
   539  
   540  		assert.True(t, rt.IsComplexObject)
   541  		assert.False(t, rt.IsMap)
   542  		assert.Equal(t, "models.TheModel", rt.GoType)
   543  		assert.Equal(t, "object", rt.SwaggerType)
   544  
   545  		sch.Properties = nil
   546  		nsch := new(spec.Schema)
   547  		nsch.Typed(tpe, "")
   548  		nsch.AllOf = []spec.Schema{*sch}
   549  		rt, err = resolver.ResolveSchema(nsch, false, true)
   550  		require.NoError(t, err)
   551  
   552  		assert.True(t, rt.IsComplexObject)
   553  		assert.False(t, rt.IsMap)
   554  		assert.Equal(t, "models.TheModel", rt.GoType)
   555  		assert.Equal(t, "object", rt.SwaggerType)
   556  
   557  		sch = new(spec.Schema)
   558  		rt, err = resolver.ResolveSchema(sch, true, true)
   559  		require.NoError(t, err)
   560  
   561  		assert.True(t, rt.IsMap)
   562  		assert.False(t, rt.IsComplexObject)
   563  		assert.Equal(t, "interface{}", rt.GoType)
   564  		assert.Equal(t, "object", rt.SwaggerType)
   565  
   566  		sch = new(spec.Schema)
   567  		var sp spec.Schema
   568  		sp.Typed("object", "")
   569  		sch.AllOf = []spec.Schema{sp}
   570  		rt, err = resolver.ResolveSchema(sch, true, true)
   571  		require.NoError(t, err)
   572  
   573  		assert.True(t, rt.IsComplexObject)
   574  		assert.False(t, rt.IsMap)
   575  		assert.Equal(t, "models.TheModel", rt.GoType)
   576  		assert.Equal(t, "object", rt.SwaggerType)
   577  	}
   578  }
   579  
   580  func TestTypeResolver_AliasTypes(t *testing.T) {
   581  	doc, resolver, err := basicTaskListResolver(t)
   582  	require.NoError(t, err)
   583  
   584  	resolver.ModelsPackage = ""
   585  	resolver.ModelName = "Currency"
   586  	defer func() {
   587  		resolver.ModelName = ""
   588  		resolver.ModelsPackage = "models"
   589  	}()
   590  
   591  	defs := doc.Spec().Definitions[resolver.ModelName]
   592  	rt, err := resolver.ResolveSchema(&defs, false, true)
   593  	require.NoError(t, err)
   594  
   595  	assert.False(t, rt.IsAnonymous)
   596  	assert.True(t, rt.IsAliased)
   597  	assert.True(t, rt.IsPrimitive)
   598  	assert.Equal(t, "Currency", rt.GoType)
   599  	assert.Equal(t, "string", rt.AliasedType)
   600  }
   601  
   602  func assertPrimitiveResolve(t testing.TB, tpe, tfmt, exp string, tr resolvedType) {
   603  	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))
   604  	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))
   605  	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))
   606  }
   607  
   608  func TestTypeResolver_ExistingModel(t *testing.T) {
   609  	doc, err := loads.Spec("../fixtures/codegen/existing-model.yml")
   610  	resolver := newTypeResolver("model", "", doc)
   611  	require.NoError(t, err)
   612  
   613  	def := doc.Spec().Definitions["JsonWebKey"]
   614  	tpe, pkg, alias := resolver.knownDefGoType("JsonWebKey", def, nil)
   615  	assert.Equal(t, "jwk.Key", tpe)
   616  	assert.Equal(t, "github.com/user/package", pkg)
   617  	assert.Equal(t, "jwk", alias)
   618  	rest, err := resolver.ResolveSchema(&def, false, true)
   619  	require.NoError(t, err)
   620  
   621  	assert.False(t, rest.IsMap)
   622  	assert.False(t, rest.IsArray)
   623  	assert.False(t, rest.IsTuple)
   624  	assert.False(t, rest.IsStream)
   625  	assert.True(t, rest.IsAliased)
   626  	assert.False(t, rest.IsBaseType)
   627  	assert.False(t, rest.IsInterface)
   628  	assert.True(t, rest.IsNullable)
   629  	assert.False(t, rest.IsPrimitive)
   630  	assert.False(t, rest.IsAnonymous)
   631  	assert.True(t, rest.IsComplexObject)
   632  	assert.False(t, rest.IsCustomFormatter)
   633  	assert.Equal(t, "jwk.Key", rest.GoType)
   634  	assert.Equal(t, "github.com/user/package", rest.Pkg)
   635  	assert.Equal(t, "jwk", rest.PkgAlias)
   636  
   637  	def = doc.Spec().Definitions["JsonWebKeySet"].Properties["keys"]
   638  	rest, err = resolver.ResolveSchema(&def, false, true)
   639  	require.NoError(t, err)
   640  
   641  	assert.False(t, rest.IsMap)
   642  	assert.True(t, rest.IsArray)
   643  	assert.False(t, rest.IsTuple)
   644  	assert.False(t, rest.IsStream)
   645  	assert.False(t, rest.IsAliased)
   646  	assert.False(t, rest.IsBaseType)
   647  	assert.False(t, rest.IsInterface)
   648  	assert.False(t, rest.IsNullable)
   649  	assert.False(t, rest.IsPrimitive)
   650  	assert.False(t, rest.IsAnonymous)
   651  	assert.False(t, rest.IsComplexObject)
   652  	assert.False(t, rest.IsCustomFormatter)
   653  	assert.Equal(t, "[]*jwk.Key", rest.GoType)
   654  	assert.Equal(t, "", rest.Pkg)
   655  	assert.Equal(t, "", rest.PkgAlias)
   656  }