Skip to content

Commit

Permalink
Support record_errors configuration
Browse files Browse the repository at this point in the history
When you configure `JsonMatchers` to `record_errors`, it will result in
all matchers returning as valid.  The matcher was written around the
idea that `.validate!` will raise an error if the JSON does not match
the schema.  However when you have `record_errors` set to `true`, things
fall apart.

First, `json_schema` will catch all errors and collect them in an array
for error reporting.  Next, `validate!` will always return `true` since
it's written to assume that it should raise.  In order to handle this
scenario, I switched the matcher to use `fully_validate`, which allows
for inspection of the errors.

The use-case that brought this up for me was the desire to have better
error reporting for when you use `allOf`.  The default error message
from `json_schema` is pretty useless because it doesn't give you any of
the errors from the sub-schemas.
  • Loading branch information
BBonifield authored and seanpdoyle committed Feb 24, 2017
1 parent ada4489 commit 1a5c39e
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 5 deletions.
29 changes: 24 additions & 5 deletions lib/json_matchers/matcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,30 @@ def initialize(schema_path, options = {})
end

def matches?(response)
JSON::Validator.validate!(
schema_path.to_s,
Payload.new(response).to_s,
options,
)
# validate! will not raise and will always return true if you configure
# the validator to record errors, so we must instead inspect
# fully_validate's errors response
if options[:record_errors]
errors = JSON::Validator.fully_validate(
schema_path.to_s,
Payload.new(response).to_s,
options,
)

# errors is an array, but it will always only return a single item
if errors.any?
@validation_failure_message = errors.first
false
else
true
end
else
JSON::Validator.validate!(
schema_path.to_s,
Payload.new(response).to_s,
options,
)
end
rescue JSON::Schema::ValidationError => ex
@validation_failure_message = ex.message
false
Expand Down
22 changes: 22 additions & 0 deletions spec/json_matchers/match_response_schema_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,28 @@
config.options.delete(:strict)
end
end

context "when options specify to record errors" do
around do |example|
JsonMatchers.configure do |config|
config.options[:record_errors] = true
end

example.run

JsonMatchers.configure do |config|
config.options.delete(:record_errors)
end
end

it "fails when the body is missing a required property" do
create_schema("foo_schema",
"type" => "object",
"required" => ["foo"])

expect(response_for({})).not_to match_response_schema("foo_schema")
end
end
end

def raise_formatted_error(error_message)
Expand Down

0 comments on commit 1a5c39e

Please sign in to comment.