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.
@@ -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