delegate_matcher 0.3 → 0.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![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
|
-
|
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
|