github.com/emreu/go-swagger@v0.22.1/generator/model_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  	"bytes"
    19  	"fmt"
    20  	"io/ioutil"
    21  	"log"
    22  	"os"
    23  	"regexp"
    24  	"strconv"
    25  	"strings"
    26  	"testing"
    27  	"text/template"
    28  
    29  	"github.com/go-openapi/loads"
    30  	"github.com/go-openapi/swag"
    31  	"github.com/stretchr/testify/assert"
    32  )
    33  
    34  type templateTest struct {
    35  	t        testing.TB
    36  	template *template.Template
    37  }
    38  
    39  func (tt *templateTest) assertRender(data interface{}, expected string) bool {
    40  	buf := bytes.NewBuffer(nil)
    41  	err := tt.template.Execute(buf, data)
    42  	if !assert.NoError(tt.t, err) {
    43  		return false
    44  	}
    45  	return assert.Equal(tt.t, expected, buf.String())
    46  }
    47  
    48  func TestGenerateModel_Sanity(t *testing.T) {
    49  	// just checks if it can render and format these things
    50  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml")
    51  	if assert.NoError(t, err) {
    52  		definitions := specDoc.Spec().Definitions
    53  
    54  		//k := "Comment"
    55  		//schema := definitions[k]
    56  		for k, schema := range definitions {
    57  			opts := opts()
    58  			genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts)
    59  
    60  			// log.Printf("trying model: %s", k)
    61  			if assert.NoError(t, err) {
    62  				//b, _ := json.MarshalIndent(genModel, "", "  ")
    63  				//fmt.Println(string(b))
    64  				rendered := bytes.NewBuffer(nil)
    65  
    66  				err := templates.MustGet("model").Execute(rendered, genModel)
    67  				if assert.NoError(t, err, "Unexpected error while rendering models for fixtures/codegen/todolist.models.yml: %v", err) {
    68  					_, err := opts.LanguageOpts.FormatContent(strings.ToLower(k)+".go", rendered.Bytes())
    69  					assert.NoError(t, err)
    70  					//if assert.NoError(t, err) {
    71  					//fmt.Println(string(formatted))
    72  					//} else {
    73  					//fmt.Println(rendered.String())
    74  					////break
    75  					//}
    76  
    77  					//assert.EqualValues(t, strings.TrimSpace(string(expected)), strings.TrimSpace(string(formatted)))
    78  				}
    79  			}
    80  		}
    81  	}
    82  }
    83  
    84  func TestGenerateModel_DocString(t *testing.T) {
    85  	templ := template.Must(template.New("docstring").Funcs(FuncMap).Parse(string(assets["docstring.gotmpl"])))
    86  	tt := templateTest{t, templ}
    87  
    88  	var gmp GenSchema
    89  	gmp.Title = "The title of the property"
    90  	gmp.Description = "The description of the property"
    91  	var expected = `The title of the property
    92  //
    93  // The description of the property`
    94  	tt.assertRender(gmp, expected)
    95  
    96  	gmp.Title = ""
    97  	expected = `The description of the property`
    98  	tt.assertRender(gmp, expected)
    99  
   100  	gmp.Description = ""
   101  	gmp.Name = "theModel"
   102  	expected = `the model`
   103  	tt.assertRender(gmp, expected)
   104  }
   105  
   106  func TestGenerateModel_PropertyValidation(t *testing.T) {
   107  	templ := template.Must(template.New("propertyValidationDocString").Funcs(FuncMap).Parse(string(assets["validation/structfield.gotmpl"])))
   108  	tt := templateTest{t, templ}
   109  
   110  	var gmp GenSchema
   111  	gmp.Required = true
   112  	tt.assertRender(gmp, `
   113  // Required: true`)
   114  	var fl float64 = 10
   115  	var in1 int64 = 20
   116  	var in2 int64 = 30
   117  	gmp.Maximum = &fl
   118  	gmp.ExclusiveMaximum = true
   119  	gmp.Minimum = &fl
   120  	gmp.ExclusiveMinimum = true
   121  	gmp.MaxLength = &in1
   122  	gmp.MinLength = &in1
   123  	gmp.Pattern = "\\w[\\w- ]+"
   124  	gmp.MaxItems = &in2
   125  	gmp.MinItems = &in2
   126  	gmp.UniqueItems = true
   127  
   128  	tt.assertRender(gmp, `
   129  // Required: true
   130  // Maximum: < 10
   131  // Minimum: > 10
   132  // Max Length: 20
   133  // Min Length: 20
   134  // Pattern: \w[\w- ]+
   135  // Max Items: 30
   136  // Min Items: 30
   137  // Unique: true`)
   138  
   139  	gmp.Required = false
   140  	gmp.ExclusiveMaximum = false
   141  	gmp.ExclusiveMinimum = false
   142  	tt.assertRender(gmp, `
   143  // Maximum: 10
   144  // Minimum: 10
   145  // Max Length: 20
   146  // Min Length: 20
   147  // Pattern: \w[\w- ]+
   148  // Max Items: 30
   149  // Min Items: 30
   150  // Unique: true`)
   151  
   152  }
   153  
   154  func TestGenerateModel_SchemaField(t *testing.T) {
   155  	tt := templateTest{t, templates.MustGet("model").Lookup("structfield")}
   156  
   157  	var gmp GenSchema
   158  	gmp.Name = "some name"
   159  	gmp.OriginalName = "some name"
   160  	gmp.resolvedType = resolvedType{GoType: "string", IsPrimitive: true, IsEmptyOmitted: true}
   161  	gmp.Title = "The title of the property"
   162  	gmp.CustomTag = "mytag:\"foobar,foobaz\""
   163  
   164  	tt.assertRender(gmp, `// The title of the property
   165  `+"SomeName string `json:\"some name,omitempty\" mytag:\"foobar,foobaz\"`\n")
   166  
   167  	var fl float64 = 10
   168  	var in1 int64 = 20
   169  	var in2 int64 = 30
   170  
   171  	gmp.Description = "The description of the property"
   172  	gmp.Required = true
   173  	gmp.Maximum = &fl
   174  	gmp.ExclusiveMaximum = true
   175  	gmp.Minimum = &fl
   176  	gmp.ExclusiveMinimum = true
   177  	gmp.MaxLength = &in1
   178  	gmp.MinLength = &in1
   179  	gmp.Pattern = "\\w[\\w- ]+"
   180  	gmp.MaxItems = &in2
   181  	gmp.MinItems = &in2
   182  	gmp.UniqueItems = true
   183  	gmp.ReadOnly = true
   184  	tt.assertRender(gmp, `// The title of the property
   185  //
   186  // The description of the property
   187  // Required: true
   188  // Read Only: true
   189  // Maximum: < 10
   190  // Minimum: > 10
   191  // Max Length: 20
   192  // Min Length: 20
   193  // Pattern: \w[\w- ]+
   194  // Max Items: 30
   195  // Min Items: 30
   196  // Unique: true
   197  `+"SomeName string `json:\"some name\" mytag:\"foobar,foobaz\"`\n")
   198  }
   199  
   200  var schTypeGenDataSimple = []struct {
   201  	Value    GenSchema
   202  	Expected string
   203  }{
   204  	{GenSchema{resolvedType: resolvedType{GoType: "string", IsPrimitive: true}}, "string"},
   205  	{GenSchema{resolvedType: resolvedType{GoType: "string", IsPrimitive: true, IsNullable: true}}, "*string"},
   206  	{GenSchema{resolvedType: resolvedType{GoType: "bool", IsPrimitive: true}}, "bool"},
   207  	{GenSchema{resolvedType: resolvedType{GoType: "int32", IsPrimitive: true}}, "int32"},
   208  	{GenSchema{resolvedType: resolvedType{GoType: "int64", IsPrimitive: true}}, "int64"},
   209  	{GenSchema{resolvedType: resolvedType{GoType: "float32", IsPrimitive: true}}, "float32"},
   210  	{GenSchema{resolvedType: resolvedType{GoType: "float64", IsPrimitive: true}}, "float64"},
   211  	{GenSchema{resolvedType: resolvedType{GoType: "strfmt.Base64", IsPrimitive: true}}, "strfmt.Base64"},
   212  	{GenSchema{resolvedType: resolvedType{GoType: "strfmt.Date", IsPrimitive: true}}, "strfmt.Date"},
   213  	{GenSchema{resolvedType: resolvedType{GoType: "strfmt.DateTime", IsPrimitive: true}}, "strfmt.DateTime"},
   214  	{GenSchema{resolvedType: resolvedType{GoType: "strfmt.URI", IsPrimitive: true}}, "strfmt.URI"},
   215  	{GenSchema{resolvedType: resolvedType{GoType: "strfmt.Email", IsPrimitive: true}}, "strfmt.Email"},
   216  	{GenSchema{resolvedType: resolvedType{GoType: "strfmt.Hostname", IsPrimitive: true}}, "strfmt.Hostname"},
   217  	{GenSchema{resolvedType: resolvedType{GoType: "strfmt.IPv4", IsPrimitive: true}}, "strfmt.IPv4"},
   218  	{GenSchema{resolvedType: resolvedType{GoType: "strfmt.IPv6", IsPrimitive: true}}, "strfmt.IPv6"},
   219  	{GenSchema{resolvedType: resolvedType{GoType: "strfmt.UUID", IsPrimitive: true}}, "strfmt.UUID"},
   220  	{GenSchema{resolvedType: resolvedType{GoType: "strfmt.UUID3", IsPrimitive: true}}, "strfmt.UUID3"},
   221  	{GenSchema{resolvedType: resolvedType{GoType: "strfmt.UUID4", IsPrimitive: true}}, "strfmt.UUID4"},
   222  	{GenSchema{resolvedType: resolvedType{GoType: "strfmt.UUID5", IsPrimitive: true}}, "strfmt.UUID5"},
   223  	{GenSchema{resolvedType: resolvedType{GoType: "strfmt.ISBN", IsPrimitive: true}}, "strfmt.ISBN"},
   224  	{GenSchema{resolvedType: resolvedType{GoType: "strfmt.ISBN10", IsPrimitive: true}}, "strfmt.ISBN10"},
   225  	{GenSchema{resolvedType: resolvedType{GoType: "strfmt.ISBN13", IsPrimitive: true}}, "strfmt.ISBN13"},
   226  	{GenSchema{resolvedType: resolvedType{GoType: "strfmt.CreditCard", IsPrimitive: true}}, "strfmt.CreditCard"},
   227  	{GenSchema{resolvedType: resolvedType{GoType: "strfmt.SSN", IsPrimitive: true}}, "strfmt.SSN"},
   228  	{GenSchema{resolvedType: resolvedType{GoType: "strfmt.HexColor", IsPrimitive: true}}, "strfmt.HexColor"},
   229  	{GenSchema{resolvedType: resolvedType{GoType: "strfmt.RGBColor", IsPrimitive: true}}, "strfmt.RGBColor"},
   230  	{GenSchema{resolvedType: resolvedType{GoType: "strfmt.Duration", IsPrimitive: true}}, "strfmt.Duration"},
   231  	{GenSchema{resolvedType: resolvedType{GoType: "strfmt.Password", IsPrimitive: true}}, "strfmt.Password"},
   232  	{GenSchema{resolvedType: resolvedType{GoType: "io.ReadCloser", IsStream: true}}, "io.ReadCloser"},
   233  	{GenSchema{resolvedType: resolvedType{GoType: "interface{}", IsInterface: true}}, "interface{}"},
   234  	{GenSchema{resolvedType: resolvedType{GoType: "[]int32", IsArray: true}}, "[]int32"},
   235  	{GenSchema{resolvedType: resolvedType{GoType: "[]string", IsArray: true}}, "[]string"},
   236  	{GenSchema{resolvedType: resolvedType{GoType: "map[string]int32", IsMap: true}}, "map[string]int32"},
   237  	{GenSchema{resolvedType: resolvedType{GoType: "models.Task", IsComplexObject: true, IsNullable: true, IsAnonymous: false}}, "*models.Task"},
   238  }
   239  
   240  func TestGenSchemaType(t *testing.T) {
   241  	tt := templateTest{t, templates.MustGet("model").Lookup("schemaType")}
   242  	for _, v := range schTypeGenDataSimple {
   243  		tt.assertRender(v.Value, v.Expected)
   244  	}
   245  }
   246  func TestGenerateModel_Primitives(t *testing.T) {
   247  	tt := templateTest{t, templates.MustGet("model").Lookup("schema")}
   248  	for _, v := range schTypeGenDataSimple {
   249  		v.Value.IncludeValidator = true
   250  		v.Value.IncludeModel = true
   251  		val := v.Value
   252  		val.ReceiverName = "o"
   253  		if val.IsComplexObject {
   254  			continue
   255  		}
   256  		val.Name = "theType"
   257  		exp := v.Expected
   258  		if val.IsInterface || val.IsStream {
   259  			tt.assertRender(&val, "type TheType "+exp+"\n  \n")
   260  			continue
   261  		}
   262  		tt.assertRender(&val, "type TheType "+exp+"\n  // Validate validates this the type\nfunc (o theType) Validate(formats strfmt.Registry) error {\n  return nil\n}\n")
   263  	}
   264  }
   265  
   266  func TestGenerateModel_Zeroes(t *testing.T) {
   267  	for _, v := range schTypeGenDataSimple {
   268  		//t.Logf("Zero for %s: %s", v.Value.GoType, v.Value.Zero())
   269  		switch v.Value.GoType {
   270  		// verifying Zero for primitive
   271  		case "string":
   272  			assert.Equal(t, `""`, v.Value.Zero())
   273  		case "bool":
   274  			assert.Equal(t, `false`, v.Value.Zero())
   275  		case "int32", "int64", "float32", "float64":
   276  			assert.Equal(t, `0`, v.Value.Zero())
   277  		// verifying Zero for primitive formatters
   278  		case "strfmt.Date", "strfmt.DateTime", "strfmt.OjbectId": // akin to structs
   279  			rex := regexp.MustCompile(regexp.QuoteMeta(v.Value.GoType) + `{}`)
   280  			assert.True(t, rex.MatchString(v.Value.Zero()))
   281  			k := v.Value
   282  			k.IsAliased = true
   283  			k.AliasedType = k.GoType
   284  			k.GoType = "myAliasedType"
   285  			rex = regexp.MustCompile(regexp.QuoteMeta(k.GoType+"("+k.AliasedType) + `{}` + `\)`)
   286  			assert.True(t, rex.MatchString(k.Zero()))
   287  			//t.Logf("Zero for %s: %s", k.GoType, k.Zero())
   288  		case "strfmt.Duration": // akin to integer
   289  			rex := regexp.MustCompile(regexp.QuoteMeta(v.Value.GoType) + `\(\d*\)`)
   290  			assert.True(t, rex.MatchString(v.Value.Zero()))
   291  			k := v.Value
   292  			k.IsAliased = true
   293  			k.AliasedType = k.GoType
   294  			k.GoType = "myAliasedType"
   295  			rex = regexp.MustCompile(regexp.QuoteMeta(k.GoType+"("+k.AliasedType) + `\(\d*\)` + `\)`)
   296  			assert.True(t, rex.MatchString(k.Zero()))
   297  			//t.Logf("Zero for %s: %s", k.GoType, k.Zero())
   298  		case "strfmt.Base64": // akin to []byte
   299  			rex := regexp.MustCompile(regexp.QuoteMeta(v.Value.GoType) + `\(\[\]byte.*\)`)
   300  			assert.True(t, rex.MatchString(v.Value.Zero()))
   301  			k := v.Value
   302  			k.IsAliased = true
   303  			k.AliasedType = k.GoType
   304  			k.GoType = "myAliasedType"
   305  			rex = regexp.MustCompile(regexp.QuoteMeta(k.GoType+"("+k.AliasedType) + `\(\[\]byte.*\)` + `\)`)
   306  			assert.True(t, rex.MatchString(k.Zero()))
   307  			// t.Logf("Zero for %s: %s", k.GoType, k.Zero())
   308  		case "interface{}":
   309  			assert.Equal(t, `nil`, v.Value.Zero())
   310  		case "io.ReadCloser":
   311  			continue
   312  		default:
   313  			switch {
   314  			case strings.HasPrefix(v.Value.GoType, "[]") || strings.HasPrefix(v.Value.GoType, "map["): // akin to slice or map
   315  				assert.True(t, strings.HasPrefix(v.Value.Zero(), "make("))
   316  
   317  			case strings.HasPrefix(v.Value.GoType, "models."):
   318  				assert.True(t, strings.HasPrefix(v.Value.Zero(), "new("))
   319  
   320  			default: // akin to string
   321  				rex := regexp.MustCompile(regexp.QuoteMeta(v.Value.GoType) + `\(".*"\)`)
   322  				assert.True(t, rex.MatchString(v.Value.Zero()))
   323  				k := v.Value
   324  				k.IsAliased = true
   325  				k.AliasedType = k.GoType
   326  				k.GoType = "myAliasedType"
   327  				rex = regexp.MustCompile(regexp.QuoteMeta(k.GoType+"("+k.AliasedType) + `\(".*"\)` + `\)`)
   328  				assert.True(t, rex.MatchString(k.Zero()))
   329  				//t.Logf("Zero for %s: %s", k.GoType, k.Zero())
   330  			}
   331  		}
   332  	}
   333  }
   334  func TestGenerateModel_Nota(t *testing.T) {
   335  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml")
   336  	if assert.NoError(t, err) {
   337  		definitions := specDoc.Spec().Definitions
   338  		k := "Nota"
   339  		schema := definitions[k]
   340  		opts := opts()
   341  		genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts)
   342  		if assert.NoError(t, err) {
   343  			buf := bytes.NewBuffer(nil)
   344  			err := templates.MustGet("model").Execute(buf, genModel)
   345  			if assert.NoError(t, err) {
   346  				res := buf.String()
   347  				assertInCode(t, "type Nota map[string]int32", res)
   348  			}
   349  		}
   350  	}
   351  }
   352  
   353  func TestGenerateModel_NotaWithRef(t *testing.T) {
   354  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml")
   355  	if assert.NoError(t, err) {
   356  		definitions := specDoc.Spec().Definitions
   357  		k := "NotaWithRef"
   358  		schema := definitions[k]
   359  		opts := opts()
   360  		genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts)
   361  		if assert.NoError(t, err) {
   362  			buf := bytes.NewBuffer(nil)
   363  			err := templates.MustGet("model").Execute(buf, genModel)
   364  			if assert.NoError(t, err) {
   365  				ff, err := opts.LanguageOpts.FormatContent("nota_with_ref.go", buf.Bytes())
   366  				if assert.NoError(t, err) {
   367  					res := string(ff)
   368  					assertInCode(t, "type NotaWithRef map[string]Notable", res)
   369  				}
   370  			}
   371  		}
   372  	}
   373  }
   374  
   375  func TestGenerateModel_NotaWithMeta(t *testing.T) {
   376  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml")
   377  	if assert.NoError(t, err) {
   378  		definitions := specDoc.Spec().Definitions
   379  		k := "NotaWithMeta"
   380  		schema := definitions[k]
   381  		opts := opts()
   382  		genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts)
   383  		if assert.NoError(t, err) {
   384  			buf := bytes.NewBuffer(nil)
   385  			err := templates.MustGet("model").Execute(buf, genModel)
   386  			if assert.NoError(t, err) {
   387  				ff, err := opts.LanguageOpts.FormatContent("nota_with_meta.go", buf.Bytes())
   388  				if assert.NoError(t, err) {
   389  					res := string(ff)
   390  					assertInCode(t, "type NotaWithMeta map[string]NotaWithMetaAnon", res)
   391  					assertInCode(t, "type NotaWithMetaAnon struct {", res)
   392  					assertInCode(t, "Comment *string `json:\"comment\"`", res)
   393  					assertInCode(t, "Count int32 `json:\"count,omitempty\"`", res)
   394  				}
   395  			}
   396  		}
   397  	}
   398  }
   399  
   400  func TestGenerateModel_RunParameters(t *testing.T) {
   401  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml")
   402  	if assert.NoError(t, err) {
   403  		definitions := specDoc.Spec().Definitions
   404  		k := "RunParameters"
   405  		schema := definitions[k]
   406  		opts := opts()
   407  		genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts)
   408  		if assert.NoError(t, err) {
   409  			assert.False(t, genModel.IsAdditionalProperties)
   410  			assert.True(t, genModel.IsComplexObject)
   411  			assert.False(t, genModel.IsMap)
   412  			assert.False(t, genModel.IsAnonymous)
   413  			buf := bytes.NewBuffer(nil)
   414  			err := templates.MustGet("model").Execute(buf, genModel)
   415  			if assert.NoError(t, err) {
   416  				res := buf.String()
   417  				assertInCode(t, "type "+k+" struct {", res)
   418  				assertInCode(t, "BranchName string `json:\"branch_name,omitempty\"`", res)
   419  				assertInCode(t, "CommitSha string `json:\"commit_sha,omitempty\"`", res)
   420  				assertInCode(t, "Refs interface{} `json:\"refs,omitempty\"`", res)
   421  			}
   422  		}
   423  	}
   424  }
   425  
   426  func TestGenerateModel_NotaWithName(t *testing.T) {
   427  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml")
   428  	if assert.NoError(t, err) {
   429  		definitions := specDoc.Spec().Definitions
   430  		k := "NotaWithName"
   431  		schema := definitions[k]
   432  		opts := opts()
   433  		genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts)
   434  		if assert.NoError(t, err) {
   435  			assert.True(t, genModel.IsAdditionalProperties)
   436  			assert.False(t, genModel.IsComplexObject)
   437  			assert.False(t, genModel.IsMap)
   438  			assert.False(t, genModel.IsAnonymous)
   439  			buf := bytes.NewBuffer(nil)
   440  			err := templates.MustGet("model").Execute(buf, genModel)
   441  			if assert.NoError(t, err) {
   442  				res := buf.String()
   443  				assertInCode(t, "type "+k+" struct {", res)
   444  				assertInCode(t, k+" map[string]int32 `json:\"-\"`", res)
   445  				assertInCode(t, "Name *string `json:\"name\"`", res)
   446  				assertInCode(t, k+") UnmarshalJSON", res)
   447  				assertInCode(t, k+") MarshalJSON", res)
   448  				assertInCode(t, "json.Marshal(stage1)", res)
   449  				assertInCode(t, "stage1.Name = m.Name", res)
   450  				assertInCode(t, "json.Marshal(m."+k+")", res)
   451  				assertInCode(t, "json.Unmarshal(data, &stage1)", res)
   452  				assertInCode(t, "json.Unmarshal(data, &stage2)", res)
   453  				assertInCode(t, "json.Unmarshal(v, &toadd)", res)
   454  				assertInCode(t, "result[k] = toadd", res)
   455  				assertInCode(t, "m."+k+" = result", res)
   456  				for _, p := range genModel.Properties {
   457  					assertInCode(t, "delete(stage2, \""+p.Name+"\")", res)
   458  				}
   459  
   460  			}
   461  		}
   462  	}
   463  }
   464  
   465  func TestGenerateModel_NotaWithRefRegistry(t *testing.T) {
   466  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml")
   467  	if assert.NoError(t, err) {
   468  		definitions := specDoc.Spec().Definitions
   469  		k := "NotaWithRefRegistry"
   470  		schema := definitions[k]
   471  		opts := opts()
   472  		genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts)
   473  		if assert.NoError(t, err) {
   474  			buf := bytes.NewBuffer(nil)
   475  			err := templates.MustGet("model").Execute(buf, genModel)
   476  			if assert.NoError(t, err) {
   477  				ff, err := opts.LanguageOpts.FormatContent("nota_with_ref_registry.go", buf.Bytes())
   478  				if assert.NoError(t, err) {
   479  					res := string(ff)
   480  					assertInCode(t, "type "+k+" map[string]map[string]map[string]Notable", res)
   481  				}
   482  			}
   483  		}
   484  	}
   485  }
   486  
   487  func TestGenerateModel_WithCustomTag(t *testing.T) {
   488  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml")
   489  	if assert.NoError(t, err) {
   490  		definitions := specDoc.Spec().Definitions
   491  		k := "WithCustomTag"
   492  		schema := definitions[k]
   493  		opts := opts()
   494  		genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts)
   495  		if assert.NoError(t, err) {
   496  			buf := bytes.NewBuffer(nil)
   497  			err := templates.MustGet("model").Execute(buf, genModel)
   498  			if assert.NoError(t, err) {
   499  				res := buf.String()
   500  				assertInCode(t, "mytag:\"foo,bar\"", res)
   501  			}
   502  		}
   503  	}
   504  }
   505  
   506  func TestGenerateModel_NotaWithMetaRegistry(t *testing.T) {
   507  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml")
   508  	if assert.NoError(t, err) {
   509  		definitions := specDoc.Spec().Definitions
   510  		k := "NotaWithMetaRegistry"
   511  		schema := definitions[k]
   512  		opts := opts()
   513  		genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts)
   514  		if assert.NoError(t, err) {
   515  			buf := bytes.NewBuffer(nil)
   516  			err := templates.MustGet("model").Execute(buf, genModel)
   517  			if assert.NoError(t, err) {
   518  				ff, err := opts.LanguageOpts.FormatContent("nota_with_meta_registry.go", buf.Bytes())
   519  				if assert.NoError(t, err) {
   520  					res := string(ff)
   521  					assertInCode(t, "type "+k+" map[string]map[string]map[string]NotaWithMetaRegistryAnon", res)
   522  					assertInCode(t, "type NotaWithMetaRegistryAnon struct {", res)
   523  					assertInCode(t, "Comment *string `json:\"comment\"`", res)
   524  					assertInCode(t, "Count int32 `json:\"count,omitempty\"`", res)
   525  				}
   526  			}
   527  		}
   528  	}
   529  }
   530  
   531  func TestGenerateModel_WithMap(t *testing.T) {
   532  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml")
   533  	if assert.NoError(t, err) {
   534  		definitions := specDoc.Spec().Definitions
   535  		schema := definitions["WithMap"]
   536  		opts := opts()
   537  		genModel, err := makeGenDefinition("WithMap", "models", schema, specDoc, opts)
   538  		if assert.NoError(t, err) {
   539  			assert.False(t, genModel.HasAdditionalProperties)
   540  			prop := getDefinitionProperty(genModel, "data")
   541  			assert.True(t, prop.HasAdditionalProperties)
   542  			assert.True(t, prop.IsMap)
   543  			assert.False(t, prop.IsComplexObject)
   544  			buf := bytes.NewBuffer(nil)
   545  			err := templates.MustGet("model").Execute(buf, genModel)
   546  			if assert.NoError(t, err) {
   547  				res := buf.String()
   548  				assertInCode(t, "type WithMap struct {", res)
   549  				assertInCode(t, "Data map[string]string `json:\"data,omitempty\"`", res)
   550  			}
   551  		}
   552  	}
   553  }
   554  
   555  func TestGenerateModel_WithMapInterface(t *testing.T) {
   556  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml")
   557  	if assert.NoError(t, err) {
   558  		definitions := specDoc.Spec().Definitions
   559  		schema := definitions["WithMapInterface"]
   560  		opts := opts()
   561  		genModel, err := makeGenDefinition("WithMapInterface", "models", schema, specDoc, opts)
   562  		if assert.NoError(t, err) {
   563  			assert.False(t, genModel.HasAdditionalProperties)
   564  			prop := getDefinitionProperty(genModel, "extraInfo")
   565  			assert.True(t, prop.HasAdditionalProperties)
   566  			assert.True(t, prop.IsMap)
   567  			assert.False(t, prop.IsComplexObject)
   568  			assert.Equal(t, "map[string]interface{}", prop.GoType)
   569  			assert.True(t, prop.Required)
   570  			assert.True(t, prop.HasValidations)
   571  			// NOTE(fredbi): NeedsValidation now deprecated
   572  			//assert.False(t, prop.NeedsValidation)
   573  			buf := bytes.NewBuffer(nil)
   574  			err := templates.MustGet("model").Execute(buf, genModel)
   575  			if assert.NoError(t, err) {
   576  				res := buf.String()
   577  				assertInCode(t, "type WithMapInterface struct {", res)
   578  				assertInCode(t, "ExtraInfo map[string]interface{} `json:\"extraInfo\"`", res)
   579  			}
   580  		}
   581  	}
   582  }
   583  
   584  func TestGenerateModel_WithMapRef(t *testing.T) {
   585  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml")
   586  	if assert.NoError(t, err) {
   587  		definitions := specDoc.Spec().Definitions
   588  		k := "WithMapRef"
   589  		schema := definitions[k]
   590  		opts := opts()
   591  		genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts)
   592  		if assert.NoError(t, err) {
   593  			assert.False(t, genModel.HasAdditionalProperties)
   594  			prop := getDefinitionProperty(genModel, "data")
   595  			assert.True(t, prop.HasAdditionalProperties)
   596  			assert.True(t, prop.IsMap)
   597  			assert.False(t, prop.IsComplexObject)
   598  			buf := bytes.NewBuffer(nil)
   599  			err := templates.MustGet("model").Execute(buf, genModel)
   600  			if assert.NoError(t, err) {
   601  				res := buf.String()
   602  				assertInCode(t, "type "+k+" struct {", res)
   603  				assertInCode(t, "Data map[string]Notable `json:\"data,omitempty\"`", res)
   604  			}
   605  		}
   606  	}
   607  }
   608  
   609  func TestGenerateModel_WithMapComplex(t *testing.T) {
   610  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml")
   611  	if assert.NoError(t, err) {
   612  		definitions := specDoc.Spec().Definitions
   613  		k := "WithMapComplex"
   614  		schema := definitions[k]
   615  		opts := opts()
   616  		genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts)
   617  		if assert.NoError(t, err) {
   618  			assert.False(t, genModel.HasAdditionalProperties)
   619  			prop := getDefinitionProperty(genModel, "data")
   620  			assert.True(t, prop.HasAdditionalProperties)
   621  			assert.True(t, prop.IsMap)
   622  			assert.False(t, prop.IsComplexObject)
   623  			buf := bytes.NewBuffer(nil)
   624  			err := templates.MustGet("model").Execute(buf, genModel)
   625  			if assert.NoError(t, err) {
   626  				res := buf.String()
   627  				assertInCode(t, "type "+k+" struct {", res)
   628  				assertInCode(t, "Data map[string]"+k+"DataAnon `json:\"data,omitempty\"`", res)
   629  			}
   630  		}
   631  	}
   632  }
   633  
   634  func TestGenerateModel_WithMapRegistry(t *testing.T) {
   635  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml")
   636  	if assert.NoError(t, err) {
   637  		definitions := specDoc.Spec().Definitions
   638  		schema := definitions["WithMapRegistry"]
   639  		opts := opts()
   640  		genModel, err := makeGenDefinition("WithMap", "models", schema, specDoc, opts)
   641  		if assert.NoError(t, err) {
   642  			assert.False(t, genModel.HasAdditionalProperties)
   643  			prop := getDefinitionProperty(genModel, "data")
   644  			assert.True(t, prop.HasAdditionalProperties)
   645  			assert.True(t, prop.IsMap)
   646  			assert.False(t, prop.IsComplexObject)
   647  			buf := bytes.NewBuffer(nil)
   648  			err := templates.MustGet("model").Execute(buf, genModel)
   649  			if assert.NoError(t, err) {
   650  				res := buf.String()
   651  				assertInCode(t, "type WithMap struct {", res)
   652  				assertInCode(t, "Data map[string]map[string]map[string]string `json:\"data,omitempty\"`", res)
   653  			}
   654  		}
   655  	}
   656  }
   657  
   658  func TestGenerateModel_WithMapRegistryRef(t *testing.T) {
   659  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml")
   660  	if assert.NoError(t, err) {
   661  		definitions := specDoc.Spec().Definitions
   662  		k := "WithMapRegistryRef"
   663  		schema := definitions[k]
   664  		opts := opts()
   665  		genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts)
   666  		if assert.NoError(t, err) {
   667  			assert.False(t, genModel.HasAdditionalProperties)
   668  			prop := getDefinitionProperty(genModel, "data")
   669  			assert.True(t, prop.HasAdditionalProperties)
   670  			assert.True(t, prop.IsMap)
   671  			assert.False(t, prop.IsComplexObject)
   672  			buf := bytes.NewBuffer(nil)
   673  			err := templates.MustGet("model").Execute(buf, genModel)
   674  			if assert.NoError(t, err) {
   675  				res := buf.String()
   676  				assertInCode(t, "type "+k+" struct {", res)
   677  				assertInCode(t, "Data map[string]map[string]map[string]Notable `json:\"data,omitempty\"`", res)
   678  			}
   679  		}
   680  	}
   681  }
   682  
   683  func TestGenerateModel_WithMapComplexRegistry(t *testing.T) {
   684  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml")
   685  	if assert.NoError(t, err) {
   686  		definitions := specDoc.Spec().Definitions
   687  		k := "WithMapComplexRegistry"
   688  		schema := definitions[k]
   689  		opts := opts()
   690  		genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts)
   691  		if assert.NoError(t, err) {
   692  			assert.False(t, genModel.HasAdditionalProperties)
   693  			prop := getDefinitionProperty(genModel, "data")
   694  			assert.True(t, prop.HasAdditionalProperties)
   695  			assert.True(t, prop.IsMap)
   696  			assert.False(t, prop.IsComplexObject)
   697  			buf := bytes.NewBuffer(nil)
   698  			err := templates.MustGet("model").Execute(buf, genModel)
   699  			if assert.NoError(t, err) {
   700  				res := buf.String()
   701  				assertInCode(t, "type "+k+" struct {", res)
   702  				assertInCode(t, "Data map[string]map[string]map[string]"+k+"DataAnon `json:\"data,omitempty\"`", res)
   703  			}
   704  		}
   705  	}
   706  }
   707  
   708  func TestGenerateModel_WithAdditional(t *testing.T) {
   709  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml")
   710  	if assert.NoError(t, err) {
   711  		definitions := specDoc.Spec().Definitions
   712  		k := "WithAdditional"
   713  		schema := definitions[k]
   714  		opts := opts()
   715  		genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts)
   716  		if assert.NoError(t, err) && assert.NotEmpty(t, genModel.ExtraSchemas) {
   717  			assert.False(t, genModel.HasAdditionalProperties)
   718  			assert.False(t, genModel.IsMap)
   719  			assert.False(t, genModel.IsAdditionalProperties)
   720  			assert.True(t, genModel.IsComplexObject)
   721  
   722  			sch := genModel.ExtraSchemas[0]
   723  			assert.True(t, sch.HasAdditionalProperties)
   724  			assert.False(t, sch.IsMap)
   725  			assert.True(t, sch.IsAdditionalProperties)
   726  			assert.False(t, sch.IsComplexObject)
   727  
   728  			if assert.NotNil(t, sch.AdditionalProperties) {
   729  				prop := findProperty(genModel.Properties, "data")
   730  				assert.False(t, prop.HasAdditionalProperties)
   731  				assert.False(t, prop.IsMap)
   732  				assert.False(t, prop.IsAdditionalProperties)
   733  				assert.True(t, prop.IsComplexObject)
   734  				buf := bytes.NewBuffer(nil)
   735  				err := templates.MustGet("model").Execute(buf, genModel)
   736  				if assert.NoError(t, err) {
   737  					res := buf.String()
   738  					assertInCode(t, "type "+k+" struct {", res)
   739  					assertInCode(t, "Data *"+k+"Data `json:\"data,omitempty\"`", res)
   740  					assertInCode(t, "type "+k+"Data struct {", res)
   741  					assertInCode(t, k+"Data map[string]string `json:\"-\"`", res)
   742  					assertInCode(t, "Name *string `json:\"name\"`", res)
   743  					assertInCode(t, k+"Data) UnmarshalJSON", res)
   744  					assertInCode(t, k+"Data) MarshalJSON", res)
   745  					assertInCode(t, "json.Marshal(stage1)", res)
   746  					assertInCode(t, "stage1.Name = m.Name", res)
   747  					assertInCode(t, "json.Marshal(m."+k+"Data)", res)
   748  					assertInCode(t, "json.Unmarshal(data, &stage1)", res)
   749  					assertInCode(t, "json.Unmarshal(data, &stage2)", res)
   750  					assertInCode(t, "json.Unmarshal(v, &toadd)", res)
   751  					assertInCode(t, "result[k] = toadd", res)
   752  					assertInCode(t, "m."+k+"Data = result", res)
   753  					for _, p := range sch.Properties {
   754  						assertInCode(t, "delete(stage2, \""+p.Name+"\")", res)
   755  					}
   756  				}
   757  			}
   758  		}
   759  	}
   760  }
   761  
   762  func TestGenerateModel_JustRef(t *testing.T) {
   763  	tt := templateTest{t, templates.MustGet("model").Lookup("schema")}
   764  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml")
   765  	if assert.NoError(t, err) {
   766  		definitions := specDoc.Spec().Definitions
   767  		schema := definitions["JustRef"]
   768  		opts := opts()
   769  		genModel, err := makeGenDefinition("JustRef", "models", schema, specDoc, opts)
   770  		if assert.NoError(t, err) {
   771  			assert.NotEmpty(t, genModel.AllOf)
   772  			assert.True(t, genModel.IsComplexObject)
   773  			assert.Equal(t, "JustRef", genModel.Name)
   774  			assert.Equal(t, "JustRef", genModel.GoType)
   775  			buf := bytes.NewBuffer(nil)
   776  			err = tt.template.Execute(buf, genModel)
   777  			assert.NoError(t, err)
   778  			res := buf.String()
   779  			assertInCode(t, "type JustRef struct {", res)
   780  			assertInCode(t, "Notable", res)
   781  		}
   782  	}
   783  }
   784  
   785  func TestGenerateModel_WithRef(t *testing.T) {
   786  	tt := templateTest{t, templates.MustGet("model").Lookup("schema")}
   787  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml")
   788  	if assert.NoError(t, err) {
   789  		definitions := specDoc.Spec().Definitions
   790  		schema := definitions["WithRef"]
   791  		opts := opts()
   792  		genModel, err := makeGenDefinition("WithRef", "models", schema, specDoc, opts)
   793  		if assert.NoError(t, err) {
   794  			assert.True(t, genModel.IsComplexObject)
   795  			assert.Equal(t, "WithRef", genModel.Name)
   796  			assert.Equal(t, "WithRef", genModel.GoType)
   797  			buf := bytes.NewBuffer(nil)
   798  			err = tt.template.Execute(buf, genModel)
   799  			assert.NoError(t, err)
   800  			res := buf.String()
   801  			assertInCode(t, "type WithRef struct {", res)
   802  			assertInCode(t, "Notes *Notable `json:\"notes,omitempty\"`", res)
   803  		}
   804  	}
   805  }
   806  
   807  func TestGenerateModel_WithNullableRef(t *testing.T) {
   808  	tt := templateTest{t, templates.MustGet("model").Lookup("schema")}
   809  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml")
   810  	if assert.NoError(t, err) {
   811  		definitions := specDoc.Spec().Definitions
   812  		schema := definitions["WithNullableRef"]
   813  		opts := opts()
   814  		genModel, err := makeGenDefinition("WithNullableRef", "models", schema, specDoc, opts)
   815  		if assert.NoError(t, err) {
   816  			assert.True(t, genModel.IsComplexObject)
   817  			assert.Equal(t, "WithNullableRef", genModel.Name)
   818  			assert.Equal(t, "WithNullableRef", genModel.GoType)
   819  			prop := getDefinitionProperty(genModel, "notes")
   820  			assert.True(t, prop.IsNullable)
   821  			assert.True(t, prop.IsComplexObject)
   822  			buf := bytes.NewBuffer(nil)
   823  			err = tt.template.Execute(buf, genModel)
   824  			assert.NoError(t, err)
   825  			res := buf.String()
   826  			assertInCode(t, "type WithNullableRef struct {", res)
   827  			assertInCode(t, "Notes *Notable `json:\"notes,omitempty\"`", res)
   828  		}
   829  	}
   830  }
   831  
   832  func TestGenerateModel_Scores(t *testing.T) {
   833  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml")
   834  	if assert.NoError(t, err) {
   835  		definitions := specDoc.Spec().Definitions
   836  		k := "Scores"
   837  		schema := definitions[k]
   838  		opts := opts()
   839  		genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts)
   840  		if assert.NoError(t, err) {
   841  			buf := bytes.NewBuffer(nil)
   842  			err := templates.MustGet("model").Execute(buf, genModel)
   843  			if assert.NoError(t, err) {
   844  				ff, err := opts.LanguageOpts.FormatContent("scores.go", buf.Bytes())
   845  				if assert.NoError(t, err) {
   846  					res := string(ff)
   847  					assertInCode(t, "type Scores []float32", res)
   848  				}
   849  			}
   850  		}
   851  	}
   852  }
   853  
   854  func TestGenerateModel_JaggedScores(t *testing.T) {
   855  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml")
   856  	if assert.NoError(t, err) {
   857  		definitions := specDoc.Spec().Definitions
   858  		k := "JaggedScores"
   859  		schema := definitions[k]
   860  		opts := opts()
   861  		genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts)
   862  		if assert.NoError(t, err) {
   863  			buf := bytes.NewBuffer(nil)
   864  			err := templates.MustGet("model").Execute(buf, genModel)
   865  			if assert.NoError(t, err) {
   866  				ff, err := opts.LanguageOpts.FormatContent("jagged_scores.go", buf.Bytes())
   867  				if assert.NoError(t, err) {
   868  					res := string(ff)
   869  					assertInCode(t, "type JaggedScores [][][]float32", res)
   870  				}
   871  			}
   872  		}
   873  	}
   874  }
   875  
   876  func TestGenerateModel_Notables(t *testing.T) {
   877  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml")
   878  	if assert.NoError(t, err) {
   879  		definitions := specDoc.Spec().Definitions
   880  		k := "Notables"
   881  		schema := definitions[k]
   882  		opts := opts()
   883  		genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts)
   884  		if assert.NoError(t, err) && assert.Equal(t, "[]*Notable", genModel.GoType) {
   885  			buf := bytes.NewBuffer(nil)
   886  			err := templates.MustGet("model").Execute(buf, genModel)
   887  			if assert.NoError(t, err) {
   888  				ff, err := opts.LanguageOpts.FormatContent("notables.go", buf.Bytes())
   889  				if assert.NoError(t, err) {
   890  					res := string(ff)
   891  					assertInCode(t, "type Notables []*Notable", res)
   892  				}
   893  			}
   894  		}
   895  	}
   896  }
   897  
   898  func TestGenerateModel_Notablix(t *testing.T) {
   899  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml")
   900  	if assert.NoError(t, err) {
   901  		definitions := specDoc.Spec().Definitions
   902  		k := "Notablix"
   903  		schema := definitions[k]
   904  		opts := opts()
   905  		genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts)
   906  		if assert.NoError(t, err) {
   907  			buf := bytes.NewBuffer(nil)
   908  			err := templates.MustGet("model").Execute(buf, genModel)
   909  			if assert.NoError(t, err) {
   910  				ff, err := opts.LanguageOpts.FormatContent("notablix.go", buf.Bytes())
   911  				if assert.NoError(t, err) {
   912  					res := string(ff)
   913  					assertInCode(t, "type Notablix [][][]*Notable", res)
   914  				}
   915  			}
   916  		}
   917  	}
   918  }
   919  
   920  func TestGenerateModel_Stats(t *testing.T) {
   921  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml")
   922  	if assert.NoError(t, err) {
   923  		definitions := specDoc.Spec().Definitions
   924  		k := "Stats"
   925  		schema := definitions[k]
   926  		opts := opts()
   927  		genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts)
   928  		if assert.NoError(t, err) {
   929  			buf := bytes.NewBuffer(nil)
   930  			err := templates.MustGet("model").Execute(buf, genModel)
   931  			if assert.NoError(t, err) {
   932  				ff, err := opts.LanguageOpts.FormatContent("stats.go", buf.Bytes())
   933  				if assert.NoError(t, err) {
   934  					res := string(ff)
   935  					assertInCode(t, "type Stats []*StatsItems0", res)
   936  					assertInCode(t, "type StatsItems0 struct {", res)
   937  					assertInCode(t, "Points []int64 `json:\"points\"`", res)
   938  				}
   939  			}
   940  		}
   941  	}
   942  }
   943  
   944  func TestGenerateModel_Statix(t *testing.T) {
   945  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml")
   946  	if assert.NoError(t, err) {
   947  		definitions := specDoc.Spec().Definitions
   948  		k := "Statix"
   949  		schema := definitions[k]
   950  		opts := opts()
   951  		genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts)
   952  		// spew.Dump(genModel)
   953  		if assert.NoError(t, err) {
   954  			buf := bytes.NewBuffer(nil)
   955  			err := templates.MustGet("model").Execute(buf, genModel)
   956  			if assert.NoError(t, err) {
   957  				ff, err := opts.LanguageOpts.FormatContent("statix.go", buf.Bytes())
   958  				if assert.NoError(t, err) {
   959  					res := string(ff)
   960  					assertInCode(t, "type Statix [][][]*StatixItems0", res)
   961  					assertInCode(t, "type StatixItems0 struct {", res)
   962  					assertInCode(t, "Points []int64 `json:\"points\"`", res)
   963  				} /*else {
   964  					fmt.Println(buf.String())
   965  				}*/
   966  			}
   967  		}
   968  	}
   969  }
   970  
   971  func TestGenerateModel_WithItems(t *testing.T) {
   972  	tt := templateTest{t, templates.MustGet("model").Lookup("schema")}
   973  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml")
   974  	if assert.NoError(t, err) {
   975  		definitions := specDoc.Spec().Definitions
   976  		schema := definitions["WithItems"]
   977  		opts := opts()
   978  		genModel, err := makeGenDefinition("WithItems", "models", schema, specDoc, opts)
   979  		if assert.NoError(t, err) {
   980  			assert.Nil(t, genModel.Items)
   981  			assert.True(t, genModel.IsComplexObject)
   982  			prop := getDefinitionProperty(genModel, "tags")
   983  			assert.NotNil(t, prop.Items)
   984  			assert.True(t, prop.IsArray)
   985  			assert.False(t, prop.IsComplexObject)
   986  			buf := bytes.NewBuffer(nil)
   987  			err := tt.template.Execute(buf, genModel)
   988  			if assert.NoError(t, err) {
   989  				res := buf.String()
   990  				assertInCode(t, "type WithItems struct {", res)
   991  				assertInCode(t, "Tags []string `json:\"tags\"`", res)
   992  			}
   993  		}
   994  	}
   995  }
   996  
   997  func TestGenerateModel_WithComplexItems(t *testing.T) {
   998  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml")
   999  	if assert.NoError(t, err) {
  1000  		definitions := specDoc.Spec().Definitions
  1001  		k := "WithComplexItems"
  1002  		schema := definitions[k]
  1003  		opts := opts()
  1004  		genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts)
  1005  		if assert.NoError(t, err) {
  1006  			assert.Nil(t, genModel.Items)
  1007  			assert.True(t, genModel.IsComplexObject)
  1008  			prop := getDefinitionProperty(genModel, "tags")
  1009  			assert.NotNil(t, prop.Items)
  1010  			assert.True(t, prop.IsArray)
  1011  			assert.False(t, prop.IsComplexObject)
  1012  			buf := bytes.NewBuffer(nil)
  1013  			err := templates.MustGet("model").Execute(buf, genModel)
  1014  			if assert.NoError(t, err) {
  1015  				b, err := opts.LanguageOpts.FormatContent("with_complex_items.go", buf.Bytes())
  1016  				if assert.NoError(t, err) {
  1017  					res := string(b)
  1018  					assertInCode(t, "type WithComplexItems struct {", res)
  1019  					assertInCode(t, "type WithComplexItemsTagsItems0 struct {", res)
  1020  					assertInCode(t, "Tags []*WithComplexItemsTagsItems0 `json:\"tags\"`", res)
  1021  				}
  1022  			}
  1023  		}
  1024  	}
  1025  }
  1026  
  1027  func TestGenerateModel_WithItemsAndAdditional(t *testing.T) {
  1028  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml")
  1029  	if assert.NoError(t, err) {
  1030  		definitions := specDoc.Spec().Definitions
  1031  		k := "WithItemsAndAdditional"
  1032  		schema := definitions[k]
  1033  		opts := opts()
  1034  		genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts)
  1035  		if assert.NoError(t, err) {
  1036  			assert.Nil(t, genModel.Items)
  1037  			assert.True(t, genModel.IsComplexObject)
  1038  			prop := getDefinitionProperty(genModel, "tags")
  1039  			assert.True(t, prop.IsComplexObject)
  1040  			buf := bytes.NewBuffer(nil)
  1041  			err := templates.MustGet("model").Execute(buf, genModel)
  1042  			if assert.NoError(t, err) {
  1043  				b, err := opts.LanguageOpts.FormatContent("with_complex_items.go", buf.Bytes())
  1044  				if assert.NoError(t, err) {
  1045  					res := string(b)
  1046  					assertInCode(t, "type "+k+" struct {", res)
  1047  					assertInCode(t, "type "+k+"TagsTuple0 struct {", res)
  1048  					// this would fail if it accepts additionalItems because it would come out as []interface{}
  1049  					assertInCode(t, "Tags *"+k+"TagsTuple0 `json:\"tags,omitempty\"`", res)
  1050  					assertInCode(t, "P0 *string `json:\"-\"`", res)
  1051  					assertInCode(t, k+"TagsTuple0Items []interface{} `json:\"-\"`", res)
  1052  				}
  1053  			}
  1054  		}
  1055  	}
  1056  }
  1057  
  1058  func TestGenerateModel_WithItemsAndAdditional2(t *testing.T) {
  1059  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml")
  1060  	if assert.NoError(t, err) {
  1061  		definitions := specDoc.Spec().Definitions
  1062  		k := "WithItemsAndAdditional2"
  1063  		schema := definitions[k]
  1064  		opts := opts()
  1065  		genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts)
  1066  		if assert.NoError(t, err) {
  1067  			assert.Nil(t, genModel.Items)
  1068  			assert.True(t, genModel.IsComplexObject)
  1069  			prop := getDefinitionProperty(genModel, "tags")
  1070  			assert.True(t, prop.IsComplexObject)
  1071  			buf := bytes.NewBuffer(nil)
  1072  			err := templates.MustGet("model").Execute(buf, genModel)
  1073  			if assert.NoError(t, err) {
  1074  				b, err := opts.LanguageOpts.FormatContent("with_complex_items.go", buf.Bytes())
  1075  				if assert.NoError(t, err) {
  1076  					res := string(b)
  1077  					assertInCode(t, "type "+k+" struct {", res)
  1078  					assertInCode(t, "type "+k+"TagsTuple0 struct {", res)
  1079  					// this would fail if it accepts additionalItems because it would come out as []interface{}
  1080  					assertInCode(t, "P0 *string `json:\"-\"`", res)
  1081  					assertInCode(t, "Tags *"+k+"TagsTuple0 `json:\"tags,omitempty\"`", res)
  1082  					assertInCode(t, k+"TagsTuple0Items []int32 `json:\"-\"`", res)
  1083  
  1084  				}
  1085  			}
  1086  		}
  1087  	}
  1088  }
  1089  
  1090  func TestGenerateModel_WithComplexAdditional(t *testing.T) {
  1091  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml")
  1092  	if assert.NoError(t, err) {
  1093  		definitions := specDoc.Spec().Definitions
  1094  		k := "WithComplexAdditional"
  1095  		schema := definitions[k]
  1096  		opts := opts()
  1097  		genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts)
  1098  		if assert.NoError(t, err) {
  1099  			assert.Nil(t, genModel.Items)
  1100  			assert.True(t, genModel.IsComplexObject)
  1101  			prop := getDefinitionProperty(genModel, "tags")
  1102  			assert.True(t, prop.IsComplexObject)
  1103  			buf := bytes.NewBuffer(nil)
  1104  			err := templates.MustGet("model").Execute(buf, genModel)
  1105  			if assert.NoError(t, err) {
  1106  				b, err := opts.LanguageOpts.FormatContent("with_complex_additional.go", buf.Bytes())
  1107  				if assert.NoError(t, err) {
  1108  					res := string(b)
  1109  					assertInCode(t, "type WithComplexAdditional struct {", res)
  1110  					assertInCode(t, "type WithComplexAdditionalTagsTuple0 struct {", res)
  1111  					assertInCode(t, "Tags *WithComplexAdditionalTagsTuple0 `json:\"tags,omitempty\"`", res)
  1112  					assertInCode(t, "P0 *string `json:\"-\"`", res)
  1113  					assertInCode(t, "WithComplexAdditionalTagsTuple0Items []*WithComplexAdditionalTagsItems `json:\"-\"`", res)
  1114  				}
  1115  			}
  1116  		}
  1117  	}
  1118  }
  1119  
  1120  func TestGenerateModel_SimpleTuple(t *testing.T) {
  1121  	tt := templateTest{t, templates.MustGet("model")}
  1122  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml")
  1123  	if assert.NoError(t, err) {
  1124  		definitions := specDoc.Spec().Definitions
  1125  		k := "SimpleTuple"
  1126  		schema := definitions[k]
  1127  		opts := opts()
  1128  		genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts)
  1129  		if assert.NoError(t, err) && assert.Len(t, genModel.ExtraSchemas, 1) {
  1130  			// NOTE: with PR#1592, an extra schema is added here because of the allOf tuple element.
  1131  			// This uncovers another issue with special AllOfs (e.g. allOf [ ..., x-nullable:true ])
  1132  			// TODO(fredbi): fix liftSpecialAllOf() to revert to: assert.Empty(t, genModel.ExtraSchemas)
  1133  			assert.True(t, genModel.IsTuple)
  1134  			assert.False(t, genModel.IsComplexObject)
  1135  			assert.False(t, genModel.IsArray)
  1136  			assert.False(t, genModel.IsAnonymous)
  1137  			assert.Equal(t, k, genModel.Name)
  1138  			assert.Equal(t, k, genModel.GoType)
  1139  			assert.Len(t, genModel.Properties, 5)
  1140  			buf := bytes.NewBuffer(nil)
  1141  			err = tt.template.Execute(buf, genModel)
  1142  			assert.NoError(t, err)
  1143  			res := buf.String()
  1144  			assertInCode(t, "swagger:model "+k, res)
  1145  			assertInCode(t, "type "+k+" struct {", res)
  1146  			assertInCode(t, "P0 *int64 `json:\"-\"`", res)
  1147  			assertInCode(t, "P1 *string `json:\"-\"`", res)
  1148  			assertInCode(t, "P2 *strfmt.DateTime `json:\"-\"`", res)
  1149  			assertInCode(t, "P3 *Notable `json:\"-\"`", res)
  1150  			// NOTE: with PR#1592, an extra schema is added here because of the allOf tuple element.
  1151  			// This uncovers another issue with special AllOfs (e.g. allOf [ ..., x-nullable:true ])
  1152  			// TODO(fredbi): fix liftSpecialAllOf() to revert to: assert.Empty(t, genModel.ExtraSchemas)
  1153  			//assertInCode(t, "P4 *Notable `json:\"-\"`", res)
  1154  			assertInCode(t, "P4 *SimpleTupleItems4 `json:\"-\"`", res)
  1155  			assertInCode(t, k+") UnmarshalJSON", res)
  1156  			assertInCode(t, k+") MarshalJSON", res)
  1157  			assertInCode(t, "json.Marshal(data)", res)
  1158  			assert.NotRegexp(t, regexp.MustCompile("lastIndex"), res)
  1159  
  1160  			for i, p := range genModel.Properties {
  1161  				m := "m.P" + strconv.Itoa(i)
  1162  				r := "&dataP" + strconv.Itoa(i)
  1163  				var rr string
  1164  				if !p.IsNullable {
  1165  					rr = "dataP" + strconv.Itoa(i)
  1166  				} else {
  1167  					rr = r
  1168  				}
  1169  				assertInCode(t, fmt.Sprintf("buf = bytes.NewBuffer(stage1[%d])", i), res)
  1170  				assertInCode(t, fmt.Sprintf("dec.Decode(%s)", r), res)
  1171  				assertInCode(t, "P"+strconv.Itoa(i)+",", res)
  1172  				assertInCode(t, fmt.Sprintf("%s = %s", m, rr), res)
  1173  			}
  1174  		}
  1175  	}
  1176  }
  1177  
  1178  func TestGenerateModel_TupleWithExtra(t *testing.T) {
  1179  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml")
  1180  	if assert.NoError(t, err) {
  1181  		definitions := specDoc.Spec().Definitions
  1182  		k := "TupleWithExtra"
  1183  		schema := definitions[k]
  1184  		opts := opts()
  1185  		genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts)
  1186  		if assert.NoError(t, err) && assert.Empty(t, genModel.ExtraSchemas) {
  1187  			assert.True(t, genModel.IsTuple)
  1188  			assert.False(t, genModel.IsComplexObject)
  1189  			assert.False(t, genModel.IsArray)
  1190  			assert.False(t, genModel.IsAnonymous)
  1191  			assert.True(t, genModel.HasAdditionalItems)
  1192  			assert.NotNil(t, genModel.AdditionalItems)
  1193  			assert.Equal(t, k, genModel.Name)
  1194  			assert.Equal(t, k, genModel.GoType)
  1195  			assert.Len(t, genModel.Properties, 4)
  1196  			buf := bytes.NewBuffer(nil)
  1197  			err := templates.MustGet("model").Execute(buf, genModel)
  1198  			if assert.NoError(t, err) {
  1199  				ff, err := opts.LanguageOpts.FormatContent("tuple_with_extra.go", buf.Bytes())
  1200  				if assert.NoError(t, err) {
  1201  					res := string(ff)
  1202  					assertInCode(t, "swagger:model "+k, res)
  1203  					assertInCode(t, "type "+k+" struct {", res)
  1204  					assertInCode(t, "P0 *int64 `json:\"-\"`", res)
  1205  					assertInCode(t, "P1 *string `json:\"-\"`", res)
  1206  					assertInCode(t, "P2 *strfmt.DateTime `json:\"-\"`", res)
  1207  					assertInCode(t, "P3 *Notable `json:\"-\"`", res)
  1208  					assertInCode(t, k+"Items []float64 `json:\"-\"`", res)
  1209  					assertInCode(t, k+") UnmarshalJSON", res)
  1210  					assertInCode(t, k+") MarshalJSON", res)
  1211  
  1212  					for i, p := range genModel.Properties {
  1213  						m := "m.P" + strconv.Itoa(i)
  1214  						r := "&dataP" + strconv.Itoa(i)
  1215  						var rr string
  1216  						if !p.IsNullable {
  1217  							rr = "dataP" + strconv.Itoa(i)
  1218  						} else {
  1219  							rr = r
  1220  						}
  1221  						assertInCode(t, fmt.Sprintf("lastIndex = %d", i), res)
  1222  						assertInCode(t, fmt.Sprintf("buf = bytes.NewBuffer(stage1[%d])", i), res)
  1223  						assertInCode(t, "dec := json.NewDecoder(buf)", res)
  1224  						assertInCode(t, fmt.Sprintf("dec.Decode(%s)", r), res)
  1225  						assertInCode(t, "P"+strconv.Itoa(i)+",", res)
  1226  						assertInCode(t, fmt.Sprintf("%s = %s", m, rr), res)
  1227  					}
  1228  					assertInCode(t, "var lastIndex int", res)
  1229  					assertInCode(t, "var toadd float64", res)
  1230  					assertInCode(t, "for _, val := range stage1[lastIndex+1:]", res)
  1231  					assertInCode(t, "buf = bytes.NewBuffer(val)", res)
  1232  					assertInCode(t, "dec := json.NewDecoder(buf)", res)
  1233  					assertInCode(t, "dec.Decode(&toadd)", res)
  1234  					assertInCode(t, "json.Marshal(data)", res)
  1235  					assertInCode(t, "for _, v := range m."+k+"Items", res)
  1236  				}
  1237  			}
  1238  		}
  1239  	}
  1240  }
  1241  
  1242  func TestGenerateModel_TupleWithComplex(t *testing.T) {
  1243  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml")
  1244  	if assert.NoError(t, err) {
  1245  		definitions := specDoc.Spec().Definitions
  1246  		k := "TupleWithComplex"
  1247  		schema := definitions[k]
  1248  		opts := opts()
  1249  		genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts)
  1250  		if assert.NoError(t, err) { //&& assert.Empty(t, genModel.ExtraSchemas) {
  1251  			assert.True(t, genModel.IsTuple)
  1252  			assert.False(t, genModel.IsComplexObject)
  1253  			assert.False(t, genModel.IsArray)
  1254  			assert.False(t, genModel.IsAnonymous)
  1255  			assert.True(t, genModel.HasAdditionalItems)
  1256  			assert.NotNil(t, genModel.AdditionalItems)
  1257  			assert.Equal(t, k, genModel.Name)
  1258  			assert.Equal(t, k, genModel.GoType)
  1259  			assert.Len(t, genModel.Properties, 4)
  1260  			buf := bytes.NewBuffer(nil)
  1261  			err := templates.MustGet("model").Execute(buf, genModel)
  1262  			if assert.NoError(t, err) {
  1263  				ff, err := opts.LanguageOpts.FormatContent("tuple_with_extra.go", buf.Bytes())
  1264  				if assert.NoError(t, err) {
  1265  					res := string(ff)
  1266  					assertInCode(t, "swagger:model "+k, res)
  1267  					assertInCode(t, "type "+k+" struct {", res)
  1268  					assertInCode(t, "P0 *int64 `json:\"-\"`", res)
  1269  					assertInCode(t, "P1 *string `json:\"-\"`", res)
  1270  					assertInCode(t, "P2 *strfmt.DateTime `json:\"-\"`", res)
  1271  					assertInCode(t, "P3 *Notable `json:\"-\"`", res)
  1272  					assertInCode(t, k+"Items []*TupleWithComplexItems `json:\"-\"`", res)
  1273  					assertInCode(t, k+") UnmarshalJSON", res)
  1274  					assertInCode(t, k+") MarshalJSON", res)
  1275  
  1276  					for i, p := range genModel.Properties {
  1277  						m := "m.P" + strconv.Itoa(i)
  1278  						r := "&dataP" + strconv.Itoa(i)
  1279  						var rr string
  1280  						if !p.IsNullable {
  1281  							rr = "dataP" + strconv.Itoa(i)
  1282  						} else {
  1283  							rr = r
  1284  						}
  1285  						assertInCode(t, fmt.Sprintf("lastIndex = %d", i), res)
  1286  						assertInCode(t, fmt.Sprintf("buf = bytes.NewBuffer(stage1[%d])", i), res)
  1287  						assertInCode(t, "dec := json.NewDecoder(buf)", res)
  1288  						assertInCode(t, fmt.Sprintf("dec.Decode(%s)", r), res)
  1289  						assertInCode(t, "P"+strconv.Itoa(i)+",", res)
  1290  						assertInCode(t, fmt.Sprintf("%s = %s", m, rr), res)
  1291  					}
  1292  
  1293  					assertInCode(t, "var lastIndex int", res)
  1294  					assertInCode(t, "var toadd *TupleWithComplexItems", res)
  1295  					assertInCode(t, "for _, val := range stage1[lastIndex+1:]", res)
  1296  					assertInCode(t, "buf = bytes.NewBuffer(val)", res)
  1297  					assertInCode(t, "dec := json.NewDecoder(buf)", res)
  1298  					assertInCode(t, "dec.Decode(toadd)", res)
  1299  					assertInCode(t, "json.Marshal(data)", res)
  1300  					assertInCode(t, "for _, v := range m."+k+"Items", res)
  1301  				}
  1302  			}
  1303  		}
  1304  	}
  1305  }
  1306  
  1307  func TestGenerateModel_WithTuple(t *testing.T) {
  1308  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml")
  1309  	if assert.NoError(t, err) {
  1310  		definitions := specDoc.Spec().Definitions
  1311  		k := "WithTuple"
  1312  		schema := definitions[k]
  1313  		opts := opts()
  1314  		genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts)
  1315  		if assert.NoError(t, err) && assert.NotEmpty(t, genModel.ExtraSchemas) && assert.NotEmpty(t, genModel.Properties) {
  1316  			assert.False(t, genModel.IsTuple)
  1317  			assert.True(t, genModel.IsComplexObject)
  1318  			assert.False(t, genModel.IsArray)
  1319  			assert.False(t, genModel.IsAnonymous)
  1320  
  1321  			sch := genModel.ExtraSchemas[0]
  1322  			assert.True(t, sch.IsTuple)
  1323  			assert.False(t, sch.IsComplexObject)
  1324  			assert.False(t, sch.IsArray)
  1325  			assert.False(t, sch.IsAnonymous)
  1326  			assert.Equal(t, k+"FlagsTuple0", sch.Name)
  1327  			assert.False(t, sch.HasAdditionalItems)
  1328  			assert.Nil(t, sch.AdditionalItems)
  1329  
  1330  			prop := genModel.Properties[0]
  1331  			assert.False(t, genModel.IsTuple)
  1332  			assert.True(t, genModel.IsComplexObject)
  1333  			assert.False(t, prop.IsArray)
  1334  			assert.False(t, prop.IsAnonymous)
  1335  			assert.Equal(t, k+"FlagsTuple0", prop.GoType)
  1336  			assert.Equal(t, "flags", prop.Name)
  1337  			buf := bytes.NewBuffer(nil)
  1338  			err := templates.MustGet("model").Execute(buf, genModel)
  1339  			if assert.NoError(t, err) {
  1340  				ff, err := opts.LanguageOpts.FormatContent("with_tuple.go", buf.Bytes())
  1341  				if assert.NoError(t, err) {
  1342  					res := string(ff)
  1343  					assertInCode(t, "swagger:model "+k+"Flags", res)
  1344  					assertInCode(t, "type "+k+"FlagsTuple0 struct {", res)
  1345  					assertInCode(t, "P0 *int64 `json:\"-\"`", res)
  1346  					assertInCode(t, "P1 *string `json:\"-\"`", res)
  1347  					assertInCode(t, k+"FlagsTuple0) UnmarshalJSON", res)
  1348  					assertInCode(t, k+"FlagsTuple0) MarshalJSON", res)
  1349  					assertInCode(t, "json.Marshal(data)", res)
  1350  					assert.NotRegexp(t, regexp.MustCompile("lastIndex"), res)
  1351  
  1352  					for i, p := range sch.Properties {
  1353  						m := "m.P" + strconv.Itoa(i)
  1354  						r := "&dataP" + strconv.Itoa(i)
  1355  						var rr string
  1356  						if !p.IsNullable {
  1357  							rr = "dataP" + strconv.Itoa(i)
  1358  						} else {
  1359  							rr = r
  1360  						}
  1361  						assertInCode(t, fmt.Sprintf("buf = bytes.NewBuffer(stage1[%d])", i), res)
  1362  						assertInCode(t, "dec := json.NewDecoder(buf)", res)
  1363  						assertInCode(t, fmt.Sprintf("dec.Decode(%s)", r), res)
  1364  						assertInCode(t, "P"+strconv.Itoa(i)+",", res)
  1365  						assertInCode(t, fmt.Sprintf("%s = %s", m, rr), res)
  1366  					}
  1367  				}
  1368  			}
  1369  		}
  1370  	}
  1371  }
  1372  
  1373  func TestGenerateModel_WithTupleWithExtra(t *testing.T) {
  1374  	tt := templateTest{t, templates.MustGet("model")}
  1375  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml")
  1376  	if assert.NoError(t, err) {
  1377  		definitions := specDoc.Spec().Definitions
  1378  		k := "WithTupleWithExtra"
  1379  		schema := definitions[k]
  1380  		opts := opts()
  1381  		genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts)
  1382  		if assert.NoError(t, err) && assert.NotEmpty(t, genModel.ExtraSchemas) && assert.NotEmpty(t, genModel.Properties) {
  1383  			assert.False(t, genModel.IsTuple)
  1384  			assert.True(t, genModel.IsComplexObject)
  1385  			assert.False(t, genModel.IsArray)
  1386  			assert.False(t, genModel.IsAnonymous)
  1387  
  1388  			sch := genModel.ExtraSchemas[0]
  1389  			assert.True(t, sch.IsTuple)
  1390  			assert.False(t, sch.IsComplexObject)
  1391  			assert.False(t, sch.IsArray)
  1392  			assert.False(t, sch.IsAnonymous)
  1393  			assert.Equal(t, k+"FlagsTuple0", sch.Name)
  1394  			assert.True(t, sch.HasAdditionalItems)
  1395  			assert.NotEmpty(t, sch.AdditionalItems)
  1396  
  1397  			prop := genModel.Properties[0]
  1398  			assert.False(t, genModel.IsTuple)
  1399  			assert.True(t, genModel.IsComplexObject)
  1400  			assert.False(t, prop.IsArray)
  1401  			assert.False(t, prop.IsAnonymous)
  1402  			assert.Equal(t, k+"FlagsTuple0", prop.GoType)
  1403  			assert.Equal(t, "flags", prop.Name)
  1404  			buf := bytes.NewBuffer(nil)
  1405  			err := tt.template.Execute(buf, genModel)
  1406  			if assert.NoError(t, err) {
  1407  				ff, err := opts.LanguageOpts.FormatContent("with_tuple.go", buf.Bytes())
  1408  				if assert.NoError(t, err) {
  1409  					res := string(ff)
  1410  					assertInCode(t, "swagger:model "+k+"Flags", res)
  1411  					assertInCode(t, "type "+k+"FlagsTuple0 struct {", res)
  1412  					assertInCode(t, "P0 *int64 `json:\"-\"`", res)
  1413  					assertInCode(t, "P1 *string `json:\"-\"`", res)
  1414  					assertInCode(t, k+"FlagsTuple0Items []float32 `json:\"-\"`", res)
  1415  					assertInCode(t, k+"FlagsTuple0) UnmarshalJSON", res)
  1416  					assertInCode(t, k+"FlagsTuple0) MarshalJSON", res)
  1417  					assertInCode(t, "json.Marshal(data)", res)
  1418  
  1419  					for i, p := range sch.Properties {
  1420  						m := "m.P" + strconv.Itoa(i)
  1421  						r := "&dataP" + strconv.Itoa(i)
  1422  						var rr string
  1423  						if !p.IsNullable {
  1424  							rr = "dataP" + strconv.Itoa(i)
  1425  						} else {
  1426  							rr = r
  1427  						}
  1428  						assertInCode(t, fmt.Sprintf("lastIndex = %d", i), res)
  1429  						assertInCode(t, fmt.Sprintf("buf = bytes.NewBuffer(stage1[%d])", i), res)
  1430  						assertInCode(t, "dec := json.NewDecoder(buf)", res)
  1431  						assertInCode(t, fmt.Sprintf("dec.Decode(%s)", r), res)
  1432  						assertInCode(t, "P"+strconv.Itoa(i)+",", res)
  1433  						assertInCode(t, fmt.Sprintf("%s = %s", m, rr), res)
  1434  					}
  1435  
  1436  					assertInCode(t, "var lastIndex int", res)
  1437  					assertInCode(t, "var toadd float32", res)
  1438  					assertInCode(t, "for _, val := range stage1[lastIndex+1:]", res)
  1439  					assertInCode(t, "buf = bytes.NewBuffer(val)", res)
  1440  					assertInCode(t, "dec := json.NewDecoder(buf)", res)
  1441  					assertInCode(t, "dec.Decode(&toadd)", res)
  1442  					assertInCode(t, "json.Marshal(data)", res)
  1443  					assertInCode(t, "for _, v := range m."+k+"FlagsTuple0Items", res)
  1444  				}
  1445  			}
  1446  		}
  1447  	}
  1448  }
  1449  
  1450  func TestGenerateModel_WithAllOfAndDiscriminator(t *testing.T) {
  1451  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml")
  1452  	if assert.NoError(t, err) {
  1453  		definitions := specDoc.Spec().Definitions
  1454  		schema := definitions["Cat"]
  1455  		opts := opts()
  1456  		genModel, err := makeGenDefinition("Cat", "models", schema, specDoc, opts)
  1457  		if assert.NoError(t, err) && assert.Len(t, genModel.AllOf, 2) {
  1458  			assert.True(t, genModel.IsComplexObject)
  1459  			assert.Equal(t, "Cat", genModel.Name)
  1460  			assert.Equal(t, "Cat", genModel.GoType)
  1461  			buf := bytes.NewBuffer(nil)
  1462  			err := templates.MustGet("model").Execute(buf, genModel)
  1463  			if assert.NoError(t, err) {
  1464  				ct, err := opts.LanguageOpts.FormatContent("cat.go", buf.Bytes())
  1465  				if assert.NoError(t, err) {
  1466  					res := string(ct)
  1467  					assertInCode(t, "type Cat struct {", res)
  1468  					assertInCode(t, "Pet", res)
  1469  					assertInCode(t, "HuntingSkill *string `json:\"huntingSkill\"`", res)
  1470  				}
  1471  			}
  1472  		}
  1473  	}
  1474  }
  1475  
  1476  func TestGenerateModel_WithAllOfAndDiscriminatorAndArrayOfPolymorphs(t *testing.T) {
  1477  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml")
  1478  	if assert.NoError(t, err) {
  1479  		definitions := specDoc.Spec().Definitions
  1480  		schema := definitions["PetWithPets"]
  1481  		opts := opts()
  1482  		genModel, err := makeGenDefinition("PetWithPets", "models", schema, specDoc, opts)
  1483  		if assert.NoError(t, err) && assert.Len(t, genModel.AllOf, 2) {
  1484  			assert.True(t, genModel.IsComplexObject)
  1485  			assert.Equal(t, "PetWithPets", genModel.Name)
  1486  			assert.Equal(t, "PetWithPets", genModel.GoType)
  1487  			buf := bytes.NewBuffer(nil)
  1488  			err := templates.MustGet("model").Execute(buf, genModel)
  1489  			if assert.NoError(t, err) {
  1490  				ct, err := opts.LanguageOpts.FormatContent("PetWithPets.go", buf.Bytes())
  1491  				if assert.NoError(t, err) {
  1492  					res := string(ct)
  1493  					assertInCode(t, "type PetWithPets struct {", res)
  1494  					assertInCode(t, "UnmarshalPetSlice", res)
  1495  				}
  1496  			}
  1497  		}
  1498  	}
  1499  }
  1500  
  1501  func TestGenerateModel_WithAllOf(t *testing.T) {
  1502  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml")
  1503  	if assert.NoError(t, err) {
  1504  		definitions := specDoc.Spec().Definitions
  1505  		schema := definitions["WithAllOf"]
  1506  		opts := opts()
  1507  		genModel, err := makeGenDefinition("WithAllOf", "models", schema, specDoc, opts)
  1508  		if assert.NoError(t, err) {
  1509  			assert.Len(t, genModel.AllOf, 7)
  1510  			assert.True(t, genModel.AllOf[1].HasAdditionalProperties)
  1511  			assert.True(t, genModel.IsComplexObject)
  1512  			assert.Equal(t, "WithAllOf", genModel.Name)
  1513  			assert.Equal(t, "WithAllOf", genModel.GoType)
  1514  			buf := bytes.NewBuffer(nil)
  1515  			err := templates.MustGet("model").Execute(buf, genModel)
  1516  			if assert.NoError(t, err) {
  1517  				ct, err := opts.LanguageOpts.FormatContent("all_of_schema.go", buf.Bytes())
  1518  				if assert.NoError(t, err) {
  1519  					res := string(ct)
  1520  					assertInCode(t, "type WithAllOf struct {", res)
  1521  					assertInCode(t, "type WithAllOfAO2P2 struct {", res)
  1522  					assertInCode(t, "type WithAllOfAO3P3 struct {", res)
  1523  					assertInCode(t, "type WithAllOfParamsAnon struct {", res)
  1524  					assertInCode(t, "type WithAllOfAO4Tuple4 struct {", res)
  1525  					assertInCode(t, "type WithAllOfAO5Tuple5 struct {", res)
  1526  					assertInCode(t, "Notable", res)
  1527  					assertInCode(t, "Title string `json:\"title,omitempty\"`", res)
  1528  					assertInCode(t, "Body string `json:\"body,omitempty\"`", res)
  1529  					assertInCode(t, "Name string `json:\"name,omitempty\"`", res)
  1530  					assertInCode(t, "P0 *float32 `json:\"-\"`", res)
  1531  					assertInCode(t, "P0 *float64 `json:\"-\"`", res)
  1532  					assertInCode(t, "P1 *strfmt.DateTime `json:\"-\"`", res)
  1533  					assertInCode(t, "P1 *strfmt.Date `json:\"-\"`", res)
  1534  					assertInCode(t, "Opinion string `json:\"opinion,omitempty\"`", res)
  1535  					assertInCode(t, "WithAllOfAO5Tuple5Items []strfmt.Password `json:\"-\"`", res)
  1536  					assertInCode(t, "AO1 map[string]int32 `json:\"-\"`", res)
  1537  					assertInCode(t, "WithAllOfAO2P2 map[string]int64 `json:\"-\"`", res)
  1538  				}
  1539  			}
  1540  		}
  1541  	}
  1542  }
  1543  
  1544  func findProperty(properties []GenSchema, name string) *GenSchema {
  1545  	for _, p := range properties {
  1546  		if p.Name == name {
  1547  			return &p
  1548  		}
  1549  	}
  1550  	return nil
  1551  }
  1552  
  1553  func getDefinitionProperty(genModel *GenDefinition, name string) *GenSchema {
  1554  	return findProperty(genModel.Properties, name)
  1555  }
  1556  
  1557  func TestNumericKeys(t *testing.T) {
  1558  	specDoc, err := loads.Spec("../fixtures/bugs/162/swagger.yml")
  1559  	if assert.NoError(t, err) {
  1560  		definitions := specDoc.Spec().Definitions
  1561  		schema := definitions["AvatarUrls"]
  1562  		opts := opts()
  1563  		genModel, err := makeGenDefinition("AvatarUrls", "models", schema, specDoc, opts)
  1564  		if assert.NoError(t, err) {
  1565  			buf := bytes.NewBuffer(nil)
  1566  			err := templates.MustGet("model").Execute(buf, genModel)
  1567  			if assert.NoError(t, err) {
  1568  				ct, err := opts.LanguageOpts.FormatContent("all_of_schema.go", buf.Bytes())
  1569  				if assert.NoError(t, err) {
  1570  					res := string(ct)
  1571  					assertInCode(t, "Nr16x16 string `json:\"16x16,omitempty\"`", res)
  1572  				}
  1573  			}
  1574  		}
  1575  	}
  1576  }
  1577  
  1578  func TestGenModel_Issue196(t *testing.T) {
  1579  	specDoc, err := loads.Spec("../fixtures/bugs/196/swagger.yml")
  1580  	if assert.NoError(t, err) {
  1581  		definitions := specDoc.Spec().Definitions
  1582  		schema := definitions["Event"]
  1583  		opts := opts()
  1584  		genModel, err := makeGenDefinition("Event", "models", schema, specDoc, opts)
  1585  		if assert.NoError(t, err) {
  1586  			buf := bytes.NewBuffer(nil)
  1587  			err := templates.MustGet("model").Execute(buf, genModel)
  1588  			if assert.NoError(t, err) {
  1589  				ct, err := opts.LanguageOpts.FormatContent("primitive_event.go", buf.Bytes())
  1590  				if assert.NoError(t, err) {
  1591  					res := string(ct)
  1592  					assertInCode(t, "Event) Validate(formats strfmt.Registry) error", res)
  1593  				}
  1594  			}
  1595  		}
  1596  	}
  1597  }
  1598  
  1599  func TestGenModel_Issue222(t *testing.T) {
  1600  	specDoc, err := loads.Spec("../fixtures/codegen/tasklist.basic.yml")
  1601  	if assert.NoError(t, err) {
  1602  		definitions := specDoc.Spec().Definitions
  1603  		k := "Price"
  1604  		opts := opts()
  1605  		genModel, err := makeGenDefinition(k, "models", definitions[k], specDoc, opts)
  1606  		if assert.NoError(t, err) && assert.True(t, genModel.HasValidations) {
  1607  			buf := bytes.NewBuffer(nil)
  1608  			err := templates.MustGet("model").Execute(buf, genModel)
  1609  			if assert.NoError(t, err) {
  1610  				ct, err := opts.LanguageOpts.FormatContent("price.go", buf.Bytes())
  1611  				if assert.NoError(t, err) {
  1612  					res := string(ct)
  1613  					assertInCode(t, "Price) Validate(formats strfmt.Registry) error", res)
  1614  					assertInCode(t, "Currency Currency `json:\"currency,omitempty\"`", res)
  1615  					assertInCode(t, "m.Currency.Validate(formats); err != nil", res)
  1616  				}
  1617  			}
  1618  		}
  1619  	}
  1620  }
  1621  
  1622  func TestGenModel_Issue243(t *testing.T) {
  1623  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml")
  1624  	if assert.NoError(t, err) {
  1625  		definitions := specDoc.Spec().Definitions
  1626  		k := "HasDynMeta"
  1627  		opts := opts()
  1628  		genModel, err := makeGenDefinition(k, "models", definitions[k], specDoc, opts)
  1629  		if assert.NoError(t, err) {
  1630  			buf := bytes.NewBuffer(nil)
  1631  			err := templates.MustGet("model").Execute(buf, genModel)
  1632  			if assert.NoError(t, err) {
  1633  				ct, err := opts.LanguageOpts.FormatContent("has_dyn_meta.go", buf.Bytes())
  1634  				if assert.NoError(t, err) {
  1635  					res := string(ct)
  1636  					if !assertInCode(t, "Metadata DynamicMetaData `json:\"metadata,omitempty\"`", res) {
  1637  						fmt.Println(res)
  1638  					}
  1639  				}
  1640  			}
  1641  		}
  1642  	}
  1643  }
  1644  
  1645  func TestGenModel_Issue252(t *testing.T) {
  1646  	specDoc, err := loads.Spec("../fixtures/bugs/252/swagger.json")
  1647  	if assert.NoError(t, err) {
  1648  		definitions := specDoc.Spec().Definitions
  1649  		k := "SodaBrand"
  1650  		opts := opts()
  1651  		genModel, err := makeGenDefinition(k, "models", definitions[k], specDoc, opts)
  1652  		if assert.NoError(t, err) && assert.False(t, genModel.IsNullable) {
  1653  			buf := bytes.NewBuffer(nil)
  1654  			err := templates.MustGet("model").Execute(buf, genModel)
  1655  			if assert.NoError(t, err) {
  1656  				ct, err := opts.LanguageOpts.FormatContent("soda_brand.go", buf.Bytes())
  1657  				if assert.NoError(t, err) {
  1658  					res := string(ct)
  1659  					b1 := assertInCode(t, "type "+k+" string", res)
  1660  					b2 := assertInCode(t, "(m "+k+") validateSodaBrand", res)
  1661  					b3 := assertInCode(t, "(m "+k+") Validate", res)
  1662  					if !(b1 && b2 && b3) {
  1663  						fmt.Println(res)
  1664  					}
  1665  				}
  1666  			}
  1667  		}
  1668  	}
  1669  }
  1670  
  1671  func TestGenModel_Issue251(t *testing.T) {
  1672  	specDoc, err := loads.Spec("../fixtures/bugs/251/swagger.yml")
  1673  	if assert.NoError(t, err) {
  1674  		definitions := specDoc.Spec().Definitions
  1675  		k := "example"
  1676  		opts := opts()
  1677  		genModel, err := makeGenDefinition(k, "models", definitions[k], specDoc, opts)
  1678  		if assert.NoError(t, err) {
  1679  			buf := bytes.NewBuffer(nil)
  1680  			err := templates.MustGet("model").Execute(buf, genModel)
  1681  			if assert.NoError(t, err) {
  1682  				ct, err := opts.LanguageOpts.FormatContent("example.go", buf.Bytes())
  1683  				if assert.NoError(t, err) {
  1684  					res := string(ct)
  1685  
  1686  					b1 := assertInCode(t, "type "+swag.ToGoName(k)+" struct", res)
  1687  					b2 := assertInCode(t, "Begin *strfmt.DateTime `json:\"begin\"`", res)
  1688  					b3 := assertInCode(t, "End strfmt.DateTime `json:\"end,omitempty\"`", res)
  1689  					b4 := assertInCode(t, "Name string `json:\"name,omitempty\"`", res)
  1690  					b5 := assertInCode(t, "(m *"+swag.ToGoName(k)+") validateBegin", res)
  1691  					//b6 := assertInCode(t, "(m *"+swag.ToGoName(k)+") validateEnd", res)
  1692  					b7 := assertInCode(t, "(m *"+swag.ToGoName(k)+") Validate", res)
  1693  					if !(b1 && b2 && b3 && b4 && b5 && b7) {
  1694  						fmt.Println(res)
  1695  					}
  1696  				}
  1697  			}
  1698  		}
  1699  	}
  1700  }
  1701  
  1702  func TestGenModel_Issue257(t *testing.T) {
  1703  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml")
  1704  	if assert.NoError(t, err) {
  1705  		definitions := specDoc.Spec().Definitions
  1706  		k := "HasSpecialCharProp"
  1707  		opts := opts()
  1708  		genModel, err := makeGenDefinition(k, "models", definitions[k], specDoc, opts)
  1709  		if assert.NoError(t, err) {
  1710  			buf := bytes.NewBuffer(nil)
  1711  			err := templates.MustGet("model").Execute(buf, genModel)
  1712  			if assert.NoError(t, err) {
  1713  				ct, err := opts.LanguageOpts.FormatContent("example.go", buf.Bytes())
  1714  				if assert.NoError(t, err) {
  1715  					res := string(ct)
  1716  
  1717  					b1 := assertInCode(t, "type "+swag.ToGoName(k)+" struct", res)
  1718  					b2 := assertInCode(t, "AtType string `json:\"@type,omitempty\"`", res)
  1719  					b3 := assertInCode(t, "Type string `json:\"type,omitempty\"`", res)
  1720  					if !(b1 && b2 && b3) {
  1721  						fmt.Println(res)
  1722  					}
  1723  				}
  1724  			}
  1725  		}
  1726  	}
  1727  }
  1728  
  1729  func TestGenModel_Issue340(t *testing.T) {
  1730  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml")
  1731  	if assert.NoError(t, err) {
  1732  		definitions := specDoc.Spec().Definitions
  1733  		k := "ImageTar"
  1734  		opts := opts()
  1735  		genModel, err := makeGenDefinition(k, "models", definitions[k], specDoc, opts)
  1736  		if assert.NoError(t, err) {
  1737  			buf := bytes.NewBuffer(nil)
  1738  			err := templates.MustGet("model").Execute(buf, genModel)
  1739  			if assert.NoError(t, err) {
  1740  				ct, err := opts.LanguageOpts.FormatContent("image_tar.go", buf.Bytes())
  1741  				if assert.NoError(t, err) {
  1742  					res := string(ct)
  1743  
  1744  					b1 := assertInCode(t, "type "+swag.ToGoName(k)+" io.ReadCloser", res)
  1745  					b2 := assertNotInCode(t, "func (m ImageTar) Validate(formats strfmt.Registry) error", res)
  1746  					if !(b1 && b2) {
  1747  						fmt.Println(res)
  1748  					}
  1749  				}
  1750  			}
  1751  		}
  1752  	}
  1753  }
  1754  
  1755  func TestGenModel_Issue381(t *testing.T) {
  1756  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml")
  1757  	if assert.NoError(t, err) {
  1758  		definitions := specDoc.Spec().Definitions
  1759  		k := "flags_list"
  1760  		opts := opts()
  1761  		genModel, err := makeGenDefinition(k, "models", definitions[k], specDoc, opts)
  1762  		if assert.NoError(t, err) {
  1763  			buf := bytes.NewBuffer(nil)
  1764  			err := templates.MustGet("model").Execute(buf, genModel)
  1765  			if assert.NoError(t, err) {
  1766  				ct, err := opts.LanguageOpts.FormatContent("flags_list.go", buf.Bytes())
  1767  				if assert.NoError(t, err) {
  1768  					res := string(ct)
  1769  					assertNotInCode(t, "m[i] != nil", res)
  1770  				}
  1771  			}
  1772  		}
  1773  	}
  1774  }
  1775  
  1776  func TestGenModel_Issue300(t *testing.T) {
  1777  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml")
  1778  	if assert.NoError(t, err) {
  1779  		definitions := specDoc.Spec().Definitions
  1780  		k := "ActionItem"
  1781  		opts := opts()
  1782  		genModel, err := makeGenDefinition(k, "models", definitions[k], specDoc, opts)
  1783  		if assert.NoError(t, err) {
  1784  			buf := bytes.NewBuffer(nil)
  1785  			err := templates.MustGet("model").Execute(buf, genModel)
  1786  			if assert.NoError(t, err) {
  1787  				ct, err := opts.LanguageOpts.FormatContent("action_item.go", buf.Bytes())
  1788  				if assert.NoError(t, err) {
  1789  					res := string(ct)
  1790  					assertInCode(t, "Name ActionName `json:\"name\"`", res)
  1791  				} else {
  1792  					fmt.Println(buf.String())
  1793  				}
  1794  			}
  1795  		}
  1796  	}
  1797  }
  1798  
  1799  func TestGenModel_Issue398(t *testing.T) {
  1800  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml")
  1801  	if assert.NoError(t, err) {
  1802  		definitions := specDoc.Spec().Definitions
  1803  		k := "Property"
  1804  		opts := opts()
  1805  		genModel, err := makeGenDefinition(k, "models", definitions[k], specDoc, opts)
  1806  		if assert.NoError(t, err) {
  1807  			buf := bytes.NewBuffer(nil)
  1808  			err := templates.MustGet("model").Execute(buf, genModel)
  1809  			if assert.NoError(t, err) {
  1810  				ct, err := opts.LanguageOpts.FormatContent("action_item.go", buf.Bytes())
  1811  				if assert.NoError(t, err) {
  1812  					res := string(ct)
  1813  					assertInCode(t, "Computed bool `json:\"computed,omitempty\"`", res)
  1814  					assertInCode(t, "Intval *int64 `json:\"intval\"`", res)
  1815  					assertInCode(t, "PropType *string `json:\"propType\"`", res)
  1816  					assertInCode(t, "Strval *string `json:\"strval\"`", res)
  1817  				} else {
  1818  					fmt.Println(buf.String())
  1819  				}
  1820  			}
  1821  		}
  1822  	}
  1823  }
  1824  
  1825  func TestGenModel_Issue454(t *testing.T) {
  1826  	specDoc, err := loads.Spec("../fixtures/bugs/454/swagger.yml")
  1827  	if assert.NoError(t, err) {
  1828  		definitions := specDoc.Spec().Definitions
  1829  		schema := definitions["genericResource"]
  1830  		opts := opts()
  1831  		genModel, err := makeGenDefinition("genericResource", "models", schema, specDoc, opts)
  1832  		if assert.NoError(t, err) {
  1833  			buf := bytes.NewBuffer(nil)
  1834  			err := templates.MustGet("model").Execute(buf, genModel)
  1835  			if assert.NoError(t, err) {
  1836  				ct, err := opts.LanguageOpts.FormatContent("generic_resource.go", buf.Bytes())
  1837  				if assert.NoError(t, err) {
  1838  					res := string(ct)
  1839  					assertInCode(t, "rcv.Meta = stage1.Meta", res)
  1840  					assertInCode(t, "json.Marshal(stage1)", res)
  1841  					assertInCode(t, "stage1.Meta = m.Meta", res)
  1842  					assertInCode(t, "json.Marshal(m.GenericResource)", res)
  1843  				}
  1844  			}
  1845  		}
  1846  	}
  1847  }
  1848  
  1849  func TestGenModel_Issue423(t *testing.T) {
  1850  	specDoc, err := loads.Spec("../fixtures/bugs/423/swagger.json")
  1851  	if assert.NoError(t, err) {
  1852  		definitions := specDoc.Spec().Definitions
  1853  		schema := definitions["SRN"]
  1854  		opts := opts()
  1855  		genModel, err := makeGenDefinition("SRN", "models", schema, specDoc, opts)
  1856  		if assert.NoError(t, err) {
  1857  			buf := bytes.NewBuffer(nil)
  1858  			err := templates.MustGet("model").Execute(buf, genModel)
  1859  			if assert.NoError(t, err) {
  1860  				ct, err := opts.LanguageOpts.FormatContent("SRN.go", buf.Bytes())
  1861  				if assert.NoError(t, err) {
  1862  					res := string(ct)
  1863  					assertInCode(t, "propSite, err := UnmarshalSite(bytes.NewBuffer(data.Site), runtime.JSONConsumer())", res)
  1864  					assertInCode(t, "result.siteField = propSite", res)
  1865  				}
  1866  			}
  1867  		}
  1868  	}
  1869  }
  1870  
  1871  func TestGenModel_Issue453(t *testing.T) {
  1872  	specDoc, err := loads.Spec("../fixtures/bugs/453/swagger.yml")
  1873  	if assert.NoError(t, err) {
  1874  		definitions := specDoc.Spec().Definitions
  1875  		k := "out_obj"
  1876  		opts := opts()
  1877  		genModel, err := makeGenDefinition(k, "models", definitions[k], specDoc, opts)
  1878  		if assert.NoError(t, err) {
  1879  			buf := bytes.NewBuffer(nil)
  1880  			err := templates.MustGet("model").Execute(buf, genModel)
  1881  			if assert.NoError(t, err) {
  1882  				ct, err := opts.LanguageOpts.FormatContent("out_obj.go", buf.Bytes())
  1883  				if assert.NoError(t, err) {
  1884  					res := string(ct)
  1885  					assertInCode(t, `func (m *OutObj) validateFld3(formats strfmt.Registry)`, res)
  1886  				} else {
  1887  					fmt.Println(buf.String())
  1888  				}
  1889  			}
  1890  		}
  1891  	}
  1892  }
  1893  
  1894  func TestGenModel_Issue455(t *testing.T) {
  1895  	specDoc, err := loads.Spec("../fixtures/bugs/455/swagger.yml")
  1896  	if assert.NoError(t, err) {
  1897  		definitions := specDoc.Spec().Definitions
  1898  		k := "out_obj"
  1899  		opts := opts()
  1900  		genModel, err := makeGenDefinition(k, "models", definitions[k], specDoc, opts)
  1901  		if assert.NoError(t, err) {
  1902  			buf := bytes.NewBuffer(nil)
  1903  			err := templates.MustGet("model").Execute(buf, genModel)
  1904  			if assert.NoError(t, err) {
  1905  				ct, err := opts.LanguageOpts.FormatContent("out_obj.go", buf.Bytes())
  1906  				if assert.NoError(t, err) {
  1907  					res := string(ct)
  1908  					assertInCode(t, `if err := validate.Required("fld2", "body", m.Fld2); err != nil {`, res)
  1909  				} else {
  1910  					fmt.Println(buf.String())
  1911  				}
  1912  			}
  1913  		}
  1914  	}
  1915  }
  1916  
  1917  func TestGenModel_Issue763(t *testing.T) {
  1918  	specDoc, err := loads.Spec("../fixtures/bugs/763/swagger.yml")
  1919  	if assert.NoError(t, err) {
  1920  		definitions := specDoc.Spec().Definitions
  1921  		k := "test_list"
  1922  		opts := opts()
  1923  		genModel, err := makeGenDefinition(k, "models", definitions[k], specDoc, opts)
  1924  		if assert.NoError(t, err) {
  1925  			buf := bytes.NewBuffer(nil)
  1926  			err := templates.MustGet("model").Execute(buf, genModel)
  1927  			if assert.NoError(t, err) {
  1928  				ct, err := opts.LanguageOpts.FormatContent("test_list.go", buf.Bytes())
  1929  				if assert.NoError(t, err) {
  1930  					res := string(ct)
  1931  					assertInCode(t, "TheArray []*int32 `json:\"the_array\"`", res)
  1932  					assertInCode(t, `validate.MinimumInt("the_array"+"."+strconv.Itoa(i), "body", int64(*m.TheArray[i]), 0, false)`, res)
  1933  					assertInCode(t, `validate.MaximumInt("the_array"+"."+strconv.Itoa(i), "body", int64(*m.TheArray[i]), 10, false)`, res)
  1934  				} else {
  1935  					fmt.Println(buf.String())
  1936  				}
  1937  			}
  1938  		}
  1939  	}
  1940  }
  1941  
  1942  func TestGenModel_Issue811_NullType(t *testing.T) {
  1943  	specDoc, err := loads.Spec("../fixtures/bugs/811/swagger.json")
  1944  	if assert.NoError(t, err) {
  1945  		definitions := specDoc.Spec().Definitions
  1946  		k := "teamRepos"
  1947  		opts := opts()
  1948  		genModel, err := makeGenDefinition(k, "models", definitions[k], specDoc, opts)
  1949  		if assert.NoError(t, err) {
  1950  			buf := bytes.NewBuffer(nil)
  1951  			err := templates.MustGet("model").Execute(buf, genModel)
  1952  			if assert.NoError(t, err) {
  1953  				ct, err := opts.LanguageOpts.FormatContent("team_repos.go", buf.Bytes())
  1954  				if assert.NoError(t, err) {
  1955  					res := string(ct)
  1956  					assertInCode(t, "Language interface{} `json:\"language,omitempty\"`", res)
  1957  				} else {
  1958  					fmt.Println(buf.String())
  1959  				}
  1960  			}
  1961  		}
  1962  	}
  1963  }
  1964  
  1965  func TestGenModel_Issue811_Emojis(t *testing.T) {
  1966  	specDoc, err := loads.Spec("../fixtures/bugs/811/swagger.json")
  1967  	if assert.NoError(t, err) {
  1968  		definitions := specDoc.Spec().Definitions
  1969  		k := "emojis"
  1970  		opts := opts()
  1971  		genModel, err := makeGenDefinition(k, "models", definitions[k], specDoc, opts)
  1972  		if assert.NoError(t, err) {
  1973  			buf := bytes.NewBuffer(nil)
  1974  			err := templates.MustGet("model").Execute(buf, genModel)
  1975  			if assert.NoError(t, err) {
  1976  				ct, err := opts.LanguageOpts.FormatContent("team_repos.go", buf.Bytes())
  1977  				if assert.NoError(t, err) {
  1978  					res := string(ct)
  1979  					assertInCode(t, "Plus1 string `json:\"+1,omitempty\"`", res)
  1980  					assertInCode(t, "Minus1 string `json:\"-1,omitempty\"`", res)
  1981  				} else {
  1982  					fmt.Println(buf.String())
  1983  				}
  1984  			}
  1985  		}
  1986  	}
  1987  }
  1988  
  1989  func TestGenModel_Issue752_EOFErr(t *testing.T) {
  1990  	specDoc, err := loads.Spec("../fixtures/codegen/azure-text-analyis.json")
  1991  	if assert.NoError(t, err) {
  1992  		definitions := specDoc.Spec().Definitions
  1993  		k := "OperationResult"
  1994  		opts := opts()
  1995  		genModel, err := makeGenDefinition(k, "models", definitions[k], specDoc, opts)
  1996  		if assert.NoError(t, err) {
  1997  			buf := bytes.NewBuffer(nil)
  1998  			err := templates.MustGet("model").Execute(buf, genModel)
  1999  			if assert.NoError(t, err) {
  2000  				ct, err := opts.LanguageOpts.FormatContent("out_obj.go", buf.Bytes())
  2001  				if assert.NoError(t, err) {
  2002  					res := string(ct)
  2003  					assertInCode(t, `&& err != io.EOF`, res)
  2004  				} else {
  2005  					fmt.Println(buf.String())
  2006  				}
  2007  			}
  2008  		}
  2009  	}
  2010  }
  2011  
  2012  func TestImports_ExistingModel(t *testing.T) {
  2013  	specDoc, err := loads.Spec("../fixtures/codegen/existing-model.yml")
  2014  	if assert.NoError(t, err) {
  2015  		definitions := specDoc.Spec().Definitions
  2016  		k := "JsonWebKeySet"
  2017  		opts := opts()
  2018  		genModel, err := makeGenDefinition(k, "models", definitions[k], specDoc, opts)
  2019  		if assert.NoError(t, err) &&
  2020  			assert.NotNil(t, genModel) &&
  2021  			assert.NotNil(t, genModel.Imports) {
  2022  			assert.Equal(t, "github.com/user/package", genModel.Imports["jwk"])
  2023  		}
  2024  		k = "JsonWebKey"
  2025  		genModel, err = makeGenDefinition(k, "models", definitions[k], specDoc, opts)
  2026  		if assert.NoError(t, err) {
  2027  			assert.NotNil(t, genModel)
  2028  			assert.NotNil(t, genModel.Imports)
  2029  			assert.Equal(t, "github.com/user/package", genModel.Imports["jwk"])
  2030  		}
  2031  	}
  2032  }
  2033  
  2034  func TestGenModel_Issue786(t *testing.T) {
  2035  	specDoc, err := loads.Spec("../fixtures/bugs/786/swagger.yml")
  2036  	if assert.NoError(t, err) {
  2037  		definitions := specDoc.Spec().Definitions
  2038  		k := "MyFirstObject"
  2039  		opts := opts()
  2040  		genModel, err := makeGenDefinition(k, "models", definitions[k], specDoc, opts)
  2041  		if assert.NoError(t, err) && assert.False(t, genModel.Properties[0].AdditionalProperties.IsNullable) {
  2042  			buf := bytes.NewBuffer(nil)
  2043  			err := templates.MustGet("model").Execute(buf, genModel)
  2044  			if assert.NoError(t, err) {
  2045  				ct, err := opts.LanguageOpts.FormatContent("MyFirstObject.go", buf.Bytes())
  2046  				if assert.NoError(t, err) {
  2047  					res := string(ct)
  2048  					assertInCode(t, `m.validateEntreeChoiceValueEnum("entree_choice"+"."+k, "body", m.EntreeChoice[k])`, res)
  2049  				} else {
  2050  					fmt.Println(buf.String())
  2051  				}
  2052  			}
  2053  		}
  2054  	}
  2055  }
  2056  
  2057  func TestGenModel_Issue822(t *testing.T) {
  2058  	specDoc, err := loads.Spec("../fixtures/bugs/822/swagger.yml")
  2059  	if assert.NoError(t, err) {
  2060  		definitions := specDoc.Spec().Definitions
  2061  		k := "Pet"
  2062  		opts := opts()
  2063  		genModel, err := makeGenDefinition(k, "models", definitions[k], specDoc, opts)
  2064  		ap := genModel.AdditionalProperties
  2065  		if assert.NoError(t, err) && assert.True(t, genModel.HasAdditionalProperties) && assert.NotNil(t, ap) && assert.False(t, ap.IsNullable) {
  2066  			buf := bytes.NewBuffer(nil)
  2067  			err := templates.MustGet("model").Execute(buf, genModel)
  2068  			if assert.NoError(t, err) {
  2069  				ct, err := opts.LanguageOpts.FormatContent("pet.go", buf.Bytes())
  2070  				if assert.NoError(t, err) {
  2071  					res := string(ct)
  2072  					assertInCode(t, `PetAdditionalProperties map[string]interface{}`, res)
  2073  					assertInCode(t, `m.PetAdditionalProperties = result`, res)
  2074  					assertInCode(t, `additional, err := json.Marshal(m.PetAdditionalProperties)`, res)
  2075  				} else {
  2076  					fmt.Println(buf.String())
  2077  				}
  2078  			}
  2079  		}
  2080  	}
  2081  }
  2082  
  2083  func TestGenModel_Issue981(t *testing.T) {
  2084  	specDoc, err := loads.Spec("../fixtures/bugs/981/swagger.json")
  2085  	if assert.NoError(t, err) {
  2086  		definitions := specDoc.Spec().Definitions
  2087  		k := "User"
  2088  		opts := opts()
  2089  		genModel, err := makeGenDefinition(k, "models", definitions[k], specDoc, opts)
  2090  		if assert.NoError(t, err) {
  2091  			buf := bytes.NewBuffer(nil)
  2092  			err := templates.MustGet("model").Execute(buf, genModel)
  2093  			if assert.NoError(t, err) {
  2094  				ct, err := opts.LanguageOpts.FormatContent("user.go", buf.Bytes())
  2095  				if assert.NoError(t, err) {
  2096  					res := string(ct)
  2097  					//fmt.Println(res)
  2098  					assertInCode(t, "FirstName string `json:\"first_name,omitempty\"`", res)
  2099  					assertInCode(t, "LastName string `json:\"last_name,omitempty\"`", res)
  2100  					assertInCode(t, "if swag.IsZero(m.Type)", res)
  2101  					assertInCode(t, `validate.MinimumInt("user_type", "body", int64(m.Type), 1, false)`, res)
  2102  					assertInCode(t, `validate.MaximumInt("user_type", "body", int64(m.Type), 5, false)`, res)
  2103  				} else {
  2104  					fmt.Println(buf.String())
  2105  				}
  2106  			}
  2107  		}
  2108  	}
  2109  
  2110  }
  2111  
  2112  func TestGenModel_Issue1341(t *testing.T) {
  2113  	specDoc, err := loads.Spec("../fixtures/bugs/1341/swagger.yaml")
  2114  	if assert.NoError(t, err) {
  2115  		definitions := specDoc.Spec().Definitions
  2116  		k := "ExecutableValueString"
  2117  		schema := definitions[k]
  2118  		opts := opts()
  2119  		genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts)
  2120  		if assert.NoError(t, err) {
  2121  			buf := bytes.NewBuffer(nil)
  2122  			err := templates.MustGet("model").Execute(buf, genModel)
  2123  			if assert.NoError(t, err) {
  2124  				ff, err := opts.LanguageOpts.FormatContent("executable_value_string.go", buf.Bytes())
  2125  				if assert.NoError(t, err) {
  2126  					res := string(ff)
  2127  					//fmt.Println(res)
  2128  					assertInCode(t, `return errors.New(422, "invalid ValueType value: %q", base.ValueType`, res)
  2129  					assertInCode(t, "result.testField = base.Test", res)
  2130  					assertInCode(t, "Test *string `json:\"Test\"`", res)
  2131  					assertInCode(t, "Test: m.Test(),", res)
  2132  				} else {
  2133  					fmt.Println(buf.String())
  2134  				}
  2135  			}
  2136  		}
  2137  	}
  2138  }
  2139  
  2140  // This tests to check that format validation is performed on non required schema properties
  2141  func TestGenModel_Issue1347(t *testing.T) {
  2142  	specDoc, err := loads.Spec("../fixtures/bugs/1347/fixture-1347.yaml")
  2143  	if assert.NoError(t, err) {
  2144  		definitions := specDoc.Spec().Definitions
  2145  		schema := definitions["ContainerConfig"]
  2146  		opts := opts()
  2147  		genModel, err := makeGenDefinition("ContainerConfig", "models", schema, specDoc, opts)
  2148  		if assert.NoError(t, err) {
  2149  			buf := bytes.NewBuffer(nil)
  2150  			err := templates.MustGet("model").Execute(buf, genModel)
  2151  			if assert.NoError(t, err) {
  2152  				ff, err := opts.LanguageOpts.FormatContent("Foo.go", buf.Bytes())
  2153  				if assert.NoError(t, err) {
  2154  					res := string(ff)
  2155  					//log.Println("1347")
  2156  					//log.Println(res)
  2157  					// Just verify that the validation call is generated even though we add a non-required property
  2158  					assertInCode(t, `validate.FormatOf("config1", "body", "hostname", m.Config1.String(), formats)`, res)
  2159  				} else {
  2160  					fmt.Println(buf.String())
  2161  				}
  2162  			}
  2163  		}
  2164  	}
  2165  }
  2166  
  2167  // This tests to check that format validation is performed on MAC format
  2168  func TestGenModel_Issue1348(t *testing.T) {
  2169  	specDoc, err := loads.Spec("../fixtures/bugs/1348/fixture-1348.yaml")
  2170  	if assert.NoError(t, err) {
  2171  		definitions := specDoc.Spec().Definitions
  2172  		k := "ContainerConfig"
  2173  		schema := definitions[k]
  2174  		opts := opts()
  2175  		genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts)
  2176  		if assert.NoError(t, err) {
  2177  			buf := bytes.NewBuffer(nil)
  2178  			err := templates.MustGet("model").Execute(buf, genModel)
  2179  			if assert.NoError(t, err) {
  2180  				ct, err := opts.LanguageOpts.FormatContent("foo.go", buf.Bytes())
  2181  				if assert.NoError(t, err) {
  2182  					res := string(ct)
  2183  					// Just verify that the validation call is generated with proper format
  2184  					assertInCode(t, `if err := validate.FormatOf("config1", "body", "mac", m.Config1.String(), formats)`, res)
  2185  				} else {
  2186  					fmt.Println(buf.String())
  2187  				}
  2188  			}
  2189  		}
  2190  	}
  2191  }
  2192  
  2193  // This tests that additionalProperties with validation is generated properly.
  2194  func TestGenModel_Issue1198(t *testing.T) {
  2195  	specDoc, err := loads.Spec("../fixtures/bugs/1198/fixture-1198.yaml")
  2196  	if assert.NoError(t, err) {
  2197  		definitions := specDoc.Spec().Definitions
  2198  		k := "pet"
  2199  		schema := definitions[k]
  2200  		opts := opts()
  2201  		genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts)
  2202  		if assert.NoError(t, err) {
  2203  			buf := bytes.NewBuffer(nil)
  2204  			err := templates.MustGet("model").Execute(buf, genModel)
  2205  			if assert.NoError(t, err) {
  2206  				ct, err := opts.LanguageOpts.FormatContent("foo.go", buf.Bytes())
  2207  				if assert.NoError(t, err) {
  2208  					res := string(ct)
  2209  					//log.Println("1198")
  2210  					//log.Println(res)
  2211  					// Just verify that the validation call is generated with proper format
  2212  					assertInCode(t, `if err := m.validateDate(formats); err != nil {`, res)
  2213  				} else {
  2214  					fmt.Println(buf.String())
  2215  				}
  2216  			}
  2217  		}
  2218  	}
  2219  }
  2220  
  2221  // This tests that additionalProperties with validation is generated properly.
  2222  func TestGenModel_Issue1397a(t *testing.T) {
  2223  	specDoc, err := loads.Spec("../fixtures/bugs/1397/fixture-1397a.yaml")
  2224  	if assert.NoError(t, err) {
  2225  		definitions := specDoc.Spec().Definitions
  2226  		k := "ContainerConfig"
  2227  		schema := definitions[k]
  2228  		opts := opts()
  2229  		genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts)
  2230  		if assert.NoError(t, err) {
  2231  			buf := bytes.NewBuffer(nil)
  2232  			err := templates.MustGet("model").Execute(buf, genModel)
  2233  			if assert.NoError(t, err) {
  2234  				ct, err := opts.LanguageOpts.FormatContent("foo.go", buf.Bytes())
  2235  				if assert.NoError(t, err) {
  2236  					res := string(ct)
  2237  					//log.Println("1397a")
  2238  					//log.Println(res)
  2239  					// Just verify that the validation call is generated with proper format
  2240  					assertInCode(t, `if swag.IsZero(m[k]) { // not required`, res)
  2241  				} else {
  2242  					fmt.Println(buf.String())
  2243  				}
  2244  			}
  2245  		}
  2246  	}
  2247  }
  2248  
  2249  // This tests that an enum of object values validates properly.
  2250  func TestGenModel_Issue1397b(t *testing.T) {
  2251  	specDoc, err := loads.Spec("../fixtures/bugs/1397/fixture-1397b.yaml")
  2252  	if assert.NoError(t, err) {
  2253  		definitions := specDoc.Spec().Definitions
  2254  		k := "ContainerConfig"
  2255  		schema := definitions[k]
  2256  		opts := opts()
  2257  		genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts)
  2258  		if assert.NoError(t, err) {
  2259  			buf := bytes.NewBuffer(nil)
  2260  			err := templates.MustGet("model").Execute(buf, genModel)
  2261  			if assert.NoError(t, err) {
  2262  				ct, err := opts.LanguageOpts.FormatContent("foo.go", buf.Bytes())
  2263  				if assert.NoError(t, err) {
  2264  					res := string(ct)
  2265  					//log.Println("1397b")
  2266  					//log.Println(res)
  2267  					// Just verify that the validation call is generated with proper format
  2268  					assertInCode(t, `if err := m.validateContainerConfigEnum("", "body", m); err != nil {`, res)
  2269  				} else {
  2270  					fmt.Println(buf.String())
  2271  				}
  2272  			}
  2273  		}
  2274  	}
  2275  }
  2276  
  2277  // This tests that additionalProperties with an array of polymorphic objects is generated properly.
  2278  func TestGenModel_Issue1409(t *testing.T) {
  2279  	specDoc, err := loads.Spec("../fixtures/bugs/1409/fixture-1409.yaml")
  2280  	if assert.NoError(t, err) {
  2281  		definitions := specDoc.Spec().Definitions
  2282  		k := "Graph"
  2283  		schema := definitions[k]
  2284  		opts := opts()
  2285  		genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts)
  2286  		if assert.NoError(t, err) {
  2287  			buf := bytes.NewBuffer(nil)
  2288  			err := templates.MustGet("model").Execute(buf, genModel)
  2289  			if assert.NoError(t, err) {
  2290  				ct, err := opts.LanguageOpts.FormatContent("foo.go", buf.Bytes())
  2291  				if assert.NoError(t, err) {
  2292  					res := string(ct)
  2293  					//log.Println("1409")
  2294  					//log.Println(res)
  2295  					// Just verify that the validation call is generated with proper format
  2296  					assertInCode(t, `nodes, err := UnmarshalNodeSlice(bytes.NewBuffer(data.Nodes), runtime.JSONConsumer())`, res)
  2297  					assertInCode(t, `if err := json.Unmarshal(raw, &rawProps); err != nil {`, res)
  2298  					assertInCode(t, `m.GraphAdditionalProperties[k] = toadd`, res)
  2299  					assertInCode(t, `b3, err = json.Marshal(m.GraphAdditionalProperties)`, res)
  2300  				} else {
  2301  					fmt.Println(buf.String())
  2302  				}
  2303  			}
  2304  		}
  2305  	}
  2306  }
  2307  
  2308  // This tests makes sure model definitions from inline schema in response are properly flattened and get validation
  2309  func TestGenModel_Issue866(t *testing.T) {
  2310  	log.SetOutput(ioutil.Discard)
  2311  	defer log.SetOutput(os.Stdout)
  2312  
  2313  	specDoc, err := loads.Spec("../fixtures/bugs/866/fixture-866.yaml")
  2314  	if assert.NoError(t, err) {
  2315  		p, ok := specDoc.Spec().Paths.Paths["/"]
  2316  		if assert.True(t, ok) {
  2317  			op := p.Get
  2318  			responses := op.Responses.StatusCodeResponses
  2319  			for k, r := range responses {
  2320  				t.Logf("Response: %d", k)
  2321  				schema := *r.Schema
  2322  				opts := opts()
  2323  				genModel, err := makeGenDefinition("GetOKBody", "models", schema, specDoc, opts)
  2324  				if assert.NoError(t, err) {
  2325  					buf := bytes.NewBuffer(nil)
  2326  					err := templates.MustGet("model").Execute(buf, genModel)
  2327  					if assert.NoError(t, err) {
  2328  						ct, err := opts.LanguageOpts.FormatContent("foo.go", buf.Bytes())
  2329  						if assert.NoError(t, err) {
  2330  							res := string(ct)
  2331  							assertInCode(t, `if err := validate.Required(`, res)
  2332  							assertInCode(t, `if err := validate.MaxLength(`, res)
  2333  							assertInCode(t, `if err := m.validateAccessToken(formats); err != nil {`, res)
  2334  							assertInCode(t, `if err := m.validateAccountID(formats); err != nil {`, res)
  2335  						} else {
  2336  							fmt.Println(buf.String())
  2337  						}
  2338  					}
  2339  				}
  2340  			}
  2341  		}
  2342  	}
  2343  }
  2344  
  2345  // This tests makes sure marshalling and validation is generated in aliased formatted definitions
  2346  func TestGenModel_Issue946(t *testing.T) {
  2347  	specDoc, err := loads.Spec("../fixtures/bugs/946/fixture-946.yaml")
  2348  	if assert.NoError(t, err) {
  2349  		definitions := specDoc.Spec().Definitions
  2350  		k := "mydate"
  2351  		schema := definitions[k]
  2352  		opts := opts()
  2353  		genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts)
  2354  		if assert.NoError(t, err) {
  2355  			buf := bytes.NewBuffer(nil)
  2356  			err := templates.MustGet("model").Execute(buf, genModel)
  2357  			if assert.NoError(t, err) {
  2358  				ct, err := opts.LanguageOpts.FormatContent("foo.go", buf.Bytes())
  2359  				if assert.NoError(t, err) {
  2360  					res := string(ct)
  2361  					assertInCode(t, `type Mydate strfmt.Date`, res)
  2362  					assertInCode(t, `func (m *Mydate) UnmarshalJSON(b []byte) error {`, res)
  2363  					assertInCode(t, `return ((*strfmt.Date)(m)).UnmarshalJSON(b)`, res)
  2364  					assertInCode(t, `func (m Mydate) MarshalJSON() ([]byte, error) {`, res)
  2365  					assertInCode(t, `return (strfmt.Date(m)).MarshalJSON()`, res)
  2366  					assertInCode(t, `if err := validate.FormatOf("", "body", "date", strfmt.Date(m).String(), formats); err != nil {`, res)
  2367  				} else {
  2368  					fmt.Println(buf.String())
  2369  				}
  2370  			}
  2371  		}
  2372  	}
  2373  }
  2374  
  2375  // This tests makes sure that docstring in inline schema in response properly reflect the Required property
  2376  func TestGenModel_Issue910(t *testing.T) {
  2377  	specDoc, err := loads.Spec("../fixtures/bugs/910/fixture-910.yaml")
  2378  	if assert.NoError(t, err) {
  2379  		p, ok := specDoc.Spec().Paths.Paths["/mytest"]
  2380  		if assert.True(t, ok) {
  2381  			op := p.Get
  2382  			responses := op.Responses.StatusCodeResponses
  2383  			for k, r := range responses {
  2384  				t.Logf("Response: %d", k)
  2385  				schema := *r.Schema
  2386  				opts := opts()
  2387  				genModel, err := makeGenDefinition("GetMyTestOKBody", "models", schema, specDoc, opts)
  2388  				if assert.NoError(t, err) {
  2389  					buf := bytes.NewBuffer(nil)
  2390  					err := templates.MustGet("model").Execute(buf, genModel)
  2391  					if assert.NoError(t, err) {
  2392  						ct, err := opts.LanguageOpts.FormatContent("foo.go", buf.Bytes())
  2393  						if assert.NoError(t, err) {
  2394  							res := string(ct)
  2395  							assertInCode(t, "// bar\n	// Required: true\n	Bar *int64 `json:\"bar\"`", res)
  2396  							assertInCode(t, "// foo\n	// Required: true\n	Foo interface{} `json:\"foo\"`", res)
  2397  							assertInCode(t, "// baz\n	Baz int64 `json:\"baz,omitempty\"`", res)
  2398  							assertInCode(t, "// quux\n	Quux []string `json:\"quux\"`", res)
  2399  							assertInCode(t, `if err := validate.Required("bar", "body", m.Bar); err != nil {`, res)
  2400  							assertInCode(t, `if err := validate.Required("foo", "body", m.Foo); err != nil {`, res)
  2401  							assertNotInCode(t, `if err := validate.Required("baz", "body", m.Baz); err != nil {`, res)
  2402  							assertNotInCode(t, `if err := validate.Required("quux", "body", m.Quux); err != nil {`, res)
  2403  							// NOTE(fredbi); fixed Required in slices. This property has actually no validation
  2404  							assertNotInCode(t, `if swag.IsZero(m.Quux) { // not required`, res)
  2405  						} else {
  2406  							fmt.Println(buf.String())
  2407  						}
  2408  					}
  2409  				}
  2410  			}
  2411  		}
  2412  	}
  2413  }
  2414  
  2415  func TestGenerateModel_Xorder(t *testing.T) {
  2416  	specDoc, err := loads.Spec("../fixtures/codegen/x-order.yml")
  2417  	if assert.NoError(t, err) {
  2418  		definitions := specDoc.Spec().Definitions
  2419  		k := "sessionData"
  2420  		schema := definitions[k]
  2421  		opts := opts()
  2422  		genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts)
  2423  		if assert.NoError(t, err) {
  2424  			buf := bytes.NewBuffer(nil)
  2425  			err := templates.MustGet("model").Execute(buf, genModel)
  2426  			if assert.NoError(t, err) {
  2427  				ff, err := opts.LanguageOpts.FormatContent("x-order.go", buf.Bytes())
  2428  				if assert.NoError(t, err) {
  2429  					res := string(ff)
  2430  					// if no x-order then alphabetical order, like DeviceID, SessionID, UMain.
  2431  					// There is x-order
  2432  					//   sessionId
  2433  					//     x-order: 0
  2434  					//   deviceId:
  2435  					//     x-order: 1
  2436  					//   uMain:
  2437  					//     x-order: 2
  2438  					// This is need for msgpack-array.
  2439  					foundDeviceID := strings.Index(res, "DeviceID")
  2440  					foundSessionID := strings.Index(res, "SessionID")
  2441  					foundUMain := strings.Index(res, "UMain")
  2442  					foundAaa := strings.Index(res, "Aaa")
  2443  					foundBbb := strings.Index(res, "Bbb")
  2444  					foundZzz := strings.Index(res, "Zzz")
  2445  					assert.True(t, foundSessionID < foundDeviceID)
  2446  					assert.True(t, foundSessionID < foundUMain)
  2447  					assert.True(t, foundUMain < foundAaa)
  2448  					assert.True(t, foundAaa < foundBbb)
  2449  					assert.True(t, foundBbb < foundZzz)
  2450  				}
  2451  			}
  2452  		}
  2453  	}
  2454  }
  2455  
  2456  func TestGenModel_Issue1623(t *testing.T) {
  2457  	specDoc, err := loads.Spec("../fixtures/enhancements/1623/swagger.yml")
  2458  	if !assert.NoError(t, err) {
  2459  		return
  2460  	}
  2461  
  2462  	definitions := specDoc.Spec().Definitions
  2463  	k := "Foo"
  2464  	schema := definitions[k]
  2465  	opts := opts()
  2466  	genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts)
  2467  	if !assert.NoError(t, err) {
  2468  		return
  2469  	}
  2470  
  2471  	buf := bytes.NewBuffer(nil)
  2472  	err = templates.MustGet("model").Execute(buf, genModel)
  2473  	if !assert.NoError(t, err) {
  2474  		fmt.Println(buf.String())
  2475  		return
  2476  	}
  2477  
  2478  	ff, err := opts.LanguageOpts.FormatContent("Foo.go", buf.Bytes())
  2479  	if !assert.NoError(t, err) {
  2480  		return
  2481  	}
  2482  
  2483  	res := string(ff)
  2484  	assertInCode(t, "ArrayHasOmitEmptyFalse []string `json:\"arrayHasOmitEmptyFalse\"`", res)
  2485  	assertInCode(t, "ArrayHasOmitEmptyTrue []string `json:\"arrayHasOmitEmptyTrue,omitempty\"`", res)
  2486  	assertInCode(t, "ArrayNoOmitEmpty []string `json:\"arrayNoOmitEmpty\"`", res)
  2487  	assertInCode(t, "GeneralHasOmitEmptyFalse string `json:\"generalHasOmitEmptyFalse\"`", res)
  2488  	assertInCode(t, "GeneralHasOmitEmptyTrue string `json:\"generalHasOmitEmptyTrue,omitempty\"`", res)
  2489  	assertInCode(t, "GeneralNoOmitEmpty string `json:\"generalNoOmitEmpty,omitempty\"`", res)
  2490  	assertInCode(t, "RefHasOmitEmptyFalse Bar `json:\"refHasOmitEmptyFalse\"`", res)
  2491  	assertInCode(t, "RefHasOmitEmptyTrue Bar `json:\"refHasOmitEmptyTrue,omitempty\"`", res)
  2492  	assertInCode(t, "RefNoOmitEmpty Bar `json:\"refNoOmitEmpty,omitempty\"`", res)
  2493  }
  2494  
  2495  func TestGenModel_KeepSpecPropertiesOrder(t *testing.T) {
  2496  	ymlFile := "../fixtures/codegen/keep-spec-order.yml"
  2497  	opts := opts()
  2498  	abcType := "abctype"
  2499  
  2500  	specDoc, err := loads.Spec(ymlFile)
  2501  	assert.NoError(t, err)
  2502  	orderedSpecDoc, err := loads.Spec(WithAutoXOrder(ymlFile))
  2503  	assert.NoError(t, err)
  2504  
  2505  	definitions := specDoc.Spec().Definitions
  2506  	orderedDefinitions := orderedSpecDoc.Spec().Definitions
  2507  
  2508  	genModel, err := makeGenDefinition(abcType, "models", definitions[abcType], specDoc, opts)
  2509  	assert.NoError(t, err)
  2510  	orderGenModel, err := makeGenDefinition(abcType, "models", orderedDefinitions[abcType], orderedSpecDoc, opts)
  2511  	assert.NoError(t, err)
  2512  
  2513  	buf := bytes.NewBuffer(nil)
  2514  	assert.NoError(t, templates.MustGet("model").Execute(buf, genModel))
  2515  	orderBuf := bytes.NewBuffer(nil)
  2516  	assert.NoError(t, templates.MustGet("model").Execute(orderBuf, orderGenModel))
  2517  
  2518  	ff, err := opts.LanguageOpts.FormatContent("keepSpecOrder.go", buf.Bytes())
  2519  	assert.NoError(t, err)
  2520  	modelCode := string(ff)
  2521  	ff, err = opts.LanguageOpts.FormatContent("keepSpecOrder-ordered.go", orderBuf.Bytes())
  2522  	assert.NoError(t, err)
  2523  	orderModelCode := string(ff)
  2524  
  2525  	//without auto order , properties sorted by alphanumeric
  2526  	foundA := strings.Index(modelCode, "Aaa")
  2527  	foundB := strings.Index(modelCode, "Bbb")
  2528  	foundC := strings.Index(modelCode, "Ccc")
  2529  	assert.True(t, foundA < foundB)
  2530  	assert.True(t, foundB < foundC)
  2531  
  2532  	foundOrderA := strings.Index(orderModelCode, "Aaa")
  2533  	foundOrderB := strings.Index(orderModelCode, "Bbb")
  2534  	foundOrderC := strings.Index(orderModelCode, "Ccc")
  2535  
  2536  	assert.True(t, foundOrderC < foundOrderB)
  2537  	assert.True(t, foundOrderB < foundOrderA)
  2538  
  2539  	foundInnerA := strings.Index(modelCode, "InnerAaa")
  2540  	foundInnerB := strings.Index(modelCode, "InnerBbb")
  2541  	foundInnerC := strings.Index(modelCode, "InnerCcc")
  2542  	assert.True(t, foundInnerA < foundInnerB)
  2543  	assert.True(t, foundInnerB < foundInnerC)
  2544  
  2545  	foundOrderInnerA := strings.Index(orderModelCode, "InnerAaa")
  2546  	foundOrderInnerB := strings.Index(orderModelCode, "InnerBbb")
  2547  	foundOrderInnerC := strings.Index(orderModelCode, "InnerCcc")
  2548  
  2549  	assert.True(t, foundOrderInnerC < foundOrderInnerB)
  2550  	assert.True(t, foundOrderInnerB < foundOrderInnerA)
  2551  }
  2552  
  2553  func TestGenModel_StrictAdditionalProperties(t *testing.T) {
  2554  	specDoc, err := loads.Spec("../fixtures/codegen/strict-additional-properties.yml")
  2555  	if assert.NoError(t, err) {
  2556  		definitions := specDoc.Spec().Definitions
  2557  		k := "Body"
  2558  		schema := definitions[k]
  2559  		opts := opts()
  2560  
  2561  		opts.StrictAdditionalProperties = true
  2562  
  2563  		genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts)
  2564  		if assert.NoError(t, err) {
  2565  			buf := bytes.NewBuffer(nil)
  2566  			err = templates.MustGet("model").Execute(buf, genModel)
  2567  			if assert.NoError(t, err) {
  2568  				ff, err := opts.LanguageOpts.FormatContent("strictAdditionalProperties.go", buf.Bytes())
  2569  				if assert.NoError(t, err) {
  2570  					res := string(ff)
  2571  					for _, tt := range []struct {
  2572  						name      string
  2573  						assertion func(testing.TB, string, string) bool
  2574  					}{
  2575  						{k, assertInCode},
  2576  						{k + "Explicit", assertInCode},
  2577  						{k + "Implicit", assertInCode},
  2578  						{k + "Disabled", assertNotInCode},
  2579  					} {
  2580  						fn := funcBody(res, "*"+tt.name+") UnmarshalJSON(data []byte) error")
  2581  						if assert.NotEmpty(t, fn, "Method UnmarshalJSON should be defined for type *"+tt.name) {
  2582  							tt.assertion(t, "dec.DisallowUnknownFields()", fn)
  2583  						}
  2584  					}
  2585  				} else {
  2586  					fmt.Println(buf.String())
  2587  				}
  2588  			}
  2589  		}
  2590  	}
  2591  }