github.com/go-swagger/go-swagger@v0.31.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  	_, resolver, e := basicTaskListResolver(t)
   113  	require.NoError(t, e)
   114  
   115  	// primitives and string formats
   116  	for _, val := range schTypeVals() {
   117  		sch := new(spec.Schema)
   118  		sch.Typed(val.Type, val.Format)
   119  
   120  		rt, err := resolver.ResolveSchema(sch, true, false)
   121  		require.NoError(t, err)
   122  
   123  		assert.False(t, rt.IsNullable, "expected %s with format %q to not be nullable", val.Type, val.Format)
   124  		assertPrimitiveResolve(t, val.Type, val.Format, val.Expected, rt)
   125  	}
   126  
   127  	// arrays of primitives and string formats
   128  	for _, val := range schTypeVals() {
   129  		var sch spec.Schema
   130  		sch.Typed(val.Type, val.Format)
   131  		rt, err := resolver.ResolveSchema(new(spec.Schema).CollectionOf(sch), true, true)
   132  		require.NoError(t, err)
   133  
   134  		assert.True(t, rt.IsArray)
   135  		assert.False(t, rt.IsEmptyOmitted)
   136  
   137  		s := new(spec.Schema).CollectionOf(sch)
   138  		s.AddExtension(xOmitEmpty, false)
   139  		rt, err = resolver.ResolveSchema(s, true, true)
   140  		require.NoError(t, err)
   141  
   142  		assert.True(t, rt.IsArray)
   143  		assert.False(t, rt.IsEmptyOmitted)
   144  
   145  		s = new(spec.Schema).CollectionOf(sch)
   146  		s.AddExtension(xOmitEmpty, true)
   147  		rt, err = resolver.ResolveSchema(s, true, true)
   148  		require.NoError(t, err)
   149  
   150  		assert.True(t, rt.IsArray)
   151  		assert.True(t, rt.IsEmptyOmitted)
   152  	}
   153  
   154  	// primitives and string formats
   155  	for _, val := range schTypeVals() {
   156  		sch := new(spec.Schema)
   157  		sch.Typed(val.Type, val.Format)
   158  		sch.Extensions = make(spec.Extensions)
   159  		sch.Extensions[xIsNullable] = true
   160  
   161  		rt, err := resolver.ResolveSchema(sch, true, false)
   162  		require.NoError(t, err)
   163  
   164  		if val.Type == "file" {
   165  			assert.False(t, rt.IsNullable, "expected %q (%q) to not be nullable", val.Type, val.Format)
   166  		} else {
   167  			assert.True(t, rt.IsNullable, "expected %q (%q) to be nullable", val.Type, val.Format)
   168  		}
   169  		assertPrimitiveResolve(t, val.Type, val.Format, val.Expected, rt)
   170  
   171  		// Test x-nullable overrides x-isnullable
   172  		sch.Extensions[xIsNullable] = false
   173  		sch.Extensions[xNullable] = true
   174  		rt, err = resolver.ResolveSchema(sch, true, true)
   175  		require.NoError(t, err)
   176  
   177  		if val.Type == "file" {
   178  			assert.False(t, rt.IsNullable, "expected %q (%q) to not be nullable", val.Type, val.Format)
   179  		} else {
   180  			assert.True(t, rt.IsNullable, "expected %q (%q) to be nullable", val.Type, val.Format)
   181  		}
   182  		assertPrimitiveResolve(t, val.Type, val.Format, val.Expected, rt)
   183  
   184  		// Test x-nullable without x-isnullable
   185  		delete(sch.Extensions, xIsNullable)
   186  		sch.Extensions[xNullable] = true
   187  		rt, err = resolver.ResolveSchema(sch, true, true)
   188  		require.NoError(t, err)
   189  
   190  		if val.Type == "file" {
   191  			assert.False(t, rt.IsNullable, "expected %q (%q) to not be nullable", val.Type, val.Format)
   192  		} else {
   193  			assert.True(t, rt.IsNullable, "expected %q (%q) to be nullable", val.Type, val.Format)
   194  		}
   195  		assertPrimitiveResolve(t, val.Type, val.Format, val.Expected, rt)
   196  	}
   197  
   198  	// arrays of primitives and string formats
   199  	for _, val := range schTypeVals() {
   200  		var sch spec.Schema
   201  		sch.Typed(val.Type, val.Format)
   202  		sch.AddExtension(xIsNullable, true)
   203  
   204  		rt, err := resolver.ResolveSchema(new(spec.Schema).CollectionOf(sch), true, true)
   205  		require.NoError(t, err)
   206  
   207  		assert.True(t, rt.IsArray)
   208  	}
   209  }
   210  
   211  func TestTypeResolver_Refs(t *testing.T) {
   212  	_, resolver, e := basicTaskListResolver(t)
   213  	require.NoError(t, e)
   214  
   215  	// referenced objects
   216  	for _, val := range schRefVals() {
   217  		sch := new(spec.Schema)
   218  		sch.Ref, _ = spec.NewRef("#/definitions/" + val.Type)
   219  
   220  		rt, err := resolver.ResolveSchema(sch, true, true)
   221  		require.NoError(t, err)
   222  
   223  		assert.Equal(t, val.Expected, rt.GoType)
   224  		assert.False(t, rt.IsAnonymous)
   225  		assert.True(t, rt.IsNullable)
   226  		assert.Equal(t, "object", rt.SwaggerType)
   227  	}
   228  
   229  	// referenced array objects
   230  	for _, val := range schRefVals() {
   231  		sch := new(spec.Schema)
   232  		sch.Ref, _ = spec.NewRef("#/definitions/" + val.Type)
   233  
   234  		rt, err := resolver.ResolveSchema(new(spec.Schema).CollectionOf(*sch), true, true)
   235  		require.NoError(t, err)
   236  
   237  		assert.True(t, rt.IsArray)
   238  		// now this behavior has moved down to the type resolver:
   239  		// * it used to be hidden to the type resolver, but rendered like that eventually
   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  		// now this behavior has moved down to the type resolver:
   267  		// * it used to be hidden to the type resolver, but rendered like that eventually
   268  		assert.Equal(t, "[]*"+val.Expected, rt.GoType)
   269  	}
   270  }
   271  
   272  func TestTypeResolver_AdditionalProperties(t *testing.T) {
   273  	_, resolver, err := basicTaskListResolver(t)
   274  	require.NoError(t, err)
   275  
   276  	// primitives as additional properties
   277  	for _, val := range schTypeVals() {
   278  		sch := new(spec.Schema)
   279  
   280  		sch.Typed(val.Type, val.Format)
   281  		parent := new(spec.Schema)
   282  		parent.AdditionalProperties = new(spec.SchemaOrBool)
   283  		parent.AdditionalProperties.Schema = sch
   284  
   285  		rt, err := resolver.ResolveSchema(parent, true, false)
   286  		require.NoError(t, err)
   287  
   288  		assert.True(t, rt.IsMap)
   289  		assert.False(t, rt.IsComplexObject)
   290  		assert.Equal(t, "map[string]"+val.Expected, rt.GoType)
   291  		assert.Equal(t, "object", rt.SwaggerType)
   292  	}
   293  
   294  	// array of primitives as additional properties
   295  	for _, val := range schTypeVals() {
   296  		sch := new(spec.Schema)
   297  
   298  		sch.Typed(val.Type, val.Format)
   299  		parent := new(spec.Schema)
   300  		parent.AdditionalProperties = new(spec.SchemaOrBool)
   301  		parent.AdditionalProperties.Schema = new(spec.Schema).CollectionOf(*sch)
   302  
   303  		rt, err := resolver.ResolveSchema(parent, true, false)
   304  		require.NoError(t, err)
   305  
   306  		assert.True(t, rt.IsMap)
   307  		assert.False(t, rt.IsComplexObject)
   308  		assert.Equal(t, "map[string][]"+val.Expected, rt.GoType)
   309  		assert.Equal(t, "object", rt.SwaggerType)
   310  	}
   311  
   312  	// refs as additional properties
   313  	for _, val := range schRefVals() {
   314  		sch := new(spec.Schema)
   315  		sch.Ref, _ = spec.NewRef("#/definitions/" + val.Type)
   316  		parent := new(spec.Schema)
   317  		parent.AdditionalProperties = new(spec.SchemaOrBool)
   318  		parent.AdditionalProperties.Schema = sch
   319  
   320  		rt, err := resolver.ResolveSchema(parent, true, true)
   321  		require.NoError(t, err)
   322  
   323  		assert.True(t, rt.IsMap)
   324  		assert.False(t, rt.IsComplexObject)
   325  		assert.Equal(t, "map[string]"+val.Expected, rt.GoType)
   326  		assert.Equal(t, "object", rt.SwaggerType)
   327  	}
   328  
   329  	// when additional properties and properties present, it's a complex object
   330  
   331  	// primitives as additional properties
   332  	for _, val := range schTypeVals() {
   333  		sch := new(spec.Schema)
   334  
   335  		sch.Typed(val.Type, val.Format)
   336  		parent := new(spec.Schema)
   337  		parent.Properties = make(map[string]spec.Schema)
   338  		parent.Properties["id"] = *spec.Int32Property()
   339  		parent.AdditionalProperties = new(spec.SchemaOrBool)
   340  		parent.AdditionalProperties.Schema = sch
   341  
   342  		rt, err := resolver.ResolveSchema(parent, true, true)
   343  		require.NoError(t, err)
   344  
   345  		assert.True(t, rt.IsComplexObject)
   346  		assert.False(t, rt.IsMap)
   347  		assert.Equal(t, "map[string]"+val.Expected, rt.GoType)
   348  		assert.Equal(t, "object", rt.SwaggerType)
   349  	}
   350  
   351  	// array of primitives as additional properties
   352  	for _, val := range schTypeVals() {
   353  		sch := new(spec.Schema)
   354  
   355  		sch.Typed(val.Type, val.Format)
   356  		parent := new(spec.Schema)
   357  		parent.Properties = make(map[string]spec.Schema)
   358  		parent.Properties["id"] = *spec.Int32Property()
   359  		parent.AdditionalProperties = new(spec.SchemaOrBool)
   360  		parent.AdditionalProperties.Schema = new(spec.Schema).CollectionOf(*sch)
   361  
   362  		rt, err := resolver.ResolveSchema(parent, true, true)
   363  		require.NoError(t, err)
   364  
   365  		assert.True(t, rt.IsComplexObject)
   366  		assert.False(t, rt.IsMap)
   367  		assert.Equal(t, "map[string][]"+val.Expected, rt.GoType)
   368  		assert.Equal(t, "object", rt.SwaggerType)
   369  	}
   370  
   371  	// refs as additional properties
   372  	for _, val := range schRefVals() {
   373  		sch := new(spec.Schema)
   374  		sch.Ref, _ = spec.NewRef("#/definitions/" + val.Type)
   375  		parent := new(spec.Schema)
   376  		parent.Properties = make(map[string]spec.Schema)
   377  		parent.Properties["id"] = *spec.Int32Property()
   378  		parent.AdditionalProperties = new(spec.SchemaOrBool)
   379  		parent.AdditionalProperties.Schema = sch
   380  
   381  		rt, err := resolver.ResolveSchema(parent, true, true)
   382  		require.NoError(t, err)
   383  
   384  		assert.True(t, rt.IsComplexObject)
   385  		assert.False(t, rt.IsMap)
   386  		assert.Equal(t, "map[string]"+val.Expected, rt.GoType)
   387  		assert.Equal(t, "object", rt.SwaggerType)
   388  	}
   389  }
   390  
   391  func TestTypeResolver_Notables(t *testing.T) {
   392  	doc, resolver, err := specResolver(t, "../fixtures/codegen/todolist.models.yml")
   393  	require.NoError(t, err)
   394  
   395  	def := doc.Spec().Definitions["Notables"]
   396  	rest, err := resolver.ResolveSchema(&def, false, true)
   397  	require.NoError(t, err)
   398  
   399  	assert.True(t, rest.IsArray)
   400  	assert.False(t, rest.IsAnonymous)
   401  	assert.False(t, rest.IsNullable)
   402  	assert.Equal(t, "[]*models.Notable", rest.GoType)
   403  }
   404  
   405  func specResolver(_ testing.TB, path string) (*loads.Document, *typeResolver, error) {
   406  	tlb, err := loads.Spec(path)
   407  	if err != nil {
   408  		return nil, nil, err
   409  	}
   410  	resolver := &typeResolver{
   411  		Doc:           tlb,
   412  		ModelsPackage: "models",
   413  	}
   414  	resolver.KnownDefs = make(map[string]struct{})
   415  	for k := range tlb.Spec().Definitions {
   416  		resolver.KnownDefs[k] = struct{}{}
   417  	}
   418  	return tlb, resolver, nil
   419  }
   420  
   421  func basicTaskListResolver(_ testing.TB) (*loads.Document, *typeResolver, error) {
   422  	tlb, err := loads.Spec("../fixtures/codegen/tasklist.basic.yml")
   423  	if err != nil {
   424  		return nil, nil, err
   425  	}
   426  	swsp := tlb.Spec()
   427  	uc := swsp.Definitions["UserCard"]
   428  	uc.AddExtension(xGoName, "UserItem")
   429  	swsp.Definitions["UserCard"] = uc
   430  	resolver := &typeResolver{
   431  		Doc:           tlb,
   432  		ModelsPackage: "models",
   433  	}
   434  
   435  	resolver.KnownDefs = make(map[string]struct{})
   436  	for k, sch := range swsp.Definitions {
   437  		resolver.KnownDefs[k] = struct{}{}
   438  		if nm, ok := sch.Extensions[xGoName]; ok {
   439  			resolver.KnownDefs[nm.(string)] = struct{}{}
   440  		}
   441  	}
   442  	return tlb, resolver, nil
   443  }
   444  
   445  func TestTypeResolver_TupleTypes(t *testing.T) {
   446  	_, resolver, err := basicTaskListResolver(t)
   447  	require.NoError(t, err)
   448  
   449  	// tuple type (items with multiple schemas)
   450  	parent := new(spec.Schema)
   451  	parent.Typed("array", "")
   452  	parent.Items = new(spec.SchemaOrArray)
   453  	parent.Items.Schemas = append(
   454  		parent.Items.Schemas,
   455  		*spec.StringProperty(),
   456  		*spec.Int64Property(),
   457  		*spec.Float64Property(),
   458  		*spec.BoolProperty(),
   459  		*spec.ArrayProperty(spec.StringProperty()),
   460  		*spec.RefProperty("#/definitions/Comment"),
   461  	)
   462  
   463  	rt, err := resolver.ResolveSchema(parent, true, true)
   464  	require.NoError(t, err)
   465  
   466  	assert.False(t, rt.IsArray)
   467  	assert.True(t, rt.IsTuple)
   468  }
   469  
   470  func TestTypeResolver_AnonymousStructs(t *testing.T) {
   471  	_, resolver, err := basicTaskListResolver(t)
   472  	require.NoError(t, err)
   473  
   474  	// anonymous structs should be accounted for
   475  	parent := new(spec.Schema)
   476  	parent.Typed("object", "")
   477  	parent.Properties = make(map[string]spec.Schema)
   478  	parent.Properties["name"] = *spec.StringProperty()
   479  	parent.Properties["age"] = *spec.Int32Property()
   480  
   481  	rt, err := resolver.ResolveSchema(parent, true, true)
   482  	require.NoError(t, err)
   483  
   484  	assert.True(t, rt.IsNullable)
   485  	assert.True(t, rt.IsAnonymous)
   486  	assert.True(t, rt.IsComplexObject)
   487  
   488  	parent.Extensions = make(spec.Extensions)
   489  	parent.Extensions[xIsNullable] = true
   490  
   491  	rt, err = resolver.ResolveSchema(parent, true, true)
   492  	require.NoError(t, err)
   493  
   494  	assert.True(t, rt.IsNullable)
   495  	assert.True(t, rt.IsAnonymous)
   496  	assert.True(t, rt.IsComplexObject)
   497  
   498  	// Also test that it's nullable with just x-nullable
   499  	parent.Extensions[xIsNullable] = false
   500  	parent.Extensions[xNullable] = false
   501  
   502  	rt, err = resolver.ResolveSchema(parent, true, true)
   503  	require.NoError(t, err)
   504  
   505  	assert.False(t, rt.IsNullable)
   506  	assert.True(t, rt.IsAnonymous)
   507  	assert.True(t, rt.IsComplexObject)
   508  }
   509  
   510  func TestTypeResolver_ObjectType(t *testing.T) {
   511  	_, resolver, e := basicTaskListResolver(t)
   512  	require.NoError(t, e)
   513  
   514  	resolver.ModelName = "TheModel"
   515  	resolver.KnownDefs["TheModel"] = struct{}{}
   516  	defer func() { resolver.ModelName = "" }()
   517  
   518  	// very poor schema definitions (as in none)
   519  	types := []string{"object", ""}
   520  	for _, tpe := range types {
   521  		sch := new(spec.Schema)
   522  		sch.Typed(tpe, "")
   523  		rt, err := resolver.ResolveSchema(sch, true, true)
   524  		require.NoError(t, err)
   525  
   526  		assert.True(t, rt.IsMap)
   527  		assert.False(t, rt.IsComplexObject)
   528  		assert.Equal(t, "interface{}", rt.GoType)
   529  		assert.Equal(t, "object", rt.SwaggerType)
   530  
   531  		sch.Properties = make(map[string]spec.Schema)
   532  		var ss spec.Schema
   533  		sch.Properties["tags"] = *(&ss).CollectionOf(*spec.StringProperty())
   534  		rt, err = resolver.ResolveSchema(sch, false, true)
   535  		require.NoError(t, err)
   536  
   537  		assert.True(t, rt.IsComplexObject)
   538  		assert.False(t, rt.IsMap)
   539  		assert.Equal(t, "models.TheModel", rt.GoType)
   540  		assert.Equal(t, "object", rt.SwaggerType)
   541  
   542  		sch.Properties = nil
   543  		nsch := new(spec.Schema)
   544  		nsch.Typed(tpe, "")
   545  		nsch.AllOf = []spec.Schema{*sch}
   546  		rt, err = resolver.ResolveSchema(nsch, false, true)
   547  		require.NoError(t, err)
   548  
   549  		assert.True(t, rt.IsComplexObject)
   550  		assert.False(t, rt.IsMap)
   551  		assert.Equal(t, "models.TheModel", rt.GoType)
   552  		assert.Equal(t, "object", rt.SwaggerType)
   553  
   554  		sch = new(spec.Schema)
   555  		rt, err = resolver.ResolveSchema(sch, true, true)
   556  		require.NoError(t, err)
   557  
   558  		assert.True(t, rt.IsMap)
   559  		assert.False(t, rt.IsComplexObject)
   560  		assert.Equal(t, "interface{}", rt.GoType)
   561  		assert.Equal(t, "object", rt.SwaggerType)
   562  
   563  		sch = new(spec.Schema)
   564  		var sp spec.Schema
   565  		sp.Typed("object", "")
   566  		sch.AllOf = []spec.Schema{sp}
   567  		rt, err = resolver.ResolveSchema(sch, true, true)
   568  		require.NoError(t, err)
   569  
   570  		assert.True(t, rt.IsComplexObject)
   571  		assert.False(t, rt.IsMap)
   572  		assert.Equal(t, "models.TheModel", rt.GoType)
   573  		assert.Equal(t, "object", rt.SwaggerType)
   574  	}
   575  }
   576  
   577  func TestTypeResolver_AliasTypes(t *testing.T) {
   578  	doc, resolver, err := basicTaskListResolver(t)
   579  	require.NoError(t, err)
   580  
   581  	resolver.ModelsPackage = ""
   582  	resolver.ModelName = "Currency"
   583  	defer func() {
   584  		resolver.ModelName = ""
   585  		resolver.ModelsPackage = "models"
   586  	}()
   587  
   588  	defs := doc.Spec().Definitions[resolver.ModelName]
   589  	rt, err := resolver.ResolveSchema(&defs, false, true)
   590  	require.NoError(t, err)
   591  
   592  	assert.False(t, rt.IsAnonymous)
   593  	assert.True(t, rt.IsAliased)
   594  	assert.True(t, rt.IsPrimitive)
   595  	assert.Equal(t, "Currency", rt.GoType)
   596  	assert.Equal(t, "string", rt.AliasedType)
   597  }
   598  
   599  func assertPrimitiveResolve(t testing.TB, tpe, tfmt, exp string, tr resolvedType) {
   600  	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))
   601  	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))
   602  	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))
   603  }
   604  
   605  func TestTypeResolver_ExistingModel(t *testing.T) {
   606  	doc, err := loads.Spec("../fixtures/codegen/existing-model.yml")
   607  	resolver := newTypeResolver("model", "", doc)
   608  	require.NoError(t, err)
   609  
   610  	def := doc.Spec().Definitions["JsonWebKey"]
   611  	tpe, pkg, alias := resolver.knownDefGoType("JsonWebKey", def, nil)
   612  	assert.Equal(t, "jwk.Key", tpe)
   613  	assert.Equal(t, "github.com/user/package", pkg)
   614  	assert.Equal(t, "jwk", alias)
   615  	rest, err := resolver.ResolveSchema(&def, false, true)
   616  	require.NoError(t, err)
   617  
   618  	assert.False(t, rest.IsMap)
   619  	assert.False(t, rest.IsArray)
   620  	assert.False(t, rest.IsTuple)
   621  	assert.False(t, rest.IsStream)
   622  	assert.True(t, rest.IsAliased)
   623  	assert.False(t, rest.IsBaseType)
   624  	assert.False(t, rest.IsInterface)
   625  	assert.True(t, rest.IsNullable)
   626  	assert.False(t, rest.IsPrimitive)
   627  	assert.False(t, rest.IsAnonymous)
   628  	assert.True(t, rest.IsComplexObject)
   629  	assert.False(t, rest.IsCustomFormatter)
   630  	assert.Equal(t, "jwk.Key", rest.GoType)
   631  	assert.Equal(t, "github.com/user/package", rest.Pkg)
   632  	assert.Equal(t, "jwk", rest.PkgAlias)
   633  
   634  	def = doc.Spec().Definitions["JsonWebKeySet"].Properties["keys"]
   635  	rest, err = resolver.ResolveSchema(&def, false, true)
   636  	require.NoError(t, err)
   637  
   638  	assert.False(t, rest.IsMap)
   639  	assert.True(t, rest.IsArray)
   640  	assert.False(t, rest.IsTuple)
   641  	assert.False(t, rest.IsStream)
   642  	assert.False(t, rest.IsAliased)
   643  	assert.False(t, rest.IsBaseType)
   644  	assert.False(t, rest.IsInterface)
   645  	assert.False(t, rest.IsNullable)
   646  	assert.False(t, rest.IsPrimitive)
   647  	assert.False(t, rest.IsAnonymous)
   648  	assert.False(t, rest.IsComplexObject)
   649  	assert.False(t, rest.IsCustomFormatter)
   650  	assert.Equal(t, "[]*jwk.Key", rest.GoType)
   651  	assert.Equal(t, "", rest.Pkg)
   652  	assert.Equal(t, "", rest.PkgAlias)
   653  }