Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

9 endless recursion fix #10

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
24 changes: 17 additions & 7 deletions lib/json/schema_builder/entity.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ def initialize(name, opts = { }, &block)
initialize_parent_with opts
initialize_with opts
eval_block &block
any_of(null) if @nullable
extract_types
@initialized = true
end
Expand Down Expand Up @@ -138,13 +139,22 @@ def _reset_fragments
end

def extract_types
any_of(null) if @nullable
if any_of.present?
everything_else = schema.data.reject { |k, v| k == "anyOf" }
return unless everything_else.present?
schema.data.select! { |k, v| k == "anyOf" }
schema.data["anyOf"].unshift everything_else
end
build_any_of if any_of.present?
end

def build_any_of
initial_object = any_of_options.find { |opt| opt.as_json['type'] == 'object' }
everything_else = schema.data.except("anyOf")
return unless everything_else.present?

schema.data.keep_if { |k| k == "anyOf" }
return any_of_options.unshift(everything_else) unless initial_object
initial_object.deep_merge! everything_else
initial_object['properties'] = children.select { |c| c.name.presence }.map { |c| [c.name, c] }.to_h
end

def any_of_options
schema.data["anyOf"]
end

def initialize_parent_with(opts)
Expand Down
1 change: 1 addition & 0 deletions lib/json/schema_builder/object.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ def initialize_children
self.properties[child.name] = child.as_json
end
end
build_any_of if @nullable
end

def extract_types
Expand Down
15 changes: 15 additions & 0 deletions spec/integration/builder_initialization_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,21 @@
}
}
},
target: {
anyOf: [
{
type: :object,
properties: {
id: {
type: :number
}
}
},
{
type: :null
}
]
},
preferences: {
anyOf: [
{
Expand Down
15 changes: 15 additions & 0 deletions spec/integration/builder_reopening_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,21 @@
}
}
},
target: {
anyOf: [
{
type: :object,
properties: {
id: {
type: :number
}
}
},
{
type: :null
}
]
},
preferences: {
anyOf: [
{
Expand Down
39 changes: 39 additions & 0 deletions spec/integration/expand_null_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
require 'spec_helper'

RSpec.describe Examples::ExpandNullTrue, type: :integration do
it_behaves_like 'a builder' do
let(:expected_json) do
{
"type": "object",
"required": [
"foo"
],
"properties": {
"foo": {
"type": "object",
"required": [
"bar"
],
"properties": {
"bar": {
"anyOf": [
{
"type": "object",
"properties": {
"baz": {
"type": "string"
}
}
},
{
"type": "null"
}
]
}
}
}
}
}
end
end
end
35 changes: 35 additions & 0 deletions spec/integration/nested_nullable_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
require 'spec_helper'

RSpec.describe Examples::NestedNullable, type: :integration do
it_behaves_like 'a builder' do
let(:expected_json) do
{
type: 'object',
properties: {
nullable_object: {
anyOf: [
{
type: 'object',
properties: {
nullable_string: {
anyOf: [
{
type: 'string'
},
{
type: 'null'
}
]
}
}
},
{
type: 'null'
}
]
}
}
}
end
end
end
7 changes: 7 additions & 0 deletions spec/support/examples/builder_initialization.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,18 @@ def example
obj = object
obj.string :name
settings_for(obj)
target_for(obj)
preferences_for(obj)
add_ids_to(obj)
obj
end

def target_for(obj)
target = obj.object :target, null: true
target.number :id
target
end

def settings_for(obj)
settings = obj.object :settings
settings.string :email
Expand Down
13 changes: 13 additions & 0 deletions spec/support/examples/expand_null_true.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module Examples
class ExpandNullTrue
include JSON::SchemaBuilder

def example
object.tap do |base_obj|
foo_obj = base_obj.object(:foo, required: true)
bar_obj = foo_obj.object(:bar, null: true, required: true)
bar_obj.string :baz
end
end
end
end
12 changes: 12 additions & 0 deletions spec/support/examples/nested_nullable.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module Examples
class NestedNullable
include JSON::SchemaBuilder

def example
object.tap do |base_obj|
obj = base_obj.object :nullable_object, null: true
obj.string :nullable_string, null: true
end
end
end
end