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

Add support for Minitest #66

Merged
merged 2 commits into from
Apr 6, 2018
Merged
Show file tree
Hide file tree
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
6 changes: 6 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,25 @@ inherit_from:
Style/BlockDelimiters:
Enabled: true
Exclude:
- 'test/**/*_test.rb'
- 'spec/**/*_spec.rb'

Style/BracesAroundHashParameters:
Enabled: true
Exclude:
- 'test/**/*_test.rb'
- 'spec/**/*_spec.rb'
- 'spec/factories.rb'

Style/SymbolArray:
Enabled: false

Layout/IndentHeredoc:
Enabled: false

Layout/IndentHash:
Enabled: true
Exclude:
- 'test/**/*_test.rb'
- 'spec/**/*_spec.rb'
- 'spec/factories.rb'
5 changes: 3 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
Contributing to json_matchers:
Contributing to `json_matchers`:

1. Fork the [official repository](https://github.com/thoughtbot/json_matchers/tree/master).
2. Make your changes in a topic branch.
3. Send a pull request.

Notes:

* Contributions without tests won't be accepted.
* Contributions without tests covering the `RSpec` matchers _and_ the `Minitest`
assertions won't be accepted.
* Please don't update the Gem version.
5 changes: 5 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
master
======

* Add `assert_json_matches_schema` and `refute_json_matches_schema` for
use in `minitest` test suites [#66]

[#66]: https://github.com/thoughtbot/json_matchers/pull/66

0.7.3
=====

Expand Down
105 changes: 61 additions & 44 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Validate the JSON returned by your Rails JSON APIs

## Installation

Add this line to your application's Gemfile:
Add this line to your application's `Gemfile`:

```ruby
group :test do
Expand All @@ -22,21 +22,45 @@ Or install it yourself as:

## Usage

Inspired by [Validating JSON Schemas with an RSpec Matcher](http://robots.thoughtbot.com/validating-json-schemas-with-an-rspec-matcher)
Inspired by [Validating JSON Schemas with an RSpec Matcher][original-blog-post].

First, include it in your `spec_helper`:
[original-blog-post]: (http://robots.thoughtbot.com/validating-json-schemas-with-an-rspec-matcher)

```ruby
# spec/spec_helper.rb
First, configure it in your test suite's helper file:

### Configure

#### RSpec

`spec/spec_helper.rb`

```ruby
require "json_matchers/rspec"

JsonMatchers.schema_root = "/spec/support/api/schemas"
```

Define your [JSON Schema](http://json-schema.org/example1.html) in the schema directory:
#### Minitest

```json
# spec/support/api/schemas/posts.json
`test/test_helper.rb`

```ruby
require "minitest/autorun"
require "json_matchers/minitest/assertions"

JsonMatchers.schema_root = "/test/support/api/schemas"

Minitest::Test.send(:include, JsonMatchers::Minitest::Assertions)
```

### Declare

Declare your [JSON Schema](http://json-schema.org/example1.html) in the schema
directory.

`spec/support/api/schemas/posts.json` or `test/support/api/schemas/posts.json`:

```json
{
"type": "object",
"required": ["posts"],
Expand All @@ -56,11 +80,16 @@ Define your [JSON Schema](http://json-schema.org/example1.html) in the schema di
}
```

Then, validate `response` against your schema with `match_json_schema`
### Validate

```ruby
# spec/requests/posts_spec.rb
#### RSpec

Validate a JSON response, a Hash, or a String against a JSON Schema with
`match_json_schema`:

`spec/requests/posts_spec.rb`

```ruby
describe "GET /posts" do
it "returns Posts" do
get posts_path, format: :json
Expand All @@ -71,28 +100,29 @@ describe "GET /posts" do
end
```

Alternatively, `match_json_schema` accepts a string:
#### Minitest

```ruby
# spec/requests/posts_spec.rb
Validate a JSON response, a Hash, or a String against a JSON Schema with
`assert_matches_json_schema`:

describe "GET /posts" do
it "returns Posts" do
get posts_path, format: :json
`test/integration/posts_test.rb`

expect(response.status).to eq 200
expect(response.body).to match_json_schema("posts")
end
```ruby
def test_GET_posts_returns_Posts
get posts_path, format: :json

assert_equal response.status, 200
assert_matches_json_schema response, "posts"
end
```

### Passing options to the validator

The matcher accepts options, which it passes to the validator:

```ruby
# spec/requests/posts_spec.rb
`spec/requests/posts_spec.rb`

```ruby
describe "GET /posts" do
it "returns Posts" do
get posts_path, format: :json
Expand All @@ -110,11 +140,11 @@ A list of available options can be found [here][options].
### Global matcher options

To configure the default options passed to *all* matchers, call
`JsonMatchers.configure`:
`JsonMatchers.configure`.

```rb
# spec/support/json_matchers.rb
`spec/support/json_matchers.rb`:

```rb
JsonMatchers.configure do |config|
config.options[:strict] = true
end
Expand All @@ -133,9 +163,9 @@ To DRY up your schema definitions, use JSON schema's `$ref`.

First, declare the singular version of your schema.

```json
# spec/support/api/schemas/post.json
`spec/support/api/schemas/post.json`:

```json
{
"type": "object",
"required": ["id", "title", "body"],
Expand All @@ -149,9 +179,9 @@ First, declare the singular version of your schema.

Then, when you declare your collection schema, reference your singular schemas.

```json
# spec/support/api/schemas/posts.json
`spec/support/api/schemas/posts.json`:

```json
{
"type": "object",
"required": ["posts"],
Expand All @@ -171,27 +201,14 @@ In this case `"post.json"` will be resolved relative to

To learn more about `$ref`, check out [Understanding JSON Schema Structuring](http://spacetelescope.github.io/understanding-json-schema/structuring.html)

## Configuration

By default, the schema directory is `spec/support/api/schemas`.

This can be configured via `JsonMatchers.schema_root`.


```ruby
# spec/support/json_matchers.rb

JsonMatchers.schema_root = "docs/api/schemas"
```

## Contributing

Please see [CONTRIBUTING].

`json_matchers` was inspired by [Validating JSON Schemas with an
RSpec Matcher][blog post] by Laila Winner.

`json_matchers` was written and is maintained by Sean Doyle.
`json_matchers` is maintained by Sean Doyle.

Many improvements and bugfixes were contributed by the [open source community].

Expand All @@ -201,7 +218,7 @@ Many improvements and bugfixes were contributed by the [open source community].

## License

json_matchers is Copyright © 2015 Sean Doyle and thoughtbot.
`json_matchers` is Copyright © 2018 thoughtbot.

It is free software, and may be redistributed under the terms specified in the
[LICENSE] file.
Expand Down
7 changes: 6 additions & 1 deletion Rakefile
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
require "bundler/gem_tasks"
require "rspec/core/rake_task"
require "rake/testtask"

RSpec::Core::RakeTask.new do |t|
t.pattern = "spec/**/*_spec.rb"
end

Rake::TestTask.new do |t|
t.test_files = FileList["test/**/*_test.rb"]
end

task(:default).clear
task default: [:spec]
task default: [:spec, :test]
1 change: 1 addition & 0 deletions json_matchers.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ Gem::Specification.new do |spec|
spec.add_development_dependency "pry"
spec.add_development_dependency "rake", "~> 10.0"
spec.add_development_dependency "rspec", ">= 2.0"
spec.add_development_dependency "minitest"
spec.add_development_dependency "factory_bot", ">= 4.8"
spec.add_development_dependency "activesupport"
end
2 changes: 0 additions & 2 deletions lib/json_matchers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ class << self
attr_accessor :schema_root
end

self.schema_root = "#{Dir.pwd}/spec/support/api/schemas"

def self.path_to_schema(schema_name)
Pathname(schema_root).join("#{schema_name}.json")
end
Expand Down
68 changes: 68 additions & 0 deletions lib/json_matchers/assertion.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
require "json"
require "json_matchers"
require "json_matchers/payload"
require "json_matchers/matcher"

module JsonMatchers
class Assertion
def initialize(schema_name, **options)
@schema_name = schema_name
@schema_path = JsonMatchers.path_to_schema(schema_name)
@matcher = Matcher.new(schema_path, options)
end

def valid?(json)
@payload = Payload.new(json)

matcher.matches?(payload.to_s)
end

def valid_failure_message
<<-FAIL
#{last_error_message}

Choose a reason for hiding this comment

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

Layout/IndentHeredoc: Use 2 spaces for indentation in a heredoc by using <<~ instead of <<-.


---

expected

#{format_json(payload)}

to match schema "#{schema_name}":

#{format_json(schema_body)}
FAIL
end

def invalid_failure_message
<<-FAIL
#{last_error_message}

Choose a reason for hiding this comment

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

Layout/IndentHeredoc: Use 2 spaces for indentation in a heredoc by using <<~ instead of <<-.


---

expected

#{format_json(payload)}

not to match schema "#{schema_name}":

#{format_json(schema_body)}
FAIL
end

private

attr_reader :payload, :matcher, :schema_name, :schema_path

def last_error_message
matcher.validation_failure_message
end

def schema_body
File.read(schema_path)
end

def format_json(json)
JSON.pretty_generate(JSON.parse(json.to_s))
end
end
end
8 changes: 4 additions & 4 deletions lib/json_matchers/matcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ def initialize(schema_path, options = {})
@options = default_options.merge(options)
end

def matches?(response)
validator = build_validator(response)
def matches?(payload)
validator = build_validator(payload)

self.errors = validator.validate!

Expand All @@ -34,10 +34,10 @@ def default_options
JsonMatchers.configuration.options || {}
end

def build_validator(response)
def build_validator(payload)
Validator.new(
options: options,
response: response,
payload: payload,
schema_path: schema_path,
)
end
Expand Down
Loading