rspec-roar_matchers 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/.rspec +1 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +67 -0
- data/Rakefile +1 -0
- data/lib/roar_matchers/have_collections.rb +26 -0
- data/lib/roar_matchers/have_links.rb +26 -0
- data/lib/roar_matchers/have_properties.rb +27 -0
- data/lib/roar_matchers/support.rb +26 -0
- data/lib/roar_matchers/version.rb +5 -0
- data/lib/roar_matchers.rb +13 -0
- data/rspec-roar_matchers.gemspec +27 -0
- data/spec/fixtures/country.rb +8 -0
- data/spec/fixtures/country_representer.rb +12 -0
- data/spec/fixtures/state.rb +7 -0
- data/spec/fixtures/state_representer.rb +6 -0
- data/spec/roar_matchers/matchers_spec.rb +66 -0
- data/spec/spec_helper.rb +18 -0
- metadata +156 -0
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Hashrocket Workstation
|
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,67 @@
|
|
1
|
+
# Rspec::RoarMatchers
|
2
|
+
|
3
|
+
Rspec::RoarMatchers is a collection of matchers designed to enforce a contract between your spec and representer. The driving concern while recently developing for an app that was making extensive use of Roar, was the fact that we were able to modify the various representers without the spec complaining.
|
4
|
+
|
5
|
+
So to ensure that any change to the representation of an object was explicit we made a few rspec matchers to do the heavy lifting.
|
6
|
+
|
7
|
+
# Usage
|
8
|
+
|
9
|
+
Below are the matchers we've defined thus far (will likely be expanding). For more information regarding implementation see `spec/roar_matchers/matchers_spec.rb`.
|
10
|
+
|
11
|
+
The will enforce bi-directionally. This means that it will fail if:
|
12
|
+
|
13
|
+
* if a property/collection/link is present in the representer but not in the spec
|
14
|
+
* if a property/collection/link is present in the spec but not in the representer
|
15
|
+
|
16
|
+
All of these matchers receive a word array as an argument.
|
17
|
+
|
18
|
+
### have_collections
|
19
|
+
|
20
|
+
```ruby
|
21
|
+
context "collection is present in both spec and representer (happy path)" do
|
22
|
+
it "passes" do
|
23
|
+
expected_collections = %w{state_or_provinces}
|
24
|
+
expect(country.extend(CountryRepresenter)).to have_collections(expected_collections)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
```
|
28
|
+
|
29
|
+
### have_links
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
context "link is present in both spec and representer (happy path)" do
|
33
|
+
it "passes" do
|
34
|
+
expected_links = %w{self}
|
35
|
+
expect(country.extend(CountryRepresenter)).to have_links(expected_links)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
```
|
39
|
+
|
40
|
+
### have_properties
|
41
|
+
|
42
|
+
```ruby
|
43
|
+
context "link is present in both spec and representer (happy path)" do
|
44
|
+
it "passes" do
|
45
|
+
expected_properties = %w{name}
|
46
|
+
expect(country.extend(CountryRepresenter)).to have_properties(expected_properties)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
```
|
50
|
+
|
51
|
+
## Installation
|
52
|
+
|
53
|
+
Add this line to your application's Gemfile:
|
54
|
+
|
55
|
+
gem 'rspec-roar_matchers'
|
56
|
+
|
57
|
+
And then execute:
|
58
|
+
|
59
|
+
$ bundle
|
60
|
+
|
61
|
+
## Contributing
|
62
|
+
|
63
|
+
1. Fork it
|
64
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
65
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
66
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
67
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,26 @@
|
|
1
|
+
RSpec::Matchers.define :have_collections do |expected_collections|
|
2
|
+
match do |representer|
|
3
|
+
first = expected_collections.all? do |expected_collection|
|
4
|
+
RoarMatchers.get_actual_collection_names(representer).include?(expected_collection)
|
5
|
+
end
|
6
|
+
|
7
|
+
second = RoarMatchers.get_actual_collection_names(representer).all? do |expected_collection|
|
8
|
+
expected_collections.include?(expected_collection)
|
9
|
+
end
|
10
|
+
|
11
|
+
first && second
|
12
|
+
end
|
13
|
+
|
14
|
+
failure_message_for_should do |representer|
|
15
|
+
actual_collection_names = RoarMatchers.get_actual_collection_names(representer)
|
16
|
+
representation_or_specification, missing = RoarMatchers.missing(actual_collection_names, expected_collections)
|
17
|
+
|
18
|
+
(<<-EOS)
|
19
|
+
expected that #{actual_collection_names}
|
20
|
+
|
21
|
+
should contain #{expected_collections}
|
22
|
+
|
23
|
+
missing collection(s) from #{representation_or_specification}: #{missing}
|
24
|
+
EOS
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
RSpec::Matchers.define :have_links do |expected_links|
|
2
|
+
match do |representer|
|
3
|
+
first = expected_links.all? do |expected_link|
|
4
|
+
RoarMatchers.get_actual_link_names(representer).include?(expected_link)
|
5
|
+
end
|
6
|
+
|
7
|
+
second = RoarMatchers.get_actual_link_names(representer).all? do |expected_link|
|
8
|
+
expected_links.include?(expected_link)
|
9
|
+
end
|
10
|
+
|
11
|
+
first && second
|
12
|
+
end
|
13
|
+
|
14
|
+
failure_message_for_should do |representer|
|
15
|
+
actual_link_names = RoarMatchers.get_actual_link_names(representer)
|
16
|
+
representation_or_specification, missing = RoarMatchers.missing(actual_link_names,expected_links)
|
17
|
+
|
18
|
+
(<<-EOS)
|
19
|
+
expected that #{actual_link_names}
|
20
|
+
|
21
|
+
should contain #{expected_links}
|
22
|
+
|
23
|
+
missing links from #{representation_or_specification}: #{missing}
|
24
|
+
EOS
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
RSpec::Matchers.define :have_properties do |expected_properties|
|
2
|
+
match do |representer|
|
3
|
+
first = expected_properties.all? do |expected_property|
|
4
|
+
RoarMatchers.get_actual_property_names(representer).include?(expected_property)
|
5
|
+
end
|
6
|
+
|
7
|
+
second = RoarMatchers.get_actual_property_names(representer).all? do |expected_property|
|
8
|
+
expected_properties.include?(expected_property)
|
9
|
+
end
|
10
|
+
|
11
|
+
first && second
|
12
|
+
end
|
13
|
+
|
14
|
+
failure_message_for_should do |representer|
|
15
|
+
actual_property_names = RoarMatchers.get_actual_property_names(representer)
|
16
|
+
representation_or_specification, missing = RoarMatchers.missing(actual_property_names,expected_properties)
|
17
|
+
|
18
|
+
(<<-EOS)
|
19
|
+
expected that #{actual_property_names}
|
20
|
+
|
21
|
+
should contain #{expected_properties}
|
22
|
+
|
23
|
+
missing properties from #{representation_or_specification}: #{missing}
|
24
|
+
EOS
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module RoarMatchers
|
2
|
+
def self.missing(actual,expected)
|
3
|
+
if (mp = (expected - actual)).any?
|
4
|
+
["Representer", mp]
|
5
|
+
else
|
6
|
+
["Spec", actual - expected]
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.get_actual_property_names(representer)
|
11
|
+
representer.instance_variable_get("@representable_attrs").reject do |attr|
|
12
|
+
attr.options[:collection]
|
13
|
+
end.map(&:name)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.get_actual_link_names(representer)
|
17
|
+
representer.to_json;
|
18
|
+
representer.links.keys
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.get_actual_collection_names(representer)
|
22
|
+
representer.instance_variable_get("@representable_attrs").select do |attr|
|
23
|
+
attr.options[:collection] && attr.name != "links_array"
|
24
|
+
end.map(&:name)
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
|
+
|
3
|
+
require 'rspec'
|
4
|
+
require 'roar_matchers/version'
|
5
|
+
require 'roar_matchers/support'
|
6
|
+
require 'roar_matchers/have_links'
|
7
|
+
require 'roar_matchers/have_properties'
|
8
|
+
require 'roar_matchers/have_collections'
|
9
|
+
|
10
|
+
module Roar
|
11
|
+
module Matchers
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'roar_matchers/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "rspec-roar_matchers"
|
8
|
+
spec.version = Rspec::RoarMatchers::VERSION
|
9
|
+
spec.authors = ["Hashrocket Workstation"]
|
10
|
+
spec.email = ["dev@hashrocket.com"]
|
11
|
+
spec.description = %q{Rspec::RoarMatchers is a collection of matchers designed to enforce a contract between your spec and representer.}
|
12
|
+
spec.summary = %q{ Rspec::RoarMatchers is a collection of matchers designed to enforce a contract between your spec and representer. The driving concern, while recently developing for an app that was making extensive use of Roar, was the fact that we were able to modify the various representers without the spec complaining. }
|
13
|
+
|
14
|
+
spec.homepage = "https://github.com/rondale-sc/rspec-roar_matchers"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
spec.files = `git ls-files`.split($/)
|
18
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
19
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
20
|
+
spec.require_paths = ["lib"]
|
21
|
+
|
22
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
23
|
+
spec.add_development_dependency "rake"
|
24
|
+
spec.add_development_dependency "roar"
|
25
|
+
spec.add_development_dependency "rspec"
|
26
|
+
spec.add_development_dependency "pry"
|
27
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "RSpec::Matchers" do
|
4
|
+
describe "#have_collection" do
|
5
|
+
let(:country) do
|
6
|
+
Country.new("Canada", [State.new("Ontario")])
|
7
|
+
end
|
8
|
+
|
9
|
+
context "collection is present in both spec and representer (happy path)" do
|
10
|
+
it "passes" do
|
11
|
+
expected_collections = %w{state_or_provinces}
|
12
|
+
expect(country.extend(CountryRepresenter)).to have_collections(expected_collections)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
context "when collection is absent in representer" do
|
17
|
+
it "fails and returns message about where to look" do
|
18
|
+
expect do
|
19
|
+
country.extend(CountryRepresenter).should have_collections(["not_in_representer"])
|
20
|
+
end.to raise_error(/missing collection\(s\) from Representer: \["not_in_representer"\]/)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "#have_links" do
|
26
|
+
let(:country) do
|
27
|
+
Country.new("United States", [State.new("Florida")])
|
28
|
+
end
|
29
|
+
|
30
|
+
context "link is present in both spec and representer (happy path)" do
|
31
|
+
it "passes" do
|
32
|
+
expected_links = %w{self}
|
33
|
+
expect(country.extend(CountryRepresenter)).to have_links(expected_links)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context "when collection is absent in representer" do
|
38
|
+
it "fails and returns message about where to look" do
|
39
|
+
expect do
|
40
|
+
country.extend(CountryRepresenter).should have_links(["not_in_representer"])
|
41
|
+
end.to raise_error(/missing links from Representer: \["not_in_representer"\]/)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "#have_properties" do
|
47
|
+
let(:country) do
|
48
|
+
Country.new("United States", [State.new("Florida")])
|
49
|
+
end
|
50
|
+
|
51
|
+
context "link is present in both spec and representer (happy path)" do
|
52
|
+
it "passes" do
|
53
|
+
expected_properties = %w{name}
|
54
|
+
expect(country.extend(CountryRepresenter)).to have_properties(expected_properties)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context "when property is absent in representer" do
|
59
|
+
it "fails and returns message about where to look" do
|
60
|
+
expect do
|
61
|
+
country.extend(CountryRepresenter).should have_properties(["not_in_representer"])
|
62
|
+
end.to raise_error(/missing properties from Representer: \["not_in_representer"\]/)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
Bundler.require(:default)
|
3
|
+
|
4
|
+
require 'roar_matchers'
|
5
|
+
require 'roar/representer/json'
|
6
|
+
require 'roar/representer/feature/hypermedia'
|
7
|
+
|
8
|
+
require_relative './fixtures/country'
|
9
|
+
require_relative './fixtures/state'
|
10
|
+
require_relative './fixtures/state_representer'
|
11
|
+
require_relative './fixtures/country_representer'
|
12
|
+
|
13
|
+
RSpec.configure do |config|
|
14
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
15
|
+
config.run_all_when_everything_filtered = true
|
16
|
+
config.filter_run :focus
|
17
|
+
config.order = "random"
|
18
|
+
end
|
metadata
ADDED
@@ -0,0 +1,156 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rspec-roar_matchers
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Hashrocket Workstation
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-08-23 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: bundler
|
16
|
+
prerelease: false
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '1.3'
|
22
|
+
none: false
|
23
|
+
type: :development
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
requirements:
|
26
|
+
- - ~>
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
version: '1.3'
|
29
|
+
none: false
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rake
|
32
|
+
prerelease: false
|
33
|
+
requirement: !ruby/object:Gem::Requirement
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
none: false
|
39
|
+
type: :development
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
requirements:
|
42
|
+
- - ! '>='
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '0'
|
45
|
+
none: false
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: roar
|
48
|
+
prerelease: false
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
none: false
|
55
|
+
type: :development
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ! '>='
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
61
|
+
none: false
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: rspec
|
64
|
+
prerelease: false
|
65
|
+
requirement: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
none: false
|
71
|
+
type: :development
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
none: false
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: pry
|
80
|
+
prerelease: false
|
81
|
+
requirement: !ruby/object:Gem::Requirement
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
none: false
|
87
|
+
type: :development
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
requirements:
|
90
|
+
- - ! '>='
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: '0'
|
93
|
+
none: false
|
94
|
+
description: Rspec::RoarMatchers is a collection of matchers designed to enforce a
|
95
|
+
contract between your spec and representer.
|
96
|
+
email:
|
97
|
+
- dev@hashrocket.com
|
98
|
+
executables: []
|
99
|
+
extensions: []
|
100
|
+
extra_rdoc_files: []
|
101
|
+
files:
|
102
|
+
- .gitignore
|
103
|
+
- .rspec
|
104
|
+
- Gemfile
|
105
|
+
- LICENSE.txt
|
106
|
+
- README.md
|
107
|
+
- Rakefile
|
108
|
+
- lib/roar_matchers.rb
|
109
|
+
- lib/roar_matchers/have_collections.rb
|
110
|
+
- lib/roar_matchers/have_links.rb
|
111
|
+
- lib/roar_matchers/have_properties.rb
|
112
|
+
- lib/roar_matchers/support.rb
|
113
|
+
- lib/roar_matchers/version.rb
|
114
|
+
- rspec-roar_matchers.gemspec
|
115
|
+
- spec/fixtures/country.rb
|
116
|
+
- spec/fixtures/country_representer.rb
|
117
|
+
- spec/fixtures/state.rb
|
118
|
+
- spec/fixtures/state_representer.rb
|
119
|
+
- spec/roar_matchers/matchers_spec.rb
|
120
|
+
- spec/spec_helper.rb
|
121
|
+
homepage: https://github.com/rondale-sc/rspec-roar_matchers
|
122
|
+
licenses:
|
123
|
+
- MIT
|
124
|
+
post_install_message:
|
125
|
+
rdoc_options: []
|
126
|
+
require_paths:
|
127
|
+
- lib
|
128
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
129
|
+
requirements:
|
130
|
+
- - ! '>='
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: '0'
|
133
|
+
none: false
|
134
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ! '>='
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
none: false
|
140
|
+
requirements: []
|
141
|
+
rubyforge_project:
|
142
|
+
rubygems_version: 1.8.24
|
143
|
+
signing_key:
|
144
|
+
specification_version: 3
|
145
|
+
summary: Rspec::RoarMatchers is a collection of matchers designed to enforce a contract
|
146
|
+
between your spec and representer. The driving concern, while recently developing
|
147
|
+
for an app that was making extensive use of Roar, was the fact that we were able
|
148
|
+
to modify the various representers without the spec complaining.
|
149
|
+
test_files:
|
150
|
+
- spec/fixtures/country.rb
|
151
|
+
- spec/fixtures/country_representer.rb
|
152
|
+
- spec/fixtures/state.rb
|
153
|
+
- spec/fixtures/state_representer.rb
|
154
|
+
- spec/roar_matchers/matchers_spec.rb
|
155
|
+
- spec/spec_helper.rb
|
156
|
+
has_rdoc:
|