Skip to content

Commit

Permalink
Merge branch 'main' into feat/schema-post
Browse files Browse the repository at this point in the history
* main:
  Allow for = character in extra property values
  Add test for anyof
  Add support for parsing anyof_type
  Add tests for anyof support
  Add support for parsing anyof_required
  • Loading branch information
webdestroya committed Nov 8, 2022
2 parents b32bc83 + a7e9715 commit 7ebaf59
Show file tree
Hide file tree
Showing 4 changed files with 159 additions and 1 deletion.
91 changes: 91 additions & 0 deletions fixtures/anyof.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://github.com/invopop/jsonschema/root-any-of",
"$ref": "#/$defs/RootAnyOf",
"$defs": {
"ChildAnyOf": {
"anyOf": [
{
"required": [
"child1",
"child4"
],
"title": "group1"
},
{
"required": [
"child2",
"child3"
],
"title": "group2"
}
],
"properties": {
"child1": {
"type": "string"
},
"child2": {
"type": "string"
},
"child3": {
"oneOf": [
{
"type": "string"
},
{
"type": "array"
}
]
},
"child4": {
"type": "string"
}
},
"additionalProperties": false,
"type": "object"
},
"RootAnyOf": {
"anyOf": [
{
"required": [
"field1",
"field4"
],
"title": "group1"
},
{
"required": [
"field2"
],
"title": "group2"
}
],
"properties": {
"field1": {
"type": "string"
},
"field2": {
"type": "string"
},
"field3": {
"anyOf": [
{
"type": "string"
},
{
"type": "array"
}
]
},
"field4": {
"type": "string"
},
"child": {
"$ref": "#/$defs/ChildAnyOf"
}
},
"additionalProperties": false,
"type": "object"
}
}
}
20 changes: 20 additions & 0 deletions fixtures/schema_with_expression.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://github.com/invopop/jsonschema/expression",
"$ref": "#/$defs/Expression",
"$defs": {
"Expression": {
"properties": {
"value": {
"type": "integer",
"foo": "bar=='baz'"
}
},
"additionalProperties": false,
"type": "object",
"required": [
"value"
]
}
}
}
28 changes: 27 additions & 1 deletion reflect.go
Original file line number Diff line number Diff line change
Expand Up @@ -705,6 +705,21 @@ func (t *Schema) genericKeywords(tags []string, parent *Schema, propertyName str
parent.OneOf = append(parent.OneOf, typeFound)
}
typeFound.Required = append(typeFound.Required, propertyName)
case "anyof_required":
var typeFound *Schema
for i := range parent.AnyOf {
if parent.AnyOf[i].Title == nameValue[1] {
typeFound = parent.AnyOf[i]
}
}
if typeFound == nil {
typeFound = &Schema{
Title: nameValue[1],
Required: []string{},
}
parent.AnyOf = append(parent.AnyOf, typeFound)
}
typeFound.Required = append(typeFound.Required, propertyName)
case "oneof_type":
if t.OneOf == nil {
t.OneOf = make([]*Schema, 0, 1)
Expand All @@ -716,6 +731,17 @@ func (t *Schema) genericKeywords(tags []string, parent *Schema, propertyName str
Type: ty,
})
}
case "anyof_type":
if t.AnyOf == nil {
t.AnyOf = make([]*Schema, 0, 1)
}
t.Type = ""
types := strings.Split(nameValue[1], ";")
for _, ty := range types {
t.AnyOf = append(t.AnyOf, &Schema{
Type: ty,
})
}
case "enum":
switch t.Type {
case "string":
Expand Down Expand Up @@ -877,7 +903,7 @@ func (t *Schema) arrayKeywords(tags []string) {

func (t *Schema) extraKeywords(tags []string) {
for _, tag := range tags {
nameValue := strings.Split(tag, "=")
nameValue := strings.SplitN(tag, "=", 2)
if len(nameValue) == 2 {
t.setExtra(nameValue[0], nameValue[1])
}
Expand Down
21 changes: 21 additions & 0 deletions reflect_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,21 @@ type ChildOneOf struct {
Child4 string `json:"child4" jsonschema:"oneof_required=group1"`
}

type RootAnyOf struct {
Field1 string `json:"field1" jsonschema:"anyof_required=group1"`
Field2 string `json:"field2" jsonschema:"anyof_required=group2"`
Field3 interface{} `json:"field3" jsonschema:"anyof_type=string;array"`
Field4 string `json:"field4" jsonschema:"anyof_required=group1"`
Field5 ChildAnyOf `json:"child"`
}

type ChildAnyOf struct {
Child1 string `json:"child1" jsonschema:"anyof_required=group1"`
Child2 string `json:"child2" jsonschema:"anyof_required=group2"`
Child3 interface{} `json:"child3" jsonschema:"anyof_required=group2,oneof_type=string;array"`
Child4 string `json:"child4" jsonschema:"anyof_required=group1"`
}

type Text string

type TextNamed string
Expand Down Expand Up @@ -314,6 +329,10 @@ func (SchemaPostTest) JSONSchemaExtend(base *Schema) {
base.Required = []string{"LastName"}
}

type Expression struct {
Value int `json:"value" jsonschema_extras:"foo=bar=='baz'"`
}

func TestReflector(t *testing.T) {
r := new(Reflector)
s := "http://example.com/schema"
Expand Down Expand Up @@ -355,6 +374,7 @@ func TestSchemaGeneration(t *testing.T) {
{&TestUser{}, &Reflector{DoNotReference: true}, "fixtures/no_reference.json"},
{&TestUser{}, &Reflector{DoNotReference: true, AssignAnchor: true}, "fixtures/no_reference_anchor.json"},
{&RootOneOf{}, &Reflector{RequiredFromJSONSchemaTags: true}, "fixtures/oneof.json"},
{&RootAnyOf{}, &Reflector{RequiredFromJSONSchemaTags: true}, "fixtures/anyof.json"},
{&CustomTypeField{}, &Reflector{
Mapper: func(i reflect.Type) *Schema {
if i == reflect.TypeOf(CustomTime{}) {
Expand Down Expand Up @@ -444,6 +464,7 @@ func TestSchemaGeneration(t *testing.T) {
{MapType{}, &Reflector{}, "fixtures/map_type.json"},
{ArrayType{}, &Reflector{}, "fixtures/array_type.json"},
{SchemaPostTest{}, &Reflector{}, "fixtures/custom_type_post.json"},
{Expression{}, &Reflector{}, "fixtures/schema_with_expression.json"},
}

for _, tt := range tests {
Expand Down

0 comments on commit 7ebaf59

Please sign in to comment.