rspec-collection_matchers 0.0.1.pre → 0.0.1
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 +7 -0
- data/.gitignore +16 -15
- data/.rspec +2 -0
- data/.travis.yml +17 -0
- data/Gemfile +15 -1
- data/LICENSE.txt +7 -2
- data/README.md +49 -11
- data/Rakefile +18 -1
- data/features/have.feature +113 -0
- data/features/support/env.rb +21 -0
- data/lib/rspec/collection_matchers.rb +3 -0
- data/lib/rspec/collection_matchers/have.rb +122 -0
- data/lib/rspec/collection_matchers/matchers.rb +62 -0
- data/lib/rspec/collection_matchers/version.rb +5 -0
- data/rspec-collection_matchers.gemspec +19 -14
- data/script/test_all +21 -0
- data/spec/rspec/collection_matchers/have_spec.rb +487 -0
- data/spec/spec_helper.rb +11 -0
- data/spec/support/classes.rb +56 -0
- data/spec/support/matchers.rb +23 -0
- data/spec/support/shared_examples.rb +12 -0
- metadata +66 -21
- data/lib/rspec-collection_matchers.rb +0 -7
- data/lib/rspec-collection_matchers/version.rb +0 -5
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'rspec/matchers'
|
2
|
+
|
3
|
+
module RSpec
|
4
|
+
module Matchers
|
5
|
+
# Passes if receiver is a collection with the submitted number of items OR
|
6
|
+
# if the receiver OWNS a collection with the submitted number of items.
|
7
|
+
#
|
8
|
+
# If the receiver OWNS the collection, you must use the name of the
|
9
|
+
# collection. So if a `Team` instance has a collection named `#players`,
|
10
|
+
# you must use that name to set the expectation.
|
11
|
+
#
|
12
|
+
# If the receiver IS the collection, you can use any name you like for
|
13
|
+
# `named_collection`. We'd recommend using either "elements", "members", or
|
14
|
+
# "items" as these are all standard ways of describing the things IN a
|
15
|
+
# collection.
|
16
|
+
#
|
17
|
+
# This also works for Strings, letting you set expectations about their
|
18
|
+
# lengths.
|
19
|
+
#
|
20
|
+
# @example
|
21
|
+
#
|
22
|
+
# # Passes if team.players.size == 11
|
23
|
+
# expect(team).to have(11).players
|
24
|
+
#
|
25
|
+
# # Passes if [1,2,3].length == 3
|
26
|
+
# expect([1,2,3]).to have(3).items #"items" is pure sugar
|
27
|
+
#
|
28
|
+
# # Passes if ['a', 'b', 'c'].count == 3
|
29
|
+
# expect([1,2,3]).to have(3).items #"items" is pure sugar
|
30
|
+
#
|
31
|
+
# # Passes if "this string".length == 11
|
32
|
+
# expect("this string").to have(11).characters #"characters" is pure sugar
|
33
|
+
def have(n)
|
34
|
+
RSpec::CollectionMatchers::Have.new(n)
|
35
|
+
end
|
36
|
+
alias :have_exactly :have
|
37
|
+
|
38
|
+
# Exactly like have() with >=.
|
39
|
+
#
|
40
|
+
# @example
|
41
|
+
# expect("this").to have_at_least(3).letters
|
42
|
+
#
|
43
|
+
# ### Warning:
|
44
|
+
#
|
45
|
+
# `expect(..).not_to have_at_least` is not supported
|
46
|
+
def have_at_least(n)
|
47
|
+
RSpec::CollectionMatchers::Have.new(n, :at_least)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Exactly like have() with <=.
|
51
|
+
#
|
52
|
+
# @example
|
53
|
+
# expect("this").to have_at_most(4).letters
|
54
|
+
#
|
55
|
+
# ### Warning:
|
56
|
+
#
|
57
|
+
# `expect(..).not_to have_at_most` is not supported
|
58
|
+
def have_at_most(n)
|
59
|
+
RSpec::CollectionMatchers::Have.new(n, :at_most)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -1,19 +1,24 @@
|
|
1
|
-
#
|
1
|
+
# coding: utf-8
|
2
2
|
lib = File.expand_path('../lib', __FILE__)
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require 'rspec
|
4
|
+
require 'rspec/collection_matchers/version'
|
5
5
|
|
6
|
-
Gem::Specification.new do |
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "rspec-collection_matchers"
|
8
|
+
spec.version = RSpec::CollectionMatchers::VERSION
|
9
|
+
spec.authors = ["Hugo Baraúna"]
|
10
|
+
spec.email = ["hugo.barauna@plataformatec.com.br"]
|
11
|
+
spec.summary = "rspec-collection_matchers-#{RSpec::CollectionMatchers::VERSION}"
|
12
|
+
spec.description = "Collection cardinality matchers, extracted from rspec-expectations"
|
13
|
+
spec.homepage = "https://github.com/rspec/rspec-collection_matchers"
|
14
|
+
spec.license = "MIT"
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_runtime_dependency "rspec-expectations", ">= 2.99.0.pre"
|
22
|
+
|
23
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
19
24
|
end
|
data/script/test_all
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
set -e -x
|
4
|
+
|
5
|
+
# idea taken from: http://blog.headius.com/2010/03/jruby-startup-time-tips.html
|
6
|
+
export JRUBY_OPTS='-X-C' # disable JIT since these processes are so short lived
|
7
|
+
|
8
|
+
# force jRuby to use client mode JVM or a compilation mode thats as close as possible,
|
9
|
+
# idea taken from https://github.com/jruby/jruby/wiki/Improving-startup-time
|
10
|
+
export JAVA_OPTS='-client -XX:+TieredCompilation -XX:TieredStopAtLevel=1'
|
11
|
+
|
12
|
+
echo "Running rspec specs"
|
13
|
+
bin/rspec spec --format progress --profile
|
14
|
+
|
15
|
+
echo "Running cucumber specs"
|
16
|
+
# TODO: it would be nice to figure out how to run the cukes w/o the overhead of
|
17
|
+
# bundler, but just running `bin/cucumber` can fail due to the fact that it
|
18
|
+
# shells out (via aruba) and executes `rspec`--which can pick up the wrong
|
19
|
+
# rspec version if we're not running with bundler.
|
20
|
+
bundle exec cucumber
|
21
|
+
|
@@ -0,0 +1,487 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'stringio'
|
3
|
+
|
4
|
+
describe "have matcher" do
|
5
|
+
let(:inflector) do
|
6
|
+
Class.new do
|
7
|
+
def self.pluralize(string)
|
8
|
+
string.to_s + 's'
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
before(:each) { stub_const("ActiveSupport::Inflector", inflector) }
|
14
|
+
|
15
|
+
def create_collection_owner_with(n)
|
16
|
+
owner = RSpec::Expectations::Helper::CollectionOwner.new
|
17
|
+
(1..n).each do |number|
|
18
|
+
owner.add_to_collection_with_length_method(number)
|
19
|
+
owner.add_to_collection_with_size_method(number)
|
20
|
+
owner.add_to_collection_with_count_method(number)
|
21
|
+
end
|
22
|
+
owner
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "expect(...).to have(n).items" do
|
26
|
+
it_behaves_like "an RSpec matcher", :valid_value => [1, 2], :invalid_value => [1] do
|
27
|
+
let(:matcher) { have(2).items }
|
28
|
+
end
|
29
|
+
|
30
|
+
it "passes if target has a collection of items with n members" do
|
31
|
+
owner = create_collection_owner_with(3)
|
32
|
+
expect(owner).to have(3).items_in_collection_with_length_method
|
33
|
+
expect(owner).to have(3).items_in_collection_with_size_method
|
34
|
+
expect(owner).to have(3).items_in_collection_with_count_method
|
35
|
+
end
|
36
|
+
|
37
|
+
it "converts :no to 0" do
|
38
|
+
owner = create_collection_owner_with(0)
|
39
|
+
expect(owner).to have(:no).items_in_collection_with_length_method
|
40
|
+
expect(owner).to have(:no).items_in_collection_with_size_method
|
41
|
+
expect(owner).to have(:no).items_in_collection_with_count_method
|
42
|
+
end
|
43
|
+
|
44
|
+
it "converts a String argument to Integer" do
|
45
|
+
owner = create_collection_owner_with(3)
|
46
|
+
expect(owner).to have('3').items_in_collection_with_length_method
|
47
|
+
expect(owner).to have('3').items_in_collection_with_size_method
|
48
|
+
expect(owner).to have('3').items_in_collection_with_count_method
|
49
|
+
end
|
50
|
+
|
51
|
+
it "fails if target has a collection of items with < n members" do
|
52
|
+
owner = create_collection_owner_with(3)
|
53
|
+
expect {
|
54
|
+
expect(owner).to have(4).items_in_collection_with_length_method
|
55
|
+
}.to fail_with("expected 4 items_in_collection_with_length_method, got 3")
|
56
|
+
expect {
|
57
|
+
expect(owner).to have(4).items_in_collection_with_size_method
|
58
|
+
}.to fail_with("expected 4 items_in_collection_with_size_method, got 3")
|
59
|
+
expect {
|
60
|
+
expect(owner).to have(4).items_in_collection_with_count_method
|
61
|
+
}.to fail_with("expected 4 items_in_collection_with_count_method, got 3")
|
62
|
+
end
|
63
|
+
|
64
|
+
it "fails if target has a collection of items with > n members" do
|
65
|
+
owner = create_collection_owner_with(3)
|
66
|
+
expect {
|
67
|
+
expect(owner).to have(2).items_in_collection_with_length_method
|
68
|
+
}.to fail_with("expected 2 items_in_collection_with_length_method, got 3")
|
69
|
+
expect {
|
70
|
+
expect(owner).to have(2).items_in_collection_with_size_method
|
71
|
+
}.to fail_with("expected 2 items_in_collection_with_size_method, got 3")
|
72
|
+
expect {
|
73
|
+
expect(owner).to have(2).items_in_collection_with_count_method
|
74
|
+
}.to fail_with("expected 2 items_in_collection_with_count_method, got 3")
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe 'expect(...).to have(1).item when ActiveSupport::Inflector is defined' do
|
79
|
+
|
80
|
+
it 'pluralizes the collection name' do
|
81
|
+
owner = create_collection_owner_with(1)
|
82
|
+
expect(owner).to have(1).item
|
83
|
+
end
|
84
|
+
|
85
|
+
context "when ActiveSupport::Inflector is partially loaded without its inflectors" do
|
86
|
+
|
87
|
+
it "does not pluralize the collection name" do
|
88
|
+
stub_const("ActiveSupport::Inflector", Module.new)
|
89
|
+
owner = create_collection_owner_with(1)
|
90
|
+
expect {
|
91
|
+
expect(owner).to have(1).item
|
92
|
+
}.to raise_error(NoMethodError)
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe 'expect(...).to have(1).item when Inflector is defined' do
|
99
|
+
before { stub_const("Inflector", inflector) }
|
100
|
+
|
101
|
+
it 'pluralizes the collection name' do
|
102
|
+
owner = create_collection_owner_with(1)
|
103
|
+
expect(owner).to have(1).item
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
describe "expect(...).to have(n).items where result responds to items but returns something other than a collection" do
|
108
|
+
it "provides a meaningful error" do
|
109
|
+
owner = Class.new do
|
110
|
+
def items
|
111
|
+
Object.new
|
112
|
+
end
|
113
|
+
end.new
|
114
|
+
expect do
|
115
|
+
expect(owner).to have(3).items
|
116
|
+
end.to raise_error("expected items to be a collection but it does not respond to #length, #size or #count")
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
describe "expect(...).not_to have(n).items" do
|
121
|
+
|
122
|
+
it "passes if target has a collection of items with < n members" do
|
123
|
+
owner = create_collection_owner_with(3)
|
124
|
+
expect(owner).not_to have(4).items_in_collection_with_length_method
|
125
|
+
expect(owner).not_to have(4).items_in_collection_with_size_method
|
126
|
+
expect(owner).not_to have(4).items_in_collection_with_count_method
|
127
|
+
end
|
128
|
+
|
129
|
+
it "passes if target has a collection of items with > n members" do
|
130
|
+
owner = create_collection_owner_with(3)
|
131
|
+
expect(owner).not_to have(2).items_in_collection_with_length_method
|
132
|
+
expect(owner).not_to have(2).items_in_collection_with_size_method
|
133
|
+
expect(owner).not_to have(2).items_in_collection_with_count_method
|
134
|
+
end
|
135
|
+
|
136
|
+
it "fails if target has a collection of items with n members" do
|
137
|
+
owner = create_collection_owner_with(3)
|
138
|
+
expect {
|
139
|
+
expect(owner).not_to have(3).items_in_collection_with_length_method
|
140
|
+
}.to fail_with("expected target not to have 3 items_in_collection_with_length_method, got 3")
|
141
|
+
expect {
|
142
|
+
expect(owner).not_to have(3).items_in_collection_with_size_method
|
143
|
+
}.to fail_with("expected target not to have 3 items_in_collection_with_size_method, got 3")
|
144
|
+
expect {
|
145
|
+
expect(owner).not_to have(3).items_in_collection_with_count_method
|
146
|
+
}.to fail_with("expected target not to have 3 items_in_collection_with_count_method, got 3")
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
describe "expect(...).to have_exactly(n).items" do
|
151
|
+
|
152
|
+
it "passes if target has a collection of items with n members" do
|
153
|
+
owner = create_collection_owner_with(3)
|
154
|
+
expect(owner).to have_exactly(3).items_in_collection_with_length_method
|
155
|
+
expect(owner).to have_exactly(3).items_in_collection_with_size_method
|
156
|
+
expect(owner).to have_exactly(3).items_in_collection_with_count_method
|
157
|
+
end
|
158
|
+
|
159
|
+
it "converts :no to 0" do
|
160
|
+
owner = create_collection_owner_with(0)
|
161
|
+
expect(owner).to have_exactly(:no).items_in_collection_with_length_method
|
162
|
+
expect(owner).to have_exactly(:no).items_in_collection_with_size_method
|
163
|
+
expect(owner).to have_exactly(:no).items_in_collection_with_count_method
|
164
|
+
end
|
165
|
+
|
166
|
+
it "fails if target has a collection of items with < n members" do
|
167
|
+
owner = create_collection_owner_with(3)
|
168
|
+
expect {
|
169
|
+
expect(owner).to have_exactly(4).items_in_collection_with_length_method
|
170
|
+
}.to fail_with("expected 4 items_in_collection_with_length_method, got 3")
|
171
|
+
expect {
|
172
|
+
expect(owner).to have_exactly(4).items_in_collection_with_size_method
|
173
|
+
}.to fail_with("expected 4 items_in_collection_with_size_method, got 3")
|
174
|
+
expect {
|
175
|
+
expect(owner).to have_exactly(4).items_in_collection_with_count_method
|
176
|
+
}.to fail_with("expected 4 items_in_collection_with_count_method, got 3")
|
177
|
+
end
|
178
|
+
|
179
|
+
it "fails if target has a collection of items with > n members" do
|
180
|
+
owner = create_collection_owner_with(3)
|
181
|
+
expect {
|
182
|
+
expect(owner).to have_exactly(2).items_in_collection_with_length_method
|
183
|
+
}.to fail_with("expected 2 items_in_collection_with_length_method, got 3")
|
184
|
+
expect {
|
185
|
+
expect(owner).to have_exactly(2).items_in_collection_with_size_method
|
186
|
+
}.to fail_with("expected 2 items_in_collection_with_size_method, got 3")
|
187
|
+
expect {
|
188
|
+
expect(owner).to have_exactly(2).items_in_collection_with_count_method
|
189
|
+
}.to fail_with("expected 2 items_in_collection_with_count_method, got 3")
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
describe "expect(...).to have_at_least(n).items" do
|
194
|
+
|
195
|
+
it "passes if target has a collection of items with n members" do
|
196
|
+
owner = create_collection_owner_with(3)
|
197
|
+
expect(owner).to have_at_least(3).items_in_collection_with_length_method
|
198
|
+
expect(owner).to have_at_least(3).items_in_collection_with_size_method
|
199
|
+
expect(owner).to have_at_least(3).items_in_collection_with_count_method
|
200
|
+
end
|
201
|
+
|
202
|
+
it "passes if target has a collection of items with > n members" do
|
203
|
+
owner = create_collection_owner_with(3)
|
204
|
+
expect(owner).to have_at_least(2).items_in_collection_with_length_method
|
205
|
+
expect(owner).to have_at_least(2).items_in_collection_with_size_method
|
206
|
+
expect(owner).to have_at_least(2).items_in_collection_with_count_method
|
207
|
+
end
|
208
|
+
|
209
|
+
it "fails if target has a collection of items with < n members" do
|
210
|
+
owner = create_collection_owner_with(3)
|
211
|
+
expect {
|
212
|
+
expect(owner).to have_at_least(4).items_in_collection_with_length_method
|
213
|
+
}.to fail_with("expected at least 4 items_in_collection_with_length_method, got 3")
|
214
|
+
expect {
|
215
|
+
expect(owner).to have_at_least(4).items_in_collection_with_size_method
|
216
|
+
}.to fail_with("expected at least 4 items_in_collection_with_size_method, got 3")
|
217
|
+
expect {
|
218
|
+
expect(owner).to have_at_least(4).items_in_collection_with_count_method
|
219
|
+
}.to fail_with("expected at least 4 items_in_collection_with_count_method, got 3")
|
220
|
+
end
|
221
|
+
|
222
|
+
it "provides educational negative failure messages" do
|
223
|
+
#given
|
224
|
+
owner = create_collection_owner_with(3)
|
225
|
+
length_matcher = have_at_least(3).items_in_collection_with_length_method
|
226
|
+
size_matcher = have_at_least(3).items_in_collection_with_size_method
|
227
|
+
count_matcher = have_at_least(3).items_in_collection_with_count_method
|
228
|
+
|
229
|
+
#when
|
230
|
+
length_matcher.matches?(owner)
|
231
|
+
size_matcher.matches?(owner)
|
232
|
+
count_matcher.matches?(owner)
|
233
|
+
|
234
|
+
#then
|
235
|
+
expect(length_matcher.failure_message_for_should_not).to eq <<-EOF
|
236
|
+
Isn't life confusing enough?
|
237
|
+
Instead of having to figure out the meaning of this:
|
238
|
+
expect(actual).not_to have_at_least(3).items_in_collection_with_length_method
|
239
|
+
We recommend that you use this instead:
|
240
|
+
expect(actual).to have_at_most(2).items_in_collection_with_length_method
|
241
|
+
EOF
|
242
|
+
|
243
|
+
expect(size_matcher.failure_message_for_should_not).to eq <<-EOF
|
244
|
+
Isn't life confusing enough?
|
245
|
+
Instead of having to figure out the meaning of this:
|
246
|
+
expect(actual).not_to have_at_least(3).items_in_collection_with_size_method
|
247
|
+
We recommend that you use this instead:
|
248
|
+
expect(actual).to have_at_most(2).items_in_collection_with_size_method
|
249
|
+
EOF
|
250
|
+
expect(count_matcher.failure_message_for_should_not).to eq <<-EOF
|
251
|
+
Isn't life confusing enough?
|
252
|
+
Instead of having to figure out the meaning of this:
|
253
|
+
expect(actual).not_to have_at_least(3).items_in_collection_with_count_method
|
254
|
+
We recommend that you use this instead:
|
255
|
+
expect(actual).to have_at_most(2).items_in_collection_with_count_method
|
256
|
+
EOF
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
describe "expect(...).to have_at_most(n).items" do
|
261
|
+
it "passes if target has a collection of items with n members" do
|
262
|
+
owner = create_collection_owner_with(3)
|
263
|
+
expect(owner).to have_at_most(3).items_in_collection_with_length_method
|
264
|
+
expect(owner).to have_at_most(3).items_in_collection_with_size_method
|
265
|
+
expect(owner).to have_at_most(3).items_in_collection_with_count_method
|
266
|
+
end
|
267
|
+
|
268
|
+
it "fails if target has a collection of items with > n members" do
|
269
|
+
owner = create_collection_owner_with(3)
|
270
|
+
expect {
|
271
|
+
expect(owner).to have_at_most(2).items_in_collection_with_length_method
|
272
|
+
}.to fail_with("expected at most 2 items_in_collection_with_length_method, got 3")
|
273
|
+
expect {
|
274
|
+
expect(owner).to have_at_most(2).items_in_collection_with_size_method
|
275
|
+
}.to fail_with("expected at most 2 items_in_collection_with_size_method, got 3")
|
276
|
+
expect {
|
277
|
+
expect(owner).to have_at_most(2).items_in_collection_with_count_method
|
278
|
+
}.to fail_with("expected at most 2 items_in_collection_with_count_method, got 3")
|
279
|
+
end
|
280
|
+
|
281
|
+
it "passes if target has a collection of items with < n members" do
|
282
|
+
owner = create_collection_owner_with(3)
|
283
|
+
expect(owner).to have_at_most(4).items_in_collection_with_length_method
|
284
|
+
expect(owner).to have_at_most(4).items_in_collection_with_size_method
|
285
|
+
expect(owner).to have_at_most(4).items_in_collection_with_count_method
|
286
|
+
end
|
287
|
+
|
288
|
+
it "provides educational negative failure messages" do
|
289
|
+
#given
|
290
|
+
owner = create_collection_owner_with(3)
|
291
|
+
length_matcher = have_at_most(3).items_in_collection_with_length_method
|
292
|
+
size_matcher = have_at_most(3).items_in_collection_with_size_method
|
293
|
+
count_matcher = have_at_most(3).items_in_collection_with_count_method
|
294
|
+
|
295
|
+
#when
|
296
|
+
length_matcher.matches?(owner)
|
297
|
+
size_matcher.matches?(owner)
|
298
|
+
count_matcher.matches?(owner)
|
299
|
+
|
300
|
+
#then
|
301
|
+
expect(length_matcher.failure_message_for_should_not).to eq <<-EOF
|
302
|
+
Isn't life confusing enough?
|
303
|
+
Instead of having to figure out the meaning of this:
|
304
|
+
expect(actual).not_to have_at_most(3).items_in_collection_with_length_method
|
305
|
+
We recommend that you use this instead:
|
306
|
+
expect(actual).to have_at_least(4).items_in_collection_with_length_method
|
307
|
+
EOF
|
308
|
+
|
309
|
+
expect(size_matcher.failure_message_for_should_not).to eq <<-EOF
|
310
|
+
Isn't life confusing enough?
|
311
|
+
Instead of having to figure out the meaning of this:
|
312
|
+
expect(actual).not_to have_at_most(3).items_in_collection_with_size_method
|
313
|
+
We recommend that you use this instead:
|
314
|
+
expect(actual).to have_at_least(4).items_in_collection_with_size_method
|
315
|
+
EOF
|
316
|
+
|
317
|
+
expect(count_matcher.failure_message_for_should_not).to eq <<-EOF
|
318
|
+
Isn't life confusing enough?
|
319
|
+
Instead of having to figure out the meaning of this:
|
320
|
+
expect(actual).not_to have_at_most(3).items_in_collection_with_count_method
|
321
|
+
We recommend that you use this instead:
|
322
|
+
expect(actual).to have_at_least(4).items_in_collection_with_count_method
|
323
|
+
EOF
|
324
|
+
end
|
325
|
+
end
|
326
|
+
|
327
|
+
describe "have(n).items(args, block)" do
|
328
|
+
it "passes args to target" do
|
329
|
+
target = double("target")
|
330
|
+
target.should_receive(:items).with("arg1","arg2").and_return([1,2,3])
|
331
|
+
expect(target).to have(3).items("arg1","arg2")
|
332
|
+
end
|
333
|
+
|
334
|
+
it "passes block to target" do
|
335
|
+
target = double("target")
|
336
|
+
block = lambda { 5 }
|
337
|
+
target.should_receive(:items).with("arg1","arg2", block).and_return([1,2,3])
|
338
|
+
expect(target).to have(3).items("arg1","arg2", block)
|
339
|
+
end
|
340
|
+
end
|
341
|
+
|
342
|
+
describe "have(n).items where target IS a collection" do
|
343
|
+
it "references the number of items IN the collection" do
|
344
|
+
expect([1,2,3]).to have(3).items
|
345
|
+
end
|
346
|
+
|
347
|
+
it "fails when the number of items IN the collection is not as expected" do
|
348
|
+
expect {
|
349
|
+
expect([1,2,3]).to have(7).items
|
350
|
+
}.to fail_with("expected 7 items, got 3")
|
351
|
+
end
|
352
|
+
end
|
353
|
+
|
354
|
+
describe "have(n).characters where target IS a String" do
|
355
|
+
it "passes if the length is correct" do
|
356
|
+
expect("this string").to have(11).characters
|
357
|
+
end
|
358
|
+
|
359
|
+
it "fails if the length is incorrect" do
|
360
|
+
expect {
|
361
|
+
expect("this string").to have(12).characters
|
362
|
+
}.to fail_with("expected 12 characters, got 11")
|
363
|
+
end
|
364
|
+
end
|
365
|
+
|
366
|
+
describe "have(n).things on an object which is not a collection nor contains one" do
|
367
|
+
it "fails" do
|
368
|
+
expect {
|
369
|
+
expect(Object.new).to have(2).things
|
370
|
+
}.to raise_error(NoMethodError) { |e|
|
371
|
+
expect(e.name).to eq :things
|
372
|
+
}
|
373
|
+
end
|
374
|
+
end
|
375
|
+
|
376
|
+
describe RSpec::CollectionMatchers::Have, "for a collection owner that implements #send" do
|
377
|
+
before(:each) do
|
378
|
+
@collection = Object.new
|
379
|
+
def @collection.floozles; [1,2] end
|
380
|
+
def @collection.send; :sent; end
|
381
|
+
end
|
382
|
+
|
383
|
+
it "works in the straightforward case" do
|
384
|
+
expect(@collection).to have(2).floozles
|
385
|
+
end
|
386
|
+
|
387
|
+
it "works when doing automatic pluralization" do
|
388
|
+
expect(@collection).to have_at_least(1).floozle
|
389
|
+
end
|
390
|
+
|
391
|
+
it "blows up when the owner doesn't respond to that method" do
|
392
|
+
expect {
|
393
|
+
expect(@collection).to have(99).problems
|
394
|
+
}.to raise_error(NoMethodError, /problems/)
|
395
|
+
end
|
396
|
+
|
397
|
+
it 'works when #send is defined directly on an array' do
|
398
|
+
array = [1, 2]
|
399
|
+
def array.send; :sent; end
|
400
|
+
|
401
|
+
expect(array).to have(2).items
|
402
|
+
end
|
403
|
+
end
|
404
|
+
|
405
|
+
if RUBY_VERSION >= '2.0'
|
406
|
+
describe RSpec::CollectionMatchers::Have, "for an Enumerator whose size is nil but count is supplied" do
|
407
|
+
let(:enumerator) { %w[a b c d].to_enum(:each) }
|
408
|
+
|
409
|
+
it 'works fine' do
|
410
|
+
expect(enumerator).to have(4).items
|
411
|
+
end
|
412
|
+
end
|
413
|
+
end
|
414
|
+
|
415
|
+
describe RSpec::CollectionMatchers::Have do
|
416
|
+
it "has method_missing as private" do
|
417
|
+
expect(described_class.private_instance_methods).to include_method(:method_missing)
|
418
|
+
end
|
419
|
+
|
420
|
+
it "does not respond_to? method_missing (because it's private)" do
|
421
|
+
formatter = described_class.new(0, StringIO.new)
|
422
|
+
expect(formatter).not_to respond_to(:method_missing)
|
423
|
+
end
|
424
|
+
|
425
|
+
describe "respond_to?" do
|
426
|
+
before :each do
|
427
|
+
@have = described_class.new(:foo)
|
428
|
+
@a_method_which_have_defines = described_class.instance_methods.first
|
429
|
+
@a_method_which_object_defines = Object.instance_methods.first
|
430
|
+
end
|
431
|
+
|
432
|
+
it "is true for a method which Have defines" do
|
433
|
+
expect(@have).to respond_to(@a_method_which_have_defines)
|
434
|
+
end
|
435
|
+
|
436
|
+
it "is true for a method that it's superclass (Object) defines" do
|
437
|
+
expect(@have).to respond_to(@a_method_which_object_defines)
|
438
|
+
end
|
439
|
+
|
440
|
+
it "is false for a method which neither Object nor nor Have defines" do
|
441
|
+
expect(@have).not_to respond_to(:foo_bar_baz)
|
442
|
+
end
|
443
|
+
|
444
|
+
it "is false if the owner doesn't respond to the method" do
|
445
|
+
have = described_class.new(99)
|
446
|
+
expect(have).not_to respond_to(:problems)
|
447
|
+
end
|
448
|
+
|
449
|
+
it "is true if the owner responds to the method" do
|
450
|
+
have = described_class.new(:a_symbol)
|
451
|
+
expect(have).to respond_to(:to_sym)
|
452
|
+
end
|
453
|
+
end
|
454
|
+
end
|
455
|
+
|
456
|
+
|
457
|
+
context "description generation" do
|
458
|
+
let(:team) do
|
459
|
+
Class.new do
|
460
|
+
def players
|
461
|
+
[1,2,3]
|
462
|
+
end
|
463
|
+
end.new
|
464
|
+
end
|
465
|
+
|
466
|
+
describe "the have matcher" do
|
467
|
+
it "generates its own description" do
|
468
|
+
expect(team).to have(3).players
|
469
|
+
expect(RSpec::Matchers.generated_description).to eq "should have 3 players"
|
470
|
+
end
|
471
|
+
end
|
472
|
+
|
473
|
+
describe "the have_at_least matcher"do
|
474
|
+
it "generates its own description" do
|
475
|
+
expect(team).to have_at_least(2).players
|
476
|
+
expect(RSpec::Matchers.generated_description).to eq "should have at least 2 players"
|
477
|
+
end
|
478
|
+
end
|
479
|
+
|
480
|
+
describe "the have_at_most matcher" do
|
481
|
+
it "generates its own description" do
|
482
|
+
expect(team).to have_at_most(4).players
|
483
|
+
expect(RSpec::Matchers.generated_description).to eq "should have at most 4 players"
|
484
|
+
end
|
485
|
+
end
|
486
|
+
end
|
487
|
+
end
|