Skip to content
This repository was archived by the owner on Nov 30, 2024. It is now read-only.

Commit 95e85f3

Browse files
committed
Differentiate between block args with defaults and without.
Fixes rspec/rspec-mocks#714.
1 parent 24420ee commit 95e85f3

File tree

5 files changed

+56
-5
lines changed

5 files changed

+56
-5
lines changed

Changelog.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
### 3.0.1 Development
2+
[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.0.0...3-0-maintenance)
3+
4+
* Fix `BlockSignature` so that it correctly differentiates between
5+
required and optional block args. (Myron Marston, rspec-mocks#714)
6+
17
### 3.0.0 / 2014-06-01
28
[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.0.0.rc1...v3.0.0)
39

lib/rspec/support.rb

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,5 +54,26 @@ def self.method_handle_for(object, method_name)
5454
end
5555
end
5656
end
57+
58+
if RUBY_PLATFORM == 'java'
59+
def self.proc_to_lambda(block)
60+
return block if block.lambda?
61+
lambda(&block)
62+
end
63+
elsif respond_to?(:define_singleton_method)
64+
def self.proc_to_lambda(block)
65+
return block if block.lambda?
66+
67+
obj = Object.new
68+
obj.define_singleton_method(:to_lambda, &block)
69+
obj.method(:to_lambda).to_proc
70+
end
71+
else # 1.8.7
72+
def self.proc_to_lambda(block)
73+
obj = Object.new
74+
(class << obj; self; end).__send__(:define_method, :to_lambda, &block)
75+
obj.method(:to_lambda).to_proc
76+
end
77+
end
5778
end
5879
end

lib/rspec/support/method_signature_verifier.rb

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -133,11 +133,8 @@ def classify_parameters
133133
#
134134
# @api private
135135
class BlockSignature < MethodSignature
136-
if RubyFeatures.optional_and_splat_args_supported?
137-
def classify_parameters
138-
super
139-
@min_non_kw_args = @max_non_kw_args unless @max_non_kw_args == INFINITY
140-
end
136+
def initialize(block)
137+
super(Support.proc_to_lambda(block))
141138
end
142139
end
143140

spec/rspec/support/method_signature_verifier_spec.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,18 @@
33

44
module RSpec
55
module Support
6+
describe BlockSignature do
7+
it 'differentiates optional vs required args', :if => RubyFeatures.optional_and_splat_args_supported? do
8+
bs = BlockSignature.new(Proc.new { |a, b| })
9+
expect(bs.min_non_kw_args).to eq(2)
10+
expect(bs.max_non_kw_args).to eq(2)
11+
12+
bs = eval("BlockSignature.new(Proc.new { |a, b=2| })")
13+
expect(bs.min_non_kw_args).to eq(1)
14+
expect(bs.max_non_kw_args).to eq(2)
15+
end
16+
end
17+
618
describe MethodSignatureVerifier do
719
describe '#verify!' do
820
let(:signature) { MethodSignature.new(test_method) }

spec/rspec/support_spec.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,5 +75,20 @@ def method_missing(name, *args, &block)
7575
end
7676
end
7777
end
78+
79+
describe ".proc_to_lambda", :if => Proc.method_defined?(:lambda?) do
80+
it "converts a proc to a lambda" do
81+
p = Proc.new { 47 }
82+
expect(p).not_to be_lambda
83+
l = Support.proc_to_lambda(p)
84+
expect(l).to be_lambda
85+
expect(l.call).to eq(47)
86+
end
87+
88+
it 'returns a lambda unchanged' do
89+
l = lambda { }
90+
expect(Support.proc_to_lambda(l)).to be(l)
91+
end
92+
end
7893
end
7994
end

0 commit comments

Comments
 (0)