shoulda_render_json 0.0.2

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: fe7eea331763e3fd06b7087a3559d028d878ecb8
4
+ data.tar.gz: 6c40596a0536786361d6851fbfcef87af00d1999
5
+ SHA512:
6
+ metadata.gz: 3e12b950d64609a53a34684d6dce5023d41a3746ed77edb339ed2ba051e0723ad3069556177ed0c6b5fa07c1081db6aec761ff08205b0ce9cc0c637101ac7c29
7
+ data.tar.gz: 2f34610282d32c4883730e769af5785bc99acb58f006e7aaaf4c63566709bf41360f04cb42d1f2c61d36408b1258702d72281279be7292da2c697a40e55253c4
data/.gitignore ADDED
@@ -0,0 +1,23 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
23
+ .DS_Store
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in shoulda_render_json.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 RSL
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,69 @@
1
+ # Shoulda RenderJson
2
+
3
+ Shoulda macros for making very basic assertions about JSON responses
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'shoulda_render_json', group: :test
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install shoulda_render_json
18
+
19
+ ## Usage
20
+
21
+ I'm going to presume you're already familiar with using Shoulda macros.
22
+ The most basic assertion for `render_json` will be that your response's content-type is
23
+ 'application/json' (Rails' default JSON content-type) and that there is a root-level node
24
+ named "foo" in the JSON.
25
+
26
+ ```ruby
27
+ should render_json('foo')
28
+ ```
29
+
30
+ Voilà! That's probably not too useful on its own though. Let's add some child node checks!
31
+
32
+ ```ruby
33
+ should render_json('foo', required: 'bar', forbidden: 'baz')
34
+ ```
35
+
36
+ Predictably this adds two additional assertions to that base assertion. First, that the node for
37
+ "foo" is required to have a child node named "bar". Second, that the node for "foo" is prohibited
38
+ from having a child node named "baz". Both of these values can be arrays as well as strings as seen
39
+ below.
40
+
41
+ ```ruby
42
+ should render_json('foo', required: %w{bar baz})
43
+ ```
44
+
45
+ Sometimes, you may need to make assertions on Arrays inside JSON responses and not just Hash/Objects.
46
+ I've got you covered there too.
47
+
48
+ ```ruby
49
+ should render_json('foo', type: Array)
50
+ ```
51
+
52
+ If you need to make assertions on the members of that Array, you can use the same `required` and
53
+ `forbidden` options but be aware these assertions will be expected to be true for *every* member
54
+ of the Array. If you've got members that violate this, you'll probably be better off writing custom
55
+ assertions anyhow.
56
+
57
+ That's it!
58
+
59
+ ## TODO
60
+
61
+ 1. Test coverage. I've extracted this from one of my own test suites so there's no tests.
62
+
63
+ ## Contributing
64
+
65
+ 1. Fork it ( https://github.com/[my-github-username]/shoulda_render_json/fork )
66
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
67
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
68
+ 4. Push to the branch (`git push origin my-new-feature`)
69
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,3 @@
1
+ module ShouldaRenderJson
2
+ VERSION = "0.0.2"
3
+ end
@@ -0,0 +1,8 @@
1
+ require 'shoulda_render_json/version'
2
+ require 'shoulda_render_json_object_matcher'
3
+ require 'shoulda_render_json_array_matcher'
4
+ require 'shoulda_render_json_test_integration'
5
+
6
+ if defined?(ActionController)
7
+ ActionController::TestCase.__send__ :extend, ShouldaRenderJsonTestIntegration
8
+ end
@@ -0,0 +1,15 @@
1
+ class ShouldaRenderJsonArrayMatcher < ShouldaRenderJsonObjectMatcher
2
+ def description
3
+ "render JSON array for #{@root}"
4
+ end
5
+
6
+ private
7
+
8
+ def expected_root_class
9
+ Array
10
+ end
11
+
12
+ def present?(key)
13
+ json[root].all?{|node| node.has_key?(key)}
14
+ end
15
+ end
@@ -0,0 +1,95 @@
1
+ class ShouldaRenderJsonObjectMatcher
2
+ attr_reader :options, :context, :root, :keys, :response, :failure_message, :negative_failure_message
3
+
4
+ def initialize(root, options = {})
5
+ @options = options
6
+ # Coercing types root: Symbol, keys: Array of Symbols
7
+ @root = root.to_s
8
+ @keys = {
9
+ required: massage_options(:required),
10
+ forbidden: massage_options(:forbidden),
11
+ }
12
+ end
13
+
14
+ def description
15
+ "render JSON Hash/Object for #{@root}"
16
+ end
17
+
18
+ def matches?(controller)
19
+ @response = controller.response
20
+ matches_content_type? &&
21
+ matches_root? &&
22
+ has_required_keys? &&
23
+ has_no_forbidden_keys?
24
+ end
25
+
26
+ private
27
+
28
+ def matches_content_type?
29
+ content_type = response.content_type
30
+ set_failure_message "Expected content type to be 'application/json' but was '#{content_type}' instead"
31
+ set_negative_failure_message "Expected content type not to be '#{content_type}'"
32
+ content_type == 'application/json'
33
+ end
34
+
35
+ def root_matches_expected_type?
36
+ matches_root? ? root_is_expected_type? : false
37
+ end
38
+
39
+ def matches_root?
40
+ klass = json[root].class
41
+ set_failure_message "Expected root level node '#{root}' as Hash/Object but it was not found [class was #{klass}]"
42
+ set_negative_failure_message "Did not expect to contain root level node '#{root}' but it was present as #{klass}"
43
+ json.has_key?(root) && json[root].is_a?(expected_root_class)
44
+ end
45
+
46
+ def has_required_keys?
47
+ return true unless keys[:required]
48
+ set_failure_message "Expected child nodes for #{format_keys(missing_keys)} but there were none"
49
+ set_negative_failure_message "Expected no child nodes for #{format_keys(missing_keys)} but they were present"
50
+ missing_keys.empty?
51
+ end
52
+
53
+ def has_no_forbidden_keys?
54
+ return true unless keys[:forbidden]
55
+ set_failure_message "Expected no child nodes for #{format_keys(forbidden_keys)} but they were present"
56
+ # Negative failure here makes no sense since they are expected to not be present
57
+ forbidden_keys.empty?
58
+ end
59
+
60
+ def missing_keys
61
+ @missing_keys ||= keys[:required].reject{|key| present?(key)}
62
+ end
63
+
64
+ def forbidden_keys
65
+ @forbidden_keys ||= keys[:forbidden].select{|key| present?(key)}
66
+ end
67
+
68
+ def set_negative_failure_message(message)
69
+ @negative_failure_message = message
70
+ end
71
+
72
+ def set_failure_message(message)
73
+ @failure_message = message
74
+ end
75
+
76
+ def format_keys(keys)
77
+ keys.map{|key| "'#{key}'"}.join(', ')
78
+ end
79
+
80
+ def json
81
+ @json ||= JSON.parse(response.body)
82
+ end
83
+
84
+ def expected_root_class
85
+ Hash
86
+ end
87
+
88
+ def massage_options(key)
89
+ [options[key]].flatten.compact.map(&:to_s)
90
+ end
91
+
92
+ def present?(key)
93
+ json[root].has_key?(key)
94
+ end
95
+ end
@@ -0,0 +1,10 @@
1
+ module ShouldaRenderJsonTestIntegration
2
+ def render_json(key, options = {})
3
+ klass = if options[:type] == Array
4
+ ShouldaRenderJsonArrayMatcher
5
+ else
6
+ ShouldaRenderJsonObjectMatcher
7
+ end
8
+ klass.new key, options
9
+ end
10
+ 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 'shoulda_render_json/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "shoulda_render_json"
8
+ spec.version = ShouldaRenderJson::VERSION
9
+ spec.authors = ["RSL"]
10
+ spec.email = ["sconds@gmail.com"]
11
+ spec.summary = %q{Shoulda macros for making very basic assertions about JSON responses}
12
+ spec.description = %q{Shoulda macros for making very basic assertions about JSON responses}
13
+ spec.homepage = "https://github.com/rsl/shoulda_render_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.6"
22
+ spec.add_development_dependency "rake"
23
+ end
metadata ADDED
@@ -0,0 +1,83 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: shoulda_render_json
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - RSL
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-06-05 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: Shoulda macros for making very basic assertions about JSON responses
42
+ email:
43
+ - sconds@gmail.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - ".gitignore"
49
+ - Gemfile
50
+ - LICENSE.txt
51
+ - README.md
52
+ - Rakefile
53
+ - lib/shoulda_render_json.rb
54
+ - lib/shoulda_render_json/version.rb
55
+ - lib/shoulda_render_json_array_matcher.rb
56
+ - lib/shoulda_render_json_object_matcher.rb
57
+ - lib/shoulda_render_json_test_integration.rb
58
+ - shoulda_render_json.gemspec
59
+ homepage: https://github.com/rsl/shoulda_render_json
60
+ licenses:
61
+ - MIT
62
+ metadata: {}
63
+ post_install_message:
64
+ rdoc_options: []
65
+ require_paths:
66
+ - lib
67
+ required_ruby_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ required_rubygems_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ requirements: []
78
+ rubyforge_project:
79
+ rubygems_version: 2.2.2
80
+ signing_key:
81
+ specification_version: 4
82
+ summary: Shoulda macros for making very basic assertions about JSON responses
83
+ test_files: []