func opBuilder(name, fname string) (codeGenOpBuilder, error) { if fname == "" { fname = "../fixtures/codegen/todolist.simple.yml" } specDoc, err := spec.Load(fname) if err != nil { return codeGenOpBuilder{}, err } op, ok := specDoc.OperationForName(name) if !ok { return codeGenOpBuilder{}, errors.New("No operation could be found for " + name) } return codeGenOpBuilder{ Name: name, APIPackage: "restapi", ModelsPackage: "models", Principal: "models.User", Target: ".", Operation: *op, Doc: specDoc, Authed: false, ExtraSchemas: make(map[string]GenSchema), }, nil }
func TestSchemaValidation_StringProps(t *testing.T) { specDoc, err := spec.Load("../fixtures/codegen/todolist.schemavalidation.yml") if assert.NoError(t, err) { k := "StringValidations" schema := specDoc.Spec().Definitions[k] gm, err := makeGenDefinition(k, "models", schema, specDoc) if assert.NoError(t, err) { prop := gm.Properties[0] if assertValidation(t, "\"name\"", "m.Name", prop) { buf := bytes.NewBuffer(nil) err := modelTemplate.Execute(buf, gm) if assert.NoError(t, err) { formatted, err := formatGoFile("string_validations.go", buf.Bytes()) if assert.NoError(t, err) { res := string(formatted) assertInCode(t, k+") Validate(formats", res) assertInCode(t, "m.validateName(formats", res) assertInCode(t, "err := validate.MinLength(\"name\",", res) assertInCode(t, "err := validate.MaxLength(\"name\",", res) assertInCode(t, "err := validate.Pattern(\"name\",", res) assertInCode(t, "errors.CompositeValidationError(res...)", res) } } } } } }
func TestSchemaValidation_Strings(t *testing.T) { specDoc, err := spec.Load("../fixtures/codegen/todolist.schemavalidation.yml") if assert.NoError(t, err) { k := "NamedString" schema := specDoc.Spec().Definitions[k] gm, err := makeGenDefinition(k, "models", schema, specDoc) if assert.NoError(t, err) { if assertValidation(t, "", "m", gm.GenSchema) { buf := bytes.NewBuffer(nil) err := modelTemplate.Execute(buf, gm) if assert.NoError(t, err) { formatted, err := formatGoFile("named_string.go", buf.Bytes()) if assert.NoError(t, err) { res := string(formatted) assertInCode(t, k+") Validate(formats", res) assertInCode(t, "err := validate.MinLength", res) assertInCode(t, "err := validate.MaxLength", res) assertInCode(t, "err := validate.Pattern", res) assertInCode(t, "errors.CompositeValidationError(res...)", res) } } } } } }
func TestSchemaValidation_NestedMapPropsComplex(t *testing.T) { specDoc, err := spec.Load("../fixtures/codegen/todolist.schemavalidation.yml") if assert.NoError(t, err) { k := "NestedMapComplexValidations" schema := specDoc.Spec().Definitions[k] gm, err := makeGenDefinition(k, "models", schema, specDoc) if assert.NoError(t, err) { prop := gm.Properties[0] if assertValidation(t, "\"meta\"", "m.Meta", prop) { buf := bytes.NewBuffer(nil) err := modelTemplate.Execute(buf, gm) if assert.NoError(t, err) { formatted, err := formatGoFile("nested_map_complex_validations.go", buf.Bytes()) if assert.NoError(t, err) { res := string(formatted) assertInCode(t, k+") Validate(formats", res) assertInCode(t, "m.validateMeta(formats", res) assertInCode(t, "for k := range m.Meta {", res) assertInCode(t, "for kk := range m.Meta[k] {", res) assertInCode(t, "for kkk := range m.Meta[k][kk] {", res) assertInCode(t, "m.Meta[k][kk][kkk].Validate(formats)", res) assertInCode(t, "err := validate.MinLength(\"name\",", res) assertInCode(t, "err := validate.MaxLength(\"name\",", res) assertInCode(t, "err := validate.Pattern(\"name\",", res) assertInCode(t, "err := validate.Minimum(\"age\",", res) assertInCode(t, "err := validate.Maximum(\"age\",", res) assertInCode(t, "err := validate.MultipleOf(\"age\",", res) assertInCode(t, "errors.CompositeValidationError(res...)", res) } } } } } }
func TestSchemaValidation_NamedNestedMap(t *testing.T) { specDoc, err := spec.Load("../fixtures/codegen/todolist.schemavalidation.yml") if assert.NoError(t, err) { k := "NamedNestedMap" schema := specDoc.Spec().Definitions[k] gm, err := makeGenDefinition(k, "models", schema, specDoc) if assert.NoError(t, err) { if assertValidation(t, "", "m", gm.GenSchema) { buf := bytes.NewBuffer(nil) err := modelTemplate.Execute(buf, gm) if assert.NoError(t, err) { formatted, err := formatGoFile("named_nested_map.go", buf.Bytes()) if assert.NoError(t, err) { res := string(formatted) assertInCode(t, k+") Validate(formats", res) assertInCode(t, "for k := range m {", res) assertInCode(t, "for kk := range m[k] {", res) assertInCode(t, "for kkk := range m[k][kk] {", res) assertInCode(t, "err := validate.Minimum(k+\".\"+kk+\".\"+kkk,", res) assertInCode(t, "err := validate.Maximum(k+\".\"+kk+\".\"+kkk,", res) assertInCode(t, "err := validate.MultipleOf(k+\".\"+kk+\".\"+kkk,", res) assertInCode(t, "errors.CompositeValidationError(res...)", res) } } } } } }
func TestSchemaValidation_NamedArrayAdditional(t *testing.T) { specDoc, err := spec.Load("../fixtures/codegen/todolist.schemavalidation.yml") if assert.NoError(t, err) { k := "NamedArrayAdditional" schema := specDoc.Spec().Definitions[k] gm, err := makeGenDefinition(k, "models", schema, specDoc) if assert.NoError(t, err) { if assertValidation(t, "", "m", gm.GenSchema) { buf := bytes.NewBuffer(nil) err := modelTemplate.Execute(buf, gm) if assert.NoError(t, err) { formatted, err := formatGoFile("named_array_additional.go", buf.Bytes()) if assert.NoError(t, err) { res := string(formatted) assertInCode(t, k+") Validate(formats", res) assertInCode(t, k+") validateP0(formats", res) assertInCode(t, k+") validateP1(formats", res) assertInCode(t, "err := validate.Required(\"0\",", res) assertInCode(t, "err := validate.MinLength(\"0\",", res) assertInCode(t, "err := validate.MaxLength(\"0\",", res) assertInCode(t, "err := validate.Pattern(\"0\",", res) assertInCode(t, "err := validate.Required(\"1\",", res) assertInCode(t, "err := validate.Minimum(\"1\",", res) assertInCode(t, "err := validate.Maximum(\"1\",", res) assertInCode(t, "err := validate.MultipleOf(\"1\",", res) assertInCode(t, "errors.CompositeValidationError(res...)", res) assertInCode(t, "m.NamedArrayAdditionalItems[i]", res) } } } } } }
func TestSchemaValidation_ArrayAdditionalProps(t *testing.T) { specDoc, err := spec.Load("../fixtures/codegen/todolist.schemavalidation.yml") if assert.NoError(t, err) { k := "ArrayAdditionalValidations" schema := specDoc.Spec().Definitions[k] gm, err := makeGenDefinition(k, "models", schema, specDoc) if assert.NoError(t, err) { prop := gm.Properties[0] if assertValidation(t, "\"args\"", "m.Args", prop) { buf := bytes.NewBuffer(nil) err := modelTemplate.Execute(buf, gm) if assert.NoError(t, err) { formatted, err := formatGoFile("array_additional_validations.go", buf.Bytes()) if assert.NoError(t, err) { res := string(formatted) assertInCode(t, k+") Validate(formats", res) assertInCode(t, "m.validateArgs(formats", res) assertInCode(t, "err := validate.Required(\"P0\",", res) assertInCode(t, "err := validate.MinLength(\"P0\",", res) assertInCode(t, "err := validate.MaxLength(\"P0\",", res) assertInCode(t, "err := validate.Pattern(\"P0\",", res) assertInCode(t, "err := validate.Required(\"P1\",", res) assertInCode(t, "err := validate.Minimum(\"P1\",", res) assertInCode(t, "err := validate.Maximum(\"P1\",", res) assertInCode(t, "err := validate.MultipleOf(\"P1\",", res) assertInCode(t, "errors.CompositeValidationError(res...)", res) assertInCode(t, "m.ArrayAdditionalValidationsArgsTuple0Items[i]", res) } } } } } }
func TestSchemaValidation_RequiredProps(t *testing.T) { specDoc, err := spec.Load("../fixtures/codegen/todolist.schemavalidation.yml") if assert.NoError(t, err) { k := "RequiredProps" schema := specDoc.Spec().Definitions[k] gm, err := makeGenDefinition(k, "models", schema, specDoc) if assert.NoError(t, err) { assert.Len(t, gm.Properties, 6) for _, p := range gm.Properties { if assert.True(t, p.Required) { buf := bytes.NewBuffer(nil) err := modelTemplate.Execute(buf, gm) if assert.NoError(t, err) { formatted, err := formatGoFile("required_props.go", buf.Bytes()) if assert.NoError(t, err) { res := string(formatted) assertInCode(t, k+") Validate(formats", res) assertInCode(t, "validate"+swag.ToGoName(p.Name), res) assertInCode(t, "err := validate.Required", res) assertInCode(t, "errors.CompositeValidationError(res...)", res) } } } } } } }
func TestGenerateModel_WithItemsAndAdditional2(t *testing.T) { specDoc, err := spec.Load("../fixtures/codegen/todolist.models.yml") if assert.NoError(t, err) { definitions := specDoc.Spec().Definitions k := "WithItemsAndAdditional2" schema := definitions[k] genModel, err := makeGenDefinition(k, "models", schema, specDoc) if assert.NoError(t, err) { assert.Nil(t, genModel.Items) assert.True(t, genModel.IsComplexObject) prop := getDefinitionProperty(genModel, "tags") assert.True(t, prop.IsComplexObject) buf := bytes.NewBuffer(nil) err := modelTemplate.Execute(buf, genModel) if assert.NoError(t, err) { b, err := formatGoFile("with_complex_items.go", buf.Bytes()) if assert.NoError(t, err) { res := string(b) assertInCode(t, "type "+k+" struct {", res) assertInCode(t, "type "+k+"TagsTuple0 struct {", res) // this would fail if it accepts additionalItems because it would come out as []interface{} assertInCode(t, "P0 string `json:\"-\"`", res) assertInCode(t, "Tags "+k+"TagsTuple0 `json:\"tags,omitempty\"`", res) assertInCode(t, k+"TagsTuple0Items []int32 `json:\"-\"`", res) } } } } }
func TestSchemaValidation_NamedNestedArray(t *testing.T) { specDoc, err := spec.Load("../fixtures/codegen/todolist.schemavalidation.yml") if assert.NoError(t, err) { k := "NamedNestedArray" schema := specDoc.Spec().Definitions[k] gm, err := makeGenDefinition(k, "models", schema, specDoc) if assert.NoError(t, err) { if assertValidation(t, "", "m", gm.GenSchema) { buf := bytes.NewBuffer(nil) err := modelTemplate.Execute(buf, gm) if assert.NoError(t, err) { formatted, err := formatGoFile("named_nested_array.go", buf.Bytes()) if assert.NoError(t, err) { res := string(formatted) assertInCode(t, k+") Validate(formats", res) assertInCode(t, "iNamedNestedArraySize := int64(len(m))", res) assertInCode(t, "iiNamedNestedArraySize := int64(len(m[i]))", res) assertInCode(t, "iiiNamedNestedArraySize := int64(len(m[i][ii]))", res) assertInCode(t, "err := validate.MinItems(\"\"", res) assertInCode(t, "err := validate.MaxItems(\"\"", res) assertInCode(t, "err := validate.MinItems(strconv.Itoa(i),", res) assertInCode(t, "err := validate.MaxItems(strconv.Itoa(i),", res) assertInCode(t, "err := validate.MinItems(strconv.Itoa(i)+\".\"+strconv.Itoa(ii),", res) assertInCode(t, "err := validate.MaxItems(strconv.Itoa(i)+\".\"+strconv.Itoa(ii),", res) assertInCode(t, "err := validate.MinLength(strconv.Itoa(i)+\".\"+strconv.Itoa(ii)+\".\"+strconv.Itoa(iii),", res) assertInCode(t, "err := validate.MaxLength(strconv.Itoa(i)+\".\"+strconv.Itoa(ii)+\".\"+strconv.Itoa(iii),", res) assertInCode(t, "err := validate.Pattern(strconv.Itoa(i)+\".\"+strconv.Itoa(ii)+\".\"+strconv.Itoa(iii),", res) assertInCode(t, "errors.CompositeValidationError(res...)", res) } } } } } }
func TestGenerateModel_WithComplexAdditional(t *testing.T) { specDoc, err := spec.Load("../fixtures/codegen/todolist.models.yml") if assert.NoError(t, err) { definitions := specDoc.Spec().Definitions k := "WithComplexAdditional" schema := definitions[k] genModel, err := makeGenDefinition(k, "models", schema, specDoc) if assert.NoError(t, err) { assert.Nil(t, genModel.Items) assert.True(t, genModel.IsComplexObject) prop := getDefinitionProperty(genModel, "tags") assert.True(t, prop.IsComplexObject) buf := bytes.NewBuffer(nil) err := modelTemplate.Execute(buf, genModel) if assert.NoError(t, err) { b, err := formatGoFile("with_complex_additional.go", buf.Bytes()) if assert.NoError(t, err) { res := string(b) assertInCode(t, "type WithComplexAdditional struct {", res) assertInCode(t, "type WithComplexAdditionalTagsTuple0 struct {", res) assertInCode(t, "Tags WithComplexAdditionalTagsTuple0 `json:\"tags,omitempty\"`", res) assertInCode(t, "P0 string `json:\"-\"`", res) assertInCode(t, "WithComplexAdditionalTagsTuple0Items []WithComplexAdditionalTagsItems `json:\"-\"`", res) } } } } }
func TestEnum_MapThing(t *testing.T) { specDoc, err := spec.Load("../fixtures/codegen/todolist.enums.yml") if assert.NoError(t, err) { definitions := specDoc.Spec().Definitions k := "MapThing" schema := definitions[k] genModel, err := makeGenDefinition(k, "models", schema, specDoc) if assert.NoError(t, err) { buf := bytes.NewBuffer(nil) err := modelTemplate.Execute(buf, genModel) if assert.NoError(t, err) { ff, err := formatGoFile("map_thing.go", buf.Bytes()) if assert.NoError(t, err) { res := string(ff) assertInCode(t, "var mapThingEnum []interface{}", res) assertInCode(t, k+") validateMapThingEnum(path, location string, value map[string]string)", res) assertInCode(t, "m.validateMapThingEnum(\"\", \"body\", m)", res) assertInCode(t, "var mapThingValueEnum []interface{}", res) assertInCode(t, k+") validateMapThingValueEnum(path, location string, value string)", res) assertInCode(t, "m.validateMapThingValueEnum(k, \"body\", m[k])", res) } } } } }
func TestEnum_SliceAndAdditionalItemsThing(t *testing.T) { specDoc, err := spec.Load("../fixtures/codegen/todolist.enums.yml") if assert.NoError(t, err) { definitions := specDoc.Spec().Definitions k := "SliceAndAdditionalItemsThing" schema := definitions[k] genModel, err := makeGenDefinition(k, "models", schema, specDoc) if assert.NoError(t, err) { buf := bytes.NewBuffer(nil) err := modelTemplate.Execute(buf, genModel) if assert.NoError(t, err) { ff, err := formatGoFile("slice_and_additional_items_thing.go", buf.Bytes()) if assert.NoError(t, err) { res := string(ff) assertInCode(t, "var sliceAndAdditionalItemsThingEnum []interface{}", res) assertInCode(t, k+") validateSliceAndAdditionalItemsThingEnum(path, location string, value SliceAndAdditionalItemsThing)", res) //assertInCode(t, "m.validateSliceAndAdditionalItemsThingEnum(\"\", \"body\", m)", res) assertInCode(t, "var sliceAndAdditionalItemsThingP0Enum []interface{}", res) assertInCode(t, k+") validateP0Enum(path, location string, value string)", res) assertInCode(t, "m.validateP0Enum(\"0\", \"body\", m.P0)", res) assertInCode(t, "var sliceAndAdditionalItemsThingItemsEnum []interface{}", res) assertInCode(t, k+") validateSliceAndAdditionalItemsThingItemsEnum(path, location string, value float32)", res) assertInCode(t, "m.validateSliceAndAdditionalItemsThingItemsEnum(strconv.Itoa(i+1), \"body\", m.SliceAndAdditionalItemsThingItems[i])", res) } } } } }
func TestSchemaValidation_AllOfProps(t *testing.T) { specDoc, err := spec.Load("../fixtures/codegen/todolist.schemavalidation.yml") if assert.NoError(t, err) { k := "AllOfValidations" schema := specDoc.Spec().Definitions[k] gm, err := makeGenDefinition(k, "models", schema, specDoc) if assert.NoError(t, err) { prop := gm.Properties[0] if assertValidation(t, "\"meta\"", "m.Meta", prop) { buf := bytes.NewBuffer(nil) err := modelTemplate.Execute(buf, gm) if assert.NoError(t, err) { formatted, err := formatGoFile("all_of_validations.go", buf.Bytes()) if assert.NoError(t, err) { res := string(formatted) assertInCode(t, k+") Validate(formats", res) assertInCode(t, "m.validateMeta(formats", res) assertInCode(t, "validate.MinLength(\"meta\"+\".\"+\"name\",", res) assertInCode(t, "validate.Minimum(\"meta\"+\".\"+\"age\",", res) assertInCode(t, "validate.MinItems(\"meta\"+\".\"+\"args\",", res) assertInCode(t, "validate.MinItems(\"meta\"+\".\"+\"assoc\",", res) assertInCode(t, "validate.MinItems(\"meta\"+\".\"+\"assoc\"+\".\"+strconv.Itoa(i),", res) assertInCode(t, "validate.MinItems(\"meta\"+\".\"+\"assoc\"+\".\"+strconv.Itoa(i)+\".\"+strconv.Itoa(ii),", res) assertInCode(t, "validate.MinLength(\"meta\"+\".\"+\"assoc\"+\".\"+strconv.Itoa(i)+\".\"+strconv.Itoa(ii)+\".\"+strconv.Itoa(iii),", res) assertInCode(t, "validate.Minimum(\"meta\"+\".\"+\"opts\"+\".\"+k,", res) assertInCode(t, "validate.Minimum(\"meta\"+\".\"+\"extOpts\"+\".\"+k+\".\"+kk+\".\"+kkk,", res) assertInCode(t, "validate.MinLength(\"meta\"+\".\"+\"coords\"+\".\"+\"name\",", res) assertInCode(t, "errors.CompositeValidationError(res...)", res) } } } } } }
func TestGenerateModel_WithTuple(t *testing.T) { specDoc, err := spec.Load("../fixtures/codegen/todolist.models.yml") if assert.NoError(t, err) { definitions := specDoc.Spec().Definitions k := "WithTuple" schema := definitions[k] genModel, err := makeGenDefinition(k, "models", schema, specDoc) if assert.NoError(t, err) && assert.NotEmpty(t, genModel.ExtraSchemas) && assert.NotEmpty(t, genModel.Properties) { assert.False(t, genModel.IsTuple) assert.True(t, genModel.IsComplexObject) assert.False(t, genModel.IsArray) assert.False(t, genModel.IsAnonymous) sch := genModel.ExtraSchemas[0] assert.True(t, sch.IsTuple) assert.False(t, sch.IsComplexObject) assert.False(t, sch.IsArray) assert.False(t, sch.IsAnonymous) assert.Equal(t, k+"FlagsTuple0", sch.Name) assert.False(t, sch.HasAdditionalItems) assert.Nil(t, sch.AdditionalItems) prop := genModel.Properties[0] assert.False(t, genModel.IsTuple) assert.True(t, genModel.IsComplexObject) assert.False(t, prop.IsArray) assert.False(t, prop.IsAnonymous) assert.Equal(t, k+"FlagsTuple0", prop.GoType) assert.Equal(t, "flags", prop.Name) buf := bytes.NewBuffer(nil) err := modelTemplate.Execute(buf, genModel) if assert.NoError(t, err) { ff, err := formatGoFile("with_tuple.go", buf.Bytes()) if assert.NoError(t, err) { res := string(ff) assertInCode(t, "swagger:model "+k+"Flags", res) assertInCode(t, "type "+k+"FlagsTuple0 struct {", res) assertInCode(t, "P0 int64 `json:\"-\"`", res) assertInCode(t, "P1 string `json:\"-\"`", res) assertInCode(t, k+"FlagsTuple0) UnmarshalJSON", res) assertInCode(t, k+"FlagsTuple0) MarshalJSON", res) assertInCode(t, "json.Marshal(data)", res) assert.NotRegexp(t, regexp.MustCompile("lastIndex"), res) for i, p := range sch.Properties { r := "m.P" + strconv.Itoa(i) if !p.IsNullable { r = "&" + r } assertInCode(t, "json.Unmarshal(stage1["+strconv.Itoa(i)+"], "+r+")", res) assertInCode(t, "P"+strconv.Itoa(i)+",", res) } } } } } }
func TestGenerateModel_TupleWithExtra(t *testing.T) { specDoc, err := spec.Load("../fixtures/codegen/todolist.models.yml") if assert.NoError(t, err) { definitions := specDoc.Spec().Definitions k := "TupleWithExtra" schema := definitions[k] genModel, err := makeGenDefinition(k, "models", schema, specDoc) if assert.NoError(t, err) && assert.Empty(t, genModel.ExtraSchemas) { assert.True(t, genModel.IsTuple) assert.False(t, genModel.IsComplexObject) assert.False(t, genModel.IsArray) assert.False(t, genModel.IsAnonymous) assert.True(t, genModel.HasAdditionalItems) assert.NotNil(t, genModel.AdditionalItems) assert.Equal(t, k, genModel.Name) assert.Equal(t, k, genModel.GoType) assert.Len(t, genModel.Properties, 4) buf := bytes.NewBuffer(nil) err := modelTemplate.Execute(buf, genModel) if assert.NoError(t, err) { ff, err := formatGoFile("tuple_with_extra.go", buf.Bytes()) if assert.NoError(t, err) { res := string(ff) assertInCode(t, "swagger:model "+k, res) assertInCode(t, "type "+k+" struct {", res) assertInCode(t, "P0 int64 `json:\"-\"`", res) assertInCode(t, "P1 string `json:\"-\"`", res) assertInCode(t, "P2 strfmt.DateTime `json:\"-\"`", res) assertInCode(t, "P3 Notable `json:\"-\"`", res) assertInCode(t, k+"Items []float64 `json:\"-\"`", res) assertInCode(t, k+") UnmarshalJSON", res) assertInCode(t, k+") MarshalJSON", res) for i, p := range genModel.Properties { r := "m.P" + strconv.Itoa(i) if !p.IsNullable { r = "&" + r } assertInCode(t, "lastIndex = "+strconv.Itoa(i), res) assertInCode(t, "json.Unmarshal(stage1["+strconv.Itoa(i)+"], "+r+")", res) assertInCode(t, "P"+strconv.Itoa(i)+",", res) } assertInCode(t, "var lastIndex int", res) assertInCode(t, "var toadd float64", res) assertInCode(t, "for _, val := range stage1[lastIndex+1:]", res) assertInCode(t, "json.Unmarshal(val, &toadd)", res) assertInCode(t, "json.Marshal(data)", res) assertInCode(t, "for _, v := range m."+k+"Items", res) } } } } }
func TestGenerateModel_WithAdditional(t *testing.T) { specDoc, err := spec.Load("../fixtures/codegen/todolist.models.yml") if assert.NoError(t, err) { definitions := specDoc.Spec().Definitions k := "WithAdditional" schema := definitions[k] genModel, err := makeGenDefinition(k, "models", schema, specDoc) if assert.NoError(t, err) && assert.NotEmpty(t, genModel.ExtraSchemas) { assert.False(t, genModel.HasAdditionalProperties) assert.False(t, genModel.IsMap) assert.False(t, genModel.IsAdditionalProperties) assert.True(t, genModel.IsComplexObject) sch := genModel.ExtraSchemas[0] assert.True(t, sch.HasAdditionalProperties) assert.False(t, sch.IsMap) assert.True(t, sch.IsAdditionalProperties) assert.False(t, sch.IsComplexObject) if assert.NotNil(t, sch.AdditionalProperties) { prop := findProperty(genModel.Properties, "data") assert.False(t, prop.HasAdditionalProperties) assert.False(t, prop.IsMap) assert.False(t, prop.IsAdditionalProperties) assert.True(t, prop.IsComplexObject) buf := bytes.NewBuffer(nil) err := modelTemplate.Execute(buf, genModel) if assert.NoError(t, err) { res := buf.String() assertInCode(t, "type "+k+" struct {", res) assertInCode(t, "Data "+k+"DataP0 `json:\"data,omitempty\"`", res) assertInCode(t, "type "+k+"DataP0 struct {", res) assertInCode(t, k+"DataP0 map[string]string `json:\"-\"`", res) assertInCode(t, "Name string `json:\"name,omitempty\"`", res) assertInCode(t, k+"DataP0) UnmarshalJSON", res) assertInCode(t, k+"DataP0) MarshalJSON", res) assertInCode(t, "json.Marshal(m)", res) assertInCode(t, "json.Marshal(m."+k+"DataP0)", res) assertInCode(t, "json.Unmarshal(data, &stage1)", res) assertInCode(t, "json.Unmarshal(data, &stage2)", res) assertInCode(t, "json.Unmarshal(v, &toadd)", res) assertInCode(t, "result[k] = toadd", res) assertInCode(t, "m."+k+"DataP0 = result", res) for _, p := range sch.Properties { assertInCode(t, "delete(stage2, \""+p.Name+"\")", res) } } } } } }
func basicTaskListResolver(t testing.TB) (*spec.Document, *typeResolver, error) { tlb, err := spec.Load("../fixtures/codegen/tasklist.basic.yml") if err != nil { return nil, nil, err } swsp := tlb.Spec() uc := swsp.Definitions["UserCard"] uc.AddExtension("x-go-name", "UserItem") swsp.Definitions["UserCard"] = uc return tlb, &typeResolver{ Doc: tlb, ModelsPackage: "models", }, nil }
func TestAdditionalProperties_Nested(t *testing.T) { specDoc, err := spec.Load("../fixtures/codegen/todolist.schemavalidation.yml") if assert.NoError(t, err) { k := "NamedNestedMapComplex" schema := specDoc.Spec().Definitions[k] tr := &typeResolver{ ModelsPackage: "", ModelName: k, Doc: specDoc, } sg := schemaGenContext{ Path: "", Name: k, Receiver: "m", IndexVar: "i", ValueExpr: "m", Schema: schema, Required: false, TypeResolver: tr, Named: true, ExtraSchemas: make(map[string]GenSchema), } fsm, lsm, err := newMapStack(&sg) if assert.NoError(t, err) { assert.NotNil(t, fsm.Type) assert.Equal(t, &schema, fsm.Type) assert.Equal(t, "", fsm.Context.Path) assert.NotNil(t, schema.AdditionalProperties.Schema) if assert.NotNil(t, fsm.Next) && assert.Nil(t, fsm.Previous) { assert.NotNil(t, fsm.Type) assert.Equal(t, &schema, fsm.Type) assert.NotEqual(t, fsm, lsm) assert.NotNil(t, fsm.Type.AdditionalProperties) assert.NotNil(t, fsm.Type.AdditionalProperties.Schema) assert.Nil(t, fsm.NewObj) assert.Nil(t, fsm.Next.NewObj) assert.NotNil(t, fsm.Next.Previous) assert.NotNil(t, fsm.Next.Next) assert.NotNil(t, fsm.Next.Next.NewObj) assert.NotNil(t, fsm.Next.Next.ValueRef) assert.Nil(t, fsm.Next.Next.Next) assert.Equal(t, fsm.Next.Next, lsm) assert.NoError(t, lsm.Build()) } } } }
func loadSpec(specFile string) (string, *spec.Document, error) { // find swagger spec document, verify it exists specPath, err := findSwaggerSpec(specFile) if err != nil { return "", nil, err } // load swagger spec specDoc, err := spec.Load(specPath) if err != nil { return "", nil, err } return specPath, specDoc, nil }
func TestSchemaValidation_NestedObjectProps(t *testing.T) { specDoc, err := spec.Load("../fixtures/codegen/todolist.schemavalidation.yml") if assert.NoError(t, err) { k := "NestedObjectValidations" schema := specDoc.Spec().Definitions[k] gm, err := makeGenDefinition(k, "models", schema, specDoc) if assert.NoError(t, err) { prop := gm.Properties[0] if assertValidation(t, "\"args\"", "m.Args", prop) { buf := bytes.NewBuffer(nil) err := modelTemplate.Execute(buf, gm) if assert.NoError(t, err) { formatted, err := formatGoFile("nested_object_validations.go", buf.Bytes()) if assert.NoError(t, err) { res := string(formatted) assertInCode(t, k+") Validate(formats", res) assertInCode(t, "m.validateArgs(formats", res) assertInCode(t, "err := validate.MinLength(\"args\"+\".\"+\"meta\"+\".\"+\"first\",", res) assertInCode(t, "err := validate.MaxLength(\"args\"+\".\"+\"meta\"+\".\"+\"first\",", res) assertInCode(t, "err := validate.Pattern(\"args\"+\".\"+\"meta\"+\".\"+\"first\",", res) assertInCode(t, "err := validate.Minimum(\"args\"+\".\"+\"meta\"+\".\"+\"second\",", res) assertInCode(t, "err := validate.Maximum(\"args\"+\".\"+\"meta\"+\".\"+\"second\",", res) assertInCode(t, "err := validate.MultipleOf(\"args\"+\".\"+\"meta\"+\".\"+\"second\",", res) assertInCode(t, "iThirdSize := int64(len(m.Args.Meta.Third))", res) assertInCode(t, "err := validate.MinItems(\"args\"+\".\"+\"meta\"+\".\"+\"third\",", res) assertInCode(t, "err := validate.MaxItems(\"args\"+\".\"+\"meta\"+\".\"+\"third\",", res) assertInCode(t, "err := validate.Minimum(\"args\"+\".\"+\"meta\"+\".\"+\"third\"+\".\"+strconv.Itoa(i),", res) assertInCode(t, "err := validate.Maximum(\"args\"+\".\"+\"meta\"+\".\"+\"third\"+\".\"+strconv.Itoa(i),", res) assertInCode(t, "err := validate.MultipleOf(\"args\"+\".\"+\"meta\"+\".\"+\"third\"+\".\"+strconv.Itoa(i),", res) assertInCode(t, "iFourthSize := int64(len(m.Args.Meta.Fourth))", res) assertInCode(t, "iiFourthSize := int64(len(m.Args.Meta.Fourth[i]))", res) assertInCode(t, "iiiFourthSize := int64(len(m.Args.Meta.Fourth[i][ii]))", res) assertInCode(t, "err := validate.MinItems(\"args\"+\".\"+\"meta\"+\".\"+\"fourth\"+\".\"+strconv.Itoa(i),", res) assertInCode(t, "err := validate.MaxItems(\"args\"+\".\"+\"meta\"+\".\"+\"fourth\"+\".\"+strconv.Itoa(i),", res) assertInCode(t, "err := validate.MinItems(\"args\"+\".\"+\"meta\"+\".\"+\"fourth\"+\".\"+strconv.Itoa(i)+\".\"+strconv.Itoa(ii),", res) assertInCode(t, "err := validate.MaxItems(\"args\"+\".\"+\"meta\"+\".\"+\"fourth\"+\".\"+strconv.Itoa(i)+\".\"+strconv.Itoa(ii),", res) assertInCode(t, "err := validate.Minimum(\"args\"+\".\"+\"meta\"+\".\"+\"fourth\"+\".\"+strconv.Itoa(i)+\".\"+strconv.Itoa(ii)+\".\"+strconv.Itoa(iii),", res) assertInCode(t, "err := validate.Maximum(\"args\"+\".\"+\"meta\"+\".\"+\"fourth\"+\".\"+strconv.Itoa(i)+\".\"+strconv.Itoa(ii)+\".\"+strconv.Itoa(iii),", res) assertInCode(t, "err := validate.MultipleOf(\"args\"+\".\"+\"meta\"+\".\"+\"fourth\"+\".\"+strconv.Itoa(i)+\".\"+strconv.Itoa(ii)+\".\"+strconv.Itoa(iii),", res) assertInCode(t, "errors.CompositeValidationError(res...)", res) } } } } } }
func TestGenerateModel_Nota(t *testing.T) { specDoc, err := spec.Load("../fixtures/codegen/todolist.models.yml") if assert.NoError(t, err) { definitions := specDoc.Spec().Definitions k := "Nota" schema := definitions[k] genModel, err := makeGenDefinition(k, "models", schema, specDoc) if assert.NoError(t, err) { buf := bytes.NewBuffer(nil) err := modelTemplate.Execute(buf, genModel) if assert.NoError(t, err) { res := buf.String() assertInCode(t, "type Nota map[string]int32", res) } } } }
func TestEnum_ObjectThing(t *testing.T) { specDoc, err := spec.Load("../fixtures/codegen/todolist.enums.yml") if assert.NoError(t, err) { definitions := specDoc.Spec().Definitions k := "ObjectThing" schema := definitions[k] genModel, err := makeGenDefinition(k, "models", schema, specDoc) if assert.NoError(t, err) { buf := bytes.NewBuffer(nil) err := modelTemplate.Execute(buf, genModel) if assert.NoError(t, err) { ff, err := formatGoFile("object_thing.go", buf.Bytes()) if assert.NoError(t, err) { res := string(ff) assertInCode(t, "var objectThingNameEnum []interface{}", res) assertInCode(t, "var objectThingFlowerEnum []interface{}", res) assertInCode(t, "var objectThingFlourEnum []interface{}", res) assertInCode(t, "var objectThingWolvesEnum []interface{}", res) assertInCode(t, "var objectThingWolvesValueEnum []interface{}", res) assertInCode(t, "var objectThingCatsItemsEnum []interface{}", res) assertInCode(t, "var objectThingLionsTuple0P0Enum []interface{}", res) assertInCode(t, "var objectThingLionsTuple0P1Enum []interface{}", res) assertInCode(t, "var objectThingLionsTuple0ItemsEnum []interface{}", res) assertInCode(t, k+") validateNameEnum(path, location string, value string)", res) assertInCode(t, k+") validateFlowerEnum(path, location string, value int32)", res) assertInCode(t, k+") validateFlourEnum(path, location string, value float32)", res) assertInCode(t, k+") validateWolvesEnum(path, location string, value map[string]string)", res) assertInCode(t, k+") validateWolvesValueEnum(path, location string, value string)", res) assertInCode(t, k+") validateCatsItemsEnum(path, location string, value string)", res) assertInCode(t, k+"LionsTuple0) validateObjectThingLionsTuple0ItemsEnum(path, location string, value float64)", res) assertInCode(t, k+") validateCats(", res) assertInCode(t, "m.validateNameEnum(\"name\", \"body\", m.Name)", res) assertInCode(t, "m.validateFlowerEnum(\"flower\", \"body\", m.Flower)", res) assertInCode(t, "m.validateFlourEnum(\"flour\", \"body\", m.Flour)", res) assertInCode(t, "m.validateWolvesEnum(\"wolves\", \"body\", m.Wolves)", res) assertInCode(t, "m.validateWolvesValueEnum(\"wolves\"+\".\"+k, \"body\", m.Wolves[k])", res) assertInCode(t, "m.validateCatsItemsEnum(\"cats\"+\".\"+strconv.Itoa(i), \"body\", m.Cats[i])", res) assertInCode(t, "m.validateP1Enum(\"P1\", \"body\", m.P1)", res) assertInCode(t, "m.validateP0Enum(\"P0\", \"body\", m.P0)", res) assertInCode(t, "m.validateObjectThingLionsTuple0ItemsEnum(strconv.Itoa(i), \"body\", m.ObjectThingLionsTuple0Items[i])", res) } } } } }
func TestGenerateModel_WithRef(t *testing.T) { tt := templateTest{t, modelTemplate.Lookup("schema")} specDoc, err := spec.Load("../fixtures/codegen/todolist.models.yml") if assert.NoError(t, err) { definitions := specDoc.Spec().Definitions schema := definitions["WithRef"] genModel, err := makeGenDefinition("WithRef", "models", schema, specDoc) if assert.NoError(t, err) { assert.True(t, genModel.IsComplexObject) assert.Equal(t, "WithRef", genModel.Name) assert.Equal(t, "WithRef", genModel.GoType) buf := bytes.NewBuffer(nil) tt.template.Execute(buf, genModel) res := buf.String() assertInCode(t, "type WithRef struct {", res) assertInCode(t, "Notes Notable `json:\"notes,omitempty\"`", res) } } }
func TestGenerateModel_SimpleTuple(t *testing.T) { tt := templateTest{t, modelTemplate} specDoc, err := spec.Load("../fixtures/codegen/todolist.models.yml") if assert.NoError(t, err) { definitions := specDoc.Spec().Definitions k := "SimpleTuple" schema := definitions[k] genModel, err := makeGenDefinition(k, "models", schema, specDoc) if assert.NoError(t, err) && assert.Empty(t, genModel.ExtraSchemas) { assert.True(t, genModel.IsTuple) assert.False(t, genModel.IsComplexObject) assert.False(t, genModel.IsArray) assert.False(t, genModel.IsAnonymous) assert.Equal(t, k, genModel.Name) assert.Equal(t, k, genModel.GoType) assert.Len(t, genModel.Properties, 5) buf := bytes.NewBuffer(nil) tt.template.Execute(buf, genModel) res := buf.String() assertInCode(t, "swagger:model "+k, res) assertInCode(t, "type "+k+" struct {", res) assertInCode(t, "P0 int64 `json:\"-\"`", res) assertInCode(t, "P1 string `json:\"-\"`", res) assertInCode(t, "P2 strfmt.DateTime `json:\"-\"`", res) assertInCode(t, "P3 Notable `json:\"-\"`", res) assertInCode(t, "P4 *Notable `json:\"-\"`", res) assertInCode(t, k+") UnmarshalJSON", res) assertInCode(t, k+") MarshalJSON", res) assertInCode(t, "json.Marshal(data)", res) assert.NotRegexp(t, regexp.MustCompile("lastIndex"), res) for i, p := range genModel.Properties { r := "m.P" + strconv.Itoa(i) if !p.IsNullable { r = "&" + r } assertInCode(t, "json.Unmarshal(stage1["+strconv.Itoa(i)+"], "+r+")", res) assertInCode(t, "P"+strconv.Itoa(i)+",", res) } } } }
func TestGenerateModel_WithAllOf(t *testing.T) { specDoc, err := spec.Load("../fixtures/codegen/todolist.models.yml") if assert.NoError(t, err) { definitions := specDoc.Spec().Definitions schema := definitions["WithAllOf"] genModel, err := makeGenDefinition("WithAllOf", "models", schema, specDoc) if assert.NoError(t, err) { assert.Len(t, genModel.AllOf, 7) assert.True(t, genModel.AllOf[1].HasAdditionalProperties) assert.True(t, genModel.IsComplexObject) assert.Equal(t, "WithAllOf", genModel.Name) assert.Equal(t, "WithAllOf", genModel.GoType) buf := bytes.NewBuffer(nil) err := modelTemplate.Execute(buf, genModel) if assert.NoError(t, err) { ct, err := formatGoFile("all_of_schema.go", buf.Bytes()) if assert.NoError(t, err) { res := string(ct) //fmt.Println(res) assertInCode(t, "type WithAllOf struct {", res) assertInCode(t, "type WithAllOfAO2P2 struct {", res) assertInCode(t, "type WithAllOfAO3P3 struct {", res) assertInCode(t, "type WithAllOfParamsAnon struct {", res) assertInCode(t, "type WithAllOfAO4Tuple4 struct {", res) assertInCode(t, "type WithAllOfAO5Tuple5 struct {", res) assertInCode(t, "Notable", res) assertInCode(t, "Title string `json:\"title,omitempty\"`", res) assertInCode(t, "Body string `json:\"body,omitempty\"`", res) assertInCode(t, "Name string `json:\"name,omitempty\"`", res) assertInCode(t, "P0 float32 `json:\"-\"`", res) assertInCode(t, "P0 float64 `json:\"-\"`", res) assertInCode(t, "P1 strfmt.DateTime `json:\"-\"`", res) assertInCode(t, "P1 strfmt.Date `json:\"-\"`", res) assertInCode(t, "Opinion string `json:\"opinion,omitempty\"`", res) assertInCode(t, "WithAllOfAO5Tuple5Items []strfmt.Password `json:\"-\"`", res) assertInCode(t, "AO1 map[string]int32 `json:\"-\"`", res) assertInCode(t, "WithAllOfAO2P2 map[string]int64 `json:\"-\"`", res) } } } } }
func TestGenerateModel_Notablix(t *testing.T) { specDoc, err := spec.Load("../fixtures/codegen/todolist.models.yml") if assert.NoError(t, err) { definitions := specDoc.Spec().Definitions k := "Notablix" schema := definitions[k] genModel, err := makeGenDefinition(k, "models", schema, specDoc) if assert.NoError(t, err) { buf := bytes.NewBuffer(nil) err := modelTemplate.Execute(buf, genModel) if assert.NoError(t, err) { ff, err := formatGoFile("notablix.go", buf.Bytes()) if assert.NoError(t, err) { res := string(ff) assertInCode(t, "type Notablix [][][]Notable", res) } } } } }
func TestSchemaValidation_NamedAllOf(t *testing.T) { specDoc, err := spec.Load("../fixtures/codegen/todolist.schemavalidation.yml") if assert.NoError(t, err) { k := "NamedAllOf" schema := specDoc.Spec().Definitions[k] gm, err := makeGenDefinition(k, "models", schema, specDoc) if assert.NoError(t, err) { if assertValidation(t, "", "m", gm.GenSchema) { buf := bytes.NewBuffer(nil) err := modelTemplate.Execute(buf, gm) if assert.NoError(t, err) { formatted, err := formatGoFile("named_all_of.go", buf.Bytes()) if assert.NoError(t, err) { res := string(formatted) assertInCode(t, k+") Validate(formats", res) assertInCode(t, k+") validateName(formats", res) assertInCode(t, k+") validateAge(formats", res) assertInCode(t, k+") validateArgs(formats", res) assertInCode(t, k+") validateAssoc(formats", res) assertInCode(t, k+") validateOpts(formats", res) assertInCode(t, k+") validateExtOpts(formats", res) assertInCode(t, k+") validateCoords(formats", res) assertInCode(t, "validate.MinLength(\"name\",", res) assertInCode(t, "validate.Minimum(\"age\",", res) assertInCode(t, "validate.MinItems(\"args\",", res) assertInCode(t, "validate.MinItems(\"assoc\",", res) assertInCode(t, "validate.MinItems(\"assoc\"+\".\"+strconv.Itoa(i),", res) assertInCode(t, "validate.MinItems(\"assoc\"+\".\"+strconv.Itoa(i)+\".\"+strconv.Itoa(ii),", res) assertInCode(t, "validate.MinLength(\"assoc\"+\".\"+strconv.Itoa(i)+\".\"+strconv.Itoa(ii)+\".\"+strconv.Itoa(iii),", res) assertInCode(t, "validate.Minimum(\"opts\"+\".\"+k,", res) assertInCode(t, "validate.Minimum(\"extOpts\"+\".\"+k+\".\"+kk+\".\"+kkk,", res) assertInCode(t, "validate.MinLength(\"coords\"+\".\"+\"name\",", res) assertInCode(t, "errors.CompositeValidationError(res...)", res) } } } } } }
func TestGenerateModel_Statix(t *testing.T) { specDoc, err := spec.Load("../fixtures/codegen/todolist.models.yml") if assert.NoError(t, err) { definitions := specDoc.Spec().Definitions k := "Statix" schema := definitions[k] genModel, err := makeGenDefinition(k, "models", schema, specDoc) if assert.NoError(t, err) { buf := bytes.NewBuffer(nil) err := modelTemplate.Execute(buf, genModel) if assert.NoError(t, err) { ff, err := formatGoFile("statix.go", buf.Bytes()) if assert.NoError(t, err) { res := string(ff) assertInCode(t, "type Statix [][][]StatixItems0", res) assertInCode(t, "type StatixItems0 struct {", res) assertInCode(t, "Points []int64 `json:\"points,omitempty\"`", res) } } } } }
func TestGenerateModel_WithMapRegistry(t *testing.T) { specDoc, err := spec.Load("../fixtures/codegen/todolist.models.yml") if assert.NoError(t, err) { definitions := specDoc.Spec().Definitions schema := definitions["WithMapRegistry"] genModel, err := makeGenDefinition("WithMap", "models", schema, specDoc) if assert.NoError(t, err) { assert.False(t, genModel.HasAdditionalProperties) prop := getDefinitionProperty(genModel, "data") assert.True(t, prop.HasAdditionalProperties) assert.True(t, prop.IsMap) assert.False(t, prop.IsComplexObject) buf := bytes.NewBuffer(nil) err := modelTemplate.Execute(buf, genModel) if assert.NoError(t, err) { res := buf.String() assertInCode(t, "type WithMap struct {", res) assertInCode(t, "Data map[string]map[string]map[string]string `json:\"data,omitempty\"`", res) } } } }