json_matchers 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +15 -0
- data/.rspec +2 -0
- data/.travis.yml +7 -0
- data/CHANGELOG.md +34 -0
- data/CONTRIBUTING.md +10 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +23 -0
- data/NEWS.md +17 -0
- data/README.md +184 -0
- data/Rakefile +9 -0
- data/json_matchers.gemspec +28 -0
- data/lib/json_matchers.rb +14 -0
- data/lib/json_matchers/errors.rb +4 -0
- data/lib/json_matchers/matcher.rb +37 -0
- data/lib/json_matchers/rspec.rb +83 -0
- data/lib/json_matchers/version.rb +3 -0
- data/spec/json_matchers/match_response_schema_spec.rb +116 -0
- data/spec/spec_helper.rb +13 -0
- data/spec/support/file_helpers.rb +42 -0
- metadata +151 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: ebd2f6c2a65cd0ad316c68b20ab44b7319b9fb47
|
4
|
+
data.tar.gz: 2a09b12a688897b183f76678991985042d3cc3db
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c6404d6214cb53692199e0533f9b824c54feb6f3961ac34d43bfb69ce7c1212794f4e36de5fd7972aa3744d9f49318ad280798cc016d620ef215e0e3ed8545de
|
7
|
+
data.tar.gz: 4068995034f0ad147fe14f4640b91cfb0d8d6262f17d900daf0b91af80f87d278b2ebca054c24553d644a43ae9de1eaa0d483e38b16be0a186d4dfd3c3202138
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
master
|
2
|
+
------
|
3
|
+
|
4
|
+
0.4.0
|
5
|
+
-----
|
6
|
+
|
7
|
+
* BREAKING CHANGE: Rename the gem to `json_matchers`.
|
8
|
+
|
9
|
+
0.3.1
|
10
|
+
-----
|
11
|
+
|
12
|
+
* BREAKING CHANGE: Rename module to `JsonMatchers`. This resolves clashing with
|
13
|
+
gems like `oj` / `oj_mimic_json` that take control of the standard library's
|
14
|
+
`json` module. As a result, the file to require is now `json_matchers`,
|
15
|
+
instead of `json/matchers`.
|
16
|
+
|
17
|
+
* No longer condone auto-loading RSpec. Add documentation around adding `require
|
18
|
+
"json_matchers/rspec"` to consumers' `spec/spec_helper.rb`
|
19
|
+
|
20
|
+
0.3.0
|
21
|
+
-----
|
22
|
+
|
23
|
+
* Pass options from matcher to `JSON::Validator`
|
24
|
+
|
25
|
+
0.2.2
|
26
|
+
-----
|
27
|
+
|
28
|
+
* Includes validation failure message in RSpec output
|
29
|
+
|
30
|
+
0.2.1
|
31
|
+
-----
|
32
|
+
|
33
|
+
* Supports RSpec 2 syntax `failure_message_for_should` and
|
34
|
+
`failure_message_for_should_not`
|
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
Contributing to json_matchers:
|
2
|
+
|
3
|
+
1. Fork the [official repository](https://github.com/thoughtbot/json_matchers/tree/master).
|
4
|
+
2. Make your changes in a topic branch.
|
5
|
+
3. Send a pull request.
|
6
|
+
|
7
|
+
Notes:
|
8
|
+
|
9
|
+
* Contributions without tests won't be accepted.
|
10
|
+
* Please don't update the Gem version.
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
Copyright (c) 2014 Sean Doyle
|
2
|
+
Copyright (c) 2015 Sean Doyle and thoughtbot, inc.
|
3
|
+
|
4
|
+
MIT License
|
5
|
+
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
7
|
+
a copy of this software and associated documentation files (the
|
8
|
+
"Software"), to deal in the Software without restriction, including
|
9
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
10
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
11
|
+
permit persons to whom the Software is furnished to do so, subject to
|
12
|
+
the following conditions:
|
13
|
+
|
14
|
+
The above copyright notice and this permission notice shall be
|
15
|
+
included in all copies or substantial portions of the Software.
|
16
|
+
|
17
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
18
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
19
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
20
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
21
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
22
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
23
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/NEWS.md
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# 0.2.0
|
2
|
+
|
3
|
+
* RSpec failure messages include both the body of the response, and the body of
|
4
|
+
the JSON Schema file
|
5
|
+
|
6
|
+
# 0.1.0
|
7
|
+
|
8
|
+
## Breaking Changes
|
9
|
+
|
10
|
+
* Remove `schema_for` in favor of using `$ref`. To learn more about `$ref`,
|
11
|
+
check out [Understanding JSON Schema Structuring](http://spacetelescope.github.io/understanding-json-schema/structuring.html)
|
12
|
+
|
13
|
+
# 0.0.1
|
14
|
+
|
15
|
+
## Features
|
16
|
+
|
17
|
+
* Validate your Rails response JSON with `match_response_schema`
|
data/README.md
ADDED
@@ -0,0 +1,184 @@
|
|
1
|
+
# JsonMatchers
|
2
|
+
|
3
|
+
Validate the JSON returned by your Rails JSON APIs
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
group :test do
|
11
|
+
gem "json_matchers"
|
12
|
+
end
|
13
|
+
```
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install json_matchers
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
Inspired by [Validating JSON Schemas with an RSpec Matcher](http://robots.thoughtbot.com/validating-json-schemas-with-an-rspec-matcher)
|
26
|
+
|
27
|
+
First, include it in your `spec_helper`:
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
# spec/spec_helper.rb
|
31
|
+
|
32
|
+
require "json_matchers/rspec"
|
33
|
+
```
|
34
|
+
|
35
|
+
Define your [JSON Schema](http://json-schema.org/example1.html) in the schema directory:
|
36
|
+
|
37
|
+
```json
|
38
|
+
# spec/support/api/schemas/posts.json
|
39
|
+
|
40
|
+
{
|
41
|
+
"type": "object",
|
42
|
+
"required": ["posts"],
|
43
|
+
"properties": {
|
44
|
+
"type": "object",
|
45
|
+
"required": ["id", "title", "body"],
|
46
|
+
"properties": {
|
47
|
+
"id": { "type": "integer" },
|
48
|
+
"title": { "type": "string" },
|
49
|
+
"body": { "type": "string" }
|
50
|
+
}
|
51
|
+
}
|
52
|
+
}
|
53
|
+
```
|
54
|
+
|
55
|
+
Then, validate your response against your schema with `match_response_schema`
|
56
|
+
|
57
|
+
```ruby
|
58
|
+
# spec/requests/posts_spec.rb
|
59
|
+
|
60
|
+
describe "GET /posts" do
|
61
|
+
it "returns Posts" do
|
62
|
+
get posts_path, format: :json
|
63
|
+
|
64
|
+
expect(response.status).to eq 200
|
65
|
+
expect(response).to match_response_schema("posts")
|
66
|
+
end
|
67
|
+
end
|
68
|
+
```
|
69
|
+
|
70
|
+
### Passing options to the validator
|
71
|
+
|
72
|
+
The matcher accepts options, which it'll pass to the validator:
|
73
|
+
|
74
|
+
```ruby
|
75
|
+
# spec/requests/posts_spec.rb
|
76
|
+
|
77
|
+
describe "GET /posts" do
|
78
|
+
it "returns Posts" do
|
79
|
+
get posts_path, format: :json
|
80
|
+
|
81
|
+
expect(response.status).to eq 200
|
82
|
+
expect(response).to match_response_schema("posts", strict: false)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
```
|
86
|
+
|
87
|
+
A list of available options can be found [here][options]
|
88
|
+
|
89
|
+
[options]: https://github.com/ruby-json-schema/json-schema/blob/2.2.4/lib/json-schema/validator.rb#L160-L162
|
90
|
+
|
91
|
+
### Embedding other Schemas
|
92
|
+
|
93
|
+
To DRY up your schema definitions, use JSON schema's `$ref`.
|
94
|
+
|
95
|
+
First, declare the singular version of your schema.
|
96
|
+
|
97
|
+
```json
|
98
|
+
# spec/support/api/schemas/post.json
|
99
|
+
|
100
|
+
{
|
101
|
+
"type": "object",
|
102
|
+
"required": ["id", "title", "body"],
|
103
|
+
"properties": {
|
104
|
+
"id": { "type": "integer" },
|
105
|
+
"title": { "type": "string" },
|
106
|
+
"body": { "type": "string" }
|
107
|
+
}
|
108
|
+
}
|
109
|
+
```
|
110
|
+
|
111
|
+
Then, when you declare your collection schema, reference your singular schemas.
|
112
|
+
|
113
|
+
```json
|
114
|
+
# spec/support/api/schemas/posts.json
|
115
|
+
|
116
|
+
{
|
117
|
+
"type": "object",
|
118
|
+
"required": ["posts"],
|
119
|
+
"properties": {
|
120
|
+
"posts": {
|
121
|
+
"type": "array",
|
122
|
+
"items": { "$ref": "post.json" }
|
123
|
+
}
|
124
|
+
}
|
125
|
+
}
|
126
|
+
```
|
127
|
+
|
128
|
+
NOTE: `$ref` resolves paths relative to the schema in question.
|
129
|
+
|
130
|
+
In this case `"post.json"` will be resolved relative to
|
131
|
+
`"spec/support/api/schemas"`.
|
132
|
+
|
133
|
+
To learn more about `$ref`, check out [Understanding JSON Schema Structuring](http://spacetelescope.github.io/understanding-json-schema/structuring.html)
|
134
|
+
|
135
|
+
## Configuration
|
136
|
+
|
137
|
+
By default, the schema directory is `spec/support/api/schemas`.
|
138
|
+
|
139
|
+
This can be configured via `JsonMatchers.schema_root`.
|
140
|
+
|
141
|
+
|
142
|
+
```ruby
|
143
|
+
# spec/support/json_matchers.rb
|
144
|
+
|
145
|
+
JsonMatchers.schema_root = "docs/api/schemas"
|
146
|
+
```
|
147
|
+
|
148
|
+
## Contributing
|
149
|
+
|
150
|
+
Please see [CONTRIBUTING].
|
151
|
+
|
152
|
+
`json_matchers` was inspired by [Validating JSON Schemas with an
|
153
|
+
RSpec Matcher][blog post] by Laila Winner.
|
154
|
+
|
155
|
+
`json_matchers` was written and is maintained by Sean Doyle.
|
156
|
+
|
157
|
+
Many improvements and bugfixes were contributed by the [open source community].
|
158
|
+
|
159
|
+
[blog post]: https://robots.thoughtbot.com/validating-json-schemas-with-an-rspec-matcher
|
160
|
+
[CONTRIBUTING]: https://github.com/thoughtbot/json_matchers/blob/master/CONTRIBUTING.md
|
161
|
+
[open source community]: https://github.com/thoughtbot/json_matchers/graphs/contributors
|
162
|
+
|
163
|
+
## License
|
164
|
+
|
165
|
+
json_matchers is Copyright © 2015 Sean Doyle and thoughtbot.
|
166
|
+
|
167
|
+
It is free software, and may be redistributed under the terms specified in the
|
168
|
+
[LICENSE] file.
|
169
|
+
|
170
|
+
[LICENSE]: LICENSE.txt
|
171
|
+
|
172
|
+
## About thoughtbot
|
173
|
+
|
174
|
+

|
175
|
+
|
176
|
+
`json_matchers` is maintained and funded by thoughtbot, inc.
|
177
|
+
The names and logos for thoughtbot are trademarks of thoughtbot, inc.
|
178
|
+
|
179
|
+
We love open source software!
|
180
|
+
See [our other projects][community].
|
181
|
+
We are [available for hire][hire].
|
182
|
+
|
183
|
+
[community]: https://thoughtbot.com/community?utm_source=github
|
184
|
+
[hire]: https://thoughtbot.com?utm_source=github
|
data/Rakefile
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "json_matchers/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "json_matchers"
|
8
|
+
spec.version = JsonMatchers::VERSION
|
9
|
+
spec.authors = ["Sean Doyle"]
|
10
|
+
spec.email = ["sean.p.doyle24@gmail.com"]
|
11
|
+
spec.summary = %q{Validate your Rails JSON API's JSON}
|
12
|
+
spec.description = %q{Validate your Rails JSON API's JSON}
|
13
|
+
spec.homepage = "https://github.com/thoughtbot/json_matchers"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency("json-schema", "~> 2.2.5")
|
22
|
+
spec.add_dependency("activesupport", '>= 3.0.0')
|
23
|
+
|
24
|
+
spec.add_development_dependency "bundler", "~> 1.7"
|
25
|
+
spec.add_development_dependency "pry"
|
26
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
27
|
+
spec.add_development_dependency "rspec-rails", ">= 2.0"
|
28
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require "json_matchers/version"
|
2
|
+
require "json_matchers/matcher"
|
3
|
+
require "json_matchers/errors"
|
4
|
+
require "active_support/all"
|
5
|
+
|
6
|
+
module JsonMatchers
|
7
|
+
mattr_accessor :schema_root
|
8
|
+
|
9
|
+
self.schema_root = "#{Dir.pwd}/spec/support/api/schemas"
|
10
|
+
|
11
|
+
def self.path_to_schema(schema_name)
|
12
|
+
Pathname(schema_root).join("#{schema_name}.json")
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require "json-schema"
|
2
|
+
|
3
|
+
module JsonMatchers
|
4
|
+
class Matcher
|
5
|
+
def initialize(schema_path, **options)
|
6
|
+
@schema_path = schema_path
|
7
|
+
@options = options
|
8
|
+
end
|
9
|
+
|
10
|
+
def matches?(response)
|
11
|
+
@response = response
|
12
|
+
|
13
|
+
validator_options = {
|
14
|
+
strict: true,
|
15
|
+
}.merge(options)
|
16
|
+
|
17
|
+
JSON::Validator.validate!(
|
18
|
+
schema_path.to_s,
|
19
|
+
response.body,
|
20
|
+
validator_options,
|
21
|
+
)
|
22
|
+
rescue JSON::Schema::ValidationError => ex
|
23
|
+
@validation_failure_message = ex.message
|
24
|
+
false
|
25
|
+
rescue JSON::ParserError
|
26
|
+
raise InvalidSchemaError
|
27
|
+
end
|
28
|
+
|
29
|
+
def validation_failure_message
|
30
|
+
@validation_failure_message.to_s
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
attr_reader :schema_path, :options
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require "json_matchers"
|
2
|
+
|
3
|
+
module JsonMatchers
|
4
|
+
class RSpec < SimpleDelegator
|
5
|
+
attr_reader :schema_name
|
6
|
+
|
7
|
+
def initialize(schema_name, **options)
|
8
|
+
@schema_name = schema_name
|
9
|
+
|
10
|
+
super(JsonMatchers::Matcher.new(schema_path, options))
|
11
|
+
end
|
12
|
+
|
13
|
+
def failure_message(response)
|
14
|
+
<<-FAIL.strip_heredoc
|
15
|
+
expected
|
16
|
+
|
17
|
+
#{response.body}
|
18
|
+
|
19
|
+
to match schema "#{schema_name}":
|
20
|
+
|
21
|
+
#{schema_body}
|
22
|
+
|
23
|
+
---
|
24
|
+
|
25
|
+
#{validation_failure_message}
|
26
|
+
|
27
|
+
FAIL
|
28
|
+
end
|
29
|
+
|
30
|
+
def failure_message_when_negated(response)
|
31
|
+
<<-FAIL.strip_heredoc
|
32
|
+
expected
|
33
|
+
|
34
|
+
#{response.body}
|
35
|
+
|
36
|
+
not to match schema "#{schema_name}":
|
37
|
+
|
38
|
+
#{schema_body}
|
39
|
+
|
40
|
+
---
|
41
|
+
|
42
|
+
#{validation_failure_message}
|
43
|
+
|
44
|
+
FAIL
|
45
|
+
end
|
46
|
+
|
47
|
+
def schema_path
|
48
|
+
JsonMatchers.path_to_schema(schema_name)
|
49
|
+
end
|
50
|
+
|
51
|
+
def schema_body
|
52
|
+
File.read(schema_path)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
if RSpec.respond_to?(:configure)
|
58
|
+
RSpec::Matchers.define :match_response_schema do |schema_name, **options|
|
59
|
+
matcher = JsonMatchers::RSpec.new(schema_name, options)
|
60
|
+
|
61
|
+
match do |response|
|
62
|
+
matcher.matches?(response)
|
63
|
+
end
|
64
|
+
|
65
|
+
if respond_to?(:failure_message)
|
66
|
+
failure_message do |response|
|
67
|
+
matcher.failure_message(response)
|
68
|
+
end
|
69
|
+
|
70
|
+
failure_message_when_negated do |response|
|
71
|
+
matcher.failure_message_when_negated(response)
|
72
|
+
end
|
73
|
+
else
|
74
|
+
failure_message_for_should do |response|
|
75
|
+
matcher.failure_message(response)
|
76
|
+
end
|
77
|
+
|
78
|
+
failure_message_for_should_not do |response|
|
79
|
+
matcher.failure_message_when_negated(response)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
describe JsonMatchers, "#match_response_schema" do
|
2
|
+
it "fails with an invalid JSON body" do
|
3
|
+
create_schema("foo", "")
|
4
|
+
|
5
|
+
expect {
|
6
|
+
expect(response_for("")).to match_response_schema("foo")
|
7
|
+
}.to raise_error(JsonMatchers::InvalidSchemaError)
|
8
|
+
end
|
9
|
+
|
10
|
+
it "does not fail with an empty JSON body" do
|
11
|
+
create_schema("foo", {})
|
12
|
+
|
13
|
+
expect(response_for({})).to match_response_schema("foo")
|
14
|
+
end
|
15
|
+
|
16
|
+
it "fails when the body is missing a required property" do
|
17
|
+
create_schema("foo_schema", {
|
18
|
+
"type" => "object",
|
19
|
+
"required" => ["foo"],
|
20
|
+
})
|
21
|
+
|
22
|
+
expect(response_for({})).not_to match_response_schema("foo_schema")
|
23
|
+
end
|
24
|
+
|
25
|
+
it "accepts options for the validator" do
|
26
|
+
create_schema("foo_schema", {
|
27
|
+
"type" => "object",
|
28
|
+
"required" => [
|
29
|
+
"id",
|
30
|
+
],
|
31
|
+
"properties" => {
|
32
|
+
"id" => { "type" => "number" },
|
33
|
+
"title" => {"type" => "string"},
|
34
|
+
},
|
35
|
+
"additionalProperties" => false,
|
36
|
+
})
|
37
|
+
|
38
|
+
expect(response_for({ "id" => 1, "title" => "bar" })).
|
39
|
+
to match_response_schema("foo_schema", strict: false)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "fails when the body contains a property with the wrong type" do
|
43
|
+
create_schema("foo_schema", {
|
44
|
+
"type" => "object",
|
45
|
+
"properties" => {
|
46
|
+
"foo" => { "type" => "string" },
|
47
|
+
}
|
48
|
+
})
|
49
|
+
|
50
|
+
expect(response_for("foo" => 1)).
|
51
|
+
not_to match_response_schema("foo_schema")
|
52
|
+
end
|
53
|
+
|
54
|
+
it "contains the body in the failure message" do
|
55
|
+
create_schema("foo", { "type" => "array" })
|
56
|
+
|
57
|
+
expect {
|
58
|
+
expect(response_for("bar" => 5)).to match_response_schema("foo")
|
59
|
+
}.to raise_error(/{"bar":5}/)
|
60
|
+
end
|
61
|
+
|
62
|
+
it "contains the body in the failure message when negated" do
|
63
|
+
create_schema("foo", { "type" => "array" })
|
64
|
+
|
65
|
+
expect {
|
66
|
+
expect(response_for([])).not_to match_response_schema("foo")
|
67
|
+
}.to raise_error(/\[\]/)
|
68
|
+
end
|
69
|
+
|
70
|
+
it "contains the schema in the failure message" do
|
71
|
+
schema = { "type" => "array" }
|
72
|
+
create_schema("foo", schema)
|
73
|
+
|
74
|
+
expect {
|
75
|
+
expect(response_for("bar" => 5)).to match_response_schema("foo")
|
76
|
+
}.to raise_error(/#{schema.to_json}/)
|
77
|
+
end
|
78
|
+
|
79
|
+
it "contains the schema in the failure message when negated" do
|
80
|
+
schema = { "type" => "array" }
|
81
|
+
create_schema("foo", schema)
|
82
|
+
|
83
|
+
expect {
|
84
|
+
expect(response_for([])).not_to match_response_schema("foo")
|
85
|
+
}.to raise_error(/#{schema.to_json}/)
|
86
|
+
end
|
87
|
+
|
88
|
+
it "does not fail when the schema matches" do
|
89
|
+
create_schema("array_schema", {
|
90
|
+
"type" => "array",
|
91
|
+
"items" => { "type" => "string" },
|
92
|
+
})
|
93
|
+
|
94
|
+
expect(response_for(["valid"])).to match_response_schema("array_schema")
|
95
|
+
end
|
96
|
+
|
97
|
+
it "supports $ref" do
|
98
|
+
create_schema("single", {
|
99
|
+
"type" => "object",
|
100
|
+
"required" => ["foo"],
|
101
|
+
"properties" => {
|
102
|
+
"foo" => { "type" => "string" },
|
103
|
+
}
|
104
|
+
})
|
105
|
+
create_schema("collection", {
|
106
|
+
"type" => "array",
|
107
|
+
"items" => { "$ref" => "single.json" },
|
108
|
+
})
|
109
|
+
|
110
|
+
valid_response = response_for([{ "foo" => "is a string" }])
|
111
|
+
invalid_response = response_for([{ "foo" => 0 }])
|
112
|
+
|
113
|
+
expect(valid_response).to match_response_schema("collection")
|
114
|
+
expect(invalid_response).not_to match_response_schema("collection")
|
115
|
+
end
|
116
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require "json_matchers/rspec"
|
2
|
+
|
3
|
+
Dir["./spec/support/*"].each { |file| require file }
|
4
|
+
|
5
|
+
RSpec.configure do |config|
|
6
|
+
config.expect_with :rspec do |expectations|
|
7
|
+
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
8
|
+
end
|
9
|
+
|
10
|
+
config.mock_with :rspec do |mocks|
|
11
|
+
mocks.verify_partial_doubles = true
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module FileHelpers
|
2
|
+
ORIGINAL_SCHEMA_ROOT = JsonMatchers.schema_root
|
3
|
+
|
4
|
+
def create_schema(name, json)
|
5
|
+
File.open("#{schema_root}/#{name}.json", "w") do |file|
|
6
|
+
case json
|
7
|
+
when NilClass, String
|
8
|
+
file.write(json.to_s)
|
9
|
+
else
|
10
|
+
file.write(json.to_json)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def response_for(json)
|
16
|
+
response_body = case json
|
17
|
+
when String, NilClass
|
18
|
+
json.to_s
|
19
|
+
else
|
20
|
+
json.to_json
|
21
|
+
end
|
22
|
+
double(body: response_body)
|
23
|
+
end
|
24
|
+
|
25
|
+
def schema_root
|
26
|
+
JsonMatchers.schema_root
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
RSpec.configure do |config|
|
31
|
+
config.include FileHelpers
|
32
|
+
|
33
|
+
config.around do |example|
|
34
|
+
JsonMatchers.schema_root = File.join(Dir.pwd, "spec", "fixtures", "schemas")
|
35
|
+
FileUtils.mkdir_p(JsonMatchers.schema_root)
|
36
|
+
|
37
|
+
example.run
|
38
|
+
|
39
|
+
FileUtils.rm_rf(JsonMatchers.schema_root)
|
40
|
+
JsonMatchers.schema_root = FileHelpers::ORIGINAL_SCHEMA_ROOT
|
41
|
+
end
|
42
|
+
end
|
metadata
ADDED
@@ -0,0 +1,151 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: json_matchers
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.4.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Sean Doyle
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-10-02 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: json-schema
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 2.2.5
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 2.2.5
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: activesupport
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 3.0.0
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 3.0.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.7'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.7'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: pry
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rake
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '10.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '10.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rspec-rails
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '2.0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '2.0'
|
97
|
+
description: Validate your Rails JSON API's JSON
|
98
|
+
email:
|
99
|
+
- sean.p.doyle24@gmail.com
|
100
|
+
executables: []
|
101
|
+
extensions: []
|
102
|
+
extra_rdoc_files: []
|
103
|
+
files:
|
104
|
+
- ".gitignore"
|
105
|
+
- ".rspec"
|
106
|
+
- ".travis.yml"
|
107
|
+
- CHANGELOG.md
|
108
|
+
- CONTRIBUTING.md
|
109
|
+
- Gemfile
|
110
|
+
- LICENSE.txt
|
111
|
+
- NEWS.md
|
112
|
+
- README.md
|
113
|
+
- Rakefile
|
114
|
+
- json_matchers.gemspec
|
115
|
+
- lib/json_matchers.rb
|
116
|
+
- lib/json_matchers/errors.rb
|
117
|
+
- lib/json_matchers/matcher.rb
|
118
|
+
- lib/json_matchers/rspec.rb
|
119
|
+
- lib/json_matchers/version.rb
|
120
|
+
- spec/json_matchers/match_response_schema_spec.rb
|
121
|
+
- spec/spec_helper.rb
|
122
|
+
- spec/support/file_helpers.rb
|
123
|
+
homepage: https://github.com/thoughtbot/json_matchers
|
124
|
+
licenses:
|
125
|
+
- MIT
|
126
|
+
metadata: {}
|
127
|
+
post_install_message:
|
128
|
+
rdoc_options: []
|
129
|
+
require_paths:
|
130
|
+
- lib
|
131
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
132
|
+
requirements:
|
133
|
+
- - ">="
|
134
|
+
- !ruby/object:Gem::Version
|
135
|
+
version: '0'
|
136
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
137
|
+
requirements:
|
138
|
+
- - ">="
|
139
|
+
- !ruby/object:Gem::Version
|
140
|
+
version: '0'
|
141
|
+
requirements: []
|
142
|
+
rubyforge_project:
|
143
|
+
rubygems_version: 2.4.8
|
144
|
+
signing_key:
|
145
|
+
specification_version: 4
|
146
|
+
summary: Validate your Rails JSON API's JSON
|
147
|
+
test_files:
|
148
|
+
- spec/json_matchers/match_response_schema_spec.rb
|
149
|
+
- spec/spec_helper.rb
|
150
|
+
- spec/support/file_helpers.rb
|
151
|
+
has_rdoc:
|