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