Skip to content

Commit

Permalink
fixes issue #242 - contract's return value is now enforced with block…
Browse files Browse the repository at this point in the history
…s properly (#251)

* fixes issue #242 - contract's return value is now enforced with blocks properly

* more robust if condition

* handle block with keyword arguments and change Gemfile syntax to work
with travis properly
  • Loading branch information
esse authored and egonSchiele committed Feb 24, 2017
1 parent 3d09338 commit 13e56bd
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 3 deletions.
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ group :test do
gem "rspec"
gem "aruba"
gem "cucumber", "~> 1.3.20"
gem "rubocop", "~> 0.29.1", :platform => [:ruby_20, :ruby_21, :ruby_22, :ruby_23]
gem "rubocop", "~> 0.29.1" if RUBY_VERSION >= "2"
end

group :development do
Expand Down
7 changes: 5 additions & 2 deletions lib/contracts/call_with.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ def call_with(this, *args, &blk)
:return_value => false)
end

if contract.is_a?(Contracts::Func)
if contract.is_a?(Contracts::Func) && blk && !nil_block_appended
blk = Contract.new(klass, arg, *contract.contracts)
elsif contract.is_a?(Contracts::Func)
args[i] = Contract.new(klass, arg, *contract.contracts)
end
end
Expand Down Expand Up @@ -73,7 +75,8 @@ def call_with(this, *args, &blk)
method.call(*args, &blk)
else
# original method name referrence
method.send_to(this, *args, &blk)
added_block = blk ? lambda { |*params| blk.call(*params) } : nil
method.send_to(this, *args, &added_block)
end

unless @ret_validator[result]
Expand Down
54 changes: 54 additions & 0 deletions spec/methods_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
RSpec.describe "Contracts:" do
describe "method called with blocks" do
module FuncTest
include Contracts::Core
include Contracts::Builtin

Contract Func[Num=>Num] => nil
def foo(&blk)
_ = blk.call(2)
nil
end

Contract Num, Func[Num=>Num] => nil
def foo2(a, &blk)
_ = blk.call(2)
nil
end

Contract Func[Num=>Num] => nil
def bar(blk)
_ = blk.call(2)
nil
end

Contract Num, Func[Num=>Num] => nil
def bar2(a, blk)
_ = blk.call(2)
nil
end
end

def obj
Object.new.tap do |o|
o.extend(FuncTest)
end
end

it "should enforce return value inside block with no other parameter" do
expect { obj.foo(&:to_s) }.to raise_error
end

it "should enforce return value inside block with other parameter" do
expect { obj.foo2(2) { |x| x.to_s } }.to raise_error
end

it "should enforce return value inside lambda with no other parameter" do
expect { obj.bar lambda { |x| x.to_s } }.to raise_error
end

it "should enforce return value inside lambda with other parameter" do
expect { obj.bar2(2, lambda { |x| x.to_s }) }.to raise_error
end
end
end

0 comments on commit 13e56bd

Please sign in to comment.