rspec-subject-extensions 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.
- data/README.md +55 -0
- data/features/README.md +35 -0
- data/features/class_methods/each_attribute_of_subject.feature +33 -0
- data/features/support/env.rb +1 -0
- data/lib/rspec/subject/extensions/class_methods.rb +66 -0
- data/lib/rspec/subject/extensions/version.rb +10 -0
- data/lib/rspec/subject/extensions.rb +13 -0
- data/lib/rspec-subject-extensions.rb +1 -0
- data/spec/rspec/subject/extensions/class_methods_spec.rb +53 -0
- data/spec/spec_helper.rb +5 -0
- metadata +285 -0
data/README.md
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
# RSpec Subject Extensions
|
2
|
+
|
3
|
+
rspec-subject-extensions adds `each` short-hand to generate a nested example group with
|
4
|
+
a single example that specifies the expected value of each attribute of the subject.
|
5
|
+
|
6
|
+
[](http://travis-ci.org/ZenCocoon/rspec-subject-extensions)
|
7
|
+
|
8
|
+
## Documentation
|
9
|
+
|
10
|
+
The [Cucumber features](http://relishapp.com/ZenCocoon/rspec-subject-extensions)
|
11
|
+
are the most comprehensive and up-to-date docs for end-users.
|
12
|
+
|
13
|
+
The [RDoc](http://rubydoc.info/gems/rspec-subject-extensions/0.1.0/frames) provides
|
14
|
+
additional information for contributors and/or extenders.
|
15
|
+
|
16
|
+
All of the documentation is open source and a work in progress. If you find it
|
17
|
+
lacking or confusing, you can help improve it by submitting requests and
|
18
|
+
patches to the [rspec-subject-extensions issue
|
19
|
+
tracker](https://github.com/ZenCocoon/rspec-subject-extensions/issues).
|
20
|
+
|
21
|
+
## Install
|
22
|
+
|
23
|
+
gem install rspec-subject-extensions
|
24
|
+
|
25
|
+
## Usage
|
26
|
+
|
27
|
+
### Each
|
28
|
+
|
29
|
+
Creates a nested example group named by `each` and the submitted `attribute`,
|
30
|
+
and then generates an example for each attribute using the submitted block.
|
31
|
+
|
32
|
+
# This ...
|
33
|
+
describe Object do
|
34
|
+
each(:item) { should be_an(Integer) }
|
35
|
+
end
|
36
|
+
|
37
|
+
# ... generates the same runtime structure as this:
|
38
|
+
describe Object do
|
39
|
+
describe "each item"
|
40
|
+
it "should be an Integer" do
|
41
|
+
subject.items.each do |item|
|
42
|
+
item.should be_an(Integer)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
The `attribute` can be a `Symbol` or a `String`.
|
49
|
+
|
50
|
+
## Also see
|
51
|
+
|
52
|
+
* [http://github.com/rspec/rspec](http://github.com/rspec/rspec)
|
53
|
+
* [http://github.com/rspec/rspec-core](http://github.com/rspec/rspec-core)
|
54
|
+
* [http://github.com/rspec/rspec-expectations](http://github.com/rspec/rspec-expectations)
|
55
|
+
* [http://github.com/rspec/rspec-mocks](http://github.com/rspec/rspec-mocks)
|
data/features/README.md
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
rspec-subject-extensions adds `each` short-hand to generate a nested example group with
|
2
|
+
a single example that specifies the expected value of each attribute of the subject.
|
3
|
+
|
4
|
+
## Each
|
5
|
+
|
6
|
+
Creates a nested example group named by +each+ and the submitted +attribute+,
|
7
|
+
and then generates an example for each attribute using the submitted block.
|
8
|
+
|
9
|
+
# This ...
|
10
|
+
describe Object do
|
11
|
+
each(:item) { should be_an(Integer) }
|
12
|
+
end
|
13
|
+
|
14
|
+
# ... generates the same runtime structure as this:
|
15
|
+
describe Object do
|
16
|
+
describe "each item"
|
17
|
+
it "should be an Integer" do
|
18
|
+
subject.items.each do |item|
|
19
|
+
item.should be_an(Integer)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
The +attribute+ can be a +Symbol+ or a +String+.
|
26
|
+
|
27
|
+
## Issues
|
28
|
+
|
29
|
+
The documentation for rspec-subject-extensions is a work in progress. We'll be adding
|
30
|
+
Cucumber features over time, and clarifying existing ones. If you have
|
31
|
+
specific features you'd like to see added, find the existing documentation
|
32
|
+
incomplete or confusing, or, better yet, wish to write a missing Cucumber
|
33
|
+
feature yourself, please [submit an
|
34
|
+
issue](http://github.com/ZenCocoon/rspec-subject-extensions/issues) or a [pull
|
35
|
+
request](http://github.com/ZenCocoon/rspec-subject-extensions).
|
@@ -0,0 +1,33 @@
|
|
1
|
+
Feature: each attribute of subject
|
2
|
+
|
3
|
+
Use the each() method as a short-hand to generate a nested example group with
|
4
|
+
a single example that specifies the expected value of each attribute of the
|
5
|
+
subject. This can be used with an implicit or explicit subject.
|
6
|
+
|
7
|
+
each() accepts a symbol or a string, and a block representing the example.
|
8
|
+
|
9
|
+
each(:item) { should be_an(Item) }
|
10
|
+
each("article") { should be_an(Article) }
|
11
|
+
|
12
|
+
Scenario: specify value of each attribute
|
13
|
+
Given a file named "example_spec.rb" with:
|
14
|
+
"""
|
15
|
+
require 'rspec/subject/extensions'
|
16
|
+
|
17
|
+
class Movie
|
18
|
+
def ratings
|
19
|
+
[9, 7, 9]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe Movie do
|
24
|
+
each(:rating) { should be_an(Integer) }
|
25
|
+
end
|
26
|
+
"""
|
27
|
+
When I run `rspec example_spec.rb --format documentation`
|
28
|
+
Then the output should contain:
|
29
|
+
"""
|
30
|
+
Movie
|
31
|
+
each rating
|
32
|
+
should be a kind of Integer
|
33
|
+
"""
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'aruba/cucumber'
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'active_support/inflector'
|
2
|
+
|
3
|
+
module RSpec
|
4
|
+
module Subject
|
5
|
+
module Extensions
|
6
|
+
module ClassMethods
|
7
|
+
# Creates a nested example group named by +each+ and the submitted +attribute+,
|
8
|
+
# and then generates an example for each attribute using the submitted block.
|
9
|
+
#
|
10
|
+
# @param [Symbol, String] attribute
|
11
|
+
# The singular name of the subject method containing all the attributes.
|
12
|
+
#
|
13
|
+
# @yield
|
14
|
+
# Example to run against each attribute.
|
15
|
+
#
|
16
|
+
# @raise [NoMethodError]
|
17
|
+
# The subject doesn't respond to the pluralized version of the attribute or it doesn't respond to each.
|
18
|
+
#
|
19
|
+
# @example
|
20
|
+
# # This ...
|
21
|
+
# describe Object do
|
22
|
+
# each(:item) { should be_an(Integer) }
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
# # ... generates the same runtime structure as this:
|
26
|
+
# describe Object do
|
27
|
+
# describe "each item"
|
28
|
+
# it "should be an Interger" do
|
29
|
+
# subject.items.each do |item|
|
30
|
+
# item.should be_an(Integer)
|
31
|
+
# end
|
32
|
+
# end
|
33
|
+
# end
|
34
|
+
# end
|
35
|
+
def each(attribute, &block)
|
36
|
+
describe("each #{attribute}") do
|
37
|
+
attribute = attribute.to_s.pluralize
|
38
|
+
|
39
|
+
example do
|
40
|
+
if subject.respond_to?(attribute) && subject.send(attribute).respond_to?(:each)
|
41
|
+
subject.send(attribute).each do |item|
|
42
|
+
self.class.class_eval do
|
43
|
+
define_method(:subject) do
|
44
|
+
@_subject ||= item
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
instance_eval(&block)
|
49
|
+
end
|
50
|
+
else
|
51
|
+
self.class.class_eval do
|
52
|
+
define_method(:subject) do
|
53
|
+
@_subject ||= super().send(attribute).each
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
instance_eval(&block)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'rspec/core'
|
2
|
+
require 'rspec/subject/extensions/class_methods'
|
3
|
+
require 'rspec/subject/extensions/version'
|
4
|
+
|
5
|
+
module RSpec
|
6
|
+
module Subject
|
7
|
+
# RSpec::Subject::Extensions let's you use short-hands to generate nested examples groups
|
8
|
+
module Extensions
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
RSpec::Core::ExampleGroup.extend(RSpec::Subject::Extensions::ClassMethods)
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'rspec/subject/extensions'
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module RSpec::Subject::Extensions::ClassMethods
|
4
|
+
describe "initialization" do
|
5
|
+
it "should extend RSpec::Core::ExampleGroup with RSpec::Subject::Extensions::ClassMethods" do
|
6
|
+
RSpec::Core::ExampleGroup.respond_to?('each').should be_true
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "#each" do
|
11
|
+
context "with an Object having #items returning an Array of Integers" do
|
12
|
+
subject do
|
13
|
+
Class.new do
|
14
|
+
def items
|
15
|
+
[1, 2]
|
16
|
+
end
|
17
|
+
end.new
|
18
|
+
end
|
19
|
+
|
20
|
+
each(:item) { should be_an(Integer) }
|
21
|
+
end
|
22
|
+
|
23
|
+
context "when it doesn't respond to the pluralized version of the attribute" do
|
24
|
+
subject { Object.new }
|
25
|
+
|
26
|
+
context "it raises an error" do
|
27
|
+
each(:item) do
|
28
|
+
expect do
|
29
|
+
should be_an(Integer)
|
30
|
+
end.to raise_error(NoMethodError)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context "when it doesn't return an object responding to each" do
|
36
|
+
subject do
|
37
|
+
Class.new do
|
38
|
+
def items
|
39
|
+
1
|
40
|
+
end
|
41
|
+
end.new
|
42
|
+
end
|
43
|
+
|
44
|
+
context "it raises an error" do
|
45
|
+
each(:item) do
|
46
|
+
expect do
|
47
|
+
should be_an(Integer)
|
48
|
+
end.to raise_error(NoMethodError)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,285 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rspec-subject-extensions
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 0
|
10
|
+
version: 0.1.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- "S\xC3\xA9bastien Grosjean"
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-07-02 00:00:00 +03:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: rspec
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 23
|
30
|
+
segments:
|
31
|
+
- 2
|
32
|
+
- 6
|
33
|
+
- 0
|
34
|
+
version: 2.6.0
|
35
|
+
type: :runtime
|
36
|
+
version_requirements: *id001
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: i18n
|
39
|
+
prerelease: false
|
40
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ">="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
hash: 11
|
46
|
+
segments:
|
47
|
+
- 0
|
48
|
+
- 5
|
49
|
+
- 0
|
50
|
+
version: 0.5.0
|
51
|
+
type: :runtime
|
52
|
+
version_requirements: *id002
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
name: activesupport
|
55
|
+
prerelease: false
|
56
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
hash: 7
|
62
|
+
segments:
|
63
|
+
- 3
|
64
|
+
- 0
|
65
|
+
version: "3.0"
|
66
|
+
type: :runtime
|
67
|
+
version_requirements: *id003
|
68
|
+
- !ruby/object:Gem::Dependency
|
69
|
+
name: rake
|
70
|
+
prerelease: false
|
71
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ~>
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
hash: 25
|
77
|
+
segments:
|
78
|
+
- 0
|
79
|
+
- 9
|
80
|
+
version: "0.9"
|
81
|
+
type: :development
|
82
|
+
version_requirements: *id004
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: cucumber
|
85
|
+
prerelease: false
|
86
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
87
|
+
none: false
|
88
|
+
requirements:
|
89
|
+
- - "="
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
hash: 23
|
92
|
+
segments:
|
93
|
+
- 1
|
94
|
+
- 0
|
95
|
+
- 0
|
96
|
+
version: 1.0.0
|
97
|
+
type: :development
|
98
|
+
version_requirements: *id005
|
99
|
+
- !ruby/object:Gem::Dependency
|
100
|
+
name: aruba
|
101
|
+
prerelease: false
|
102
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
103
|
+
none: false
|
104
|
+
requirements:
|
105
|
+
- - "="
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
hash: 11
|
108
|
+
segments:
|
109
|
+
- 0
|
110
|
+
- 4
|
111
|
+
- 2
|
112
|
+
version: 0.4.2
|
113
|
+
type: :development
|
114
|
+
version_requirements: *id006
|
115
|
+
- !ruby/object:Gem::Dependency
|
116
|
+
name: nokogiri
|
117
|
+
prerelease: false
|
118
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
119
|
+
none: false
|
120
|
+
requirements:
|
121
|
+
- - "="
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
hash: 15
|
124
|
+
segments:
|
125
|
+
- 1
|
126
|
+
- 4
|
127
|
+
- 4
|
128
|
+
version: 1.4.4
|
129
|
+
type: :development
|
130
|
+
version_requirements: *id007
|
131
|
+
- !ruby/object:Gem::Dependency
|
132
|
+
name: relish
|
133
|
+
prerelease: false
|
134
|
+
requirement: &id008 !ruby/object:Gem::Requirement
|
135
|
+
none: false
|
136
|
+
requirements:
|
137
|
+
- - "="
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
hash: 15
|
140
|
+
segments:
|
141
|
+
- 0
|
142
|
+
- 4
|
143
|
+
- 0
|
144
|
+
version: 0.4.0
|
145
|
+
type: :development
|
146
|
+
version_requirements: *id008
|
147
|
+
- !ruby/object:Gem::Dependency
|
148
|
+
name: yard
|
149
|
+
prerelease: false
|
150
|
+
requirement: &id009 !ruby/object:Gem::Requirement
|
151
|
+
none: false
|
152
|
+
requirements:
|
153
|
+
- - ~>
|
154
|
+
- !ruby/object:Gem::Version
|
155
|
+
hash: 7
|
156
|
+
segments:
|
157
|
+
- 0
|
158
|
+
- 7
|
159
|
+
- 2
|
160
|
+
version: 0.7.2
|
161
|
+
type: :development
|
162
|
+
version_requirements: *id009
|
163
|
+
- !ruby/object:Gem::Dependency
|
164
|
+
name: guard-rspec
|
165
|
+
prerelease: false
|
166
|
+
requirement: &id010 !ruby/object:Gem::Requirement
|
167
|
+
none: false
|
168
|
+
requirements:
|
169
|
+
- - "="
|
170
|
+
- !ruby/object:Gem::Version
|
171
|
+
hash: 9
|
172
|
+
segments:
|
173
|
+
- 0
|
174
|
+
- 1
|
175
|
+
- 9
|
176
|
+
version: 0.1.9
|
177
|
+
type: :development
|
178
|
+
version_requirements: *id010
|
179
|
+
- !ruby/object:Gem::Dependency
|
180
|
+
name: guard-cucumber
|
181
|
+
prerelease: false
|
182
|
+
requirement: &id011 !ruby/object:Gem::Requirement
|
183
|
+
none: false
|
184
|
+
requirements:
|
185
|
+
- - ~>
|
186
|
+
- !ruby/object:Gem::Version
|
187
|
+
hash: 9
|
188
|
+
segments:
|
189
|
+
- 0
|
190
|
+
- 5
|
191
|
+
- 1
|
192
|
+
version: 0.5.1
|
193
|
+
type: :development
|
194
|
+
version_requirements: *id011
|
195
|
+
- !ruby/object:Gem::Dependency
|
196
|
+
name: growl
|
197
|
+
prerelease: false
|
198
|
+
requirement: &id012 !ruby/object:Gem::Requirement
|
199
|
+
none: false
|
200
|
+
requirements:
|
201
|
+
- - "="
|
202
|
+
- !ruby/object:Gem::Version
|
203
|
+
hash: 17
|
204
|
+
segments:
|
205
|
+
- 1
|
206
|
+
- 0
|
207
|
+
- 3
|
208
|
+
version: 1.0.3
|
209
|
+
type: :development
|
210
|
+
version_requirements: *id012
|
211
|
+
- !ruby/object:Gem::Dependency
|
212
|
+
name: appraisal
|
213
|
+
prerelease: false
|
214
|
+
requirement: &id013 !ruby/object:Gem::Requirement
|
215
|
+
none: false
|
216
|
+
requirements:
|
217
|
+
- - ~>
|
218
|
+
- !ruby/object:Gem::Version
|
219
|
+
hash: 31
|
220
|
+
segments:
|
221
|
+
- 0
|
222
|
+
- 3
|
223
|
+
- 6
|
224
|
+
version: 0.3.6
|
225
|
+
type: :development
|
226
|
+
version_requirements: *id013
|
227
|
+
description: rspec-subject-extensions let's you use short-hands to generate nested examples groups
|
228
|
+
email: public@zencocoon.com
|
229
|
+
executables: []
|
230
|
+
|
231
|
+
extensions: []
|
232
|
+
|
233
|
+
extra_rdoc_files:
|
234
|
+
- README.md
|
235
|
+
files:
|
236
|
+
- lib/rspec-subject-extensions.rb
|
237
|
+
- lib/rspec/subject/extensions.rb
|
238
|
+
- lib/rspec/subject/extensions/class_methods.rb
|
239
|
+
- lib/rspec/subject/extensions/version.rb
|
240
|
+
- README.md
|
241
|
+
- features/README.md
|
242
|
+
- features/class_methods/each_attribute_of_subject.feature
|
243
|
+
- features/support/env.rb
|
244
|
+
- spec/rspec/subject/extensions/class_methods_spec.rb
|
245
|
+
- spec/spec_helper.rb
|
246
|
+
has_rdoc: true
|
247
|
+
homepage: http://github.com/ZenCocoon/rspec-subject-extensions
|
248
|
+
licenses: []
|
249
|
+
|
250
|
+
post_install_message:
|
251
|
+
rdoc_options:
|
252
|
+
- --charset=UTF-8
|
253
|
+
require_paths:
|
254
|
+
- lib
|
255
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
256
|
+
none: false
|
257
|
+
requirements:
|
258
|
+
- - ">="
|
259
|
+
- !ruby/object:Gem::Version
|
260
|
+
hash: 3
|
261
|
+
segments:
|
262
|
+
- 0
|
263
|
+
version: "0"
|
264
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
265
|
+
none: false
|
266
|
+
requirements:
|
267
|
+
- - ">="
|
268
|
+
- !ruby/object:Gem::Version
|
269
|
+
hash: 3
|
270
|
+
segments:
|
271
|
+
- 0
|
272
|
+
version: "0"
|
273
|
+
requirements: []
|
274
|
+
|
275
|
+
rubyforge_project:
|
276
|
+
rubygems_version: 1.6.2
|
277
|
+
signing_key:
|
278
|
+
specification_version: 3
|
279
|
+
summary: rspec-subject-extensions-0.1.0
|
280
|
+
test_files:
|
281
|
+
- features/README.md
|
282
|
+
- features/class_methods/each_attribute_of_subject.feature
|
283
|
+
- features/support/env.rb
|
284
|
+
- spec/rspec/subject/extensions/class_methods_spec.rb
|
285
|
+
- spec/spec_helper.rb
|