Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix test runs for optional dependencies #196

Merged
merged 5 commits into from
Dec 2, 2014
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 1 addition & 6 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -2,9 +2,4 @@ source "https://rubygems.org"

gemspec

gem "json", :platforms => :mri_18

group :development do
gem "rake"
gem "minitest", '~> 5.0'
end
gem "json", ">= 1.7", :platforms => [:mri_18, :mri_19]
26 changes: 26 additions & 0 deletions README.textile
Original file line number Diff line number Diff line change
@@ -278,6 +278,32 @@ data = {
JSON::Validator.validate(schema, data, :version => :draft2)
</pre>

h3. Explicitly specifying the type of the data

By default, json-schema accepts a variety of different types for the data parameter, and it will try to work out what to do with it dynamically. You can pass it a string uri (in which case it will download the json from that location before validating), a string of JSON text, or simply a ruby object (such as an array or hash representing parsed json). However, sometimes the nature of the data is ambiguous (for example, is "http://github.com" just a string, or is it a uri?). In other situations, you have already parsed your JSON, and you don't need to re-parse it.

If you want to be explict about what kind of data is being parsed, JSON schema supports a number of options:

<pre>
require 'rubygems'
require 'json-schema'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should generally start leaving these off in the code examples, it's just noisy. It's safe to assume that people will know to require the library they're using.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah that's a good point.

Let me raise an issue so we don't forget


schema = {
"type" => "string"
}

# examines the data, determines it's a uri, then tries to load data from it
JSON::Validator.validate(schema, 'https://api.github.com') # returns false

# data is already parsed json - just accept it as-is
JSON::Validator.validate(schema, 'https://api.github.com', :parse_data => false) # returns true

# data is parsed to a json string
JSON::Validator.validate(schema, '"https://api.github.com"', :json => true) # returns true

# loads data from the uri
JSON::Validator.validate(schema, 'https://api.github.com', :uri => true) # returns false
</pre>

h3. Extend an existing schema and validate against it

4 changes: 0 additions & 4 deletions gemfiles/Gemfile.multi_json.x
Original file line number Diff line number Diff line change
@@ -3,7 +3,3 @@ source "https://rubygems.org"
gemspec :path => "../"

gem "multi_json"

group :development do
gem "rake"
end
4 changes: 0 additions & 4 deletions gemfiles/Gemfile.uuidtools.x
Original file line number Diff line number Diff line change
@@ -3,7 +3,3 @@ source "https://rubygems.org"
gemspec :path => "../"

gem "uuidtools"

group :development do
gem "rake"
end
4 changes: 0 additions & 4 deletions gemfiles/Gemfile.yajl-ruby.x
Original file line number Diff line number Diff line change
@@ -3,7 +3,3 @@ source "https://rubygems.org"
gemspec :path => "../"

gem "yajl-ruby"

group :development do
gem "rake"
end
3 changes: 3 additions & 0 deletions json-schema.gemspec
Original file line number Diff line number Diff line change
@@ -19,6 +19,9 @@ Gem::Specification.new do |s|
s.license = "MIT"
s.required_rubygems_version = ">= 1.8"

s.add_development_dependency "rake"
s.add_development_dependency "minitest", '~> 5.0'
s.add_development_dependency "webmock"

s.add_runtime_dependency "addressable", '~> 2.3'
end
29 changes: 16 additions & 13 deletions lib/json-schema/validator.rb
Original file line number Diff line number Diff line change
@@ -24,7 +24,8 @@ class Validator
:errors_as_objects => false,
:insert_defaults => false,
:clear_cache => true,
:strict => false
:strict => false,
:parse_data => true
}
@@validators = {}
@@default_validator = nil
@@ -400,7 +401,7 @@ def parse(s)
else
case @@json_backend.to_s
when 'json'
JSON.parse(s)
JSON.parse(s, :quirks_mode => true)
when 'yajl'
json = StringIO.new(s)
parser = Yajl::Parser.new
@@ -550,20 +551,22 @@ def initialize_schema(schema)


def initialize_data(data)
if @options[:json]
data = JSON::Validator.parse(data)
elsif @options[:uri]
json_uri = normalized_uri(data)
data = JSON::Validator.parse(custom_open(json_uri))
elsif data.is_a?(String)
begin
if @options[:parse_data]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you make this an early return to simplify the rightward drift? eg return unless @options[:parse_data]

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The diff is a bit unfortunate - this method is actually returning JSON::Schema.stringify(data) at the end, which is what we want to do either with parse_data or without it. I could return early but I'd have to duplicate that line.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I just totally overlooked that, alright.

if @options[:json]
data = JSON::Validator.parse(data)
rescue
elsif @options[:uri]
json_uri = normalized_uri(data)
data = JSON::Validator.parse(custom_open(json_uri))
elsif data.is_a?(String)
begin
json_uri = normalized_uri(data)
data = JSON::Validator.parse(custom_open(json_uri))
data = JSON::Validator.parse(data)
rescue
# Silently discard the error - the data will not change
begin
json_uri = normalized_uri(data)
data = JSON::Validator.parse(custom_open(json_uri))
rescue
# Silently discard the error - the data will not change
end
end
end
end
1 change: 0 additions & 1 deletion test/test_bad_schema_ref.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
require File.expand_path('../test_helper', __FILE__)
require 'webmock'
require 'socket'


11 changes: 1 addition & 10 deletions test/test_common_test_suite.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
require File.expand_path('../test_helper', __FILE__)
require 'webmock'
require 'json'

class CommonTestSuiteTest < Minitest::Test
@@ -26,23 +25,14 @@ class CommonTestSuiteTest < Minitest::Test
]
})

include WebMock::API

def setup
WebMock.enable!

Dir["#{TEST_DIR}/../remotes/**/*.json"].each do |path|
schema = path.sub(%r{^.*/remotes/}, '')
stub_request(:get, "http://localhost:1234/#{schema}").
to_return(:body => File.read(path), :status => 200)
end
end

def teardown
WebMock.disable!
WebMock.reset!
end

Dir["#{TEST_DIR}/*"].each do |suite|
version = File.basename(suite).to_sym
Dir["#{suite}/**/*.json"].each do |tfile|
@@ -63,6 +53,7 @@ def teardown
define_method("test_#{err_id}") do
errors = JSON::Validator.fully_validate(schema,
t["data"],
:parse_data => false,
:validate_schema => true,
:version => version
)
1 change: 1 addition & 0 deletions test/test_helper.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require 'minitest/autorun'
require 'webmock/minitest'

$:.unshift(File.expand_path('../../lib', __FILE__))
require 'json-schema'
135 changes: 135 additions & 0 deletions test/test_initialize_data.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
require File.expand_path('../test_helper', __FILE__)

class InitializeDataTest < Minitest::Test

def refute_block(&blk)
result = blk.call
refute(result)
end

def test_parse_character_string
schema = {'type' => 'string'}
data = 'hello world'

assert(JSON::Validator.validate(schema, data))

assert(JSON::Validator.validate(schema, data, :parse_data => false))

refute_block do
begin
JSON::Validator.validate(schema, data, :json => true)
rescue
false
end
end

assert_raises(Errno::ENOENT) { JSON::Validator.validate(schema, data, :uri => true) }
end

def test_parse_integer_string
schema = {'type' => 'integer'}
data = '42'

assert(JSON::Validator.validate(schema, data))

refute(JSON::Validator.validate(schema, data, :parse_data => false))

assert(JSON::Validator.validate(schema, data, :json => true))

assert_raises(Errno::ENOENT) { JSON::Validator.validate(schema, data, :uri => true) }
end

def test_parse_hash_string
schema = { 'type' => 'object', 'properties' => { 'a' => { 'type' => 'string' } } }
data = '{"a": "b"}'

assert(JSON::Validator.validate(schema, data))

refute(JSON::Validator.validate(schema, data, :parse_data => false))

assert(JSON::Validator.validate(schema, data, :json => true))

assert_raises(Errno::ENOENT) { JSON::Validator.validate(schema, data, :uri => true) }
end

def test_parse_json_string
schema = {'type' => 'string'}
data = '"hello world"'

assert(JSON::Validator.validate(schema, data))

assert(JSON::Validator.validate(schema, data, :parse_data => false))

assert(JSON::Validator.validate(schema, data, :json => true))

assert_raises(Errno::ENOENT) { JSON::Validator.validate(schema, data, :uri => true) }
end

def test_parse_valid_uri_string
schema = {'type' => 'string'}
data = 'http://foo.bar/'

stub_request(:get, "foo.bar").to_return(:body => '"hello world"', :status => 200)

assert(JSON::Validator.validate(schema, data))

assert(JSON::Validator.validate(schema, data, :parse_data => false))

refute_block do
begin
JSON::Validator.validate(schema, data, :json => true)
rescue
false
end
end

assert(JSON::Validator.validate(schema, data, :uri => true))
end

def test_parse_invalid_uri_string
schema = {'type' => 'string'}
data = 'http://foo.bar/'

stub_request(:get, "foo.bar").to_timeout

assert(JSON::Validator.validate(schema, data))

assert(JSON::Validator.validate(schema, data, :parse_data => false))

refute_block do
begin
JSON::Validator.validate(schema, data, :json => true)
rescue
false
end
end

assert_raises(Timeout::Error) { JSON::Validator.validate(schema, data, :uri => true) }
end

def test_parse_integer
schema = {'type' => 'integer'}
data = 42

assert(JSON::Validator.validate(schema, data))

assert(JSON::Validator.validate(schema, data, :parse_data => false))

assert_raises(TypeError) { JSON::Validator.validate(schema, data, :json => true) }

assert_raises(TypeError) { JSON::Validator.validate(schema, data, :uri => true) }
end

def test_parse_hash
schema = { 'type' => 'object', 'properties' => { 'a' => { 'type' => 'string' } } }
data = { 'a' => 'b' }

assert(JSON::Validator.validate(schema, data))

assert(JSON::Validator.validate(schema, data, :parse_data => false))

assert_raises(TypeError) { JSON::Validator.validate(schema, data, :json => true) }

assert_raises(TypeError) { JSON::Validator.validate(schema, data, :uri => true) }
end
end