rspec-collection_matchers 0.0.1.pre → 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -0,0 +1,5 @@
1
+ module RSpec
2
+ module CollectionMatchers
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -1,19 +1,24 @@
1
- # -*- encoding: utf-8 -*-
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-collection_matchers/version'
4
+ require 'rspec/collection_matchers/version'
5
5
 
6
- Gem::Specification.new do |gem|
7
- gem.name = "rspec-collection_matchers"
8
- gem.version = Rspec::CollectionMatchers::VERSION
9
- gem.authors = ["Myron Marston"]
10
- gem.email = ["myron.marston@gmail.com"]
11
- gem.description = %q{}
12
- gem.summary = %q{Collection cardinality matchers, extracted from rspec-expectations}
13
- gem.homepage = ""
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
- gem.files = `git ls-files`.split($/)
16
- gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
- gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
- gem.require_paths = ["lib"]
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