json-matchers 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: be6efc3180dbb7fd3f49c438edb2c1d5c096342d
4
- data.tar.gz: 1808696767e661d8393224272dd30a7cc5dd9a23
3
+ metadata.gz: bb439f8416d8a3a906aa121c633bc82bd63a57c8
4
+ data.tar.gz: 8269af55c9374e98ea6329aaab7a7f46c8f028ef
5
5
  SHA512:
6
- metadata.gz: ed7c67b4b54f84cf64cabe106c54aac6da88fda5432e948e7bf993a8e5caef1aa20fa3a8a151eedc0efff256d6646cb12c4980df3161d1d91b44fe60e40b4c29
7
- data.tar.gz: 6575e174274e7be924af6dce791b590d10d6f4fb16d392c24e497afe8c171c7a892f0238cc37f3f1d3261c98ad99d66ebf691221f0312c3132a0e80f23647d33
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
- You can even embed schemas inside other schemas!
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, embed the singular schema with
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": <%= schema_for("post") %>
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/shoulda-matchers-json.rb
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]/shoulda-matchers-json/fork )
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 match_response_schema(schema_name)
14
- schema_parser = SchemaParser.new(schema_root)
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
 
@@ -1,7 +1,6 @@
1
1
  module JSON
2
2
  module Matchers
3
- InvalidError = Class.new(StandardError)
4
- DoesNotMatch = Class.new(InvalidError)
3
+ InvalidSchemaError = Class.new(StandardError)
5
4
  MissingSchema = Class.new(Errno::ENOENT)
6
5
  end
7
6
  end
@@ -2,19 +2,15 @@ require "json-schema"
2
2
 
3
3
  module JSON
4
4
  module Matchers
5
- Matcher = Struct.new(:schema) do
5
+ Matcher = Struct.new(:schema_path) do
6
6
  def matches?(response)
7
- JSON::Validator.validate!(json_schema, response.body, strict: true)
7
+ @response = response
8
+
9
+ JSON::Validator.validate!(schema_path.to_s, response.body, strict: true)
8
10
  rescue JSON::Schema::ValidationError
9
- raise DoesNotMatch, response.body
11
+ false
10
12
  rescue JSON::ParserError
11
- raise InvalidError
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
@@ -1,5 +1,10 @@
1
1
  if RSpec.respond_to?(:configure)
2
- RSpec.configure do |config|
3
- config.include JSON::Matchers
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
@@ -1,5 +1,5 @@
1
1
  module JSON
2
2
  module Matchers
3
- VERSION = "0.0.1"
3
+ VERSION = "0.1.0"
4
4
  end
5
5
  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::InvalidError)
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 ERB" do
50
- create_schema "array_schema", <<-JSON.strip_heredoc
51
- {
52
- "type": "array",
53
- "items": <%= { type: "string" }.to_json %>
54
- }
55
- JSON
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
- expect(response_for(["valid"])).to match_response_schema("array_schema")
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
- original_schema_root = JSON::Matchers.schema_root
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 = original_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.1
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