Skip to content

Commit

Permalink
Merge pull request #345 from iainbeeston/move-absolutize-ref-uri-to-u…
Browse files Browse the repository at this point in the history
…ri-module

Moved Validator#absolutized_uri and RefAttribute's ref parsing into the URI module
  • Loading branch information
iainbeeston authored Oct 5, 2016
2 parents 7158532 + eccf80f commit 8e47deb
Show file tree
Hide file tree
Showing 6 changed files with 237 additions and 142 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).

### Changed
- Made the `:clear_cache` option for `validate` also clear the URI parse cache
- Moved `JSON::Validator.absolutize_ref` and the ref manipulating code in
`JSON::Schema::RefAttribute` into `JSON::Util::URI`

## [2.7.0] - 2016-09-29

Expand Down
18 changes: 1 addition & 17 deletions lib/json-schema/attributes/ref.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,23 +22,7 @@ def self.validate(current_schema, data, fragments, processor, validator, options
def self.get_referenced_uri_and_schema(s, current_schema, validator)
uri,schema = nil,nil

temp_uri = JSON::Util::URI.parse(s['$ref'])
temp_uri.defer_validation do
if temp_uri.relative?
temp_uri.merge!(current_schema.uri)
# Check for absolute path
path, fragment = s['$ref'].split("#")
if path.nil? || path == ''
temp_uri.path = current_schema.uri.path
elsif path[0,1] == "/"
temp_uri.path = Pathname.new(path).cleanpath.to_s
else
temp_uri.join!(path)
end
temp_uri.fragment = fragment
end
temp_uri.fragment = "" if temp_uri.fragment.nil? || temp_uri.fragment.empty?
end
temp_uri = JSON::Util::URI.normalize_ref(s['$ref'], current_schema.uri)

# Grab the parent schema from the schema list
schema_key = temp_uri.to_s.split("#")[0] + "#"
Expand Down
37 changes: 37 additions & 0 deletions lib/json-schema/util/uri.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,43 @@ def self.normalized_uri(uri, base_path = Dir.pwd)
normalized_uri
end

def self.absolutize_ref(ref, base)
ref_uri = strip_fragment(ref.dup)

return ref_uri if ref_uri.absolute?
return parse(base) if ref_uri.path.empty?

uri = strip_fragment(base.dup).join(ref_uri.path)
normalized_uri(uri)
end

def self.normalize_ref(ref, base)
ref_uri = parse(ref)
base_uri = parse(base)

ref_uri.defer_validation do
if ref_uri.relative?
ref_uri.merge!(base_uri)

# Check for absolute path
path, fragment = ref.to_s.split("#")
if path.nil? || path == ''
ref_uri.path = base_uri.path
elsif path[0,1] == "/"
ref_uri.path = Pathname.new(path).cleanpath.to_s
else
ref_uri.join!(path)
end

ref_uri.fragment = fragment
end

ref_uri.fragment = "" if ref_uri.fragment.nil? || ref_uri.fragment.empty?
end

ref_uri
end

def self.parse(uri)
if uri.is_a?(Addressable::URI)
return uri.dup
Expand Down
13 changes: 1 addition & 12 deletions lib/json-schema/validator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -131,25 +131,14 @@ def validate
end

def load_ref_schema(parent_schema, ref)
schema_uri = absolutize_ref_uri(ref, parent_schema.uri)
schema_uri = JSON::Util::URI.absolutize_ref(ref, parent_schema.uri)
return true if self.class.schema_loaded?(schema_uri)

schema = @options[:schema_reader].read(schema_uri)
self.class.add_schema(schema)
build_schemas(schema)
end

def absolutize_ref_uri(ref, parent_schema_uri)
ref_uri = JSON::Util::URI.strip_fragment(ref)

return ref_uri if ref_uri.absolute?
# This is a self reference and thus the schema does not need to be re-loaded
return parent_schema_uri if ref_uri.path.empty?

uri = JSON::Util::URI.strip_fragment(parent_schema_uri.dup)
Util::URI.normalized_uri(uri.join(ref_uri.path))
end

# Build all schemas with IDs, mapping out the namespace
def build_schemas(parent_schema)
schema = parent_schema.schema
Expand Down
113 changes: 0 additions & 113 deletions test/uri_parsing_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,6 @@
require File.expand_path('../support/test_helper', __FILE__)

class UriParsingTest < Minitest::Test
def populate_cache_with(str, &blk)
cached_uri = Addressable::URI.parse(str)
Addressable::URI.stub(:parse, cached_uri, &blk)
cached_uri
end

def teardown
JSON::Util::URI.clear_cache
end

def test_asian_characters
schema = {
"$schema"=> "http://json-schema.org/draft-04/schema#",
Expand Down Expand Up @@ -74,107 +64,4 @@ def test_schema_from_file_with_spaces
schema = "test/schemas/ref john with spaces schema.json"
assert_valid schema, data
end

def test_normalized_uri
str = "https://www.google.com/search"
uri = Addressable::URI.new(scheme: 'https',
host: 'www.google.com',
path: 'search')
assert_equal uri, JSON::Util::URI.normalized_uri(str, '/home')
end

def test_normalized_uri_with_empty_fragment
str = "https://www.google.com/search#"
uri = Addressable::URI.new(scheme: 'https',
host: 'www.google.com',
path: 'search',
fragment: nil)
assert_equal uri, JSON::Util::URI.normalized_uri(str, '/home')
end

def test_normalized_uri_with_fragment
str = "https://www.google.com/search#foo"
uri = Addressable::URI.new(scheme: 'https',
host: 'www.google.com',
path: 'search',
fragment: 'foo')
assert_equal uri, JSON::Util::URI.normalized_uri(str, '/home')
end

def test_normalized_uri_for_absolute_path
str = "/foo/bar.json"
uri = Addressable::URI.new(scheme: 'file',
path: '///foo/bar.json')
assert_equal uri, JSON::Util::URI.normalized_uri(str, '/home')
end

def test_normalized_uri_for_relartive_path
str = "foo/bar.json"
uri = Addressable::URI.new(scheme: 'file',
path: '///home/foo/bar.json')
assert_equal uri, JSON::Util::URI.normalized_uri(str, '/home')
end

def test_uri_parse
str = "https://www.google.com/search"
uri = Addressable::URI.new(scheme: 'https',
host: 'www.google.com',
path: 'search')
assert_equal uri, JSON::Util::URI.parse(str)
end

def test_invalid_uri_parse
uri = ":::::::"
assert_raises(JSON::Schema::UriError) do
JSON::Util::URI.parse(uri)
end
end

def test_normalization_cache
cached_uri = populate_cache_with('www.google.com') do
JSON::Util::URI.normalized_uri('foo')
end

assert_equal(cached_uri, JSON::Util::URI.normalized_uri('foo'))

JSON::Util::URI.clear_cache

refute_equal(cached_uri, JSON::Util::URI.normalized_uri('foo'))
end

def test_parse_cache
cached_uri = populate_cache_with('www.google.com') do
JSON::Util::URI.parse('foo')
end

assert_equal(cached_uri, JSON::Util::URI.parse('foo'))

JSON::Util::URI.clear_cache

refute_equal(cached_uri, JSON::Util::URI.parse('foo'))
end

def test_validator_clear_cache_for_normalized_uri
cached_uri = populate_cache_with('www.google.com') do
JSON::Util::URI.normalized_uri('foo')
end

assert_equal(cached_uri, JSON::Util::URI.normalized_uri('foo'))

validation_errors({"type" => "string"}, "foo", :clear_cache => true)

refute_equal(cached_uri, JSON::Util::URI.normalized_uri('foo'))
end

def test_validator_clear_cache_for_parse
cached_uri = populate_cache_with('www.google.com') do
JSON::Util::URI.parse('foo')
end

assert_equal(cached_uri, JSON::Util::URI.parse('foo'))

validation_errors({"type" => "string"}, "foo", :clear_cache => true)

refute_equal(cached_uri, JSON::Util::URI.parse('foo'))
end
end
Loading

0 comments on commit 8e47deb

Please sign in to comment.