delegate_matcher 0.3 → 0.4

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.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +3 -3
  3. data/README.md +101 -8
  4. data/README.md.erb +216 -0
  5. data/Rakefile +6 -1
  6. data/delegate_matcher.gemspec +1 -1
  7. data/lib/delegate_matcher/delegate.rb +5 -12
  8. data/lib/delegate_matcher/delegate_matcher.rb +5 -14
  9. data/lib/delegate_matcher/delegation.rb +32 -23
  10. data/lib/delegate_matcher/dispatcher.rb +4 -1
  11. data/lib/delegate_matcher/expected.rb +31 -18
  12. data/lib/delegate_matcher/nil_delegate.rb +3 -2
  13. data/lib/delegate_matcher/stub_delegate.rb +7 -3
  14. data/lib/delegate_matcher/version.rb +1 -1
  15. data/spec/{lib → examples}/active_support_delegation_spec.rb +11 -2
  16. data/spec/{lib → examples}/forwardable_delegation_spec.rb +11 -2
  17. data/spec/shared/author.rb +23 -0
  18. data/spec/{lib/shared/a_simple_delegator.rb → shared/basic.rb} +4 -6
  19. data/spec/{lib/shared → shared}/nil_check.rb +15 -15
  20. data/spec/shared/post_delegation.rb +42 -0
  21. data/spec/shared/post_methods.rb +15 -0
  22. data/spec/spec_helper.rb +1 -1
  23. data/spec/to_a_class_method_spec.rb +37 -0
  24. data/spec/to_a_class_variable_spec.rb +38 -0
  25. data/spec/to_a_constant_spec.rb +37 -0
  26. data/spec/to_an_instance_method_spec.rb +39 -0
  27. data/spec/to_an_instance_variable_spec.rb +35 -0
  28. data/spec/to_an_object_spec.rb +45 -0
  29. data/spec/to_multiple_targets_spec.rb +34 -0
  30. data/spec/with_args_spec.rb +151 -0
  31. data/spec/with_as_spec.rb +25 -0
  32. data/spec/with_block_spec.rb +75 -0
  33. data/spec/with_prefix_spec.rb +37 -0
  34. data/spec/with_return_value_spec.rb +46 -0
  35. data/spec/with_to_spec.rb +53 -0
  36. metadata +45 -43
  37. data/.bundle/config +0 -3
  38. data/spec/lib/aggregate_delegate_matcher_spec.rb +0 -62
  39. data/spec/lib/class_method_spec.rb +0 -84
  40. data/spec/lib/class_variable_spec.rb +0 -85
  41. data/spec/lib/constant_spec.rb +0 -86
  42. data/spec/lib/delegate_spec.rb +0 -15
  43. data/spec/lib/instance_method_spec.rb +0 -84
  44. data/spec/lib/instance_variable_spec.rb +0 -102
  45. data/spec/lib/object_spec.rb +0 -103
  46. data/spec/lib/shared/args.rb +0 -24
  47. data/spec/lib/shared/args_and_a_block.rb +0 -6
  48. data/spec/lib/shared/author.rb +0 -10
  49. data/spec/lib/shared/block.rb +0 -71
  50. data/spec/lib/shared/different_method_name.rb +0 -12
  51. data/spec/lib/shared/different_return_value.rb +0 -19
  52. data/spec/lib/shared/prefix.rb +0 -16
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b01a0155696471c53b2e5d758ee3acfb321fe843
4
- data.tar.gz: 5c153cefb6be729954baf5f1a71251f929ab7d15
3
+ metadata.gz: 5e342a7ea43c74991c773ae7093fd017383dd22e
4
+ data.tar.gz: f9b3cec53a47692c6b65ca529b46a59bc89a8a68
5
5
  SHA512:
6
- metadata.gz: d2bbb26693117c40694240b49c5f1ecc192aaa0d6bdd5a3b1dbecb6e5c1bfc4b4b6e40a6a462143139001f036726dea5ff865ffb90a2b394f15107ee411f2c9e
7
- data.tar.gz: a52c23c8dea9252b407dc9aead40ace210095d19de17ab469547bd8514589f1e0c2ccfbf9e8c2648f43820ab533b2a4d23a4212908c50a4e25b6b12a89ac6419
6
+ metadata.gz: 4a91f85a9c888ea5e659c1dbdeeac00a0395eabf55149beba29a3d123bd22d38e6e5d1a209df6e3a747483b1a6e22dfe158aea9834f7c62e79d44e00c57bf6b7
7
+ data.tar.gz: f2c93b90808e178b51b6ac52bffc6e7ff62473397618371c258b5f1c6421683b652a3cac70a4128213f7ad9544b1df1f51956492498f68530406ffd2304d177a
data/Gemfile.lock CHANGED
@@ -1,8 +1,8 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- delegate_matcher (0.3)
5
- proc_extensions (~> 0.1)
4
+ delegate_matcher (0.4)
5
+ proc_extensions (~> 0.2)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
@@ -66,7 +66,7 @@ GEM
66
66
  parser (2.2.3.0)
67
67
  ast (>= 1.1, < 3.0)
68
68
  powerpack (0.1.1)
69
- proc_extensions (0.1.2)
69
+ proc_extensions (0.2)
70
70
  sourcify (~> 0.5)
71
71
  pry (0.10.3)
72
72
  coderay (~> 1.1.0)
data/README.md CHANGED
@@ -41,6 +41,7 @@ This matcher allows you to validate delegation to:
41
41
  * class variables
42
42
  * constants
43
43
  * arbitrary objects
44
+ * multiple targets
44
45
 
45
46
  ```ruby
46
47
  describe Post do
@@ -112,13 +113,29 @@ describe Post do
112
113
  end
113
114
  ```
114
115
 
115
- Also, in some cases the delegator might make minor changes to the arguments. While this is arguably no
116
+ Also, in some cases, the delegator change the arguments. While this is arguably no
116
117
  longer true delegation you can still check that arguments are correctly passed by using a second `with`
117
118
  method to specify the arguments expected by the delegate.
118
119
 
119
120
  ```ruby
120
121
  describe Post do
121
- it { should delegate(:name).with('Ms.')to(:author).with('Miss') } # name('Ms.') => author.name('Miss')
122
+ it { should delegate(:name).with('Ms.').to(:author).with('Miss') } # name('Ms.') => author.name('Miss')
123
+ end
124
+ ```
125
+ You can use the `with(no_args).` rather than `with.` or `with().` to test delegation with no arguments passed
126
+ to the delegator.
127
+
128
+ ```ruby
129
+ describe Post do
130
+ it { should delegate(:name).with(no_args).to(:author) } # name() => author.name()
131
+ end
132
+ ```
133
+
134
+ For the second `with` you can use any RSpec argument matcher.
135
+
136
+ ```ruby
137
+ describe Post do
138
+ it { should delegate(:name).with('Ms.').to(:author).with(anything) } # name('Ms.') => author.name(*)
122
139
  end
123
140
  ```
124
141
 
@@ -144,6 +161,11 @@ describe Post do
144
161
  end
145
162
  ```
146
163
 
164
+ If the `proc` passed to `with_block` is not the same `proc` used y the delegator
165
+ then the sources of the `proc`'s will be compared for equality using the `proc_extensions` gem.
166
+ For this comparison to work the `proc` must not be not have been created via an `eval` of a string
167
+ and must be the only `proc` declared on that line of source code.
168
+
147
169
  See [proc_extensions](https://github.com/dwhelan/proc_extensions/) for more details on how the source for procs is compared.
148
170
 
149
171
  ### Return Value
@@ -156,10 +178,55 @@ describe Post do
156
178
  end
157
179
  ```
158
180
 
181
+ ### Multiple Targets
182
+ You can test delegation to more than one target by specifing more than one target via `to`.
183
+ ```ruby
184
+ require 'spec_helper'
185
+
186
+ module RSpec
187
+ module Matchers
188
+ module DelegateMatcher
189
+ module Composite
190
+ describe 'delegation to multiple targets' do
191
+ class Post
192
+ include PostMethods
193
+
194
+ attr_accessor :authors, :catherine_asaro, :isaac_asimov
195
+
196
+ def initialize
197
+ self.catherine_asaro = Author.new('Catherine Asaro')
198
+ self.isaac_asimov = Author.new('Isaac Asimov')
199
+ self.authors = [catherine_asaro, isaac_asimov]
200
+ end
201
+
202
+ def name
203
+ authors.map(&:name)
204
+ end
205
+ end
206
+
207
+ subject { Post.new }
208
+
209
+ it { should delegate(:name).to(*subject.authors) }
210
+ it { should delegate(:name).to(subject.catherine_asaro, subject.isaac_asimov) }
211
+ it { should delegate(:name).to(:catherine_asaro, :isaac_asimov) }
212
+ it { should delegate(:name).to(:@catherine_asaro, :@isaac_asimov) }
213
+ end
214
+ end
215
+ end
216
+ end
217
+ end
218
+
219
+ ```
220
+
159
221
  ### Active Support
160
222
  You can test delegation based on the [delegate](http://api.rubyonrails.org/classes/Module.html#method-i-delegate) method in the Active Support gem.
161
223
 
162
224
  ```ruby
225
+ require 'spec_helper'
226
+ require 'active_support/core_ext/module/delegation'
227
+
228
+ module ActiveSupportDelegation
229
+ # rubocop:disable Style/ClassVars
163
230
  class Post
164
231
  attr_accessor :author
165
232
 
@@ -172,15 +239,24 @@ You can test delegation based on the [delegate](http://api.rubyonrails.org/class
172
239
  delegate :name, to: :class, prefix: true
173
240
  delegate :count, to: :@@authors
174
241
  delegate :first, to: :GENRES
242
+ delegate :length, to: :'author.name', prefix: :name
175
243
 
176
244
  def initialize
177
245
  @author = Author.new
178
246
  end
247
+
248
+ def inspect
249
+ 'post'
250
+ end
179
251
  end
180
252
 
181
253
  class Author
182
- def name
183
- @name ||= 'Catherine Asaro'
254
+ def initialize
255
+ @name = 'Catherine Asaro'
256
+ end
257
+
258
+ def name(*)
259
+ @name
184
260
  end
185
261
  end
186
262
 
@@ -197,6 +273,7 @@ You can test delegation based on the [delegate](http://api.rubyonrails.org/class
197
273
  it { should delegate(:name).to(:author).with_prefix(:writer) }
198
274
  it { should delegate(:name).to(:author).with_block }
199
275
  it { should delegate(:name).to(:author).with('Ms.') }
276
+ it { should delegate(:name).to(:author).with('Ms.').with_block }
200
277
 
201
278
  it { should delegate(:name).to(:class).with_prefix }
202
279
  it { should delegate(:count).to(:@@authors) }
@@ -205,15 +282,19 @@ You can test delegation based on the [delegate](http://api.rubyonrails.org/class
205
282
  it { should delegate(:name_length).to(:'author.name').as(:length) }
206
283
  it { should delegate(:length).to(:'author.name').with_prefix(:name) }
207
284
  end
285
+ end
286
+
208
287
  ```
209
288
  However, don't use the following features as they are not supported by the delegate method:
210
289
  * delegation to objects
211
- * different arguments passed to delegate
212
290
 
213
291
  ### Forwardable Module
214
292
  You can test delegation based on the [Forwardable](http://ruby-doc.org/stdlib-2.0.0/libdoc/forwardable/rdoc/Forwardable.html) module.
215
293
 
216
294
  ```ruby
295
+ require 'spec_helper'
296
+
297
+ module ForwardableDelegation
217
298
  class Post
218
299
  extend Forwardable
219
300
 
@@ -226,11 +307,21 @@ You can test delegation based on the [Forwardable](http://ruby-doc.org/stdlib-2.
226
307
  def_delegator :author, :name
227
308
  def_delegator :author, :name, :author_name
228
309
  def_delegator :author, :name, :writer
310
+
311
+ def_delegator :'author.name', :length, :name_length
312
+
313
+ def inspect
314
+ 'post'
315
+ end
229
316
  end
230
317
 
231
318
  class Author
232
- def name
233
- @name ||= 'Catherine Asaro'
319
+ def initialize
320
+ @name = 'Catherine Asaro'
321
+ end
322
+
323
+ def name(*)
324
+ @name
234
325
  end
235
326
  end
236
327
 
@@ -244,19 +335,21 @@ You can test delegation based on the [Forwardable](http://ruby-doc.org/stdlib-2.
244
335
  it { should delegate(:name).to(:author) }
245
336
  it { should delegate(:name).to(:author).with('Ms.') }
246
337
  it { should delegate(:name).to(:author).with_block }
338
+ it { should delegate(:name).to(:author).with('Ms.').with_block }
247
339
  it { should delegate(:name).to(:author).with_prefix }
248
340
  it { should delegate(:writer).to(:author).as(:name) }
249
341
 
250
342
  it { should delegate(:name_length).to(:'author.name').as(:length) }
251
343
  it { should delegate(:length).to(:'author.name').with_prefix(:name) }
252
344
  end
345
+ end
346
+
253
347
  ```
254
348
  However, don't use the following features as they are not supported by the Forwardable module:
255
349
  * `allow_nil`
256
350
  * delegation to class variables
257
351
  * delegation to constants
258
352
  * delegation to objects
259
- * different arguments passed to the delegate
260
353
 
261
354
  ## Contributing
262
355
  1. Fork it ( https://github.com/dwhelan/delegate_matcher/fork )
data/README.md.erb ADDED
@@ -0,0 +1,216 @@
1
+ [![Gem Version](https://badge.fury.io/rb/delegate_matcher.png)](http://badge.fury.io/rb/delegate_matcher)
2
+ [![Build Status](https://travis-ci.org/dwhelan/delegate_matcher.png?branch=master)](https://travis-ci.org/dwhelan/delegate_matcher)
3
+ [![Code Climate](https://codeclimate.com/github/dwhelan/delegate_matcher/badges/gpa.svg)](https://codeclimate.com/github/dwhelan/delegate_matcher)
4
+ [![Coverage Status](https://coveralls.io/repos/dwhelan/delegate_matcher/badge.svg?branch=master&service=github)](https://coveralls.io/github/dwhelan/delegate_matcher?branch=master)
5
+
6
+ # Delegate Matcher
7
+ An RSpec matcher for validating delegation. This matcher works with delegation based on the [Forwardable](http://ruby-doc.org/stdlib-2.0.0/libdoc/forwardable/rdoc/Forwardable.html) module,
8
+ the [delegate](http://api.rubyonrails.org/classes/Module.html#method-i-delegate) method in the Active Support gem or with
9
+ simple custom delegation.
10
+
11
+ ## Installation
12
+ Add this line to your application's Gemfile:
13
+
14
+ ```ruby
15
+ gem 'delegate_matcher'
16
+ ```
17
+
18
+ And then execute:
19
+
20
+ ```bash
21
+ $ bundle
22
+ ```
23
+
24
+ Or install it yourself as:
25
+
26
+ ```bash
27
+ $ gem install delegate_matcher
28
+ ```
29
+
30
+ Then add the following to your `spec_helper.rb` file:
31
+
32
+ ```ruby
33
+ require 'delegate_matcher'
34
+ ```
35
+
36
+ ## Usage
37
+ This matcher allows you to validate delegation to:
38
+ * instance methods
39
+ * class methods
40
+ * instance variables
41
+ * class variables
42
+ * constants
43
+ * arbitrary objects
44
+ * multiple targets
45
+
46
+ ```ruby
47
+ describe Post do
48
+ it { should delegate(:name).to(:author) } # name => author().name instance method
49
+ it { should delegate(:name).to(:class) } # name => self.class.name class method
50
+ it { should delegate(:name).to(:@author) } # name => @author.name instance variable
51
+ it { should delegate(:name).to(:@@author) } # name => @@author.name class variable
52
+ it { should delegate(:first).to(:GENRES) } # first => GENRES.first constant
53
+ it { should delegate(:name).to(author) } # name => author.name object
54
+ end
55
+ ```
56
+
57
+ ### Delegate Method Name
58
+ If the name of the method being invoked on the delegate is different from the method being called you
59
+ can check this using the `with_prefix` method (based on Active Support `delegate` method) or the
60
+ `as` method.
61
+
62
+ ```ruby
63
+ describe Post do
64
+ it { should delegate(:name).to(:author).with_prefix } # author_name => author.name
65
+ it { should delegate(:name).to(:author).with_prefix(:writer) } # writer_name => author.name
66
+ it { should delegate(:writer).to(:author).as(:name) } # writer => author.name
67
+ end
68
+ ```
69
+
70
+ **Note**: if you are delegating to an object (i.e. `to` is not a string or symbol) then a prefix of `''` will be used:
71
+
72
+ ```ruby
73
+ describe Post do
74
+ it { should delegate(:name).to(author).with_prefix } # an error will be raised
75
+ it { should delegate(:name).to(author).with_prefix(:writer) } # writer_name => author.name
76
+ end
77
+ ```
78
+
79
+ You can test delegation to a chain of objects by using a `to` that can be `eval`'d.
80
+
81
+ ```ruby
82
+ describe Post do
83
+ it { should delegate(:name_length).to(:'author.name').as(:length) } # name_length => author.name.length
84
+ it { should delegate(:length).to(:'author.name').with_prefix(:name) } # name_length => author.name.length
85
+ end
86
+ ```
87
+
88
+ ### Handling Nil Delegates
89
+ If you expect the delegate to return `nil` when the delegate is `nil` rather than raising an error
90
+ then you can check this using the `allow_nil` method.
91
+
92
+ ```ruby
93
+ describe Post do
94
+ it { should delegate(:name).to(:author).allow_nil } # name => author && author.name
95
+ it { should delegate(:name).to(:author).allow_nil(true) } # name => author && author.name
96
+ it { should delegate(:name).to(:author).allow_nil(false) } # name => author.name
97
+ end
98
+ ```
99
+
100
+ Nil handling is only checked if `allow_nil` is specified.
101
+
102
+ Note that the matcher will raise an error if you use this when checking delegation to an
103
+ object since the matcher cannot validate `nil` handling as it cannot gain access to the subject
104
+ reference to the object to set it `nil`.
105
+
106
+ ### Arguments
107
+ If the method being delegated takes arguments you can supply them with the `with` method. The matcher
108
+ will check that the provided arguments are in turn passed to the delegate.
109
+
110
+ ```ruby
111
+ describe Post do
112
+ it { should delegate(:name).with('Ms.').to(:author) } # name('Ms.') => author.name('Ms.')
113
+ end
114
+ ```
115
+
116
+ Also, in some cases, the delegator change the arguments. While this is arguably no
117
+ longer true delegation you can still check that arguments are correctly passed by using a second `with`
118
+ method to specify the arguments expected by the delegate.
119
+
120
+ ```ruby
121
+ describe Post do
122
+ it { should delegate(:name).with('Ms.').to(:author).with('Miss') } # name('Ms.') => author.name('Miss')
123
+ end
124
+ ```
125
+ You can use the `with(no_args).` rather than `with.` or `with().` to test delegation with no arguments passed
126
+ to the delegator.
127
+
128
+ ```ruby
129
+ describe Post do
130
+ it { should delegate(:name).with(no_args).to(:author) } # name() => author.name()
131
+ end
132
+ ```
133
+
134
+ For the second `with` you can use any RSpec argument matcher.
135
+
136
+ ```ruby
137
+ describe Post do
138
+ it { should delegate(:name).with('Ms.').to(:author).with(anything) } # name('Ms.') => author.name(*)
139
+ end
140
+ ```
141
+
142
+ ### Blocks
143
+ You can check that a block passed is in turn passed to the delegate via the `with_block` method.
144
+ By default, block delegation is only checked if `with_a_block` or `without_a_block` is specified.
145
+
146
+ ```ruby
147
+ describe Post do
148
+ it { should delegate(:name).to(author).with_a_block } # name(&block) => author.name(&block)
149
+ it { should delegate(:name).to(author).with_block } # name(&block) => author.name(&block) # alias for with_a_block
150
+
151
+ it { should delegate(:name).to(author).without_a_block } # name(&block) => author.name
152
+ it { should delegate(:name).to(author).without_block } # name(&block) => author.name # alias for without_a_block
153
+ end
154
+ ```
155
+ You can also pass an explicit block in which case the block passed will be compared against
156
+ the block received by the delegate. The comparison is based on having equivalent source for the blocks.
157
+
158
+ ```ruby
159
+ describe Post do
160
+ it { should delegate(:tainted?).to(authors).as(:all?).with_block { |a| a.tainted? } } # tainted? => authors.all? { |a| a.tainted? }
161
+ end
162
+ ```
163
+
164
+ If the `proc` passed to `with_block` is not the same `proc` used y the delegator
165
+ then the sources of the `proc`'s will be compared for equality using the `proc_extensions` gem.
166
+ For this comparison to work the `proc` must not be not have been created via an `eval` of a string
167
+ and must be the only `proc` declared on that line of source code.
168
+
169
+ See [proc_extensions](https://github.com/dwhelan/proc_extensions/) for more details on how the source for procs is compared.
170
+
171
+ ### Return Value
172
+ Normally the matcher will check that the value return is the same as the value
173
+ returned from the delegate. You can skip this check by using `without_return`.
174
+
175
+ ```ruby
176
+ describe Post do
177
+ it { should delegate(:name).to(:author).without_return }
178
+ end
179
+ ```
180
+
181
+ ### Multiple Targets
182
+ You can test delegation to more than one target by specifing more than one target via `to`.
183
+ ```ruby
184
+ <%= File.open('./spec/to_multiple_targets_spec.rb', 'rb') { |f| f.read } %>
185
+ ```
186
+
187
+ ### Active Support
188
+ You can test delegation based on the [delegate](http://api.rubyonrails.org/classes/Module.html#method-i-delegate) method in the Active Support gem.
189
+
190
+ ```ruby
191
+ <%= File.open('./spec/examples/active_support_delegation_spec.rb', 'rb') { |f| f.read } %>
192
+ ```
193
+ However, don't use the following features as they are not supported by the delegate method:
194
+ * delegation to objects
195
+
196
+ ### Forwardable Module
197
+ You can test delegation based on the [Forwardable](http://ruby-doc.org/stdlib-2.0.0/libdoc/forwardable/rdoc/Forwardable.html) module.
198
+
199
+ ```ruby
200
+ <%= File.open('./spec/examples/forwardable_delegation_spec.rb', 'rb') { |f| f.read } %>
201
+ ```
202
+ However, don't use the following features as they are not supported by the Forwardable module:
203
+ * `allow_nil`
204
+ * delegation to class variables
205
+ * delegation to constants
206
+ * delegation to objects
207
+
208
+ ## Contributing
209
+ 1. Fork it ( https://github.com/dwhelan/delegate_matcher/fork )
210
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
211
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
212
+ 4. Push to the branch (`git push origin my-new-feature`)
213
+ 5. Create a new Pull Request
214
+
215
+ ## Notes
216
+ This matcher was inspired by [Alan Winograd](https://github.com/awinograd) via the gist https://gist.github.com/awinograd/6158961
data/Rakefile CHANGED
@@ -7,4 +7,9 @@ RuboCop::RakeTask.new do |task|
7
7
  task.options << '--display-cop-names'
8
8
  end
9
9
 
10
- task default: [:spec, :rubocop, :build]
10
+ desc 'Updates README with code examples'
11
+ task :readme do
12
+ `erb README.md.erb > README.md`
13
+ end
14
+
15
+ task default: [:spec, :rubocop, :readme, :build]
@@ -19,7 +19,7 @@ Gem::Specification.new do |gem|
19
19
  gem.test_files = gem.files.grep(%r{^spec/})
20
20
  gem.require_paths = ['lib']
21
21
 
22
- gem.add_runtime_dependency 'proc_extensions', '~> 0.1'
22
+ gem.add_runtime_dependency 'proc_extensions', '~> 0.2'
23
23
 
24
24
  gem.add_development_dependency 'activesupport', '~> 4.2'
25
25
  gem.add_development_dependency 'bundler', '~> 1.7'
@@ -6,10 +6,11 @@ module RSpec
6
6
 
7
7
  RSpec::Mocks::Syntax.enable_expect(self)
8
8
 
9
- attr_reader :received, :args
9
+ attr_reader :to, :received, :args
10
10
 
11
- def initialize(expected)
11
+ def initialize(expected, to)
12
12
  self.expected = expected
13
+ self.to = to
13
14
  self.received = false
14
15
  end
15
16
 
@@ -33,26 +34,18 @@ module RSpec
33
34
  end
34
35
 
35
36
  def argument_description
36
- args ? "(#{args.map { |a| format('%p', a) }.join(', ')})" : ''
37
- end
38
-
39
- def return_value
40
- self
37
+ args ? "(#{args.map(&:inspect).join(', ')})" : ''
41
38
  end
42
39
 
43
40
  private
44
41
 
45
42
  attr_accessor :expected
46
- attr_writer :received, :args, :block
43
+ attr_writer :to, :received, :args, :block
47
44
 
48
45
  def subject
49
46
  expected.subject
50
47
  end
51
48
 
52
- def to
53
- expected.to
54
- end
55
-
56
49
  def name
57
50
  to.to_s
58
51
  end
@@ -4,7 +4,9 @@ module RSpec
4
4
  module Matchers
5
5
  define(:delegate) do |method_name|
6
6
  match do |subject|
7
- delegation_ok?(method_name, subject)
7
+ fail 'need to provide a "to"' unless expected.to
8
+ expected.subject = subject
9
+ delegation.ok?
8
10
  end
9
11
 
10
12
  description do
@@ -19,7 +21,7 @@ module RSpec
19
21
  delegation.failure_message(true) || super
20
22
  end
21
23
 
22
- chain(:to) { |to| expected.to = to }
24
+ chain(:to) { |*to| expected.to = *to; expected.method_name = method_name }
23
25
  chain(:as) { |as| expected.as = as }
24
26
  chain(:allow_nil) { |allow_nil = true| expected.allow_nil = allow_nil }
25
27
  chain(:with_prefix) { |prefix = nil| expected.prefix = prefix }
@@ -27,6 +29,7 @@ module RSpec
27
29
  chain(:with_a_block) { |&block| expected.block = block || true }
28
30
  chain(:without_a_block) { expected.block = false }
29
31
  chain(:without_return) { expected.check_return = false }
32
+ chain(:and_return) { |value| expected.return_value = value }
30
33
 
31
34
  alias_method :with_block, :with_a_block
32
35
  alias_method :without_block, :without_a_block
@@ -40,18 +43,6 @@ module RSpec
40
43
  def expected
41
44
  @expected ||= DelegateMatcher::Expected.new
42
45
  end
43
-
44
- def delegation_ok?(method_name, subject)
45
- fail 'need to provide a "to"' unless expected.to
46
-
47
- expected.method_name = method_name
48
- expected.subject = subject
49
-
50
- delegation.ok?
51
- end
52
46
  end
53
47
  end
54
48
  end
55
-
56
- # TODO: Handle nested delegation strings "a.b.c"
57
- # TODO: Test SingleForwardable