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