json_matchers 0.7.3 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.rubocop.yml +11 -0
- data/.ruby-version +1 -1
- data/.thoughtbot.rubocop.yml +13 -3
- data/.travis.yml +1 -1
- data/CONTRIBUTING.md +3 -2
- data/Gemfile +1 -1
- data/NEWS.md +8 -0
- data/README.md +61 -44
- data/Rakefile +6 -1
- data/json_matchers.gemspec +3 -0
- data/lib/json_matchers.rb +0 -2
- data/lib/json_matchers/assertion.rb +68 -0
- data/lib/json_matchers/matcher.rb +4 -4
- data/lib/json_matchers/minitest/assertions.rb +26 -0
- data/lib/json_matchers/payload.rb +1 -1
- data/lib/json_matchers/rspec.rb +19 -79
- data/lib/json_matchers/validator.rb +2 -3
- data/lib/json_matchers/version.rb +1 -1
- data/spec/factories.rb +88 -0
- data/spec/json_matchers/match_json_schema_spec.rb +160 -174
- data/spec/spec_helper.rb +1 -1
- data/spec/support/factory_bot.rb +9 -0
- data/spec/support/fake_response.rb +9 -0
- data/spec/support/fake_schema.rb +9 -0
- data/spec/support/file_helpers.rb +0 -26
- data/test/json_matchers/minitest/assertions_test.rb +177 -0
- data/test/support/factory_bot.rb +5 -0
- data/test/support/json_matchers/test_case.rb +18 -0
- data/test/test_helper.rb +8 -0
- metadata +63 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 915cc934b6081cff12a854f252864b3e6a563b638a2852872ea5e50d9373832e
|
4
|
+
data.tar.gz: f580d61fdbd56461ffe9fc13295adbac531492ddf66abb33f875bdfc7f31bf74
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 94538a59b1dce067f741957af0c1d7c1057004dde8dfd887253de6cfb6f586de917ac73a9c8e9649e9175c477dc7e5cc98f093d8d17973c3814d5666ecb0aa7e
|
7
|
+
data.tar.gz: 6a63c1185707740da0498e7b9962fc8edc15fd7a6915f927a5c7d0d582334cde79d74fecaa31634974f43dd869400dd939b090a5e383819acf75c1eaaddcfa52
|
data/.rubocop.yml
CHANGED
@@ -4,14 +4,25 @@ inherit_from:
|
|
4
4
|
Style/BlockDelimiters:
|
5
5
|
Enabled: true
|
6
6
|
Exclude:
|
7
|
+
- 'test/**/*_test.rb'
|
7
8
|
- 'spec/**/*_spec.rb'
|
8
9
|
|
9
10
|
Style/BracesAroundHashParameters:
|
10
11
|
Enabled: true
|
11
12
|
Exclude:
|
13
|
+
- 'test/**/*_test.rb'
|
12
14
|
- 'spec/**/*_spec.rb'
|
15
|
+
- 'spec/factories.rb'
|
16
|
+
|
17
|
+
Style/SymbolArray:
|
18
|
+
Enabled: false
|
19
|
+
|
20
|
+
Layout/IndentHeredoc:
|
21
|
+
Enabled: false
|
13
22
|
|
14
23
|
Layout/IndentHash:
|
15
24
|
Enabled: true
|
16
25
|
Exclude:
|
26
|
+
- 'test/**/*_test.rb'
|
17
27
|
- 'spec/**/*_spec.rb'
|
28
|
+
- 'spec/factories.rb'
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.5.0
|
data/.thoughtbot.rubocop.yml
CHANGED
@@ -352,8 +352,18 @@ Style/TrailingCommaInArguments:
|
|
352
352
|
- no_comma
|
353
353
|
Enabled: true
|
354
354
|
|
355
|
-
Style/
|
356
|
-
Description: 'Checks for trailing comma in
|
355
|
+
Style/TrailingCommaInHashLiteral:
|
356
|
+
Description: 'Checks for trailing comma in hash literals.'
|
357
|
+
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-trailing-array-commas'
|
358
|
+
EnforcedStyleForMultiline: comma
|
359
|
+
SupportedStylesForMultiline:
|
360
|
+
- comma
|
361
|
+
- consistent_comma
|
362
|
+
- no_comma
|
363
|
+
Enabled: true
|
364
|
+
|
365
|
+
Style/TrailingCommaInArrayLiteral:
|
366
|
+
Description: 'Checks for trailing comma in array literals.'
|
357
367
|
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-trailing-array-commas'
|
358
368
|
EnforcedStyleForMultiline: comma
|
359
369
|
SupportedStylesForMultiline:
|
@@ -450,7 +460,7 @@ Lint/CircularArgumentReference:
|
|
450
460
|
Description: "Don't refer to the keyword argument in the default value."
|
451
461
|
Enabled: false
|
452
462
|
|
453
|
-
|
463
|
+
Layout/ConditionPosition:
|
454
464
|
Description: >-
|
455
465
|
Checks for condition placed in a confusing position relative to
|
456
466
|
the keyword.
|
data/.travis.yml
CHANGED
data/CONTRIBUTING.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
Contributing to json_matchers
|
1
|
+
Contributing to `json_matchers`:
|
2
2
|
|
3
3
|
1. Fork the [official repository](https://github.com/thoughtbot/json_matchers/tree/master).
|
4
4
|
2. Make your changes in a topic branch.
|
@@ -6,5 +6,6 @@ Contributing to json_matchers:
|
|
6
6
|
|
7
7
|
Notes:
|
8
8
|
|
9
|
-
* Contributions without tests
|
9
|
+
* Contributions without tests covering the `RSpec` matchers _and_ the `Minitest`
|
10
|
+
assertions won't be accepted.
|
10
11
|
* Please don't update the Gem version.
|
data/Gemfile
CHANGED
data/NEWS.md
CHANGED
data/README.md
CHANGED
@@ -4,7 +4,7 @@ Validate the JSON returned by your Rails JSON APIs
|
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
7
|
-
Add this line to your application's Gemfile
|
7
|
+
Add this line to your application's `Gemfile`:
|
8
8
|
|
9
9
|
```ruby
|
10
10
|
group :test do
|
@@ -22,21 +22,45 @@ Or install it yourself as:
|
|
22
22
|
|
23
23
|
## Usage
|
24
24
|
|
25
|
-
Inspired by [Validating JSON Schemas with an RSpec Matcher]
|
25
|
+
Inspired by [Validating JSON Schemas with an RSpec Matcher][original-blog-post].
|
26
26
|
|
27
|
-
|
27
|
+
[original-blog-post]: (http://robots.thoughtbot.com/validating-json-schemas-with-an-rspec-matcher)
|
28
28
|
|
29
|
-
|
30
|
-
|
29
|
+
First, configure it in your test suite's helper file:
|
30
|
+
|
31
|
+
### Configure
|
32
|
+
|
33
|
+
#### RSpec
|
31
34
|
|
35
|
+
`spec/spec_helper.rb`
|
36
|
+
|
37
|
+
```ruby
|
32
38
|
require "json_matchers/rspec"
|
39
|
+
|
40
|
+
JsonMatchers.schema_root = "/spec/support/api/schemas"
|
33
41
|
```
|
34
42
|
|
35
|
-
|
43
|
+
#### Minitest
|
36
44
|
|
37
|
-
|
38
|
-
|
45
|
+
`test/test_helper.rb`
|
46
|
+
|
47
|
+
```ruby
|
48
|
+
require "minitest/autorun"
|
49
|
+
require "json_matchers/minitest/assertions"
|
50
|
+
|
51
|
+
JsonMatchers.schema_root = "/test/support/api/schemas"
|
52
|
+
|
53
|
+
Minitest::Test.send(:include, JsonMatchers::Minitest::Assertions)
|
54
|
+
```
|
55
|
+
|
56
|
+
### Declare
|
57
|
+
|
58
|
+
Declare your [JSON Schema](http://json-schema.org/example1.html) in the schema
|
59
|
+
directory.
|
39
60
|
|
61
|
+
`spec/support/api/schemas/posts.json` or `test/support/api/schemas/posts.json`:
|
62
|
+
|
63
|
+
```json
|
40
64
|
{
|
41
65
|
"type": "object",
|
42
66
|
"required": ["posts"],
|
@@ -56,11 +80,16 @@ Define your [JSON Schema](http://json-schema.org/example1.html) in the schema di
|
|
56
80
|
}
|
57
81
|
```
|
58
82
|
|
59
|
-
|
83
|
+
### Validate
|
60
84
|
|
61
|
-
|
62
|
-
# spec/requests/posts_spec.rb
|
85
|
+
#### RSpec
|
63
86
|
|
87
|
+
Validate a JSON response, a Hash, or a String against a JSON Schema with
|
88
|
+
`match_json_schema`:
|
89
|
+
|
90
|
+
`spec/requests/posts_spec.rb`
|
91
|
+
|
92
|
+
```ruby
|
64
93
|
describe "GET /posts" do
|
65
94
|
it "returns Posts" do
|
66
95
|
get posts_path, format: :json
|
@@ -71,18 +100,19 @@ describe "GET /posts" do
|
|
71
100
|
end
|
72
101
|
```
|
73
102
|
|
74
|
-
|
103
|
+
#### Minitest
|
75
104
|
|
76
|
-
|
77
|
-
|
105
|
+
Validate a JSON response, a Hash, or a String against a JSON Schema with
|
106
|
+
`assert_matches_json_schema`:
|
78
107
|
|
79
|
-
|
80
|
-
it "returns Posts" do
|
81
|
-
get posts_path, format: :json
|
108
|
+
`test/integration/posts_test.rb`
|
82
109
|
|
83
|
-
|
84
|
-
|
85
|
-
|
110
|
+
```ruby
|
111
|
+
def test_GET_posts_returns_Posts
|
112
|
+
get posts_path, format: :json
|
113
|
+
|
114
|
+
assert_equal response.status, 200
|
115
|
+
assert_matches_json_schema response, "posts"
|
86
116
|
end
|
87
117
|
```
|
88
118
|
|
@@ -90,9 +120,9 @@ end
|
|
90
120
|
|
91
121
|
The matcher accepts options, which it passes to the validator:
|
92
122
|
|
93
|
-
|
94
|
-
# spec/requests/posts_spec.rb
|
123
|
+
`spec/requests/posts_spec.rb`
|
95
124
|
|
125
|
+
```ruby
|
96
126
|
describe "GET /posts" do
|
97
127
|
it "returns Posts" do
|
98
128
|
get posts_path, format: :json
|
@@ -110,11 +140,11 @@ A list of available options can be found [here][options].
|
|
110
140
|
### Global matcher options
|
111
141
|
|
112
142
|
To configure the default options passed to *all* matchers, call
|
113
|
-
`JsonMatchers.configure
|
143
|
+
`JsonMatchers.configure`.
|
114
144
|
|
115
|
-
|
116
|
-
# spec/support/json_matchers.rb
|
145
|
+
`spec/support/json_matchers.rb`:
|
117
146
|
|
147
|
+
```rb
|
118
148
|
JsonMatchers.configure do |config|
|
119
149
|
config.options[:strict] = true
|
120
150
|
end
|
@@ -133,9 +163,9 @@ To DRY up your schema definitions, use JSON schema's `$ref`.
|
|
133
163
|
|
134
164
|
First, declare the singular version of your schema.
|
135
165
|
|
136
|
-
|
137
|
-
# spec/support/api/schemas/post.json
|
166
|
+
`spec/support/api/schemas/post.json`:
|
138
167
|
|
168
|
+
```json
|
139
169
|
{
|
140
170
|
"type": "object",
|
141
171
|
"required": ["id", "title", "body"],
|
@@ -149,9 +179,9 @@ First, declare the singular version of your schema.
|
|
149
179
|
|
150
180
|
Then, when you declare your collection schema, reference your singular schemas.
|
151
181
|
|
152
|
-
|
153
|
-
# spec/support/api/schemas/posts.json
|
182
|
+
`spec/support/api/schemas/posts.json`:
|
154
183
|
|
184
|
+
```json
|
155
185
|
{
|
156
186
|
"type": "object",
|
157
187
|
"required": ["posts"],
|
@@ -171,19 +201,6 @@ In this case `"post.json"` will be resolved relative to
|
|
171
201
|
|
172
202
|
To learn more about `$ref`, check out [Understanding JSON Schema Structuring](http://spacetelescope.github.io/understanding-json-schema/structuring.html)
|
173
203
|
|
174
|
-
## Configuration
|
175
|
-
|
176
|
-
By default, the schema directory is `spec/support/api/schemas`.
|
177
|
-
|
178
|
-
This can be configured via `JsonMatchers.schema_root`.
|
179
|
-
|
180
|
-
|
181
|
-
```ruby
|
182
|
-
# spec/support/json_matchers.rb
|
183
|
-
|
184
|
-
JsonMatchers.schema_root = "docs/api/schemas"
|
185
|
-
```
|
186
|
-
|
187
204
|
## Contributing
|
188
205
|
|
189
206
|
Please see [CONTRIBUTING].
|
@@ -191,7 +208,7 @@ Please see [CONTRIBUTING].
|
|
191
208
|
`json_matchers` was inspired by [Validating JSON Schemas with an
|
192
209
|
RSpec Matcher][blog post] by Laila Winner.
|
193
210
|
|
194
|
-
`json_matchers`
|
211
|
+
`json_matchers` is maintained by Sean Doyle.
|
195
212
|
|
196
213
|
Many improvements and bugfixes were contributed by the [open source community].
|
197
214
|
|
@@ -201,7 +218,7 @@ Many improvements and bugfixes were contributed by the [open source community].
|
|
201
218
|
|
202
219
|
## License
|
203
220
|
|
204
|
-
json_matchers is Copyright ©
|
221
|
+
`json_matchers` is Copyright © 2018 thoughtbot.
|
205
222
|
|
206
223
|
It is free software, and may be redistributed under the terms specified in the
|
207
224
|
[LICENSE] file.
|
data/Rakefile
CHANGED
@@ -1,9 +1,14 @@
|
|
1
1
|
require "bundler/gem_tasks"
|
2
2
|
require "rspec/core/rake_task"
|
3
|
+
require "rake/testtask"
|
3
4
|
|
4
5
|
RSpec::Core::RakeTask.new do |t|
|
5
6
|
t.pattern = "spec/**/*_spec.rb"
|
6
7
|
end
|
7
8
|
|
9
|
+
Rake::TestTask.new do |t|
|
10
|
+
t.test_files = FileList["test/**/*_test.rb"]
|
11
|
+
end
|
12
|
+
|
8
13
|
task(:default).clear
|
9
|
-
task default: [:spec]
|
14
|
+
task default: [:spec, :test]
|
data/json_matchers.gemspec
CHANGED
@@ -24,4 +24,7 @@ Gem::Specification.new do |spec|
|
|
24
24
|
spec.add_development_dependency "pry"
|
25
25
|
spec.add_development_dependency "rake", "~> 10.0"
|
26
26
|
spec.add_development_dependency "rspec", ">= 2.0"
|
27
|
+
spec.add_development_dependency "minitest"
|
28
|
+
spec.add_development_dependency "factory_bot", ">= 4.8"
|
29
|
+
spec.add_development_dependency "activesupport"
|
27
30
|
end
|
data/lib/json_matchers.rb
CHANGED
@@ -0,0 +1,68 @@
|
|
1
|
+
require "json"
|
2
|
+
require "json_matchers"
|
3
|
+
require "json_matchers/payload"
|
4
|
+
require "json_matchers/matcher"
|
5
|
+
|
6
|
+
module JsonMatchers
|
7
|
+
class Assertion
|
8
|
+
def initialize(schema_name, **options)
|
9
|
+
@schema_name = schema_name
|
10
|
+
@schema_path = JsonMatchers.path_to_schema(schema_name)
|
11
|
+
@matcher = Matcher.new(schema_path, options)
|
12
|
+
end
|
13
|
+
|
14
|
+
def valid?(json)
|
15
|
+
@payload = Payload.new(json)
|
16
|
+
|
17
|
+
matcher.matches?(payload.to_s)
|
18
|
+
end
|
19
|
+
|
20
|
+
def valid_failure_message
|
21
|
+
<<-FAIL
|
22
|
+
#{last_error_message}
|
23
|
+
|
24
|
+
---
|
25
|
+
|
26
|
+
expected
|
27
|
+
|
28
|
+
#{format_json(payload)}
|
29
|
+
|
30
|
+
to match schema "#{schema_name}":
|
31
|
+
|
32
|
+
#{format_json(schema_body)}
|
33
|
+
FAIL
|
34
|
+
end
|
35
|
+
|
36
|
+
def invalid_failure_message
|
37
|
+
<<-FAIL
|
38
|
+
#{last_error_message}
|
39
|
+
|
40
|
+
---
|
41
|
+
|
42
|
+
expected
|
43
|
+
|
44
|
+
#{format_json(payload)}
|
45
|
+
|
46
|
+
not to match schema "#{schema_name}":
|
47
|
+
|
48
|
+
#{format_json(schema_body)}
|
49
|
+
FAIL
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
attr_reader :payload, :matcher, :schema_name, :schema_path
|
55
|
+
|
56
|
+
def last_error_message
|
57
|
+
matcher.validation_failure_message
|
58
|
+
end
|
59
|
+
|
60
|
+
def schema_body
|
61
|
+
File.read(schema_path)
|
62
|
+
end
|
63
|
+
|
64
|
+
def format_json(json)
|
65
|
+
JSON.pretty_generate(JSON.parse(json.to_s))
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -8,8 +8,8 @@ module JsonMatchers
|
|
8
8
|
@options = default_options.merge(options)
|
9
9
|
end
|
10
10
|
|
11
|
-
def matches?(
|
12
|
-
validator = build_validator(
|
11
|
+
def matches?(payload)
|
12
|
+
validator = build_validator(payload)
|
13
13
|
|
14
14
|
self.errors = validator.validate!
|
15
15
|
|
@@ -34,10 +34,10 @@ module JsonMatchers
|
|
34
34
|
JsonMatchers.configuration.options || {}
|
35
35
|
end
|
36
36
|
|
37
|
-
def build_validator(
|
37
|
+
def build_validator(payload)
|
38
38
|
Validator.new(
|
39
39
|
options: options,
|
40
|
-
|
40
|
+
payload: payload,
|
41
41
|
schema_path: schema_path,
|
42
42
|
)
|
43
43
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require "json_matchers"
|
2
|
+
require "json_matchers/assertion"
|
3
|
+
|
4
|
+
module JsonMatchers
|
5
|
+
self.schema_root = File.join("test", "support", "api", "schemas")
|
6
|
+
|
7
|
+
module Minitest
|
8
|
+
module Assertions
|
9
|
+
def assert_matches_json_schema(payload, schema_name)
|
10
|
+
assertion = Assertion.new(schema_name)
|
11
|
+
|
12
|
+
payload_is_valid = assertion.valid?(payload)
|
13
|
+
|
14
|
+
assert payload_is_valid, -> { assertion.valid_failure_message }
|
15
|
+
end
|
16
|
+
|
17
|
+
def refute_matches_json_schema(payload, schema_name)
|
18
|
+
assertion = Assertion.new(schema_name)
|
19
|
+
|
20
|
+
payload_is_valid = assertion.valid?(payload)
|
21
|
+
|
22
|
+
refute payload_is_valid, -> { assertion.invalid_failure_message }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|