json-matchers 0.0.1 → 0.1.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 +4 -4
- data/NEWS.md +7 -0
- data/README.md +14 -6
- data/lib/json/matchers.rb +2 -6
- data/lib/json/matchers/errors.rb +1 -2
- data/lib/json/matchers/matcher.rb +6 -10
- data/lib/json/matchers/rspec.rb +7 -2
- data/lib/json/matchers/version.rb +1 -1
- data/spec/json/matchers/match_response_schema_spec.rb +20 -15
- data/spec/spec_helper.rb +0 -2
- data/spec/support/file_helpers.rb +4 -3
- metadata +1 -4
- data/lib/json/matchers/schema_parser.rb +0 -22
- data/spec/json/matchers/schema_parser_spec.rb +0 -68
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: bb439f8416d8a3a906aa121c633bc82bd63a57c8
|
|
4
|
+
data.tar.gz: 8269af55c9374e98ea6329aaab7a7f46c8f028ef
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4b14aa4ae10098b51424ecd895385c49c5227704ac18bdd452acb18ab81a1ed4c8142e79374eda069991fe283532d35c4d72c6006626697321199088b64710be
|
|
7
|
+
data.tar.gz: 00a674630bea1085faaceefddb183b13ea7ee039125b6ec1b0c930d3bf8116d80c0ae44da84b7103a2f414f62f89bb7975e678e74defac3320d86730615b0460
|
data/NEWS.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
# 0.1.0
|
|
2
|
+
|
|
3
|
+
## Breaking Changes
|
|
4
|
+
|
|
5
|
+
* Remove `schema_for` in favor of using `$ref`. To learn more about `$ref`,
|
|
6
|
+
check out [Understanding JSON Schema Structuring](http://spacetelescope.github.io/understanding-json-schema/structuring.html)
|
|
7
|
+
|
|
1
8
|
# 0.0.1
|
|
2
9
|
|
|
3
10
|
## Features
|
data/README.md
CHANGED
|
@@ -65,7 +65,9 @@ describe "GET /posts" do
|
|
|
65
65
|
end
|
|
66
66
|
```
|
|
67
67
|
|
|
68
|
-
|
|
68
|
+
### Embedding other Schemas
|
|
69
|
+
|
|
70
|
+
To DRY up your schema definitions, use JSON schema's `$ref`.
|
|
69
71
|
|
|
70
72
|
First, declare the singular version of your schema.
|
|
71
73
|
|
|
@@ -83,8 +85,7 @@ First, declare the singular version of your schema.
|
|
|
83
85
|
}
|
|
84
86
|
```
|
|
85
87
|
|
|
86
|
-
Then, when you declare your collection schema,
|
|
87
|
-
`ERB` and `schema_for`!
|
|
88
|
+
Then, when you declare your collection schema, reference your singular schemas.
|
|
88
89
|
|
|
89
90
|
```json
|
|
90
91
|
# spec/support/api/schemas/posts.json
|
|
@@ -95,12 +96,19 @@ Then, when you declare your collection schema, embed the singular schema with
|
|
|
95
96
|
"properties": {
|
|
96
97
|
"posts": {
|
|
97
98
|
"type": "array",
|
|
98
|
-
"items":
|
|
99
|
+
"items": { "$ref": "post.json" }
|
|
99
100
|
}
|
|
100
101
|
}
|
|
101
102
|
}
|
|
102
103
|
```
|
|
103
104
|
|
|
105
|
+
NOTE: `$ref` resolves paths relative to the schema in question.
|
|
106
|
+
|
|
107
|
+
In this case `"post.json"` will be resolved relative to
|
|
108
|
+
`"spec/support/api/schemas"`.
|
|
109
|
+
|
|
110
|
+
To learn more about `$ref`, check out [Understanding JSON Schema Structuring](http://spacetelescope.github.io/understanding-json-schema/structuring.html)
|
|
111
|
+
|
|
104
112
|
## Configuration
|
|
105
113
|
|
|
106
114
|
By default, the schema directory is `spec/support/api/schemas`.
|
|
@@ -109,14 +117,14 @@ This can be configured via `JSON::Matchers.schema_root`.
|
|
|
109
117
|
|
|
110
118
|
|
|
111
119
|
```ruby
|
|
112
|
-
# spec/support/
|
|
120
|
+
# spec/support/json-matchers.rb
|
|
113
121
|
|
|
114
122
|
JSON::Matchers.schema_root = "docs/api/schemas"
|
|
115
123
|
```
|
|
116
124
|
|
|
117
125
|
## Contributing
|
|
118
126
|
|
|
119
|
-
1. Fork it ( https://github.com/[my-github-username]/
|
|
127
|
+
1. Fork it ( https://github.com/[my-github-username]/json-matchers/fork )
|
|
120
128
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
|
121
129
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
|
122
130
|
4. Push to the branch (`git push origin my-new-feature`)
|
data/lib/json/matchers.rb
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
require "json/matchers/version"
|
|
2
2
|
require "json/matchers/matcher"
|
|
3
|
-
require "json/matchers/schema_parser"
|
|
4
3
|
require "json/matchers/errors"
|
|
5
4
|
require "active_support/all"
|
|
6
5
|
|
|
@@ -10,12 +9,9 @@ module JSON
|
|
|
10
9
|
|
|
11
10
|
self.schema_root = "#{Dir.pwd}/spec/support/api/schemas"
|
|
12
11
|
|
|
13
|
-
def
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
Matcher.new(schema_parser.schema_for(schema_name))
|
|
12
|
+
def self.path_to_schema(schema_name)
|
|
13
|
+
Pathname(schema_root).join("#{schema_name}.json")
|
|
17
14
|
end
|
|
18
|
-
alias match_json_schema match_response_schema
|
|
19
15
|
end
|
|
20
16
|
end
|
|
21
17
|
|
data/lib/json/matchers/errors.rb
CHANGED
|
@@ -2,19 +2,15 @@ require "json-schema"
|
|
|
2
2
|
|
|
3
3
|
module JSON
|
|
4
4
|
module Matchers
|
|
5
|
-
Matcher = Struct.new(:
|
|
5
|
+
Matcher = Struct.new(:schema_path) do
|
|
6
6
|
def matches?(response)
|
|
7
|
-
|
|
7
|
+
@response = response
|
|
8
|
+
|
|
9
|
+
JSON::Validator.validate!(schema_path.to_s, response.body, strict: true)
|
|
8
10
|
rescue JSON::Schema::ValidationError
|
|
9
|
-
|
|
11
|
+
false
|
|
10
12
|
rescue JSON::ParserError
|
|
11
|
-
raise
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
private
|
|
15
|
-
|
|
16
|
-
def json_schema
|
|
17
|
-
JSON.parse(schema)
|
|
13
|
+
raise InvalidSchemaError
|
|
18
14
|
end
|
|
19
15
|
end
|
|
20
16
|
end
|
data/lib/json/matchers/rspec.rb
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
if RSpec.respond_to?(:configure)
|
|
2
|
-
RSpec.
|
|
3
|
-
|
|
2
|
+
RSpec::Matchers.define :match_response_schema do |schema_name|
|
|
3
|
+
match do |response|
|
|
4
|
+
schema_path = JSON::Matchers.path_to_schema(schema_name)
|
|
5
|
+
matcher = JSON::Matchers::Matcher.new(schema_path)
|
|
6
|
+
|
|
7
|
+
matcher.matches?(response)
|
|
8
|
+
end
|
|
4
9
|
end
|
|
5
10
|
end
|
|
@@ -4,7 +4,7 @@ describe JSON::Matchers, "#match_response_schema" do
|
|
|
4
4
|
|
|
5
5
|
expect {
|
|
6
6
|
expect(response_for("")).to match_response_schema("foo")
|
|
7
|
-
}.to raise_error(JSON::Matchers::
|
|
7
|
+
}.to raise_error(JSON::Matchers::InvalidSchemaError)
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
it "does not fail with an empty JSON body" do
|
|
@@ -19,9 +19,7 @@ describe JSON::Matchers, "#match_response_schema" do
|
|
|
19
19
|
required: ["foo"],
|
|
20
20
|
})
|
|
21
21
|
|
|
22
|
-
expect
|
|
23
|
-
expect(response_for({})).to match_response_schema("array_schema")
|
|
24
|
-
}.to raise_error(JSON::Matchers::DoesNotMatch, /{}/)
|
|
22
|
+
expect(response_for({})).not_to match_response_schema("array_schema")
|
|
25
23
|
end
|
|
26
24
|
|
|
27
25
|
it "fails when the body contains a property with the wrong type" do
|
|
@@ -32,9 +30,7 @@ describe JSON::Matchers, "#match_response_schema" do
|
|
|
32
30
|
}
|
|
33
31
|
})
|
|
34
32
|
|
|
35
|
-
expect
|
|
36
|
-
expect(response_for({foo: 1})).to match_response_schema("array_schema")
|
|
37
|
-
}.to raise_error(JSON::Matchers::DoesNotMatch, /{"foo":1}/)
|
|
33
|
+
expect(response_for({foo: 1})).not_to match_response_schema("array_schema")
|
|
38
34
|
end
|
|
39
35
|
|
|
40
36
|
it "does not fail when the schema matches" do
|
|
@@ -46,14 +42,23 @@ describe JSON::Matchers, "#match_response_schema" do
|
|
|
46
42
|
expect(response_for(["valid"])).to match_response_schema("array_schema")
|
|
47
43
|
end
|
|
48
44
|
|
|
49
|
-
it "supports
|
|
50
|
-
create_schema
|
|
51
|
-
|
|
52
|
-
"
|
|
53
|
-
"
|
|
54
|
-
|
|
55
|
-
|
|
45
|
+
it "supports $ref" do
|
|
46
|
+
create_schema("single", {
|
|
47
|
+
"type" => "object",
|
|
48
|
+
"required" => ["foo"],
|
|
49
|
+
"properties" => {
|
|
50
|
+
"foo" => { "type" => "string" }
|
|
51
|
+
}
|
|
52
|
+
})
|
|
53
|
+
create_schema("collection", {
|
|
54
|
+
"type" => "array",
|
|
55
|
+
"items" => { "$ref" => "single.json" }
|
|
56
|
+
})
|
|
56
57
|
|
|
57
|
-
|
|
58
|
+
valid_response = response_for([{foo: "is a string"}])
|
|
59
|
+
invalid_response = response_for([{foo: 0}])
|
|
60
|
+
|
|
61
|
+
expect(valid_response).to match_response_schema("collection")
|
|
62
|
+
expect(invalid_response).not_to match_response_schema("collection")
|
|
58
63
|
end
|
|
59
64
|
end
|
data/spec/spec_helper.rb
CHANGED
|
@@ -3,9 +3,7 @@ require "json/matchers"
|
|
|
3
3
|
Dir["./spec/support/*"].each { |file| require file }
|
|
4
4
|
|
|
5
5
|
RSpec.configure do |config|
|
|
6
|
-
config.include JSON::Matchers
|
|
7
6
|
config.expect_with :rspec do |expectations|
|
|
8
|
-
|
|
9
7
|
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
|
10
8
|
end
|
|
11
9
|
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
module FileHelpers
|
|
2
|
+
ORIGINAL_SCHEMA_ROOT = JSON::Matchers.schema_root
|
|
3
|
+
|
|
2
4
|
def create_schema(name, json)
|
|
3
5
|
File.open("#{schema_root}/#{name}.json", "w") do |file|
|
|
4
6
|
case json
|
|
@@ -29,13 +31,12 @@ RSpec.configure do |config|
|
|
|
29
31
|
config.include FileHelpers
|
|
30
32
|
|
|
31
33
|
config.around do |example|
|
|
32
|
-
|
|
33
|
-
JSON::Matchers.schema_root = "#{Dir.pwd}/spec/fixtures/schemas"
|
|
34
|
+
JSON::Matchers.schema_root = File.join(Dir.pwd, "spec", "fixtures", "schemas")
|
|
34
35
|
FileUtils.mkdir_p(JSON::Matchers.schema_root)
|
|
35
36
|
|
|
36
37
|
example.run
|
|
37
38
|
|
|
38
39
|
FileUtils.rm_rf(JSON::Matchers.schema_root)
|
|
39
|
-
JSON::Matchers.schema_root =
|
|
40
|
+
JSON::Matchers.schema_root = FileHelpers::ORIGINAL_SCHEMA_ROOT
|
|
40
41
|
end
|
|
41
42
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: json-matchers
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0
|
|
4
|
+
version: 0.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Sean Doyle
|
|
@@ -114,10 +114,8 @@ files:
|
|
|
114
114
|
- lib/json/matchers/errors.rb
|
|
115
115
|
- lib/json/matchers/matcher.rb
|
|
116
116
|
- lib/json/matchers/rspec.rb
|
|
117
|
-
- lib/json/matchers/schema_parser.rb
|
|
118
117
|
- lib/json/matchers/version.rb
|
|
119
118
|
- spec/json/matchers/match_response_schema_spec.rb
|
|
120
|
-
- spec/json/matchers/schema_parser_spec.rb
|
|
121
119
|
- spec/spec_helper.rb
|
|
122
120
|
- spec/support/file_helpers.rb
|
|
123
121
|
homepage: https://github.com/seanpdoyle/json-matchers
|
|
@@ -146,7 +144,6 @@ specification_version: 4
|
|
|
146
144
|
summary: Validate your Rails JSON API's JSON
|
|
147
145
|
test_files:
|
|
148
146
|
- spec/json/matchers/match_response_schema_spec.rb
|
|
149
|
-
- spec/json/matchers/schema_parser_spec.rb
|
|
150
147
|
- spec/spec_helper.rb
|
|
151
148
|
- spec/support/file_helpers.rb
|
|
152
149
|
has_rdoc:
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
module JSON
|
|
2
|
-
module Matchers
|
|
3
|
-
class SchemaParser
|
|
4
|
-
|
|
5
|
-
attr_reader :schema_path
|
|
6
|
-
|
|
7
|
-
def initialize(schema_path)
|
|
8
|
-
@schema_path = Pathname(schema_path)
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
def schema_for(schema_name)
|
|
12
|
-
file = schema_path.join("#{schema_name}.json")
|
|
13
|
-
|
|
14
|
-
if file.exist?
|
|
15
|
-
ERB.new(file.read).result(binding)
|
|
16
|
-
else
|
|
17
|
-
raise MissingSchema, file.to_s
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
require "json/matchers/schema_parser"
|
|
2
|
-
|
|
3
|
-
describe JSON::Matchers::SchemaParser do
|
|
4
|
-
describe "#schema_for" do
|
|
5
|
-
it "returns the JSON string for a given schema" do
|
|
6
|
-
create_schema("foo", { type: "array" })
|
|
7
|
-
|
|
8
|
-
schema_parser = JSON::Matchers::SchemaParser.new(schema_root)
|
|
9
|
-
|
|
10
|
-
expect(schema_parser.schema_for("foo")).to eq '{"type":"array"}'
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
it "can embed other schemas" do
|
|
14
|
-
create_schema "post", <<-JSON.strip
|
|
15
|
-
{
|
|
16
|
-
"type": "object",
|
|
17
|
-
"required": ["id", "title", "body"],
|
|
18
|
-
"properties": {
|
|
19
|
-
"id": { "type": "integer" },
|
|
20
|
-
"title": { "type": "string" },
|
|
21
|
-
"body": { "type": "string" }
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
JSON
|
|
25
|
-
create_schema "posts", <<-JSON.strip
|
|
26
|
-
{
|
|
27
|
-
"type": "object",
|
|
28
|
-
"required": ["posts"],
|
|
29
|
-
"properties": {
|
|
30
|
-
"posts": {
|
|
31
|
-
"type": "array",
|
|
32
|
-
"items": <%= schema_for("post") %>
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
JSON
|
|
37
|
-
|
|
38
|
-
schema_parser = JSON::Matchers::SchemaParser.new(schema_root)
|
|
39
|
-
schema = schema_parser.schema_for("posts")
|
|
40
|
-
|
|
41
|
-
expect(JSON.parse(schema)).to eq({
|
|
42
|
-
"type" => "object",
|
|
43
|
-
"required" => ["posts"],
|
|
44
|
-
"properties" => {
|
|
45
|
-
"posts" => {
|
|
46
|
-
"type" => "array",
|
|
47
|
-
"items" => {
|
|
48
|
-
"type" => "object",
|
|
49
|
-
"required" => ["id", "title", "body"],
|
|
50
|
-
"properties" => {
|
|
51
|
-
"id" => { "type" => "integer" },
|
|
52
|
-
"title" => { "type" => "string" },
|
|
53
|
-
"body" => { "type" => "string" }
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
})
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
it "fails when the schema is missing" do
|
|
62
|
-
schema_parser = JSON::Matchers::SchemaParser.new(schema_root)
|
|
63
|
-
expect {
|
|
64
|
-
schema_parser.schema_for("missing")
|
|
65
|
-
}.to raise_error(JSON::Matchers::MissingSchema, /missing.json/)
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
end
|