json_matchers 0.7.3 → 0.8.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 +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
|