delegate_matcher 0.1 → 0.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 70876c332f24b6734e75025e90814f096a922405
4
- data.tar.gz: e7ba6dd00b072b61cfdd84d6be52015f4a974ddf
3
+ metadata.gz: d9489b0d0927d6b2af4766edaf7edc2d4788867e
4
+ data.tar.gz: d27938e9a9fe51eeb68dbfccdc807caf07883d0a
5
5
  SHA512:
6
- metadata.gz: 88355c0fecfc0e24710bc03e37f66a52ac70c72968427cc912577d30548981eae932af200b0e8d47a326dae4405de47f19fc74fce95107c97d85999ffd0d652b
7
- data.tar.gz: cbb8a022a4701b3a1d06d674ed6fd2298313a87c59b78e76618bf37d86ead5e5fb38f52c894fb34a1099851dc174d31d5b473d3707632b3e8630d975b05b8c8a
6
+ metadata.gz: ea5fb6b338a5f50a1ef0b1f07d5b3c3d54e54a054b406c6cd7536213509cf04e2a1925da61707311e55a8016405150e5f32c27dedcca19d1ae75021daef464e9
7
+ data.tar.gz: 9ebfe282eb0fd612c71cf5ba18618c6ff51a5025f7ecac20795a788d8de5c5acef7b3a9fcfc88ab174050964ccf945703159a20ab8f0068bf8b1b7c290724409
data/Gemfile.lock CHANGED
@@ -1,7 +1,8 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- delegate_matcher (0.1)
4
+ delegate_matcher (0.2)
5
+ proc_extensions (~> 0.1)
5
6
 
6
7
  GEM
7
8
  remote: https://rubygems.org/
@@ -29,6 +30,8 @@ GEM
29
30
  domain_name (0.5.25)
30
31
  unf (>= 0.0.5, < 1.0.0)
31
32
  ffi (1.9.10)
33
+ file-tail (1.1.0)
34
+ tins (~> 1.0)
32
35
  formatador (0.2.5)
33
36
  guard (2.13.0)
34
37
  formatador (>= 0.2.4)
@@ -63,6 +66,8 @@ GEM
63
66
  parser (2.2.3.0)
64
67
  ast (>= 1.1, < 3.0)
65
68
  powerpack (0.1.1)
69
+ proc_extensions (0.1.2)
70
+ sourcify (~> 0.5)
66
71
  pry (0.10.3)
67
72
  coderay (~> 1.1.0)
68
73
  method_source (~> 0.8.1)
@@ -103,6 +108,12 @@ GEM
103
108
  ruby-progressbar (~> 1.7)
104
109
  tins (<= 1.6.0)
105
110
  ruby-progressbar (1.7.5)
111
+ ruby2ruby (2.2.0)
112
+ ruby_parser (~> 3.1)
113
+ sexp_processor (~> 4.0)
114
+ ruby_parser (3.7.2)
115
+ sexp_processor (~> 4.1)
116
+ sexp_processor (4.6.0)
106
117
  shellany (0.0.1)
107
118
  simplecov (0.10.0)
108
119
  docile (~> 1.1.0)
@@ -110,6 +121,11 @@ GEM
110
121
  simplecov-html (~> 0.10.0)
111
122
  simplecov-html (0.10.0)
112
123
  slop (3.6.0)
124
+ sourcify (0.5.0)
125
+ file-tail (>= 1.0.5)
126
+ ruby2ruby (>= 1.2.5)
127
+ ruby_parser (>= 2.0.5)
128
+ sexp_processor (>= 3.0.5)
113
129
  term-ansicolor (1.3.2)
114
130
  tins (~> 1.0)
115
131
  thor (0.19.1)
data/README.md CHANGED
@@ -67,7 +67,7 @@ describe Post do
67
67
  end
68
68
  ```
69
69
 
70
- **Note**: if you are delegating to an object then you must provide an expicit prefix to `with_prefix`:
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
71
 
72
72
  ```ruby
73
73
  describe Post do
@@ -116,16 +116,27 @@ end
116
116
 
117
117
  ### Blocks
118
118
  You can check that a block passed is in turn passed to the delegate via the `with_block` method.
119
+ By default, block delegation is only checked if `with_a_block` or `without_a_block` is specified.
119
120
 
120
121
  ```ruby
121
122
  describe Post do
122
- it { should delegate(:name).to(author).with_a_block } # name(&block) => author().name(&block)
123
- it { should delegate(:name).to(author).with_block } # name(&block) => author().name(&block) # alias for with_a_block
123
+ it { should delegate(:name).to(author).with_a_block } # name(&block) => author.name(&block)
124
+ it { should delegate(:name).to(author).with_block } # name(&block) => author.name(&block) # alias for with_a_block
124
125
 
125
- it { should delegate(:name).to(author).without_a_block } # name(&block) => author().name
126
- it { should delegate(:name).to(author).without_block } # name(&block) => author().name # alias for without_a_block
126
+ it { should delegate(:name).to(author).without_a_block } # name(&block) => author.name
127
+ it { should delegate(:name).to(author).without_block } # name(&block) => author.name # alias for without_a_block
127
128
  end
128
129
  ```
130
+ You can also pass an explicit block in which case the block passed will be compared against
131
+ the block received by the delegate. The comparison is based on having equivalent source for the blocks.
132
+
133
+ ```ruby
134
+ describe Post do
135
+ it { should delegate(:tainted?).to(authors).as(:all?).with_block { |a| a.tainted? } } # tainted? => authors.all? { |a| a.tainted? }
136
+ end
137
+ ```
138
+
139
+ See [proc_extensions](https://github.com/dwhelan/proc_extensions/) for more details on how the source for procs is compared.
129
140
 
130
141
  ### Return Value
131
142
  Normally the matcher will check that the value return is the same as the value
@@ -137,8 +148,6 @@ describe Post do
137
148
  end
138
149
  ```
139
150
 
140
- By default, block delegation is only checked if `with_a_block` or `without_a_block` is specified.
141
-
142
151
  ### Active Support
143
152
  You can test delegation based on the [delegate](http://api.rubyonrails.org/classes/Module.html#method-i-delegate) method in the Active Support gem.
144
153
 
@@ -19,21 +19,23 @@ 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_development_dependency 'activesupport', '~> 4.2'
23
- gem.add_development_dependency 'bundler', '~> 1.7'
24
- gem.add_development_dependency 'coveralls', '~> 0.7'
25
- gem.add_development_dependency 'guard', '~> 2.13'
26
- gem.add_development_dependency 'guard-rspec', '~> 4.6'
22
+ gem.add_runtime_dependency 'proc_extensions', '~> 0.1'
23
+
24
+ gem.add_development_dependency 'activesupport', '~> 4.2'
25
+ gem.add_development_dependency 'bundler', '~> 1.7'
26
+ gem.add_development_dependency 'coveralls', '~> 0.7'
27
+ gem.add_development_dependency 'guard', '~> 2.13'
28
+ gem.add_development_dependency 'guard-rspec', '~> 4.6'
27
29
 
28
30
  if RUBY_VERSION =~ /2/
29
- gem.add_development_dependency 'pry-byebug', '~> 3.3'
31
+ gem.add_development_dependency 'pry-byebug', '~> 3.3'
30
32
  else
31
- gem.add_development_dependency 'pry-debugger', '~> 0.2'
33
+ gem.add_development_dependency 'pry-debugger', '~> 0.2'
32
34
  end
33
35
 
34
- gem.add_development_dependency 'rake', '~> 10.0'
35
- gem.add_development_dependency 'rspec', '~> 3.0'
36
- gem.add_development_dependency 'rspec-its', '~> 1.1'
37
- gem.add_development_dependency 'rubocop', '~> 0.30'
38
- gem.add_development_dependency 'simplecov', '~> 0.9'
36
+ gem.add_development_dependency 'rake', '~> 10.0'
37
+ gem.add_development_dependency 'rspec', '~> 3.0'
38
+ gem.add_development_dependency 'rspec-its', '~> 1.1'
39
+ gem.add_development_dependency 'rubocop', '~> 0.30'
40
+ gem.add_development_dependency 'simplecov', '~> 0.9'
39
41
  end
@@ -0,0 +1,13 @@
1
+ module RSpec
2
+ module Matchers
3
+ module DelegateMatcher
4
+ module Block
5
+ attr_accessor :block
6
+
7
+ def block_source
8
+ ProcSource.new(block)
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -2,9 +2,11 @@ module RSpec
2
2
  module Matchers
3
3
  module DelegateMatcher
4
4
  class Delegate
5
+ include Block
6
+
5
7
  RSpec::Mocks::Syntax.enable_expect(self)
6
8
 
7
- attr_reader :received, :args, :block
9
+ attr_reader :received, :args
8
10
 
9
11
  def initialize(expected)
10
12
  self.expected = expected
@@ -24,7 +24,7 @@ module RSpec
24
24
  chain(:allow_nil) { |allow_nil = true| expected.allow_nil = allow_nil }
25
25
  chain(:with_prefix) { |prefix = nil| expected.prefix = prefix }
26
26
  chain(:with) { |*args| expected.args = args }
27
- chain(:with_a_block) { expected.block = true }
27
+ chain(:with_a_block) { |&block| expected.block = block || true }
28
28
  chain(:without_a_block) { expected.block = false }
29
29
  chain(:without_return) { expected.check_return = false }
30
30
 
@@ -53,5 +53,4 @@ module RSpec
53
53
  end
54
54
  end
55
55
 
56
- # TODO: Handle delegation to a class method?
57
- # TODO: How to handle delegation if delegate_double is called with something else
56
+ # TODO: Handle nested delegation strings "a.b.c"
@@ -1,4 +1,5 @@
1
1
  require 'rspec/matchers'
2
+ require 'proc_extensions'
2
3
 
3
4
  module RSpec
4
5
  module Matchers
@@ -40,14 +41,17 @@ module RSpec
40
41
  expected.as_args.nil? || delegate.args.eql?(expected.as_args)
41
42
  end
42
43
 
44
+ # rubocop:disable Metrics/AbcSize
43
45
  def block_ok?
44
46
  case
45
47
  when expected.block.nil?
46
48
  true
47
- when expected.block
49
+ when expected.block == false
50
+ delegate.block.nil?
51
+ when expected.block == true
48
52
  delegate.block == dispatcher.block
49
53
  else
50
- delegate.block.nil?
54
+ delegate.block_source == expected.block_source
51
55
  end
52
56
  end
53
57
 
@@ -56,6 +60,9 @@ module RSpec
56
60
  end
57
61
 
58
62
  def failure_message(negated)
63
+ # TODO: Should include the line below
64
+ # return nil if negated == delegate.received
65
+
59
66
  message = [
60
67
  argument_failure_message(negated),
61
68
  block_failure_message(negated),
@@ -81,7 +88,7 @@ module RSpec
81
88
  when negated
82
89
  "a block was #{expected.block ? '' : 'not '}passed"
83
90
  when expected.block
84
- delegate.block.nil? ? 'a block was not passed' : "a different block #{delegate.block} was passed"
91
+ delegate.block.nil? ? 'a block was not passed' : "a different block '#{ProcSource.new(delegate.block)}' was passed"
85
92
  else
86
93
  'a block was passed'
87
94
  end
@@ -13,7 +13,7 @@ module RSpec
13
13
  end
14
14
 
15
15
  def block
16
- @block ||= proc {}
16
+ @block ||= expected.block.is_a?(Proc) ? expected.block : proc {}
17
17
  end
18
18
 
19
19
  private
@@ -2,7 +2,9 @@ module RSpec
2
2
  module Matchers
3
3
  module DelegateMatcher
4
4
  class Expected
5
- attr_accessor :subject, :to, :method_name, :block, :as, :allow_nil, :check_return
5
+ include Block
6
+
7
+ attr_accessor :subject, :to, :method_name, :as, :allow_nil, :check_return
6
8
  attr_reader :args
7
9
 
8
10
  def initialize
@@ -92,10 +94,12 @@ module RSpec
92
94
  case
93
95
  when block.nil?
94
96
  ''
95
- when block
97
+ when block == true
96
98
  ' with a block'
97
- else
99
+ when block == false
98
100
  ' without a block'
101
+ else
102
+ " with block '#{block_source}'"
99
103
  end
100
104
  end
101
105
 
@@ -13,10 +13,12 @@ module RSpec
13
13
  private
14
14
 
15
15
  def stub_receiver
16
+ # binding.pry
16
17
  allow(receiver).to receive(expected.as) do |*args, &block|
17
18
  self.args = args
18
19
  self.block = block
19
20
  self.received = true
21
+ # binding.pry
20
22
  return_value
21
23
  end
22
24
  end
@@ -1,3 +1,3 @@
1
1
  module DelegateMatcher
2
- VERSION ||= '0.1'.freeze
2
+ VERSION ||= '0.2'.freeze
3
3
  end
@@ -1,6 +1,7 @@
1
1
  require 'forwardable'
2
2
 
3
3
  require 'delegate_matcher/version'
4
+ require 'delegate_matcher/block'
4
5
  require 'delegate_matcher/expected'
5
6
  require 'delegate_matcher/dispatcher'
6
7
  require 'delegate_matcher/delegate'
@@ -0,0 +1,84 @@
1
+ require 'spec_helper'
2
+
3
+ module RSpec
4
+ module Matchers
5
+ module DelegateMatcher
6
+ module ToMethod
7
+ describe 'delegation to a method' do
8
+ class Post
9
+ def self.author
10
+ @author ||= Author.new
11
+ end
12
+ end
13
+
14
+ subject { Post }
15
+
16
+ let(:receiver) { :author }
17
+
18
+ it_behaves_like 'a simple delegator' do
19
+ before do
20
+ class Post
21
+ def self.name
22
+ author.name
23
+ end
24
+ end
25
+ end
26
+ include_examples 'a delegator without a nil check'
27
+ end
28
+
29
+ it_behaves_like 'a delegator with a nil check' do
30
+ before do
31
+ class Post
32
+ def self.name
33
+ author.name if author
34
+ end
35
+ end
36
+ end
37
+ end
38
+
39
+ it_behaves_like 'a delegator with args and a block' do
40
+ before do
41
+ class Post
42
+ def self.name(*args, &block)
43
+ author.name(*args, &block)
44
+ end
45
+ end
46
+ end
47
+ end
48
+
49
+ it_behaves_like 'a delegator with a different method name', :other_name do
50
+ before do
51
+ class Post
52
+ def self.name
53
+ author.other_name
54
+ end
55
+ end
56
+ end
57
+ end
58
+
59
+ it_behaves_like 'a delegator with a prefix', 'author' do
60
+ before do
61
+ class Post
62
+ def self.author_name
63
+ author.name
64
+ end
65
+ end
66
+ end
67
+ it { should delegate(:name).to(:author).with_prefix }
68
+ end
69
+
70
+ it_behaves_like 'a delegator with a different return value', 'Ann Rand' do
71
+ before do
72
+ class Post
73
+ def self.name
74
+ author.name
75
+ 'Ann Rand'
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
@@ -36,7 +36,7 @@ module RSpec
36
36
  end
37
37
  end
38
38
 
39
- it_behaves_like 'a delegator with args and a block', :arg1 do
39
+ it_behaves_like 'a delegator with args and a block' do
40
40
  before do
41
41
  class Post
42
42
  def name(*args, &block)
@@ -37,7 +37,7 @@ module RSpec
37
37
  end
38
38
  end
39
39
 
40
- it_behaves_like 'a delegator with args and a block', :arg1 do
40
+ it_behaves_like 'a delegator with args and a block' do
41
41
  before do
42
42
  class Post
43
43
  def name(*args, &block)
@@ -36,7 +36,7 @@ module RSpec
36
36
  end
37
37
  end
38
38
 
39
- it_behaves_like 'a delegator with args and a block', :arg1 do
39
+ it_behaves_like 'a delegator with args and a block' do
40
40
  before do
41
41
  class Post
42
42
  def name(*args, &block)
@@ -8,6 +8,11 @@ module RSpec
8
8
  class Post
9
9
  def initialize
10
10
  @author = Author.new
11
+ @authors ||= [@author]
12
+ end
13
+
14
+ def inspect
15
+ 'post'
11
16
  end
12
17
  end
13
18
 
@@ -37,7 +42,7 @@ module RSpec
37
42
  end
38
43
  end
39
44
 
40
- it_behaves_like 'a delegator with args and a block', :arg1 do
45
+ it_behaves_like 'a delegator with args and a block' do
41
46
  before do
42
47
  class Post
43
48
  def name(*args, &block)
@@ -47,6 +52,17 @@ module RSpec
47
52
  end
48
53
  end
49
54
 
55
+ it_behaves_like 'a delegator with its own block' do
56
+ before do
57
+ class Post
58
+ # rubocop:disable Style/SymbolProc
59
+ def tainted?
60
+ @authors.all? { |a| a.tainted? }
61
+ end
62
+ end
63
+ end
64
+ end
65
+
50
66
  it_behaves_like 'a delegator with a different method name', :other_name do
51
67
  before do
52
68
  class Post
@@ -14,7 +14,7 @@ shared_examples 'a delegator with a block' do
14
14
  it { expect(matcher.failure_message_when_negated).to match(/a block was passed/) }
15
15
  end
16
16
 
17
- context 'without a block' do
17
+ context 'without a block' do
18
18
  let(:matcher) { delegate(:name).to(receiver).without_a_block }
19
19
  it { expect(matcher.description).to eq "delegate name to #{receiver} without a block" }
20
20
  it { expect(matcher.failure_message).to match(/a block was passed/) }
@@ -22,6 +22,32 @@ shared_examples 'a delegator with a block' do
22
22
  end
23
23
  end
24
24
 
25
+ shared_examples 'a delegator with its own block' do
26
+ # rubocop:disable Style/SymbolProc
27
+ it { should delegate(:tainted?).to(:@authors).as(:all?).with_block { |a| a.tainted? } }
28
+ it { should_not delegate(:tainted?).to(:@authors).as(:all?).with_block { |a| a.to_s } }
29
+
30
+ describe 'description' do
31
+ before { matcher.matches? subject }
32
+
33
+ context 'with a block' do
34
+ let(:matcher) { delegate(:tainted?).to(:@authors).as(:all?).with_block { |a| a.tainted? } }
35
+ it { expect(matcher.description).to eq "delegate tainted? to @authors.all? with block 'proc { |a| a.tainted? }'" }
36
+ it { expect(matcher.failure_message_when_negated).to match(/a block was passed/) }
37
+ end
38
+
39
+ context 'with a different block' do
40
+ let(:matcher) { delegate(:tainted?).to(:@authors).as(:all?).with_block { |a| a.to_s } }
41
+ it { expect(matcher.failure_message).to match(/a different block 'proc { |a| a.tainted? }' was passed/) }
42
+ end
43
+
44
+ context 'without a block' do
45
+ let(:matcher) { delegate(:tainted?).to(:@authors).as(:all?).without_block }
46
+ it { expect(matcher.failure_message).to match(/a block was passed/) }
47
+ end
48
+ end
49
+ end
50
+
25
51
  shared_examples 'a delegator without a block' do
26
52
  it { should delegate(:name).to(receiver).without_block }
27
53
  it { should delegate(:name).to(receiver).without_a_block }
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: delegate_matcher
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.1'
4
+ version: '0.2'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Declan Whelan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-12-13 00:00:00.000000000 Z
11
+ date: 2015-12-15 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: proc_extensions
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.1'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.1'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: activesupport
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -183,6 +197,7 @@ files:
183
197
  - Rakefile
184
198
  - delegate_matcher.gemspec
185
199
  - lib/delegate_matcher.rb
200
+ - lib/delegate_matcher/block.rb
186
201
  - lib/delegate_matcher/delegate.rb
187
202
  - lib/delegate_matcher/delegate_matcher.rb
188
203
  - lib/delegate_matcher/delegation.rb
@@ -193,13 +208,14 @@ files:
193
208
  - lib/delegate_matcher/version.rb
194
209
  - spec/lib/active_support_delegation_spec.rb
195
210
  - spec/lib/aggregate_delegate_matcher_spec.rb
211
+ - spec/lib/class_method_spec.rb
212
+ - spec/lib/class_variable_spec.rb
213
+ - spec/lib/constant_spec.rb
196
214
  - spec/lib/delegate_spec.rb
197
- - spec/lib/delegate_to_class_variable_spec.rb
198
- - spec/lib/delegate_to_constant_spec.rb
199
- - spec/lib/delegate_to_instance_variable_spec.rb
200
- - spec/lib/delegate_to_method_spec.rb
201
- - spec/lib/delegate_to_object_spec.rb
202
215
  - spec/lib/forwardable_delegation_spec.rb
216
+ - spec/lib/instance_method_spec.rb
217
+ - spec/lib/instance_variable_spec.rb
218
+ - spec/lib/object_spec.rb
203
219
  - spec/lib/shared/a_simple_delegator.rb
204
220
  - spec/lib/shared/args.rb
205
221
  - spec/lib/shared/args_and_a_block.rb
@@ -230,20 +246,21 @@ required_rubygems_version: !ruby/object:Gem::Requirement
230
246
  version: '0'
231
247
  requirements: []
232
248
  rubyforge_project:
233
- rubygems_version: 2.4.6
249
+ rubygems_version: 2.4.5.1
234
250
  signing_key:
235
251
  specification_version: 4
236
252
  summary: A matcher for testing ruby delegation.
237
253
  test_files:
238
254
  - spec/lib/active_support_delegation_spec.rb
239
255
  - spec/lib/aggregate_delegate_matcher_spec.rb
256
+ - spec/lib/class_method_spec.rb
257
+ - spec/lib/class_variable_spec.rb
258
+ - spec/lib/constant_spec.rb
240
259
  - spec/lib/delegate_spec.rb
241
- - spec/lib/delegate_to_class_variable_spec.rb
242
- - spec/lib/delegate_to_constant_spec.rb
243
- - spec/lib/delegate_to_instance_variable_spec.rb
244
- - spec/lib/delegate_to_method_spec.rb
245
- - spec/lib/delegate_to_object_spec.rb
246
260
  - spec/lib/forwardable_delegation_spec.rb
261
+ - spec/lib/instance_method_spec.rb
262
+ - spec/lib/instance_variable_spec.rb
263
+ - spec/lib/object_spec.rb
247
264
  - spec/lib/shared/a_simple_delegator.rb
248
265
  - spec/lib/shared/args.rb
249
266
  - spec/lib/shared/args_and_a_block.rb