Skip to content

Commit

Permalink
feat(jsonschema): Field to tell if RootSchema is an array or object.
Browse files Browse the repository at this point in the history
  • Loading branch information
dustmop committed Jun 6, 2018
1 parent 1280440 commit 8bd68f0
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 4 deletions.
8 changes: 8 additions & 0 deletions keywords.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,14 @@ func NewType() Validator {
return &Type{}
}

// FirstValue returns the first element in the values of this type.
func (t Type) FirstValue() string {
if len(t.vals) == 0 {
return ""
}
return t.vals[0]
}

// Validate checks to see if input data satisfies the type constraint
func (t Type) Validate(propPath string, data interface{}, errs *[]ValError) {
jt := DataType(data)
Expand Down
20 changes: 16 additions & 4 deletions schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,15 @@ type RootSchema struct {
// for current and previous published drafts of JSON Schema
// vocabularies as deemed reasonable.
SchemaURI string `json:"$schema"`
// Whether the top-level of the schema is an array or not.
// Assume it's an object otherwise.
TopIsArray bool
}

func determineTopIsArray(sch *Schema) bool {
validator := sch.Validators["type"]
typeValidator, ok := validator.(*Type)
return ok && typeValidator.FirstValue() == "array"
}

// UnmarshalJSON implements the json.Unmarshaler interface for
Expand All @@ -55,6 +64,7 @@ func (rs *RootSchema) UnmarshalJSON(data []byte) error {
if err := json.Unmarshal(data, sch); err != nil {
return err
}
topIsArray := determineTopIsArray(sch)

if sch.schemaType == schemaTypeFalse || sch.schemaType == schemaTypeTrue {
*rs = RootSchema{Schema: *sch}
Expand All @@ -69,8 +79,9 @@ func (rs *RootSchema) UnmarshalJSON(data []byte) error {
}

root := &RootSchema{
Schema: *sch,
SchemaURI: suri.SchemaURI,
Schema: *sch,
SchemaURI: suri.SchemaURI,
TopIsArray: topIsArray,
}

// collect IDs for internal referencing:
Expand Down Expand Up @@ -122,8 +133,9 @@ func (rs *RootSchema) UnmarshalJSON(data []byte) error {
}

*rs = RootSchema{
Schema: *sch,
SchemaURI: suri.SchemaURI,
Schema: *sch,
SchemaURI: suri.SchemaURI,
TopIsArray: topIsArray,
}
return nil
}
Expand Down
33 changes: 33 additions & 0 deletions schema_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,39 @@ func ExampleBasic() {
// /friends/0: {"firstName":"Nas"} "lastName" value is required
}

func TestTopLevelType(t *testing.T) {
schemaObject := []byte(`{
"title": "Car",
"type": "object",
"properties": {
"color": {
"type": "string"
}
},
"required": ["color"]
}`)
rs := &RootSchema{}
if err := json.Unmarshal(schemaObject, rs); err != nil {
panic("unmarshal schema: " + err.Error())
}
if rs.TopIsArray {
t.Errorf("error: schemaObject should not be an array")
}

schemaArray := []byte(`{
"title": "Cities",
"type": "array",
"items" : { "title" : "REFERENCE", "$ref" : "#" }
}`)
rs = &RootSchema{}
if err := json.Unmarshal(schemaArray, rs); err != nil {
panic("unmarshal schema: " + err.Error())
}
if !rs.TopIsArray {
t.Errorf("error: schemaArray should not be an object")
}
}

func TestMust(t *testing.T) {
defer func() {
if r := recover(); r != nil {
Expand Down

0 comments on commit 8bd68f0

Please sign in to comment.