match_json 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6700101a6f7589f99d3ac22a5e22392cca6bef8b
4
+ data.tar.gz: e608c2d863253955e52214efad1bc0ff984c0352
5
+ SHA512:
6
+ metadata.gz: 59005a3e78998816e9fac442cf60296e5c9a7bb5e111ac787eb78129c8f22465e7b221aef64617014f8059102fd5b2b7346c4216fdf3a13a5b7c9f53c70f5341
7
+ data.tar.gz: 1cc241114b0cc43d5cec22b479b4b5823920d07e17cda729ea04688ca2121eefb8810df813146fcd2622b997d58c081b1ec4c2116a481e400bc7fcaf3701f961
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in match_json.gemspec
4
+ gemspec
5
+
6
+ gem 'rspec', git: 'https://github.com/rspec/rspec.git'
7
+ gem 'rspec-core', git: 'https://github.com/rspec/rspec-core.git'
8
+ gem 'rspec-mocks', git: 'https://github.com/rspec/rspec-mocks.git'
9
+ gem 'rspec-expectations', git: 'https://github.com/rspec/rspec-expectations.git'
10
+ gem 'rspec-support', git: 'https://github.com/rspec/rspec-support.git'
11
+
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Pavel Gabriel and White Payments Technologies FZE
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,94 @@
1
+ # MatchJson
2
+
3
+ Easily test your JSON in RSpec and Cucumber.
4
+
5
+ This matcher can't be the only tool when you test your JSON. We also
6
+ recommend to use [json-schema](https://github.com/ruby-json-schema/json-schema)
7
+ as a perfect companion to MatchJson.
8
+
9
+ ## Usage: RSpec
10
+
11
+ In RSpec we add this matcher: ```include_json```
12
+
13
+ So you can use it as follows:
14
+
15
+ ```ruby
16
+ it 'returns charge' do
17
+ get '/charges/#{charge.id}'
18
+
19
+ expect(response).to include_json(<<-JSON)
20
+ {
21
+ "id": "{uuid}",
22
+ "amount": 100,
23
+ "currency": "USD",
24
+ "created_at": "{date_time_iso8601}"
25
+ }
26
+ JSON
27
+ end
28
+
29
+ it 'returns list of charges' do
30
+ get '/charges'
31
+
32
+ expect(response).to include_json(<<-JSON)
33
+ {
34
+ "charges": [
35
+ {
36
+ "id": "{uuid}",
37
+ "amount": 100,
38
+ "currency": "USD",
39
+ "created_at": "{date_time_iso8601}"
40
+ }
41
+ ]
42
+ }
43
+ JSON
44
+ end
45
+ ```
46
+
47
+ As you can see for cases when you do not know the value of some properties like
48
+ ```id``` or ```created_at``` or even ```email``` you can use 'pattern' instead.
49
+
50
+ You can use the following predefined patterns:
51
+
52
+ * date_time_iso8601
53
+ * date
54
+ * uuid
55
+ * email
56
+ * string
57
+
58
+ You also can add your own pattern in this way:
59
+
60
+ ```ruby
61
+ MatchJson::Matchers::IncludeJson::PATTERNS['id'] = /\A\d{6}\z/
62
+ ```
63
+
64
+ and then use it in your spec:
65
+
66
+ ```ruby
67
+ it 'uses patten to check value' do
68
+ expect(%Q({"one": "123456"})).to include_json(%Q({"one": "{id}"}))
69
+ end
70
+ ```
71
+
72
+ ## Installation
73
+
74
+ Add this line to your application's Gemfile:
75
+
76
+ ```ruby
77
+ gem 'match_json'
78
+ ```
79
+
80
+ And then execute:
81
+
82
+ $ bundle
83
+
84
+ Or install it yourself as:
85
+
86
+ $ gem install match_json
87
+
88
+ ## Contributing
89
+
90
+ 1. Fork it ( https://github.com/[my-github-username]/match_json/fork )
91
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
92
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
93
+ 4. Push to the branch (`git push origin my-new-feature`)
94
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,98 @@
1
+
2
+ module MatchJson
3
+ module Matchers
4
+ class IncludeJson
5
+ PATTERNS = {
6
+ 'date_time_iso8601' => /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/,
7
+ 'date' => /^\d{4}-\d{2}-\d{2}/,
8
+ 'uuid' => /\h{32}/,
9
+ 'email' => /\A[-a-z0-9_+\.]+\@([-a-z0-9]+\.)+[a-z0-9]{2,6}\z/i,
10
+ 'string' => /\A.+\z/i
11
+ }
12
+
13
+ def initialize(expected_json)
14
+ @expected_json = JSON.parse(expected_json)
15
+ end
16
+
17
+ def matches?(actual_json)
18
+ @actual_json = actual_json.respond_to?(:body) ? JSON.parse(actual_json.body) : JSON.parse(actual_json)
19
+
20
+ match = catch(:match) { json_included?(@actual_json, @expected_json) }
21
+ end
22
+
23
+ def failure_message
24
+ @failure_message
25
+ end
26
+
27
+ def failure_message_when_negated
28
+ "does not support negation"
29
+ end
30
+
31
+ private
32
+
33
+ def json_included?(actual, expected)
34
+ equal_value?(actual, expected)
35
+ end
36
+
37
+ def hash_included?(actual, expected, nested, raise_error)
38
+ expected.each do |key, value|
39
+ if (!equal_value?(actual[key], value, "#{nested} > #{key}", raise_error))
40
+ @failure_message = %Q("#{key}"=>#{value} was not found in\n #{actual})
41
+
42
+ if raise_error
43
+ throw(:match, false)
44
+ else
45
+ return false
46
+ end
47
+ end
48
+ end
49
+ end
50
+
51
+ def array_included?(actual, expected, nested, raise_error)
52
+ expected.each do |value|
53
+ if (!actual.any? { |actual_value| equal_value?(actual_value, value, nested, false) })
54
+ @failure_message = %Q("#{value}" was not found in\n )
55
+ @failure_message << %Q("#{nested}"=>) if !nested.empty?
56
+ @failure_message << "#{actual}"
57
+
58
+ if raise_error
59
+ throw(:match, false)
60
+ else
61
+ return false
62
+ end
63
+ end
64
+ end
65
+ end
66
+
67
+ def equal_value?(actual, expected, nested = '', raise_error = true)
68
+ case expected
69
+ when Array then array_included?(actual, expected, nested, raise_error)
70
+ when Hash then hash_included?(actual, expected, nested, raise_error)
71
+ when String then compare_with_pattern(expected, actual)
72
+ else
73
+ actual == expected
74
+ end
75
+ end
76
+
77
+ def compare_with_pattern(value, actual)
78
+ case
79
+ when regexp?(value)
80
+ reg_exp = value.match(/{re:(.*)}/)[1]
81
+ actual =~ Regexp.new(reg_exp)
82
+ when pattern?(value)
83
+ actual =~ PATTERNS["#{value.gsub('{', '').gsub('}', '')}"]
84
+ else
85
+ value == actual
86
+ end
87
+ end
88
+
89
+ def pattern?(str)
90
+ !!(str =~ /\A\{\w+\}\z/)
91
+ end
92
+
93
+ def regexp?(str)
94
+ !!(str =~ /\A\{re:.+\}\z/)
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,13 @@
1
+ require 'match_json/matchers/include_json'
2
+
3
+ module MatchJson
4
+ module Matchers
5
+ def include_json(json)
6
+ MatchJson::Matchers::IncludeJson.new(json)
7
+ end
8
+ end
9
+ end
10
+
11
+ RSpec.configure do |config|
12
+ config.include MatchJson::Matchers
13
+ end
@@ -0,0 +1,3 @@
1
+ module MatchJson
2
+ VERSION = "0.0.1"
3
+ end
data/lib/match_json.rb ADDED
@@ -0,0 +1,7 @@
1
+ require "json"
2
+ require "match_json/version"
3
+ require "match_json/matchers"
4
+
5
+ module MatchJson
6
+ # Your code goes here...
7
+ end
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'match_json/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "match_json"
8
+ spec.version = MatchJson::VERSION
9
+ spec.authors = ["Pavel Gabriel", "White Payments"]
10
+ spec.email = ["alovak@gmail.com"]
11
+ spec.summary = %q{RSpec matcher for JSON documents}
12
+ spec.description = %q{Easily test your JSON in RSpec and Cucumber.}
13
+ spec.homepage = "https://github.com/WhitePayments/match_json"
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_development_dependency "bundler", "~> 1.7"
22
+ spec.add_development_dependency "rake", "~> 10.0"
23
+ end
@@ -0,0 +1,81 @@
1
+ require 'spec_helper'
2
+
3
+ describe "include_json" do
4
+ it 'passes when object is partially included' do
5
+ expect(%Q({ "one": 1, "two": 2 })).to include_json(%Q({ "one": 1 }))
6
+ end
7
+
8
+ it "fails when expected object is not included" do
9
+ expect {
10
+ expect(%Q({ "one": 1 })).to include_json(%Q({ "one": 2 }))
11
+ }.to fail_with(%Q("one"=>2 was not found in\n {"one"=>1}))
12
+ end
13
+
14
+ it 'passes when array is partially included' do
15
+ expect(%Q([1, 2, 3])).to include_json(%Q([3, 2]))
16
+ expect(%Q([1, 2, 3])).to include_json(%Q([1, 2, 3]))
17
+ end
18
+
19
+ it 'fails when there is no such array' do
20
+ expect {
21
+ expect(%Q([1, 2, 3])).to include_json(%Q([3, 5]))
22
+ }.to fail_with(%Q("5" was not found in\n [1, 2, 3]))
23
+ end
24
+
25
+ context 'when object contains array' do
26
+ it 'passes when array included' do
27
+ expect(%Q({ "array" : [1, 2, 3] })).to include_json(%Q({ "array" : [3, 2, 1] }))
28
+ end
29
+
30
+ it 'fails with there is no such array' do
31
+ expect {
32
+ expect(%Q({ "array" : [1, 2, 3] })).to include_json(%Q({ "array" : [5, 1] }))
33
+ }.to fail_with(%Q("5" was not found in\n " > array"=>[1, 2, 3]))
34
+ end
35
+ end
36
+
37
+ context 'when array contains object' do
38
+ it 'passes when object included in array' do
39
+ expect(%Q([ { "one": 1 }, { "two": 2 }])).to include_json(%Q([ { "one": 1 }]))
40
+ end
41
+
42
+ it 'fails when there is no such object in array' do
43
+ expect {
44
+ expect(%Q([ { "one": 1 }, { "two": 2 }])).to include_json(%Q([ { "one": 2 }]))
45
+ }.to fail_with(%Q(\"{"one"=>2}\" was not found in\n [{"one"=>1}, {"two"=>2}]))
46
+ end
47
+ end
48
+
49
+ context 'in multilevel structure' do
50
+ it 'fails if object was not found' do
51
+ expect {
52
+ expect(%Q([ { "one": { "array": [1,2,3] } } ])).to include_json(%Q([ { "one": { "array": [1,2,3,4] } } ]))
53
+ }.to fail_with(%Q("{"one"=>{"array"=>[1, 2, 3, 4]}}" was not found in\n [{"one"=>{"array"=>[1, 2, 3]}}]))
54
+ end
55
+ end
56
+
57
+ context 'with pattern' do
58
+ it 'passes when value matches pattern' do
59
+ expect(%Q({"one": "test@exmaple.com"})).to include_json(%Q({"one": "{email}"}))
60
+ expect(%Q({"one": "2020-12-22"})).to include_json(%Q({"one": "{date}"}))
61
+ end
62
+ end
63
+
64
+ context 'with custom pattern' do
65
+ before do
66
+ MatchJson::Matchers::IncludeJson::PATTERNS['id'] = /\A\d{6}\z/
67
+ end
68
+
69
+ after do
70
+ MatchJson::Matchers::IncludeJson::PATTERNS.delete('id')
71
+ end
72
+
73
+ it 'uses patten to check value' do
74
+ expect(%Q({"one": "123456"})).to include_json(%Q({"one": "{id}"}))
75
+
76
+ expect {
77
+ expect(%Q({"one": "abcdef"})).to include_json(%Q({"one": "{id}"}))
78
+ }.to fail_with(%Q("one"=>{id} was not found in\n {"one"=>"abcdef"}))
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,10 @@
1
+ require 'match_json'
2
+ require 'byebug'
3
+
4
+ Dir['./spec/support/**/*'].each do |f|
5
+ require f.sub(%r{\./spec/}, '')
6
+ end
7
+
8
+ RSpec.configure do |config|
9
+ config.include RSpec::Matchers::FailMatchers
10
+ end
@@ -0,0 +1,41 @@
1
+ module RSpec
2
+ module Matchers
3
+ # Matchers for testing RSpec matchers. Include them with:
4
+ #
5
+ # require 'rspec/matchers/fail_matchers'
6
+ # RSpec.configure do |config|
7
+ # config.include RSpec::Matchers::FailMatchers
8
+ # end
9
+ #
10
+ module FailMatchers
11
+ # Matches if an expectation fails
12
+ #
13
+ # @example
14
+ # expect { some_expectation }.to fail
15
+ def fail
16
+ raise_error(RSpec::Expectations::ExpectationNotMetError)
17
+ end
18
+
19
+ # Matches if an expectation fails with the provided message
20
+ #
21
+ # @example
22
+ # expect { some_expectation }.to fail_with("some failure message")
23
+ # expect { some_expectation }.to fail_with(/some failure message/)
24
+ def fail_with(message)
25
+ raise_error(RSpec::Expectations::ExpectationNotMetError, message)
26
+ end
27
+
28
+ # Matches if an expectation fails including the provided message
29
+ #
30
+ # @example
31
+ # expect { some_expectation }.to fail_including("portion of some failure message")
32
+ def fail_including(snippet)
33
+ raise_error(
34
+ RSpec::Expectations::ExpectationNotMetError,
35
+ a_string_including(snippet)
36
+ )
37
+ end
38
+ end
39
+ end
40
+ end
41
+
metadata ADDED
@@ -0,0 +1,89 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: match_json
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Pavel Gabriel
8
+ - White Payments
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2015-02-27 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '1.7'
21
+ type: :development
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: '1.7'
28
+ - !ruby/object:Gem::Dependency
29
+ name: rake
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: '10.0'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '10.0'
42
+ description: Easily test your JSON in RSpec and Cucumber.
43
+ email:
44
+ - alovak@gmail.com
45
+ executables: []
46
+ extensions: []
47
+ extra_rdoc_files: []
48
+ files:
49
+ - ".gitignore"
50
+ - Gemfile
51
+ - LICENSE.txt
52
+ - README.md
53
+ - Rakefile
54
+ - lib/match_json.rb
55
+ - lib/match_json/matchers.rb
56
+ - lib/match_json/matchers/include_json.rb
57
+ - lib/match_json/version.rb
58
+ - match_json.gemspec
59
+ - spec/match_json/matchers_spec.rb
60
+ - spec/spec_helper.rb
61
+ - spec/support/fail_matchers.rb
62
+ homepage: https://github.com/WhitePayments/match_json
63
+ licenses:
64
+ - MIT
65
+ metadata: {}
66
+ post_install_message:
67
+ rdoc_options: []
68
+ require_paths:
69
+ - lib
70
+ required_ruby_version: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ required_rubygems_version: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ version: '0'
80
+ requirements: []
81
+ rubyforge_project:
82
+ rubygems_version: 2.4.5
83
+ signing_key:
84
+ specification_version: 4
85
+ summary: RSpec matcher for JSON documents
86
+ test_files:
87
+ - spec/match_json/matchers_spec.rb
88
+ - spec/spec_helper.rb
89
+ - spec/support/fail_matchers.rb