Skip to content

Commit

Permalink
Dereference child schemas for schemas without ref
Browse files Browse the repository at this point in the history
If you have a subschema that says that it is expanded, it
might actually have children that have not yet been expanded.
If the subschema did not have a reference, we were not recursing
any further.
  • Loading branch information
Katrina Owen committed Mar 1, 2019
1 parent aedee73 commit 00849bc
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 2 deletions.
19 changes: 17 additions & 2 deletions lib/json_schema/reference_expander.rb
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,18 @@ def build_schema_paths(uri, schema)
def dereference(ref_schema, ref_stack)
ref = ref_schema.reference

# Some schemas don't have a reference, but do
# have children. If that's the case, we need to
# dereference the subschemas.
if !ref
schema_children(ref_schema) do |subschema|
next unless subschema.reference

dereference(subschema, ref_stack)
end
return true
end

# detects a reference cycle
if ref_stack.include?(ref)
message = %{Reference loop detected: #{ref_stack.sort.join(", ")}.}
Expand Down Expand Up @@ -114,9 +126,12 @@ def dereference(ref_schema, ref_stack)
# schema as the reference schema.
next if ref_schema == subschema

next if subschema.expanded?

if subschema.reference
# If the subschema has a reference, then
# we don't need to recurse if the schema is
# already expanded.
next if subschema.expanded?

if !subschema.reference.uri
# the subschema's ref is local to the file that the
# subschema is in; however since there's no URI
Expand Down
53 changes: 53 additions & 0 deletions test/json_schema/reference_expander_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,59 @@
assert_equal 3, schema1.properties["foo"].properties["omg"].max_length
end

it "it handles oneOf with nested references to an external schema" do
sample1 = {
"$schema" => "http://json-schema.org/draft-04/hyper-schema",
"type" => "object",
"properties" => {
"foo" => {
"$ref" => "http://json-schema.org/b.json#"
}
}
}
schema1 = JsonSchema::Parser.new.parse!(sample1)
schema1.uri = "http://json-schema.org/a.json"

sample2 = {
"$schema" => "http://json-schema.org/draft-04/hyper-schema",
"type" => "object",
"properties" => {
"bar" => {
"oneOf" => [
{"type" => "null"},
{"$ref" => "http://json-schema.org/c.json#"}
]
}
},
}
schema2 = JsonSchema::Parser.new.parse!(sample2)
schema2.uri = "http://json-schema.org/b.json"

sample3 = {
"$schema" => "http://json-schema.org/draft-04/hyper-schema",
"type" => "object",
"properties" => {
"baz" => {
"type" => "string",
"maxLength" => 3
}
}
}
schema3 = JsonSchema::Parser.new.parse!(sample3)
schema3.uri = "http://json-schema.org/c.json"

# Initialize a store and add our schema to it.
store = JsonSchema::DocumentStore.new
store.add_schema(schema1)
store.add_schema(schema2)
store.add_schema(schema3)

expander = JsonSchema::ReferenceExpander.new
expander.expand(schema1, store: store)

assert_equal 3, schema1.properties["foo"].properties["bar"].one_of[1].properties["baz"].max_length
end

it "expands a schema with a reference to an external schema with a nested local property reference" do
sample1 = {
"$schema" => "http://json-schema.org/draft-04/hyper-schema",
Expand Down

0 comments on commit 00849bc

Please sign in to comment.