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.
- checksums.yaml +4 -4
- data/Gemfile.lock +3 -3
- data/README.md +101 -8
- data/README.md.erb +216 -0
- data/Rakefile +6 -1
- data/delegate_matcher.gemspec +1 -1
- data/lib/delegate_matcher/delegate.rb +5 -12
- data/lib/delegate_matcher/delegate_matcher.rb +5 -14
- data/lib/delegate_matcher/delegation.rb +32 -23
- data/lib/delegate_matcher/dispatcher.rb +4 -1
- data/lib/delegate_matcher/expected.rb +31 -18
- data/lib/delegate_matcher/nil_delegate.rb +3 -2
- data/lib/delegate_matcher/stub_delegate.rb +7 -3
- data/lib/delegate_matcher/version.rb +1 -1
- data/spec/{lib → examples}/active_support_delegation_spec.rb +11 -2
- data/spec/{lib → examples}/forwardable_delegation_spec.rb +11 -2
- data/spec/shared/author.rb +23 -0
- data/spec/{lib/shared/a_simple_delegator.rb → shared/basic.rb} +4 -6
- data/spec/{lib/shared → shared}/nil_check.rb +15 -15
- data/spec/shared/post_delegation.rb +42 -0
- data/spec/shared/post_methods.rb +15 -0
- data/spec/spec_helper.rb +1 -1
- data/spec/to_a_class_method_spec.rb +37 -0
- data/spec/to_a_class_variable_spec.rb +38 -0
- data/spec/to_a_constant_spec.rb +37 -0
- data/spec/to_an_instance_method_spec.rb +39 -0
- data/spec/to_an_instance_variable_spec.rb +35 -0
- data/spec/to_an_object_spec.rb +45 -0
- data/spec/to_multiple_targets_spec.rb +34 -0
- data/spec/with_args_spec.rb +151 -0
- data/spec/with_as_spec.rb +25 -0
- data/spec/with_block_spec.rb +75 -0
- data/spec/with_prefix_spec.rb +37 -0
- data/spec/with_return_value_spec.rb +46 -0
- data/spec/with_to_spec.rb +53 -0
- metadata +45 -43
- data/.bundle/config +0 -3
- data/spec/lib/aggregate_delegate_matcher_spec.rb +0 -62
- data/spec/lib/class_method_spec.rb +0 -84
- data/spec/lib/class_variable_spec.rb +0 -85
- data/spec/lib/constant_spec.rb +0 -86
- data/spec/lib/delegate_spec.rb +0 -15
- data/spec/lib/instance_method_spec.rb +0 -84
- data/spec/lib/instance_variable_spec.rb +0 -102
- data/spec/lib/object_spec.rb +0 -103
- data/spec/lib/shared/args.rb +0 -24
- data/spec/lib/shared/args_and_a_block.rb +0 -6
- data/spec/lib/shared/author.rb +0 -10
- data/spec/lib/shared/block.rb +0 -71
- data/spec/lib/shared/different_method_name.rb +0 -12
- data/spec/lib/shared/different_return_value.rb +0 -19
- data/spec/lib/shared/prefix.rb +0 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5e342a7ea43c74991c773ae7093fd017383dd22e
|
4
|
+
data.tar.gz: f9b3cec53a47692c6b65ca529b46a59bc89a8a68
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
5
|
-
proc_extensions (~> 0.
|
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.
|
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
|
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
|
183
|
-
@name
|
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
|
233
|
-
@name
|
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
|
+
[](http://badge.fury.io/rb/delegate_matcher)
|
2
|
+
[](https://travis-ci.org/dwhelan/delegate_matcher)
|
3
|
+
[](https://codeclimate.com/github/dwhelan/delegate_matcher)
|
4
|
+
[](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
|
-
|
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]
|
data/delegate_matcher.gemspec
CHANGED
@@ -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.
|
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
|
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
|
-
|
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) {
|
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
|