Skip to content

Commit

Permalink
Add "description" and "additionalProperties" to Schema JSONGenerator (#…
Browse files Browse the repository at this point in the history
…46)

* Add "description" and "additionalProperties" to Schema JSONGenerator

* Update README in section Generating JSON Schema

---------

Co-authored-by: Kamil Skrzypiński <[email protected]>
  • Loading branch information
skarlcf and Kamil Skrzypiński authored Oct 23, 2024
1 parent accc526 commit 1d2df47
Show file tree
Hide file tree
Showing 16 changed files with 78 additions and 25 deletions.
32 changes: 19 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1421,12 +1421,12 @@ class PersonMapper < Shale::Mapper
attribute :age, :integer

json do
properties max_properties: 5
properties max_properties: 5, additional_properties: false

map "first_name", to: :first_name, schema: { required: true }
map "last_name", to: :last_name, schema: { required: true }
map "address", to: :age, schema: { max_length: 128 }
map "age", to: :age, schema: { minimum: 1, maximum: 150 }
map "address", to: :address, schema: { max_length: 128, description: "Street, home number, city and country" }
map "age", to: :age, schema: { minimum: 1, maximum: 150, description: "Person age" }
end
end

Expand All @@ -1444,31 +1444,37 @@ Shale::Schema.to_json(
# "$defs": {
# "Person": {
# "type": "object",
# "maxProperties": 5,
# "properties": {
# "first_name": {
# "type": "string"
# },
# "last_name": {
# "type": "string"
# },
# "age": {
# "address": {
# "type": [
# "integer",
# "string",
# "null"
# ],
# "minimum": 1,
# "maximum": 150
# },
# "address": {
# "maxLength": 128,
# "description": "Street, home number, city and country"
# },
# "age": {
# "type": [
# "string",
# "integer",
# "null"
# ],
# "maxLength": 128
# "minimum": 1,
# "maximum": 150,
# "description": "Person age"
# }
# },
# "required": ["first_name", "last_name"]
# "required": [
# "first_name",
# "last_name"
# ],
# "maxProperties": 5,
# "additionalProperties": false
# }
# }
# }
Expand Down
4 changes: 3 additions & 1 deletion lib/shale/mapping/dict_base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,15 @@ def map(key, to: nil, receiver: nil, using: nil, group: nil, render_nil: nil, sc
# @param [Integer] min_properties
# @param [Integer] max_properties
# @param [Hash] dependent_required
# @param [Boolean] additional_properties
#
# @api public
def properties(min_properties: nil, max_properties: nil, dependent_required: nil)
def properties(min_properties: nil, max_properties: nil, dependent_required: nil, additional_properties: nil)
@root = {
min_properties: min_properties,
max_properties: max_properties,
dependent_required: dependent_required,
additional_properties: additional_properties,
}
end

Expand Down
3 changes: 2 additions & 1 deletion lib/shale/schema/json_generator/boolean.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ class Boolean < Base
#
# @api private
def as_type
{ 'type' => 'boolean' }
{ 'type' => 'boolean',
'description' => schema[:description] }.compact
end
end
end
Expand Down
3 changes: 2 additions & 1 deletion lib/shale/schema/json_generator/collection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ def as_json
'maxItems' => schema[:max_items],
'uniqueItems' => schema[:unique],
'minContains' => schema[:min_contains],
'maxContains' => schema[:max_contains] }.compact
'maxContains' => schema[:max_contains],
'description' => schema[:description] }.compact
end
end
end
Expand Down
4 changes: 3 additions & 1 deletion lib/shale/schema/json_generator/date.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ class Date < Base
#
# @api private
def as_type
{ 'type' => 'string', 'format' => 'date' }
{ 'type' => 'string',
'format' => 'date',
'description' => schema[:description] }.compact
end
end
end
Expand Down
3 changes: 2 additions & 1 deletion lib/shale/schema/json_generator/float.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ def as_type
'exclusiveMaximum' => schema[:exclusive_maximum],
'minimum' => schema[:minimum],
'maximum' => schema[:maximum],
'multipleOf' => schema[:multiple_of] }.compact
'multipleOf' => schema[:multiple_of],
'description' => schema[:description] }.compact
end
end
end
Expand Down
3 changes: 2 additions & 1 deletion lib/shale/schema/json_generator/integer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ def as_type
'exclusiveMaximum' => schema[:exclusive_maximum],
'minimum' => schema[:minimum],
'maximum' => schema[:maximum],
'multipleOf' => schema[:multiple_of] }.compact
'multipleOf' => schema[:multiple_of],
'description' => schema[:description] }.compact
end
end
end
Expand Down
2 changes: 2 additions & 0 deletions lib/shale/schema/json_generator/object.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ def as_type
'minProperties' => @root[:min_properties],
'maxProperties' => @root[:max_properties],
'dependentRequired' => @root[:dependent_required],
'description' => @root[:description],
'additionalProperties' => @root[:additional_properties],
}.compact
end
end
Expand Down
3 changes: 2 additions & 1 deletion lib/shale/schema/json_generator/string.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ def as_type
'format' => schema[:format],
'minLength' => schema[:min_length],
'maxLength' => schema[:max_length],
'pattern' => schema[:pattern] }.compact
'pattern' => schema[:pattern],
'description' => schema[:description] }.compact
end
end
end
Expand Down
4 changes: 3 additions & 1 deletion lib/shale/schema/json_generator/time.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ class Time < Base
#
# @api private
def as_type
{ 'type' => 'string', 'format' => 'date-time' }
{ 'type' => 'string',
'format' => 'date-time',
'description' => schema[:description] }.compact
end
end
end
Expand Down
3 changes: 2 additions & 1 deletion lib/shale/schema/json_generator/value.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ class Value < Base
#
# @api private
def as_type
{ 'type' => %w[boolean integer number object string] }
{ 'type' => %w[boolean integer number object string],
'description' => schema[:description] }.compact
end
end
end
Expand Down
28 changes: 26 additions & 2 deletions spec/shale/schema/json_generator/boolean_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,32 @@
RSpec.describe Shale::Schema::JSONGenerator::Boolean do
describe '#as_type' do
it 'returns JSON Schema fragment as Hash' do
expected = { 'type' => 'boolean' }
expect(described_class.new('foo').as_type).to eq(expected)
expect(described_class.new('foo').as_type).to eq({ 'type' => 'boolean' })
end

context 'when schema is passed' do
it 'can include string keywords from JSON schema' do
schema = {
description: 'Attribute description',
}
expected = {
'type' => 'boolean',
'description' => 'Attribute description',
}
expect(described_class.new('foo', schema: schema).as_type).to eq(expected)
end

it 'can use a subset of schema keywords' do
schema = {}
expected = { 'type' => 'boolean' }
expect(described_class.new('foo', schema: schema).as_type).to eq(expected)
end

it 'will not use keywords for other types' do
schema = { unique_items: true }
expected = { 'type' => 'boolean' }
expect(described_class.new('foo', schema: schema).as_type).to eq(expected)
end
end
end
end
3 changes: 2 additions & 1 deletion spec/shale/schema/json_generator/collection_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
unique: true,
min_contains: 5,
max_contains: 10,
description: 'Attribute description',
}
expected = {
'type' => 'array',
Expand All @@ -35,7 +36,7 @@
'uniqueItems' => true,
'minContains' => 5,
'maxContains' => 10,

'description' => 'Attribute description',
}
expect(described_class.new(type, schema: schema).as_json).to eq(expected)
end
Expand Down
2 changes: 2 additions & 0 deletions spec/shale/schema/json_generator/float_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
minimum: 0,
maximum: 100,
multiple_of: 4,
description: 'Attribute description',
}
expected = {
'type' => 'number',
Expand All @@ -25,6 +26,7 @@
'minimum' => 0,
'maximum' => 100,
'multipleOf' => 4,
'description' => 'Attribute description',
}
expect(described_class.new('foo', schema: schema).as_type).to eq(expected)
end
Expand Down
4 changes: 4 additions & 0 deletions spec/shale/schema/json_generator/object_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,16 @@
'properties' => {
'bar' => { 'type' => %w[boolean null] },
},
'description' => 'Attribute description',
'additionalProperties' => false,
}

root = {
min_properties: 1,
max_properties: 5,
dependent_required: { 'foo' => ['bar'] },
description: 'Attribute description',
additional_properties: false,
}

expect(described_class.new('foo', types, root).as_type).to eq(expected)
Expand Down
2 changes: 2 additions & 0 deletions spec/shale/schema/json_generator/string_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@
min_length: 5,
max_length: 10,
pattern: 'foo-bar',
description: 'Attribute description',
}
expected = {
'type' => 'string',
'format' => 'email',
'minLength' => 5,
'maxLength' => 10,
'pattern' => 'foo-bar',
'description' => 'Attribute description',
}
expect(described_class.new('foo', schema: schema).as_type).to eq(expected)
end
Expand Down

0 comments on commit 1d2df47

Please sign in to comment.