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

Correctly handle record_errors scenario #51

Conversation

BBonifield
Copy link
Contributor

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.

create_schema("foo_schema", {
"type" => "object",
"required" => ["foo"],
})

Choose a reason for hiding this comment

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

Indent the right brace the same as the first position after the preceding left parenthesis.


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

Choose a reason for hiding this comment

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

Use 2 spaces for indentation in a hash, relative to the first position after the preceding left parenthesis.

end

it "fails when the body is missing a required property" do
create_schema("foo_schema", {

Choose a reason for hiding this comment

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

Redundant curly braces around a hash parameter.

JSON::Validator.validate!(
schema_path.to_s,
Payload.new(response).to_s,
options

Choose a reason for hiding this comment

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

Put a comma after the last parameter of a multiline method call.

errors = JSON::Validator.fully_validate(
schema_path.to_s,
Payload.new(response).to_s,
options

Choose a reason for hiding this comment

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

Put a comma after the last parameter of a multiline method call.

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

Choose a reason for hiding this comment

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

Line is too long. [85/80]

Payload.new(response).to_s,
options,
)
# validate! will not raise and will always return true if you configure the validator

Choose a reason for hiding this comment

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

Line is too long. [91/80]

create_schema("foo_schema",
"type" => "object",
"required" => ["foo"],
)

Choose a reason for hiding this comment

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

Closing method call brace must be on the same line as the last argument when opening brace is on the same line as the first argument.

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

Choose a reason for hiding this comment

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

Avoid comma after the last parameter of a method call, unless each item is on its own line.

@nomasprime
Copy link

We need allOf for code reuse otherwise maintainability of JSON schema is a PITA.

Can this be merged in ASAP? Currently scratching heads at failing test and this would really help debug.

seanpdoyle added a commit that referenced this pull request Feb 24, 2017
Closes [#51].

Extract `JsonMatchers::Validator` to encapsulate error reporting
behavior.

`JSON::Validator` exposes a `#validate!` method that will raise on
validation failures, and a `#fully_validate!` method that won't raise,
but will return an array of error messages instead.

Additionally, this commit introduces the `#with_options` test helper
that scopes configuration options to a given test block.

[#51]: #51
seanpdoyle added a commit that referenced this pull request Feb 24, 2017
Closes [#51].

Extract `JsonMatchers::Validator` to encapsulate error reporting
behavior.

`JSON::Validator` exposes a `#validate!` method that will raise on
validation failures, and a `#fully_validate!` method that won't raise,
but will return an array of error messages instead.

Additionally, this commit introduces the `#with_options` test helper
that scopes configuration options to a given test block.

[#51]: #51
seanpdoyle added a commit that referenced this pull request Feb 24, 2017
Closes [#51].

Extract `JsonMatchers::Validator` to encapsulate error reporting
behavior.

`JSON::Validator` exposes a `#validate!` method that will raise on
validation failures, and a `#fully_validate!` method that won't raise,
but will return an array of error messages instead.

[#51]: #51
seanpdoyle added a commit that referenced this pull request Feb 24, 2017
Closes [#51].

Extract `JsonMatchers::Validator` to encapsulate error reporting
behavior.

`JSON::Validator` exposes a `#validate!` method that will raise on
validation failures, and a `#fully_validate!` method that won't raise,
but will return an array of error messages instead.

[#51]: #51
@seanpdoyle
Copy link
Collaborator

Thank you @BBonifield for this contribution!

This will make failure messages much more informative.

This PR was merged in 1a5c39e.

I've opened #52 as a follow-up.

What are the downsides to leaving record_errors: false as the default?

Do you think we should default it to true? Are there downsides to that?

@seanpdoyle seanpdoyle closed this Feb 24, 2017
seanpdoyle added a commit that referenced this pull request Feb 24, 2017
Closes [#51].

By default, `JsonMatchers.configuration.options[:record_errors] = true`.

Extract `JsonMatchers::Validator` to encapsulate error reporting
behavior.

`JSON::Validator` exposes a `#validate!` method that will raise on
validation failures, and a `#fully_validate!` method that won't raise,
but will return an array of error messages instead.

[#51]: #51
seanpdoyle added a commit that referenced this pull request Feb 24, 2017
Ensure that validation is always configured with  `record_errors: true`,
based on the following [comments]:

> By default, the underlying Validator will raise an error when passed
> invalid JSON. Unfortunately, this error tends to be high-level and
> [vague](#51).

> When configured with `record_errors: true`, the validator will collect
> and return an array of error messages instead of raising.

> This feels like a [reasonable
> default](#51 (comment)),
> so this PR makes it so.

[comments]: #52 (comment)
seanpdoyle added a commit that referenced this pull request Feb 24, 2017
Ensure that validation is always configured with  `record_errors: true`,
based on the following [comments]:

> By default, the underlying Validator will raise an error when passed
> invalid JSON. Unfortunately, this error tends to be high-level and
> [vague](#51).

> When configured with `record_errors: true`, the validator will collect
> and return an array of error messages instead of raising.

> This feels like a [reasonable
> default](#51 (comment)),
> so this PR makes it so.

[comments]: #52 (comment)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants