func newMapStack(context *schemaGenContext) (first, last *mapStack, err error) { ms := &mapStack{ Type: &context.Schema, Context: context, } l := ms for l.HasMore() { tpe, err := l.Context.TypeResolver.ResolveSchema(l.Type.AdditionalProperties.Schema, true, true) if err != nil { return nil, nil, err } if !tpe.IsMap { if tpe.IsComplexObject && tpe.IsAnonymous { nw := l.Context.makeNewStruct(l.Context.Name+" Anon", *l.Type.AdditionalProperties.Schema) sch := spec.RefProperty("#/definitions/" + nw.Name) l.NewObj = nw l.Type.AdditionalProperties.Schema = sch l.ValueRef = l.Context.NewAdditionalProperty(*sch) } break } l.Next = &mapStack{ Previous: l, Type: l.Type.AdditionalProperties.Schema, Context: l.Context.NewAdditionalProperty(*l.Type.AdditionalProperties.Schema), } l = l.Next } return ms, l, nil }
func (sg *schemaGenContext) buildArray() error { tpe, err := sg.TypeResolver.ResolveSchema(sg.Schema.Items.Schema, true, false) if err != nil { return err } // check if the element is a complex object, if so generate a new type for it if tpe.IsComplexObject && tpe.IsAnonymous { pg := sg.makeNewStruct(sg.Name+" items"+strconv.Itoa(sg.Index), *sg.Schema.Items.Schema) if err := pg.makeGenSchema(); err != nil { return err } sg.MergeResult(pg, false) sg.ExtraSchemas[pg.Name] = pg.GenSchema sg.Schema.Items.Schema = spec.RefProperty("#/definitions/" + pg.Name) sg.IsVirtual = true if err := sg.makeGenSchema(); err != nil { return err } return nil } elProp := sg.NewSliceBranch(sg.Schema.Items.Schema) elProp.Required = true if err := elProp.makeGenSchema(); err != nil { return err } sg.MergeResult(elProp, false) sg.GenSchema.IsBaseType = elProp.GenSchema.IsBaseType sg.GenSchema.ItemsEnum = elProp.GenSchema.Enum elProp.GenSchema.Suffix = "Items" sg.GenSchema.GoType = "[]" + elProp.GenSchema.GoType // TODO: this is probably not right. Should just respect what type resolvers said nn := elProp.GenSchema.IsNullable elProp.GenSchema.IsNullable = tpe.IsNullable && !tpe.HasDiscriminator if nn && !tpe.HasDiscriminator && !tpe.IsPrimitive { sg.GenSchema.GoType = "[]*" + elProp.GenSchema.GoType } schemaCopy := elProp.GenSchema schemaCopy.Required = false hv, _ := hasValidations(sg.Schema.Items.Schema, false) schemaCopy.HasValidations = elProp.GenSchema.IsNullable || hv sg.GenSchema.Items = &schemaCopy if sg.Named { sg.GenSchema.AliasedType = sg.GenSchema.GoType } return nil }
func TestTypeResolver_NestedAliasedSlice(t *testing.T) { specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml") if assert.NoError(t, err) { definitions := specDoc.Spec().Definitions k := "Statix" schema := definitions[k] tr := newTypeResolver("models", specDoc) specDoc.Spec().Definitions["StatixItems0"] = *schema.Items.Schema.Items.Schema.Items.Schema schema.Items.Schema.Items.Schema.Items.Schema = spec.RefProperty("#/definitions/StatixItems0") tr.KnownDefs["StatixItems0"] = struct{}{} tr.ModelName = k rt, err := tr.ResolveSchema(&schema, false, false) if assert.NoError(t, err) { assert.Equal(t, "[][][]models.StatixItems0", rt.AliasedType) } } }
func (sg *schemaGenContext) buildAdditionalItems() error { wantsAdditionalItems := sg.Schema.AdditionalItems != nil && (sg.Schema.AdditionalItems.Allows || sg.Schema.AdditionalItems.Schema != nil) sg.GenSchema.HasAdditionalItems = wantsAdditionalItems if wantsAdditionalItems { // check if the element is a complex object, if so generate a new type for it tpe, err := sg.TypeResolver.ResolveSchema(sg.Schema.AdditionalItems.Schema, true, true) if err != nil { return err } if tpe.IsComplexObject && tpe.IsAnonymous { pg := sg.makeNewStruct(sg.Name+" Items", *sg.Schema.AdditionalItems.Schema) if err := pg.makeGenSchema(); err != nil { return err } sg.Schema.AdditionalItems.Schema = spec.RefProperty("#/definitions/" + pg.Name) pg.GenSchema.HasValidations = true sg.MergeResult(pg, false) sg.ExtraSchemas[pg.Name] = pg.GenSchema } it := sg.NewAdditionalItems(sg.Schema.AdditionalItems.Schema) if tpe.IsInterface { it.Untyped = true } if err := it.makeGenSchema(); err != nil { return err } sg.MergeResult(it, true) sg.GenSchema.AdditionalItems = &it.GenSchema } return nil }
func TestValidateParameters(t *testing.T) { doc, _ := loads.Analyzed(PetStoreJSONMessage, "") validator := NewSpecValidator(spec.MustLoadSwagger20Schema(), strfmt.Default) validator.spec = doc validator.analyzer = analysis.New(doc.Spec()) res := validator.validateParameters() assert.Empty(t, res.Errors) sw := doc.Spec() sw.Paths.Paths["/pets"].Get.Parameters = append(sw.Paths.Paths["/pets"].Get.Parameters, *spec.QueryParam("limit").Typed("string", "")) res = validator.validateParameters() assert.NotEmpty(t, res.Errors) doc, _ = loads.Analyzed(PetStoreJSONMessage, "") sw = doc.Spec() sw.Paths.Paths["/pets"].Post.Parameters = append(sw.Paths.Paths["/pets"].Post.Parameters, *spec.BodyParam("fake", spec.RefProperty("#/definitions/Pet"))) validator = NewSpecValidator(spec.MustLoadSwagger20Schema(), strfmt.Default) validator.spec = doc validator.analyzer = analysis.New(doc.Spec()) res = validator.validateParameters() assert.NotEmpty(t, res.Errors) assert.Len(t, res.Errors, 1) assert.Contains(t, res.Errors[0].Error(), "has more than 1 body param") doc, _ = loads.Analyzed(PetStoreJSONMessage, "") sw = doc.Spec() pp := sw.Paths.Paths["/pets/{id}"] pp.Delete = nil var nameParams []spec.Parameter for _, p := range pp.Parameters { if p.Name == "id" { p.Name = "name" nameParams = append(nameParams, p) } } pp.Parameters = nameParams sw.Paths.Paths["/pets/{name}"] = pp validator = NewSpecValidator(spec.MustLoadSwagger20Schema(), strfmt.Default) validator.spec = doc validator.analyzer = analysis.New(doc.Spec()) res = validator.validateParameters() assert.NotEmpty(t, res.Errors) assert.Len(t, res.Errors, 1) assert.Contains(t, res.Errors[0].Error(), "overlaps with") doc, _ = loads.Analyzed(PetStoreJSONMessage, "") validator = NewSpecValidator(spec.MustLoadSwagger20Schema(), strfmt.Default) validator.spec = doc validator.analyzer = analysis.New(doc.Spec()) sw = doc.Spec() pp = sw.Paths.Paths["/pets/{id}"] pp.Delete = nil pp.Get.Parameters = nameParams pp.Parameters = nil sw.Paths.Paths["/pets/{id}"] = pp res = validator.validateParameters() assert.NotEmpty(t, res.Errors) assert.Len(t, res.Errors, 2) assert.Contains(t, res.Errors[1].Error(), "is not present in path \"/pets/{id}\"") assert.Contains(t, res.Errors[0].Error(), "has no parameter definition") }