diff --git a/lib/json/schema_generator.rb b/lib/json/schema_generator.rb index a216340..d0a8b50 100644 --- a/lib/json/schema_generator.rb +++ b/lib/json/schema_generator.rb @@ -10,8 +10,7 @@ class SchemaGenerator class << self def generate name, data, opts = {} - generator = JSON::SchemaGenerator.new name, opts - generator.generate data + JSON::SchemaGenerator.new(name, opts).generate data end end @@ -72,7 +71,7 @@ def create_primitive(statement_group, key, value, required_keys) raise "Unknown Primitive Type for #{key}! #{value.class}" end - statement_group.add "\"type\": \"#{type}\"" + statement_group.add "\"oneOf\": [{\"type\": \"#{type}\"}, {\"type\": \"null\"}]" statement_group.add "\"required\": #{required}" if @version == DRAFT3 statement_group.add "\"default\": #{value.inspect}" if @defaults end @@ -122,28 +121,20 @@ def create_hash_properties(data, required_keys) def create_array(statement_group, data, required_keys) statement_group.add '"type": "array"' statement_group.add '"required": true' if @version == DRAFT3 - if data.size == 0 - statement_group.add '"minItems": 0' - else - statement_group.add '"minItems": 1' - end - statement_group.add '"uniqueItems": true' + # FIXME - Code assumes that all items in the array have the same structure + # Assume lowest common denominator - allow 0 items and unique not required + statement_group.add '"minItems": 0' + + # TODO - consider a eq? method for StatementGroup class to evaluate LCD schema from all items in array statement_group.add create_values("items", data.first, required_keys, true) statement_group end def detect_required(collection) - begin - required_keys = @brute_search.find_required - rescue - if collection.respond_to? :keys - required_keys = collection.keys - else - required_keys = nil - end - end - required_keys + @brute_search.find_required + rescue NoMethodError + collection.keys if collection.respond_to?(:keys) end def result diff --git a/lib/json/schema_generator/brute_force_required_search.rb b/lib/json/schema_generator/brute_force_required_search.rb index 4e32f33..06f0c11 100644 --- a/lib/json/schema_generator/brute_force_required_search.rb +++ b/lib/json/schema_generator/brute_force_required_search.rb @@ -5,19 +5,11 @@ class SchemaGenerator class BruteForceRequiredSearch def initialize(data) @data = data.dup - if data.is_a? Array - @json_path = ['$[*]'] - else - @json_path = ['$'] - end + @json_path = data.is_a?(Array) ? ['$[*]'] : ['$'] end def push(key, value) - if value.is_a? Array - @json_path.push "#{key}[*]" - else - @json_path.push key - end + @json_path.push value.is_a?(Array) ? "#{key}[*]" : key end def pop @@ -42,16 +34,12 @@ def required? child_key end end - def child_keys + def child_keys JsonPath.new(current_path).on(@data).map(&:keys).flatten.uniq end def find_required - required = [] - child_keys.each do |child_key| - required << child_key if required? child_key - end - required + child_keys.select {|k| required? k} end end end