Skip to content

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

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Merged
merged 3 commits into from
Feb 24, 2017
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
@@ -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
7 changes: 5 additions & 2 deletions lib/contracts/call_with.rb
Original file line number Diff line number Diff line change
@@ -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
@@ -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]
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