github.com/Percona-Lab/go-swagger@v0.19.0/generator/schemavalidation_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  	"log"
    21  	"regexp"
    22  	"testing"
    23  
    24  	"github.com/go-openapi/loads"
    25  	"github.com/go-openapi/swag"
    26  	"github.com/stretchr/testify/assert"
    27  )
    28  
    29  func init() {
    30  	log.SetFlags(log.LstdFlags | log.Lshortfile)
    31  }
    32  
    33  func reqm(str string) *regexp.Regexp {
    34  	return regexp.MustCompile(regexp.QuoteMeta(str))
    35  }
    36  
    37  func reqOri(str string) *regexp.Regexp {
    38  	return regexp.MustCompile(str)
    39  }
    40  
    41  func assertInCode(t testing.TB, expr, code string) bool {
    42  	return assert.Regexp(t, reqm(expr), code)
    43  }
    44  
    45  func assertRegexpInCode(t testing.TB, expr, code string) bool {
    46  	return assert.Regexp(t, reqOri(expr), code)
    47  }
    48  
    49  func assertNotInCode(t testing.TB, expr, code string) bool {
    50  	return assert.NotRegexp(t, reqm(expr), code)
    51  }
    52  
    53  // Unused
    54  // func assertRegexpNotInCode(t testing.TB, expr, code string) bool {
    55  // 	return assert.NotRegexp(t, reqOri(expr), code)
    56  // }
    57  
    58  func assertValidation(t testing.TB, pth, expr string, gm GenSchema) bool {
    59  	if !assert.True(t, gm.HasValidations, "expected the schema to have validations") {
    60  		return false
    61  	}
    62  	if !assert.Equal(t, pth, gm.Path, "paths don't match") {
    63  		return false
    64  	}
    65  	if !assert.Equal(t, expr, gm.ValueExpression, "expressions don't match") {
    66  		return false
    67  	}
    68  	return true
    69  }
    70  
    71  func TestSchemaValidation_RequiredProps(t *testing.T) {
    72  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.schemavalidation.yml")
    73  	if assert.NoError(t, err) {
    74  		k := "RequiredProps"
    75  		schema := specDoc.Spec().Definitions[k]
    76  
    77  		opts := opts()
    78  		gm, err := makeGenDefinition(k, "models", schema, specDoc, opts)
    79  		if assert.NoError(t, err) {
    80  			assert.Len(t, gm.Properties, 6)
    81  			for _, p := range gm.Properties {
    82  				if assert.True(t, p.Required) {
    83  					buf := bytes.NewBuffer(nil)
    84  					err := templates.MustGet("model").Execute(buf, gm)
    85  					if assert.NoError(t, err) {
    86  						formatted, err := opts.LanguageOpts.FormatContent("required_props.go", buf.Bytes())
    87  						if assert.NoError(t, err) {
    88  							res := string(formatted)
    89  							assertInCode(t, k+") Validate(formats", res)
    90  							assertInCode(t, "validate"+swag.ToGoName(p.Name), res)
    91  							assertInCode(t, "err := validate.Required", res)
    92  							assertInCode(t, "errors.CompositeValidationError(res...)", res)
    93  						}
    94  					}
    95  				}
    96  			}
    97  		}
    98  	}
    99  }
   100  
   101  func TestSchemaValidation_Strings(t *testing.T) {
   102  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.schemavalidation.yml")
   103  	if assert.NoError(t, err) {
   104  		k := "NamedString"
   105  		schema := specDoc.Spec().Definitions[k]
   106  
   107  		opts := opts()
   108  		gm, err := makeGenDefinition(k, "models", schema, specDoc, opts)
   109  		if assert.NoError(t, err) {
   110  			if assertValidation(t, "", "m", gm.GenSchema) {
   111  				buf := bytes.NewBuffer(nil)
   112  				err := templates.MustGet("model").Execute(buf, gm)
   113  				if assert.NoError(t, err) {
   114  					formatted, err := opts.LanguageOpts.FormatContent("named_string.go", buf.Bytes())
   115  					if assert.NoError(t, err) {
   116  						res := string(formatted)
   117  						assertInCode(t, k+") Validate(formats", res)
   118  						assertInCode(t, "err := validate.MinLength", res)
   119  						assertInCode(t, "err := validate.MaxLength", res)
   120  						assertInCode(t, "err := validate.Pattern", res)
   121  						assertInCode(t, "errors.CompositeValidationError(res...)", res)
   122  					}
   123  				}
   124  			}
   125  		}
   126  	}
   127  }
   128  
   129  func TestSchemaValidation_StringProps(t *testing.T) {
   130  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.schemavalidation.yml")
   131  	if assert.NoError(t, err) {
   132  		k := "StringValidations"
   133  		schema := specDoc.Spec().Definitions[k]
   134  
   135  		opts := opts()
   136  		gm, err := makeGenDefinition(k, "models", schema, specDoc, opts)
   137  		if assert.NoError(t, err) {
   138  			prop := gm.Properties[0]
   139  			if assertValidation(t, "\"name\"", "m.Name", prop) {
   140  				buf := bytes.NewBuffer(nil)
   141  				err := templates.MustGet("model").Execute(buf, gm)
   142  				if assert.NoError(t, err) {
   143  					formatted, err := opts.LanguageOpts.FormatContent("string_validations.go", buf.Bytes())
   144  					if assert.NoError(t, err) {
   145  						res := string(formatted)
   146  						assertInCode(t, k+") Validate(formats", res)
   147  						assertInCode(t, "m.validateName(formats", res)
   148  						assertInCode(t, "err := validate.MinLength(\"name\",", res)
   149  						assertInCode(t, "err := validate.MaxLength(\"name\",", res)
   150  						assertInCode(t, "err := validate.Pattern(\"name\",", res)
   151  						assertInCode(t, "errors.CompositeValidationError(res...)", res)
   152  					}
   153  				}
   154  			}
   155  		}
   156  	}
   157  }
   158  
   159  func TestSchemaValidation_NamedNumber(t *testing.T) {
   160  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.schemavalidation.yml")
   161  	if assert.NoError(t, err) {
   162  		k := "NamedNumber"
   163  		schema := specDoc.Spec().Definitions[k]
   164  
   165  		opts := opts()
   166  		gm, err := makeGenDefinition(k, "models", schema, specDoc, opts)
   167  		if assert.NoError(t, err) {
   168  			if assertValidation(t, "", "m", gm.GenSchema) {
   169  				buf := bytes.NewBuffer(nil)
   170  				err := templates.MustGet("model").Execute(buf, gm)
   171  				if assert.NoError(t, err) {
   172  					formatted, err := opts.LanguageOpts.FormatContent("named_number.go", buf.Bytes())
   173  					if assert.NoError(t, err) {
   174  						res := string(formatted)
   175  						//fmt.Println(res)
   176  						assertInCode(t, k+") Validate(formats", res)
   177  						assertInCode(t, "err := validate.MinimumInt", res)
   178  						assertInCode(t, "err := validate.MaximumInt", res)
   179  						assertInCode(t, "err := validate.MultipleOf", res)
   180  						assertInCode(t, "errors.CompositeValidationError(res...)", res)
   181  					}
   182  				}
   183  			}
   184  		}
   185  	}
   186  }
   187  
   188  func TestSchemaValidation_NumberProps(t *testing.T) {
   189  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.schemavalidation.yml")
   190  	if assert.NoError(t, err) {
   191  		k := "NumberValidations"
   192  		schema := specDoc.Spec().Definitions[k]
   193  
   194  		opts := opts()
   195  		gm, err := makeGenDefinition(k, "models", schema, specDoc, opts)
   196  		if assert.NoError(t, err) {
   197  			prop := gm.Properties[0]
   198  			if assertValidation(t, "\"age\"", "m.Age", prop) {
   199  				buf := bytes.NewBuffer(nil)
   200  				err := templates.MustGet("model").Execute(buf, gm)
   201  				if assert.NoError(t, err) {
   202  					formatted, err := opts.LanguageOpts.FormatContent("number_validations.go", buf.Bytes())
   203  					if assert.NoError(t, err) {
   204  						res := string(formatted)
   205  						assertInCode(t, k+") Validate(formats", res)
   206  						assertInCode(t, "m.validateAge(formats", res)
   207  						assertInCode(t, "err := validate.MinimumInt(\"age\",", res)
   208  						assertInCode(t, "err := validate.MaximumInt(\"age\",", res)
   209  						assertInCode(t, "err := validate.MultipleOf(\"age\",", res)
   210  						assertInCode(t, "errors.CompositeValidationError(res...)", res)
   211  					}
   212  				}
   213  			}
   214  		}
   215  	}
   216  }
   217  
   218  func TestSchemaValidation_NamedArray(t *testing.T) {
   219  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.schemavalidation.yml")
   220  	if assert.NoError(t, err) {
   221  		k := "NamedArray"
   222  		schema := specDoc.Spec().Definitions[k]
   223  
   224  		opts := opts()
   225  		gm, err := makeGenDefinition(k, "models", schema, specDoc, opts)
   226  		if assert.NoError(t, err) {
   227  			if assertValidation(t, "", "m", gm.GenSchema) {
   228  				buf := bytes.NewBuffer(nil)
   229  				err := templates.MustGet("model").Execute(buf, gm)
   230  				if assert.NoError(t, err) {
   231  					formatted, err := opts.LanguageOpts.FormatContent("named_array.go", buf.Bytes())
   232  					if assert.NoError(t, err) {
   233  						res := string(formatted)
   234  						assertInCode(t, k+") Validate(formats", res)
   235  						assertInCode(t, "err := validate.MinItems(\"\"", res)
   236  						assertInCode(t, "err := validate.MaxItems(\"\"", res)
   237  						assertInCode(t, "err := validate.MinLength(strconv.Itoa(i),", res)
   238  						assertInCode(t, "err := validate.MaxLength(strconv.Itoa(i),", res)
   239  						assertInCode(t, "err := validate.Pattern(strconv.Itoa(i),", res)
   240  						assertInCode(t, "errors.CompositeValidationError(res...)", res)
   241  					}
   242  				}
   243  			}
   244  		}
   245  	}
   246  }
   247  
   248  func TestSchemaValidation_ArrayProps(t *testing.T) {
   249  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.schemavalidation.yml")
   250  	if assert.NoError(t, err) {
   251  		k := "ArrayValidations"
   252  		schema := specDoc.Spec().Definitions[k]
   253  
   254  		opts := opts()
   255  		gm, err := makeGenDefinition(k, "models", schema, specDoc, opts)
   256  		if assert.NoError(t, err) {
   257  			prop := gm.Properties[0]
   258  			if assertValidation(t, "\"tags\"", "m.Tags", prop) {
   259  				buf := bytes.NewBuffer(nil)
   260  				err := templates.MustGet("model").Execute(buf, gm)
   261  				if assert.NoError(t, err) {
   262  					formatted, err := opts.LanguageOpts.FormatContent("array_validations.go", buf.Bytes())
   263  					if assert.NoError(t, err) {
   264  						res := string(formatted)
   265  						assertInCode(t, k+") Validate(formats", res)
   266  						assertInCode(t, "m.validateTags(formats", res)
   267  						assertInCode(t, "err := validate.MinItems(\"tags\"", res)
   268  						assertInCode(t, "err := validate.MaxItems(\"tags\"", res)
   269  						assertInCode(t, "err := validate.MinLength(\"tags\"+\".\"+strconv.Itoa(i),", res)
   270  						assertInCode(t, "err := validate.MaxLength(\"tags\"+\".\"+strconv.Itoa(i),", res)
   271  						assertInCode(t, "err := validate.Pattern(\"tags\"+\".\"+strconv.Itoa(i),", res)
   272  						assertInCode(t, "errors.CompositeValidationError(res...)", res)
   273  					}
   274  				}
   275  			}
   276  		}
   277  	}
   278  }
   279  
   280  func TestSchemaValidation_NamedNestedArray(t *testing.T) {
   281  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.schemavalidation.yml")
   282  	if assert.NoError(t, err) {
   283  		k := "NamedNestedArray"
   284  		schema := specDoc.Spec().Definitions[k]
   285  
   286  		opts := opts()
   287  		gm, err := makeGenDefinition(k, "models", schema, specDoc, opts)
   288  		if assert.NoError(t, err) {
   289  			if assertValidation(t, "", "m", gm.GenSchema) {
   290  				buf := bytes.NewBuffer(nil)
   291  				err := templates.MustGet("model").Execute(buf, gm)
   292  				if assert.NoError(t, err) {
   293  					formatted, err := opts.LanguageOpts.FormatContent("named_nested_array.go", buf.Bytes())
   294  					if assert.NoError(t, err) {
   295  						res := string(formatted)
   296  						assertInCode(t, k+") Validate(formats", res)
   297  						assertInCode(t, "iNamedNestedArraySize := int64(len(m))", res)
   298  						assertInCode(t, "iiNamedNestedArraySize := int64(len(m[i]))", res)
   299  						assertInCode(t, "iiiNamedNestedArraySize := int64(len(m[i][ii]))", res)
   300  						assertInCode(t, "err := validate.MinItems(\"\"", res)
   301  						assertInCode(t, "err := validate.MaxItems(\"\"", res)
   302  						assertInCode(t, "err := validate.MinItems(strconv.Itoa(i),", res)
   303  						assertInCode(t, "err := validate.MaxItems(strconv.Itoa(i),", res)
   304  						assertInCode(t, "err := validate.MinItems(strconv.Itoa(i)+\".\"+strconv.Itoa(ii),", res)
   305  						assertInCode(t, "err := validate.MaxItems(strconv.Itoa(i)+\".\"+strconv.Itoa(ii),", res)
   306  						assertInCode(t, "err := validate.MinLength(strconv.Itoa(i)+\".\"+strconv.Itoa(ii)+\".\"+strconv.Itoa(iii),", res)
   307  						assertInCode(t, "err := validate.MaxLength(strconv.Itoa(i)+\".\"+strconv.Itoa(ii)+\".\"+strconv.Itoa(iii),", res)
   308  						assertInCode(t, "err := validate.Pattern(strconv.Itoa(i)+\".\"+strconv.Itoa(ii)+\".\"+strconv.Itoa(iii),", res)
   309  						assertInCode(t, "errors.CompositeValidationError(res...)", res)
   310  					}
   311  				}
   312  			}
   313  		}
   314  	}
   315  }
   316  
   317  func TestSchemaValidation_NestedArrayProps(t *testing.T) {
   318  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.schemavalidation.yml")
   319  	if assert.NoError(t, err) {
   320  		k := "NestedArrayValidations"
   321  		schema := specDoc.Spec().Definitions[k]
   322  
   323  		opts := opts()
   324  		gm, err := makeGenDefinition(k, "models", schema, specDoc, opts)
   325  		if assert.NoError(t, err) {
   326  			prop := gm.Properties[0]
   327  			if assertValidation(t, "\"tags\"", "m.Tags", prop) {
   328  				buf := bytes.NewBuffer(nil)
   329  				err := templates.MustGet("model").Execute(buf, gm)
   330  				if assert.NoError(t, err) {
   331  					formatted, err := opts.LanguageOpts.FormatContent("nested_array_validations.go", buf.Bytes())
   332  					if assert.NoError(t, err) {
   333  						res := string(formatted)
   334  						assertInCode(t, k+") Validate(formats", res)
   335  						assertInCode(t, "m.validateTags(formats", res)
   336  						assertInCode(t, "iTagsSize := int64(len(m.Tags))", res)
   337  						assertInCode(t, "iiTagsSize := int64(len(m.Tags[i]))", res)
   338  						assertInCode(t, "iiiTagsSize := int64(len(m.Tags[i][ii]))", res)
   339  						assertInCode(t, "err := validate.MinItems(\"tags\"", res)
   340  						assertInCode(t, "err := validate.MaxItems(\"tags\"", res)
   341  						assertInCode(t, "err := validate.MinItems(\"tags\"+\".\"+strconv.Itoa(i),", res)
   342  						assertInCode(t, "err := validate.MaxItems(\"tags\"+\".\"+strconv.Itoa(i),", res)
   343  						assertInCode(t, "err := validate.MinItems(\"tags\"+\".\"+strconv.Itoa(i)+\".\"+strconv.Itoa(ii),", res)
   344  						assertInCode(t, "err := validate.MaxItems(\"tags\"+\".\"+strconv.Itoa(i)+\".\"+strconv.Itoa(ii),", res)
   345  						assertInCode(t, "err := validate.MinLength(\"tags\"+\".\"+strconv.Itoa(i)+\".\"+strconv.Itoa(ii)+\".\"+strconv.Itoa(iii),", res)
   346  						assertInCode(t, "err := validate.MaxLength(\"tags\"+\".\"+strconv.Itoa(i)+\".\"+strconv.Itoa(ii)+\".\"+strconv.Itoa(iii),", res)
   347  						assertInCode(t, "err := validate.Pattern(\"tags\"+\".\"+strconv.Itoa(i)+\".\"+strconv.Itoa(ii)+\".\"+strconv.Itoa(iii),", res)
   348  						assertInCode(t, "errors.CompositeValidationError(res...)", res)
   349  					}
   350  				}
   351  			}
   352  		}
   353  	}
   354  }
   355  
   356  func TestSchemaValidation_NamedNestedObject(t *testing.T) {
   357  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.schemavalidation.yml")
   358  	if assert.NoError(t, err) {
   359  		k := "NamedNestedObject"
   360  		schema := specDoc.Spec().Definitions[k]
   361  
   362  		opts := opts()
   363  		gm, err := makeGenDefinition(k, "models", schema, specDoc, opts)
   364  		if assert.NoError(t, err) {
   365  			if assertValidation(t, "", "m", gm.GenSchema) {
   366  				buf := bytes.NewBuffer(nil)
   367  				err := templates.MustGet("model").Execute(buf, gm)
   368  				if assert.NoError(t, err) {
   369  					formatted, err := opts.LanguageOpts.FormatContent("named_nested_object.go", buf.Bytes())
   370  					if assert.NoError(t, err) {
   371  						res := string(formatted)
   372  						assertInCode(t, k+") Validate(formats", res)
   373  						assertInCode(t, k+"Meta) Validate(formats", res)
   374  						assertInCode(t, k+") validateMeta(formats", res)
   375  						assertInCode(t, "m.Meta.Validate(formats)", res)
   376  						assertInCode(t, "err := validate.MinLength(\"meta\"+\".\"+\"first\",", res)
   377  						assertInCode(t, "err := validate.MaxLength(\"meta\"+\".\"+\"first\",", res)
   378  						assertInCode(t, "err := validate.Pattern(\"meta\"+\".\"+\"first\",", res)
   379  						assertInCode(t, "err := validate.Minimum(\"meta\"+\".\"+\"second\",", res)
   380  						assertInCode(t, "err := validate.Maximum(\"meta\"+\".\"+\"second\",", res)
   381  						assertInCode(t, "err := validate.MultipleOf(\"meta\"+\".\"+\"second\",", res)
   382  						assertInCode(t, "iThirdSize := int64(len(m.Third))", res)
   383  						assertInCode(t, "err := validate.MinItems(\"meta\"+\".\"+\"third\",", res)
   384  						assertInCode(t, "err := validate.MaxItems(\"meta\"+\".\"+\"third\",", res)
   385  						assertInCode(t, "err := validate.Minimum(\"meta\"+\".\"+\"third\"+\".\"+strconv.Itoa(i),", res)
   386  						assertInCode(t, "err := validate.Maximum(\"meta\"+\".\"+\"third\"+\".\"+strconv.Itoa(i),", res)
   387  						assertInCode(t, "err := validate.MultipleOf(\"meta\"+\".\"+\"third\"+\".\"+strconv.Itoa(i),", res)
   388  						assertInCode(t, "iFourthSize := int64(len(m.Fourth))", res)
   389  						assertInCode(t, "iiFourthSize := int64(len(m.Fourth[i]))", res)
   390  						assertInCode(t, "iiiFourthSize := int64(len(m.Fourth[i][ii]))", res)
   391  						assertInCode(t, "err := validate.MinItems(\"meta\"+\".\"+\"fourth\"+\".\"+strconv.Itoa(i),", res)
   392  						assertInCode(t, "err := validate.MaxItems(\"meta\"+\".\"+\"fourth\"+\".\"+strconv.Itoa(i),", res)
   393  						assertInCode(t, "err := validate.MinItems(\"meta\"+\".\"+\"fourth\"+\".\"+strconv.Itoa(i)+\".\"+strconv.Itoa(ii),", res)
   394  						assertInCode(t, "err := validate.MaxItems(\"meta\"+\".\"+\"fourth\"+\".\"+strconv.Itoa(i)+\".\"+strconv.Itoa(ii),", res)
   395  						assertInCode(t, "err := validate.Minimum(\"meta\"+\".\"+\"fourth\"+\".\"+strconv.Itoa(i)+\".\"+strconv.Itoa(ii)+\".\"+strconv.Itoa(iii),", res)
   396  						assertInCode(t, "err := validate.Maximum(\"meta\"+\".\"+\"fourth\"+\".\"+strconv.Itoa(i)+\".\"+strconv.Itoa(ii)+\".\"+strconv.Itoa(iii),", res)
   397  						assertInCode(t, "err := validate.MultipleOf(\"meta\"+\".\"+\"fourth\"+\".\"+strconv.Itoa(i)+\".\"+strconv.Itoa(ii)+\".\"+strconv.Itoa(iii),", res)
   398  						assertInCode(t, "errors.CompositeValidationError(res...)", res)
   399  					}
   400  				}
   401  			}
   402  		}
   403  	}
   404  }
   405  
   406  func TestSchemaValidation_NestedObjectProps(t *testing.T) {
   407  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.schemavalidation.yml")
   408  	if assert.NoError(t, err) {
   409  		k := "NestedObjectValidations"
   410  		schema := specDoc.Spec().Definitions[k]
   411  
   412  		opts := opts()
   413  		gm, err := makeGenDefinition(k, "models", schema, specDoc, opts)
   414  		if assert.NoError(t, err) {
   415  			prop := gm.Properties[0]
   416  			if assertValidation(t, "\"args\"", "m.Args", prop) {
   417  				buf := bytes.NewBuffer(nil)
   418  				err := templates.MustGet("model").Execute(buf, gm)
   419  				if assert.NoError(t, err) {
   420  					formatted, err := opts.LanguageOpts.FormatContent("nested_object_validations.go", buf.Bytes())
   421  					if assert.NoError(t, err) {
   422  						res := string(formatted)
   423  						assertInCode(t, k+") Validate(formats", res)
   424  						assertInCode(t, k+"Args) Validate(formats", res)
   425  						assertInCode(t, k+"ArgsMeta) Validate(formats", res)
   426  						assertInCode(t, "m.validateArgs(formats", res)
   427  						assertInCode(t, "err := validate.MinLength(\"args\"+\".\"+\"meta\"+\".\"+\"first\",", res)
   428  						assertInCode(t, "err := validate.MaxLength(\"args\"+\".\"+\"meta\"+\".\"+\"first\",", res)
   429  						assertInCode(t, "err := validate.Pattern(\"args\"+\".\"+\"meta\"+\".\"+\"first\",", res)
   430  						assertInCode(t, "err := validate.Minimum(\"args\"+\".\"+\"meta\"+\".\"+\"second\",", res)
   431  						assertInCode(t, "err := validate.Maximum(\"args\"+\".\"+\"meta\"+\".\"+\"second\",", res)
   432  						assertInCode(t, "err := validate.MultipleOf(\"args\"+\".\"+\"meta\"+\".\"+\"second\",", res)
   433  						assertInCode(t, "iThirdSize := int64(len(m.Third))", res)
   434  						assertInCode(t, "err := validate.MinItems(\"args\"+\".\"+\"meta\"+\".\"+\"third\",", res)
   435  						assertInCode(t, "err := validate.MaxItems(\"args\"+\".\"+\"meta\"+\".\"+\"third\",", res)
   436  						assertInCode(t, "err := validate.Minimum(\"args\"+\".\"+\"meta\"+\".\"+\"third\"+\".\"+strconv.Itoa(i),", res)
   437  						assertInCode(t, "err := validate.Maximum(\"args\"+\".\"+\"meta\"+\".\"+\"third\"+\".\"+strconv.Itoa(i),", res)
   438  						assertInCode(t, "err := validate.MultipleOf(\"args\"+\".\"+\"meta\"+\".\"+\"third\"+\".\"+strconv.Itoa(i),", res)
   439  						assertInCode(t, "iFourthSize := int64(len(m.Fourth))", res)
   440  						assertInCode(t, "iiFourthSize := int64(len(m.Fourth[i]))", res)
   441  						assertInCode(t, "iiiFourthSize := int64(len(m.Fourth[i][ii]))", res)
   442  						assertInCode(t, "err := validate.MinItems(\"args\"+\".\"+\"meta\"+\".\"+\"fourth\"+\".\"+strconv.Itoa(i),", res)
   443  						assertInCode(t, "err := validate.MaxItems(\"args\"+\".\"+\"meta\"+\".\"+\"fourth\"+\".\"+strconv.Itoa(i),", res)
   444  						assertInCode(t, "err := validate.MinItems(\"args\"+\".\"+\"meta\"+\".\"+\"fourth\"+\".\"+strconv.Itoa(i)+\".\"+strconv.Itoa(ii),", res)
   445  						assertInCode(t, "err := validate.MaxItems(\"args\"+\".\"+\"meta\"+\".\"+\"fourth\"+\".\"+strconv.Itoa(i)+\".\"+strconv.Itoa(ii),", res)
   446  						assertInCode(t, "err := validate.Minimum(\"args\"+\".\"+\"meta\"+\".\"+\"fourth\"+\".\"+strconv.Itoa(i)+\".\"+strconv.Itoa(ii)+\".\"+strconv.Itoa(iii),", res)
   447  						assertInCode(t, "err := validate.Maximum(\"args\"+\".\"+\"meta\"+\".\"+\"fourth\"+\".\"+strconv.Itoa(i)+\".\"+strconv.Itoa(ii)+\".\"+strconv.Itoa(iii),", res)
   448  						assertInCode(t, "err := validate.MultipleOf(\"args\"+\".\"+\"meta\"+\".\"+\"fourth\"+\".\"+strconv.Itoa(i)+\".\"+strconv.Itoa(ii)+\".\"+strconv.Itoa(iii),", res)
   449  						assertInCode(t, "errors.CompositeValidationError(res...)", res)
   450  					}
   451  				}
   452  			}
   453  		}
   454  	}
   455  }
   456  
   457  func TestSchemaValidation_NamedArrayMulti(t *testing.T) {
   458  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.schemavalidation.yml")
   459  	if assert.NoError(t, err) {
   460  		k := "NamedArrayMulti"
   461  		schema := specDoc.Spec().Definitions[k]
   462  
   463  		opts := opts()
   464  		gm, err := makeGenDefinition(k, "models", schema, specDoc, opts)
   465  		if assert.NoError(t, err) {
   466  			if assertValidation(t, "", "m", gm.GenSchema) {
   467  				buf := bytes.NewBuffer(nil)
   468  				err := templates.MustGet("model").Execute(buf, gm)
   469  				if assert.NoError(t, err) {
   470  					formatted, err := opts.LanguageOpts.FormatContent("named_array_multi.go", buf.Bytes())
   471  					if assert.NoError(t, err) {
   472  						res := string(formatted)
   473  						assertInCode(t, k+") Validate(formats", res)
   474  						assertInCode(t, k+") validateP0(formats", res)
   475  						assertInCode(t, k+") validateP1(formats", res)
   476  						assertInCode(t, "err := validate.Required(\"0\",", res)
   477  						assertInCode(t, "err := validate.MinLength(\"0\",", res)
   478  						assertInCode(t, "err := validate.MaxLength(\"0\",", res)
   479  						assertInCode(t, "err := validate.Pattern(\"0\",", res)
   480  						assertInCode(t, "err := validate.Required(\"1\",", res)
   481  						assertInCode(t, "err := validate.Minimum(\"1\",", res)
   482  						assertInCode(t, "err := validate.Maximum(\"1\",", res)
   483  						assertInCode(t, "err := validate.MultipleOf(\"1\",", res)
   484  						assertInCode(t, "errors.CompositeValidationError(res...)", res)
   485  					}
   486  				}
   487  			}
   488  		}
   489  	}
   490  }
   491  
   492  func TestSchemaValidation_ArrayMultiProps(t *testing.T) {
   493  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.schemavalidation.yml")
   494  	if assert.NoError(t, err) {
   495  		k := "ArrayMultiValidations"
   496  		schema := specDoc.Spec().Definitions[k]
   497  
   498  		opts := opts()
   499  		gm, err := makeGenDefinition(k, "models", schema, specDoc, opts)
   500  		if assert.NoError(t, err) {
   501  			prop := gm.Properties[0]
   502  			if assertValidation(t, "\"args\"", "m.Args", prop) {
   503  				buf := bytes.NewBuffer(nil)
   504  				err := templates.MustGet("model").Execute(buf, gm)
   505  				if assert.NoError(t, err) {
   506  					formatted, err := opts.LanguageOpts.FormatContent("array_multi_validations.go", buf.Bytes())
   507  					if assert.NoError(t, err) {
   508  						res := string(formatted)
   509  						assertInCode(t, k+") Validate(formats", res)
   510  						assertInCode(t, "m.validateArgs(formats", res)
   511  						assertInCode(t, "err := validate.Required(\"P0\",", res)
   512  						assertInCode(t, "err := validate.MinLength(\"P0\",", res)
   513  						assertInCode(t, "err := validate.MaxLength(\"P0\",", res)
   514  						assertInCode(t, "err := validate.Pattern(\"P0\",", res)
   515  						assertInCode(t, "err := validate.Required(\"P1\",", res)
   516  						assertInCode(t, "err := validate.Minimum(\"P1\",", res)
   517  						assertInCode(t, "err := validate.Maximum(\"P1\",", res)
   518  						assertInCode(t, "err := validate.MultipleOf(\"P1\",", res)
   519  						assertInCode(t, "errors.CompositeValidationError(res...)", res)
   520  					}
   521  				}
   522  			}
   523  		}
   524  	}
   525  }
   526  
   527  func TestSchemaValidation_NamedArrayAdditional(t *testing.T) {
   528  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.schemavalidation.yml")
   529  	if assert.NoError(t, err) {
   530  		k := "NamedArrayAdditional"
   531  		schema := specDoc.Spec().Definitions[k]
   532  
   533  		opts := opts()
   534  		gm, err := makeGenDefinition(k, "models", schema, specDoc, opts)
   535  		if assert.NoError(t, err) {
   536  			if assertValidation(t, "", "m", gm.GenSchema) {
   537  				buf := bytes.NewBuffer(nil)
   538  				err := templates.MustGet("model").Execute(buf, gm)
   539  				if assert.NoError(t, err) {
   540  					formatted, err := opts.LanguageOpts.FormatContent("named_array_additional.go", buf.Bytes())
   541  					if assert.NoError(t, err) {
   542  						res := string(formatted)
   543  						assertInCode(t, k+") Validate(formats", res)
   544  						assertInCode(t, k+") validateP0(formats", res)
   545  						assertInCode(t, k+") validateP1(formats", res)
   546  						assertInCode(t, "err := validate.Required(\"0\",", res)
   547  						assertInCode(t, "err := validate.MinLength(\"0\",", res)
   548  						assertInCode(t, "err := validate.MaxLength(\"0\",", res)
   549  						assertInCode(t, "err := validate.Pattern(\"0\",", res)
   550  						assertInCode(t, "err := validate.Required(\"1\",", res)
   551  						assertInCode(t, "err := validate.Minimum(\"1\",", res)
   552  						assertInCode(t, "err := validate.Maximum(\"1\",", res)
   553  						assertInCode(t, "err := validate.MultipleOf(\"1\",", res)
   554  						assertInCode(t, "errors.CompositeValidationError(res...)", res)
   555  						assertInCode(t, "m.NamedArrayAdditionalItems[i]", res)
   556  
   557  					}
   558  				}
   559  			}
   560  		}
   561  	}
   562  }
   563  
   564  func TestSchemaValidation_ArrayAdditionalProps(t *testing.T) {
   565  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.schemavalidation.yml")
   566  	if assert.NoError(t, err) {
   567  		k := "ArrayAdditionalValidations"
   568  		schema := specDoc.Spec().Definitions[k]
   569  
   570  		opts := opts()
   571  		gm, err := makeGenDefinition(k, "models", schema, specDoc, opts)
   572  		if assert.NoError(t, err) {
   573  			prop := gm.Properties[0]
   574  			if assertValidation(t, "\"args\"", "m.Args", prop) {
   575  				buf := bytes.NewBuffer(nil)
   576  				err := templates.MustGet("model").Execute(buf, gm)
   577  				if assert.NoError(t, err) {
   578  					formatted, err := opts.LanguageOpts.FormatContent("array_additional_validations.go", buf.Bytes())
   579  					if assert.NoError(t, err) {
   580  						res := string(formatted)
   581  						assertInCode(t, k+") Validate(formats", res)
   582  						assertInCode(t, "m.validateArgs(formats", res)
   583  						assertInCode(t, "err := validate.Required(\"P0\",", res)
   584  						assertInCode(t, "err := validate.MinLength(\"P0\",", res)
   585  						assertInCode(t, "err := validate.MaxLength(\"P0\",", res)
   586  						assertInCode(t, "err := validate.Pattern(\"P0\",", res)
   587  						assertInCode(t, "err := validate.Required(\"P1\",", res)
   588  						assertInCode(t, "err := validate.Minimum(\"P1\",", res)
   589  						assertInCode(t, "err := validate.Maximum(\"P1\",", res)
   590  						assertInCode(t, "err := validate.MultipleOf(\"P1\",", res)
   591  						assertInCode(t, "errors.CompositeValidationError(res...)", res)
   592  						assertInCode(t, "m.ArrayAdditionalValidationsArgsTuple0Items[i]", res)
   593  					}
   594  				}
   595  			}
   596  		}
   597  	}
   598  }
   599  
   600  func TestSchemaValidation_NamedMap(t *testing.T) {
   601  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.schemavalidation.yml")
   602  	if assert.NoError(t, err) {
   603  		k := "NamedMap"
   604  		schema := specDoc.Spec().Definitions[k]
   605  
   606  		opts := opts()
   607  		gm, err := makeGenDefinition(k, "models", schema, specDoc, opts)
   608  		if assert.NoError(t, err) {
   609  			if assertValidation(t, "", "m", gm.GenSchema) {
   610  				buf := bytes.NewBuffer(nil)
   611  				err := templates.MustGet("model").Execute(buf, gm)
   612  				if assert.NoError(t, err) {
   613  					formatted, err := opts.LanguageOpts.FormatContent("named_map.go", buf.Bytes())
   614  					if assert.NoError(t, err) {
   615  						res := string(formatted)
   616  						assertInCode(t, k+") Validate(formats", res)
   617  						assertInCode(t, "for k := range m {", res)
   618  						assertInCode(t, "err := validate.MinimumInt(k,", res)
   619  						assertInCode(t, "err := validate.MaximumInt(k,", res)
   620  						assertInCode(t, "err := validate.MultipleOf(k,", res)
   621  						assertInCode(t, "errors.CompositeValidationError(res...)", res)
   622  					}
   623  				}
   624  			}
   625  		}
   626  	}
   627  }
   628  
   629  func TestSchemaValidation_MapProps(t *testing.T) {
   630  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.schemavalidation.yml")
   631  	if assert.NoError(t, err) {
   632  		k := "MapValidations"
   633  		schema := specDoc.Spec().Definitions[k]
   634  
   635  		opts := opts()
   636  		gm, err := makeGenDefinition(k, "models", schema, specDoc, opts)
   637  		if assert.NoError(t, err) {
   638  			prop := gm.Properties[0]
   639  			if assertValidation(t, "\"meta\"", "m.Meta", prop) {
   640  				buf := bytes.NewBuffer(nil)
   641  				err := templates.MustGet("model").Execute(buf, gm)
   642  				if assert.NoError(t, err) {
   643  					formatted, err := opts.LanguageOpts.FormatContent("map_validations.go", buf.Bytes())
   644  					if assert.NoError(t, err) {
   645  						res := string(formatted)
   646  						assertInCode(t, k+") Validate(formats", res)
   647  						assertInCode(t, "m.validateMeta(formats", res)
   648  						assertInCode(t, "for k := range m.Meta {", res)
   649  						assertInCode(t, "err := validate.MinimumInt(\"meta\"+\".\"+k,", res)
   650  						assertInCode(t, "err := validate.MaximumInt(\"meta\"+\".\"+k,", res)
   651  						assertInCode(t, "err := validate.MultipleOf(\"meta\"+\".\"+k,", res)
   652  						assertInCode(t, "errors.CompositeValidationError(res...)", res)
   653  					}
   654  				}
   655  			}
   656  		}
   657  	}
   658  }
   659  
   660  func TestSchemaValidation_NamedMapComplex(t *testing.T) {
   661  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.schemavalidation.yml")
   662  	if assert.NoError(t, err) {
   663  		k := "NamedMapComplex"
   664  		schema := specDoc.Spec().Definitions[k]
   665  
   666  		opts := opts()
   667  		gm, err := makeGenDefinition(k, "models", schema, specDoc, opts)
   668  		if assert.NoError(t, err) {
   669  			if assertValidation(t, "", "m", gm.GenSchema) {
   670  				buf := bytes.NewBuffer(nil)
   671  				err := templates.MustGet("model").Execute(buf, gm)
   672  				if assert.NoError(t, err) {
   673  					formatted, err := opts.LanguageOpts.FormatContent("named_map_complex.go", buf.Bytes())
   674  					if assert.NoError(t, err) {
   675  						res := string(formatted)
   676  						assertInCode(t, k+") Validate(formats", res)
   677  						assertInCode(t, "for k := range m {", res)
   678  						assertInCode(t, "val.Validate(formats)", res)
   679  						assertInCode(t, "err := validate.MinLength(\"name\",", res)
   680  						assertInCode(t, "err := validate.MaxLength(\"name\",", res)
   681  						assertInCode(t, "err := validate.Pattern(\"name\",", res)
   682  						assertInCode(t, "err := validate.MinimumInt(\"age\",", res)
   683  						assertInCode(t, "err := validate.MaximumInt(\"age\",", res)
   684  						assertInCode(t, "err := validate.MultipleOf(\"age\",", res)
   685  						assertInCode(t, "errors.CompositeValidationError(res...)", res)
   686  					}
   687  				}
   688  			}
   689  		}
   690  	}
   691  }
   692  
   693  func TestSchemaValidation_MapComplexProps(t *testing.T) {
   694  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.schemavalidation.yml")
   695  	if assert.NoError(t, err) {
   696  		k := "MapComplexValidations"
   697  		schema := specDoc.Spec().Definitions[k]
   698  		opts := opts()
   699  		gm, err := makeGenDefinition(k, "models", schema, specDoc, opts)
   700  		if assert.NoError(t, err) {
   701  			prop := gm.Properties[0]
   702  			if assertValidation(t, "\"meta\"", "m.Meta", prop) {
   703  				buf := bytes.NewBuffer(nil)
   704  				err := templates.MustGet("model").Execute(buf, gm)
   705  				if assert.NoError(t, err) {
   706  					formatted, err := opts.LanguageOpts.FormatContent("map_complex_validations.go", buf.Bytes())
   707  					if assert.NoError(t, err) {
   708  						res := string(formatted)
   709  						assertInCode(t, k+") Validate(formats", res)
   710  						assertInCode(t, "for k := range m.Meta {", res)
   711  						assertInCode(t, "val.Validate(formats)", res)
   712  						assertInCode(t, "err := validate.MinLength(\"name\",", res)
   713  						assertInCode(t, "err := validate.MaxLength(\"name\",", res)
   714  						assertInCode(t, "err := validate.Pattern(\"name\",", res)
   715  						assertInCode(t, "err := validate.MinimumInt(\"age\",", res)
   716  						assertInCode(t, "err := validate.MaximumInt(\"age\",", res)
   717  						assertInCode(t, "err := validate.MultipleOf(\"age\",", res)
   718  						assertInCode(t, "errors.CompositeValidationError(res...)", res)
   719  					}
   720  				}
   721  			}
   722  		}
   723  	}
   724  }
   725  
   726  func TestSchemaValidation_NamedNestedMap(t *testing.T) {
   727  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.schemavalidation.yml")
   728  	if assert.NoError(t, err) {
   729  		k := "NamedNestedMap"
   730  		schema := specDoc.Spec().Definitions[k]
   731  
   732  		opts := opts()
   733  		gm, err := makeGenDefinition(k, "models", schema, specDoc, opts)
   734  		if assert.NoError(t, err) {
   735  			if assertValidation(t, "", "m", gm.GenSchema) {
   736  				buf := bytes.NewBuffer(nil)
   737  				err := templates.MustGet("model").Execute(buf, gm)
   738  				if assert.NoError(t, err) {
   739  					formatted, err := opts.LanguageOpts.FormatContent("named_nested_map.go", buf.Bytes())
   740  					if assert.NoError(t, err) {
   741  						res := string(formatted)
   742  						assertInCode(t, k+") Validate(formats", res)
   743  						assertInCode(t, "for k := range m {", res)
   744  						assertInCode(t, "for kk := range m[k] {", res)
   745  						assertInCode(t, "for kkk := range m[k][kk] {", res)
   746  						assertInCode(t, "err := validate.MinimumInt(k+\".\"+kk+\".\"+kkk,", res)
   747  						assertInCode(t, "err := validate.MaximumInt(k+\".\"+kk+\".\"+kkk,", res)
   748  						assertInCode(t, "err := validate.MultipleOf(k+\".\"+kk+\".\"+kkk,", res)
   749  						assertInCode(t, "errors.CompositeValidationError(res...)", res)
   750  					}
   751  				}
   752  			}
   753  		}
   754  	}
   755  }
   756  
   757  func TestSchemaValidation_NestedMapProps(t *testing.T) {
   758  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.schemavalidation.yml")
   759  	if assert.NoError(t, err) {
   760  		k := "NestedMapValidations"
   761  		schema := specDoc.Spec().Definitions[k]
   762  
   763  		opts := opts()
   764  		gm, err := makeGenDefinition(k, "models", schema, specDoc, opts)
   765  		if assert.NoError(t, err) {
   766  			prop := gm.Properties[0]
   767  			if assertValidation(t, "\"meta\"", "m.Meta", prop) {
   768  				buf := bytes.NewBuffer(nil)
   769  				err := templates.MustGet("model").Execute(buf, gm)
   770  				if assert.NoError(t, err) {
   771  					formatted, err := opts.LanguageOpts.FormatContent("nested_map_validations.go", buf.Bytes())
   772  					if assert.NoError(t, err) {
   773  						res := string(formatted)
   774  						assertInCode(t, k+") Validate(formats", res)
   775  						assertInCode(t, "m.validateMeta(formats", res)
   776  						assertInCode(t, "for k := range m.Meta {", res)
   777  						assertInCode(t, "for kk := range m.Meta[k] {", res)
   778  						assertInCode(t, "for kkk := range m.Meta[k][kk] {", res)
   779  						assertInCode(t, "err := validate.MinimumInt(\"meta\"+\".\"+k+\".\"+kk+\".\"+kkk,", res)
   780  						assertInCode(t, "err := validate.MaximumInt(\"meta\"+\".\"+k+\".\"+kk+\".\"+kkk,", res)
   781  						assertInCode(t, "err := validate.MultipleOf(\"meta\"+\".\"+k+\".\"+kk+\".\"+kkk,", res)
   782  						assertInCode(t, "errors.CompositeValidationError(res...)", res)
   783  					}
   784  				}
   785  			}
   786  		}
   787  	}
   788  }
   789  func TestAdditionalProperties_Simple(t *testing.T) {
   790  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.schemavalidation.yml")
   791  	if assert.NoError(t, err) {
   792  		k := "NamedMapComplex"
   793  		schema := specDoc.Spec().Definitions[k]
   794  		tr := &typeResolver{
   795  			ModelsPackage: "",
   796  			ModelName:     k,
   797  			Doc:           specDoc,
   798  		}
   799  
   800  		sg := schemaGenContext{
   801  			Path:         "",
   802  			Name:         k,
   803  			Receiver:     "m",
   804  			IndexVar:     "i",
   805  			ValueExpr:    "m",
   806  			Schema:       schema,
   807  			Required:     false,
   808  			TypeResolver: tr,
   809  			Named:        true,
   810  			ExtraSchemas: make(map[string]GenSchema),
   811  		}
   812  
   813  		fsm, lsm, err := newMapStack(&sg)
   814  		if assert.NoError(t, err) {
   815  			assert.NotNil(t, fsm.Type)
   816  			assert.Equal(t, &schema, fsm.Type)
   817  			assert.Equal(t, fsm, lsm)
   818  			assert.NotNil(t, fsm.Type.AdditionalProperties)
   819  			assert.NotNil(t, fsm.Type.AdditionalProperties.Schema)
   820  			assert.NotNil(t, fsm.NewObj)
   821  			assert.Nil(t, fsm.Next)
   822  			assert.Equal(t, "#/definitions/NamedMapComplexAnon", fsm.Type.AdditionalProperties.Schema.Ref.GetURL().String())
   823  
   824  			assert.NoError(t, lsm.Build())
   825  		}
   826  	}
   827  }
   828  
   829  func TestAdditionalProperties_Nested(t *testing.T) {
   830  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.schemavalidation.yml")
   831  	if assert.NoError(t, err) {
   832  		k := "NamedNestedMapComplex"
   833  		schema := specDoc.Spec().Definitions[k]
   834  		tr := &typeResolver{
   835  			ModelsPackage: "",
   836  			ModelName:     k,
   837  			Doc:           specDoc,
   838  		}
   839  
   840  		sg := schemaGenContext{
   841  			Path:         "",
   842  			Name:         k,
   843  			Receiver:     "m",
   844  			IndexVar:     "i",
   845  			ValueExpr:    "m",
   846  			Schema:       schema,
   847  			Required:     false,
   848  			TypeResolver: tr,
   849  			Named:        true,
   850  			ExtraSchemas: make(map[string]GenSchema),
   851  		}
   852  
   853  		fsm, lsm, err := newMapStack(&sg)
   854  		if assert.NoError(t, err) {
   855  			assert.NotNil(t, fsm.Type)
   856  			assert.Equal(t, &schema, fsm.Type)
   857  			assert.Equal(t, "", fsm.Context.Path)
   858  
   859  			assert.NotNil(t, schema.AdditionalProperties.Schema)
   860  			if assert.NotNil(t, fsm.Next) && assert.Nil(t, fsm.Previous) {
   861  				assert.NotNil(t, fsm.Type)
   862  				assert.Equal(t, &schema, fsm.Type)
   863  				assert.NotEqual(t, fsm, lsm)
   864  				assert.NotNil(t, fsm.Type.AdditionalProperties)
   865  				assert.NotNil(t, fsm.Type.AdditionalProperties.Schema)
   866  				assert.Nil(t, fsm.NewObj)
   867  				assert.Nil(t, fsm.Next.NewObj)
   868  				assert.NotNil(t, fsm.Next.Previous)
   869  				assert.NotNil(t, fsm.Next.Next)
   870  				assert.NotNil(t, fsm.Next.Next.NewObj)
   871  				assert.NotNil(t, fsm.Next.Next.ValueRef)
   872  				assert.Nil(t, fsm.Next.Next.Next)
   873  				assert.Equal(t, fsm.Next.Next, lsm)
   874  				assert.NoError(t, lsm.Build())
   875  			}
   876  		}
   877  	}
   878  }
   879  
   880  func TestSchemaValidation_NamedNestedMapComplex(t *testing.T) {
   881  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.schemavalidation.yml")
   882  	if assert.NoError(t, err) {
   883  		k := "NamedNestedMapComplex"
   884  		schema := specDoc.Spec().Definitions[k]
   885  
   886  		opts := opts()
   887  		gm, err := makeGenDefinition(k, "models", schema, specDoc, opts)
   888  		if assert.NoError(t, err) {
   889  			if assertValidation(t, "", "m", gm.GenSchema) {
   890  				if assert.True(t, gm.GenSchema.AdditionalProperties.HasValidations) {
   891  					if assert.True(t, gm.GenSchema.AdditionalProperties.AdditionalProperties.HasValidations) {
   892  						buf := bytes.NewBuffer(nil)
   893  						err := templates.MustGet("model").Execute(buf, gm)
   894  						if assert.NoError(t, err) {
   895  							formatted, err := opts.LanguageOpts.FormatContent("named_nested_map_complex.go", buf.Bytes())
   896  							if assert.NoError(t, err) {
   897  								res := string(formatted)
   898  								assertInCode(t, k+") Validate(formats", res)
   899  								assertInCode(t, "for k := range m {", res)
   900  								assertInCode(t, "for kk := range m[k] {", res)
   901  								assertInCode(t, "for kkk := range m[k][kk] {", res)
   902  								assertInCode(t, "val.Validate(formats)", res)
   903  								assertInCode(t, "err := validate.MinLength(\"name\",", res)
   904  								assertInCode(t, "err := validate.MaxLength(\"name\",", res)
   905  								assertInCode(t, "err := validate.Pattern(\"name\",", res)
   906  								assertInCode(t, "err := validate.MinimumInt(\"age\",", res)
   907  								assertInCode(t, "err := validate.MaximumInt(\"age\",", res)
   908  								assertInCode(t, "err := validate.MultipleOf(\"age\",", res)
   909  								assertInCode(t, "errors.CompositeValidationError(res...)", res)
   910  							} else {
   911  								fmt.Println(buf.String())
   912  							}
   913  						}
   914  					}
   915  				}
   916  			}
   917  		}
   918  	}
   919  }
   920  
   921  func TestSchemaValidation_NestedMapPropsComplex(t *testing.T) {
   922  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.schemavalidation.yml")
   923  	if assert.NoError(t, err) {
   924  		k := "NestedMapComplexValidations"
   925  		schema := specDoc.Spec().Definitions[k]
   926  
   927  		opts := opts()
   928  		gm, err := makeGenDefinition(k, "models", schema, specDoc, opts)
   929  		if assert.NoError(t, err) {
   930  			prop := gm.Properties[0]
   931  			if assertValidation(t, "\"meta\"", "m.Meta", prop) {
   932  				buf := bytes.NewBuffer(nil)
   933  				err := templates.MustGet("model").Execute(buf, gm)
   934  				if assert.NoError(t, err) {
   935  					formatted, err := opts.LanguageOpts.FormatContent("nested_map_complex_validations.go", buf.Bytes())
   936  					if assert.NoError(t, err) {
   937  						res := string(formatted)
   938  						assertInCode(t, k+") Validate(formats", res)
   939  						assertInCode(t, "m.validateMeta(formats", res)
   940  						assertInCode(t, "for k := range m.Meta {", res)
   941  						assertInCode(t, "for kk := range m.Meta[k] {", res)
   942  						assertInCode(t, "for kkk := range m.Meta[k][kk] {", res)
   943  						assertInCode(t, "val.Validate(formats)", res)
   944  						assertInCode(t, "err := validate.MinLength(\"name\",", res)
   945  						assertInCode(t, "err := validate.MaxLength(\"name\",", res)
   946  						assertInCode(t, "err := validate.Pattern(\"name\",", res)
   947  						assertInCode(t, "err := validate.MinimumInt(\"age\",", res)
   948  						assertInCode(t, "err := validate.MaximumInt(\"age\",", res)
   949  						assertInCode(t, "err := validate.MultipleOf(\"age\",", res)
   950  						assertInCode(t, "errors.CompositeValidationError(res...)", res)
   951  					}
   952  				}
   953  			}
   954  		}
   955  	}
   956  }
   957  
   958  func TestSchemaValidation_NamedAllOf(t *testing.T) {
   959  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.schemavalidation.yml")
   960  	if assert.NoError(t, err) {
   961  		k := "NamedAllOf"
   962  		schema := specDoc.Spec().Definitions[k]
   963  
   964  		opts := opts()
   965  		gm, err := makeGenDefinition(k, "models", schema, specDoc, opts)
   966  		if assert.NoError(t, err) {
   967  			if assertValidation(t, "", "m", gm.GenSchema) {
   968  				buf := bytes.NewBuffer(nil)
   969  				err := templates.MustGet("model").Execute(buf, gm)
   970  				if assert.NoError(t, err) {
   971  					formatted, err := opts.LanguageOpts.FormatContent("named_all_of.go", buf.Bytes())
   972  					if assert.NoError(t, err) {
   973  						res := string(formatted)
   974  						assertInCode(t, k+") Validate(formats", res)
   975  						assertInCode(t, k+") validateName(formats", res)
   976  						assertInCode(t, k+") validateAge(formats", res)
   977  						assertInCode(t, k+") validateArgs(formats", res)
   978  						assertInCode(t, k+") validateAssoc(formats", res)
   979  						assertInCode(t, k+") validateOpts(formats", res)
   980  						assertInCode(t, k+") validateExtOpts(formats", res)
   981  						assertInCode(t, k+") validateCoords(formats", res)
   982  						assertInCode(t, "validate.MinLength(\"name\",", res)
   983  						assertInCode(t, "validate.MinimumInt(\"age\",", res)
   984  						assertInCode(t, "validate.MinItems(\"args\",", res)
   985  						assertInCode(t, "validate.MinItems(\"assoc\",", res)
   986  						assertInCode(t, "validate.MinItems(\"assoc\"+\".\"+strconv.Itoa(i),", res)
   987  						assertInCode(t, "validate.MinItems(\"assoc\"+\".\"+strconv.Itoa(i)+\".\"+strconv.Itoa(ii),", res)
   988  						assertInCode(t, "validate.MinLength(\"assoc\"+\".\"+strconv.Itoa(i)+\".\"+strconv.Itoa(ii)+\".\"+strconv.Itoa(iii),", res)
   989  						assertInCode(t, "validate.Minimum(\"opts\"+\".\"+k,", res)
   990  						assertInCode(t, "validate.MinimumInt(\"extOpts\"+\".\"+k+\".\"+kk+\".\"+kkk,", res)
   991  						assertInCode(t, "validate.MinLength(\"coords\"+\".\"+\"name\",", res)
   992  						assertInCode(t, "errors.CompositeValidationError(res...)", res)
   993  					}
   994  				}
   995  			}
   996  		}
   997  	}
   998  }
   999  
  1000  func TestSchemaValidation_AllOfProps(t *testing.T) {
  1001  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.schemavalidation.yml")
  1002  	if assert.NoError(t, err) {
  1003  		k := "AllOfValidations"
  1004  		schema := specDoc.Spec().Definitions[k]
  1005  
  1006  		opts := opts()
  1007  		gm, err := makeGenDefinition(k, "models", schema, specDoc, opts)
  1008  		if assert.NoError(t, err) {
  1009  			prop := gm.Properties[0]
  1010  			if assertValidation(t, "\"meta\"", "m.Meta", prop) {
  1011  				buf := bytes.NewBuffer(nil)
  1012  				err := templates.MustGet("model").Execute(buf, gm)
  1013  				if assert.NoError(t, err) {
  1014  					formatted, err := opts.LanguageOpts.FormatContent("all_of_validations.go", buf.Bytes())
  1015  					if assert.NoError(t, err) {
  1016  						res := string(formatted)
  1017  						assertInCode(t, k+") Validate(formats", res)
  1018  						assertInCode(t, "m.validateMeta(formats", res)
  1019  						assertInCode(t, "validate.MinLength(\"meta\"+\".\"+\"name\",", res)
  1020  						assertInCode(t, "validate.MinimumInt(\"meta\"+\".\"+\"age\",", res)
  1021  						assertInCode(t, "validate.MinItems(\"meta\"+\".\"+\"args\",", res)
  1022  						assertInCode(t, "validate.MinItems(\"meta\"+\".\"+\"assoc\",", res)
  1023  						assertInCode(t, "validate.MinItems(\"meta\"+\".\"+\"assoc\"+\".\"+strconv.Itoa(i),", res)
  1024  						assertInCode(t, "validate.MinItems(\"meta\"+\".\"+\"assoc\"+\".\"+strconv.Itoa(i)+\".\"+strconv.Itoa(ii),", res)
  1025  						assertInCode(t, "validate.MinLength(\"meta\"+\".\"+\"assoc\"+\".\"+strconv.Itoa(i)+\".\"+strconv.Itoa(ii)+\".\"+strconv.Itoa(iii),", res)
  1026  						assertInCode(t, "validate.MinimumInt(\"meta\"+\".\"+\"opts\"+\".\"+k,", res)
  1027  						assertInCode(t, "validate.MinimumInt(\"meta\"+\".\"+\"extOpts\"+\".\"+k+\".\"+kk+\".\"+kkk,", res)
  1028  						assertInCode(t, "validate.MinLength(\"meta\"+\".\"+\"coords\"+\".\"+\"name\",", res)
  1029  						assertInCode(t, "errors.CompositeValidationError(res...)", res)
  1030  					}
  1031  				}
  1032  			}
  1033  		}
  1034  	}
  1035  }
  1036  
  1037  func TestSchemaValidation_RefedAllOf(t *testing.T) {
  1038  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.schemavalidation.yml")
  1039  	if assert.NoError(t, err) {
  1040  		k := "RefedAllOfValidations"
  1041  		schema := specDoc.Spec().Definitions[k]
  1042  
  1043  		opts := opts()
  1044  		gm, err := makeGenDefinition(k, "models", schema, specDoc, opts)
  1045  		if assert.NoError(t, err) && assert.Len(t, gm.AllOf, 2) {
  1046  			//prop := gm.AllOf[0]
  1047  			//if assertValidation(t, "\"meta\"", "m.Meta", prop) {
  1048  			buf := bytes.NewBuffer(nil)
  1049  			err := templates.MustGet("model").Execute(buf, gm)
  1050  			if assert.NoError(t, err) {
  1051  				formatted, err := opts.LanguageOpts.FormatContent("all_of_validations.go", buf.Bytes())
  1052  				if assert.NoError(t, err) {
  1053  					res := string(formatted)
  1054  					assertInCode(t, k+") Validate(formats", res)
  1055  					assertInCode(t, "m.NamedString.Validate(formats)", res)
  1056  					assertInCode(t, "m.NamedNumber.Validate(formats)", res)
  1057  					assertInCode(t, "errors.CompositeValidationError(res...)", res)
  1058  				}
  1059  			}
  1060  			//}
  1061  		}
  1062  	}
  1063  }
  1064  
  1065  func TestSchemaValidation_SimpleZeroAllowed(t *testing.T) {
  1066  
  1067  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.schemavalidation.yml")
  1068  	if assert.NoError(t, err) {
  1069  		k := "SimpleZeroAllowed"
  1070  		schema := specDoc.Spec().Definitions[k]
  1071  
  1072  		opts := opts()
  1073  		gm, err := makeGenDefinition(k, "models", schema, specDoc, opts)
  1074  		if assert.NoError(t, err) {
  1075  			buf := bytes.NewBuffer(nil)
  1076  			err := templates.MustGet("model").Execute(buf, gm)
  1077  			if assert.NoError(t, err) {
  1078  				formatted, err := opts.LanguageOpts.FormatContent("simple_zero_allowed.go", buf.Bytes())
  1079  				if assert.NoError(t, err) {
  1080  					res := string(formatted)
  1081  					assertInCode(t, k+") Validate(formats", res)
  1082  					assertInCode(t, "swag.IsZero(m.ID)", res)
  1083  					assertInCode(t, "validate.Required(\"name\", \"body\", m.Name)", res)
  1084  					assertInCode(t, "validate.MinLength(\"id\", \"body\", string(m.ID), 2)", res)
  1085  					assertInCode(t, "validate.Required(\"urls\", \"body\", m.Urls)", res)
  1086  					assertInCode(t, "errors.CompositeValidationError(res...)", res)
  1087  				}
  1088  			}
  1089  		}
  1090  	}
  1091  }
  1092  
  1093  func TestSchemaValidation_Pet(t *testing.T) {
  1094  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.schemavalidation.yml")
  1095  	if assert.NoError(t, err) {
  1096  		k := "Pet"
  1097  		schema := specDoc.Spec().Definitions[k]
  1098  
  1099  		opts := opts()
  1100  		gm, err := makeGenDefinition(k, "models", schema, specDoc, opts)
  1101  		if assert.NoError(t, err) {
  1102  			buf := bytes.NewBuffer(nil)
  1103  			err := templates.MustGet("model").Execute(buf, gm)
  1104  			if assert.NoError(t, err) {
  1105  				formatted, err := opts.LanguageOpts.FormatContent("pet.go", buf.Bytes())
  1106  				if assert.NoError(t, err) {
  1107  					res := string(formatted)
  1108  					assertInCode(t, k+") Validate(formats", res)
  1109  					assertInCode(t, "swag.IsZero(m.Status)", res)
  1110  					assertInCode(t, "swag.IsZero(m.Tags)", res)
  1111  					assertInCode(t, "validate.Required(\"name\", \"body\", m.Name)", res)
  1112  					assertInCode(t, "validate.Required(\"photoUrls\", \"body\", m.PhotoUrls)", res)
  1113  					assertInCode(t, "errors.CompositeValidationError(res...)", res)
  1114  				}
  1115  			}
  1116  		}
  1117  	}
  1118  }
  1119  
  1120  func TestSchemaValidation_UpdateOrg(t *testing.T) {
  1121  	specDoc, err := loads.Spec("../fixtures/codegen/todolist.schemavalidation.yml")
  1122  	if assert.NoError(t, err) {
  1123  		k := "UpdateOrg"
  1124  		schema := specDoc.Spec().Definitions[k]
  1125  
  1126  		opts := opts()
  1127  		gm, err := makeGenDefinition(k, "models", schema, specDoc, opts)
  1128  		if assert.NoError(t, err) {
  1129  			buf := bytes.NewBuffer(nil)
  1130  			err := templates.MustGet("model").Execute(buf, gm)
  1131  			if assert.NoError(t, err) {
  1132  				formatted, err := opts.LanguageOpts.FormatContent("pet.go", buf.Bytes())
  1133  				if assert.NoError(t, err) {
  1134  					res := string(formatted)
  1135  					assertInCode(t, k+") Validate(formats", res)
  1136  					assertInCode(t, "swag.IsZero(m.TagExpiration)", res)
  1137  					assertInCode(t, "validate.MinimumInt(\"tag_expiration\", \"body\", int64(*m.TagExpiration)", res)
  1138  					assertInCode(t, "validate.MaximumInt(\"tag_expiration\", \"body\", int64(*m.TagExpiration)", res)
  1139  					assertInCode(t, "errors.CompositeValidationError(res...)", res)
  1140  				} else {
  1141  					fmt.Println(buf.String())
  1142  				}
  1143  			}
  1144  		}
  1145  	}
  1146  }