Skip to content

Commit

Permalink
Moved Validator#absolutized_uri and RefAttribute's ref parsing into t…
Browse files Browse the repository at this point in the history
…he URI module

I just noticed that we have this URI processing method in Validator, and
similar code in RefAttribute. I had thought we'd moved all of these into
the URI module, but these must have been missed.

I've taken the opportunity to tidy them up slightly too.

One day we might be able to unify these methods
  • Loading branch information
iainbeeston committed Oct 5, 2016
1 parent 7158532 commit eccf80f
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 eccf80f

Please sign in to comment.