diff --git a/lib/json_schemer/schema.rb b/lib/json_schemer/schema.rb index db68a4af..1a96d5ba 100644 --- a/lib/json_schemer/schema.rb +++ b/lib/json_schemer/schema.rb @@ -329,28 +329,27 @@ def parse VOCABULARY_KEYWORD_CLASS.new(vocabulary, self, '$vocabulary') end - if root == self && (!value.is_a?(Hash) || !value.key?(meta_schema.id_keyword)) + keywords = meta_schema.keywords + exclusive_ref = value.is_a?(Hash) && value.key?('$ref') && keywords.fetch('$ref').exclusive? + + if root == self && (!value.is_a?(Hash) || !value.key?(meta_schema.id_keyword) || exclusive_ref) ID_KEYWORD_CLASS.new(base_uri, self, meta_schema.id_keyword) end - if value.is_a?(Hash) - keywords = meta_schema.keywords - - if value.key?('$ref') && keywords.fetch('$ref').exclusive? - @parsed['$ref'] = keywords.fetch('$ref').new(value.fetch('$ref'), self, '$ref') - defs_keyword = meta_schema.defs_keyword - if value.key?(defs_keyword) && keywords.key?(defs_keyword) - @parsed[defs_keyword] = keywords.fetch(defs_keyword).new(value.fetch(defs_keyword), self, defs_keyword) - end - else - keyword_order = meta_schema.keyword_order - last = keywords.size - - value.sort do |(keyword_a, _value_a), (keyword_b, _value_b)| - keyword_order.fetch(keyword_a, last) <=> keyword_order.fetch(keyword_b, last) - end.each do |keyword, value| - @parsed[keyword] ||= keywords.fetch(keyword, UNKNOWN_KEYWORD_CLASS).new(value, self, keyword) - end + if exclusive_ref + @parsed['$ref'] = keywords.fetch('$ref').new(value.fetch('$ref'), self, '$ref') + defs_keyword = meta_schema.defs_keyword + if value.key?(defs_keyword) && keywords.key?(defs_keyword) + @parsed[defs_keyword] = keywords.fetch(defs_keyword).new(value.fetch(defs_keyword), self, defs_keyword) + end + elsif value.is_a?(Hash) + keyword_order = meta_schema.keyword_order + last = keywords.size + + value.sort do |(keyword_a, _value_a), (keyword_b, _value_b)| + keyword_order.fetch(keyword_a, last) <=> keyword_order.fetch(keyword_b, last) + end.each do |keyword, value| + @parsed[keyword] ||= keywords.fetch(keyword, UNKNOWN_KEYWORD_CLASS).new(value, self, keyword) end end diff --git a/test/ref_test.rb b/test/ref_test.rb index d9f812a5..1cf8edef 100644 --- a/test/ref_test.rb +++ b/test/ref_test.rb @@ -379,4 +379,20 @@ def test_exclusive_ref_supports_definitions assert(schema.valid?(1)) refute(schema.valid?('1')) end + + def test_exclusive_ref_supports_definitions_with_id_and_json_pointer + schema = JSONSchemer.schema({ + '$schema' => 'http://json-schema.org/draft-07/schema#', + '$id' => 'https://example.com/schema', + '$ref' => '#/definitions/yah', + 'definitions' => { + 'yah' => { + '$id' => '#yah', + 'type' => 'integer' + } + } + }) + assert(schema.valid?(1)) + refute(schema.valid?('1')) + end end