From b3a073259da37f57f6ff1475eea44b09c6c7b24b Mon Sep 17 00:00:00 2001 From: Mamoru TASAKA Date: Sun, 31 Jan 2021 20:41:21 +0900 Subject: [PATCH] Backport some patches from the upstream Ruby 3.0: apply the upstream WIP patch for keyword separation --- ...on-t-use-exceptions-for-control-flow.patch | 102 +++++ ...pecify-error-class-to-suppress-RSpec.patch | 73 ++++ ....0-0003-Fix-misspellings-in-comments.patch | 40 ++ ...only-when-there-is-a-Func-check.-bug.patch | 30 ++ ...ementation-spec-to-be-3.0-compatible.patch | 387 ++++++++++++++++++ rubygem-contracts.spec | 23 +- 6 files changed, 654 insertions(+), 1 deletion(-) create mode 100644 rubygem-contracts-0.16.0-0001-Don-t-use-exceptions-for-control-flow.patch create mode 100644 rubygem-contracts-0.16.0-0002-Update-spec-to-specify-error-class-to-suppress-RSpec.patch create mode 100644 rubygem-contracts-0.16.0-0003-Fix-misspellings-in-comments.patch create mode 100644 rubygem-contracts-0.16.0-0004-Wrapping-blocks-only-when-there-is-a-Func-check.-bug.patch create mode 100644 rubygem-contracts-0.16.0-0005-Update-implementation-spec-to-be-3.0-compatible.patch diff --git a/rubygem-contracts-0.16.0-0001-Don-t-use-exceptions-for-control-flow.patch b/rubygem-contracts-0.16.0-0001-Don-t-use-exceptions-for-control-flow.patch new file mode 100644 index 0000000..5a06144 --- /dev/null +++ b/rubygem-contracts-0.16.0-0001-Don-t-use-exceptions-for-control-flow.patch @@ -0,0 +1,102 @@ +From 726e28c473b8d4453b4485922a2c52e9511bfc42 Mon Sep 17 00:00:00 2001 +From: Chris Seaton +Date: Fri, 10 Nov 2017 17:20:38 +0000 +Subject: [PATCH 1/5] Don't use exceptions for control flow + +--- + lib/contracts/call_with.rb | 22 +++++++++++++-------- + lib/contracts/method_handler.rb | 34 +++++++++++++-------------------- + 2 files changed, 27 insertions(+), 29 deletions(-) + +diff --git a/lib/contracts/call_with.rb b/lib/contracts/call_with.rb +index c8a8b62..2735d1e 100644 +--- a/lib/contracts/call_with.rb ++++ b/lib/contracts/call_with.rb +@@ -1,6 +1,10 @@ + module Contracts + module CallWith + def call_with(this, *args, &blk) ++ call_with_inner(false, this, *args, &blk) ++ end ++ ++ def call_with_inner(returns, this, *args, &blk) + args << blk if blk + + # Explicitly append blk=nil if nil != Proc contract violation anticipated +@@ -16,14 +20,16 @@ module Contracts + validator = @args_validators[i] + + unless validator && validator[arg] +- return unless Contract.failure_callback(:arg => arg, +- :contract => contract, +- :class => klass, +- :method => method, +- :contracts => self, +- :arg_pos => i+1, +- :total_args => args.size, +- :return_value => false) ++ data = {:arg => arg, ++ :contract => contract, ++ :class => klass, ++ :method => method, ++ :contracts => self, ++ :arg_pos => i+1, ++ :total_args => args.size, ++ :return_value => false} ++ return ParamContractError.new("as return value", data) if returns ++ return unless Contract.failure_callback(data) + end + + if contract.is_a?(Contracts::Func) && blk && !nil_block_appended +diff --git a/lib/contracts/method_handler.rb b/lib/contracts/method_handler.rb +index ee16b6b..fe301cd 100644 +--- a/lib/contracts/method_handler.rb ++++ b/lib/contracts/method_handler.rb +@@ -125,31 +125,23 @@ module Contracts + # function. Otherwise we return the result. + # If we run out of functions, we raise the last error, but + # convert it to_contract_error. +- success = false +- i = 0 +- result = nil ++ + expected_error = decorated_methods[0].failure_exception ++ last_error = nil + +- until success +- decorated_method = decorated_methods[i] +- i += 1 +- begin +- success = true +- result = decorated_method.call_with(self, *args, &blk) +- rescue expected_error => error +- success = false +- unless decorated_methods[i] +- begin +- ::Contract.failure_callback(error.data, false) +- rescue expected_error => final_error +- raise final_error.to_contract_error +- end +- end +- end ++ decorated_methods.each do |decorated_method| ++ result = decorated_method.call_with_inner(true, self, *args, &blk) ++ return result unless result.is_a?(ParamContractError) ++ last_error = result + end + +- # Return the result of successfully called method +- result ++ begin ++ if ::Contract.failure_callback(last_error.data, false) ++ decorated_methods.last.call_with_inner(false, self, *args, &blk) ++ end ++ rescue expected_error => final_error ++ raise final_error.to_contract_error ++ end + end + end + +-- +2.29.2 + diff --git a/rubygem-contracts-0.16.0-0002-Update-spec-to-specify-error-class-to-suppress-RSpec.patch b/rubygem-contracts-0.16.0-0002-Update-spec-to-specify-error-class-to-suppress-RSpec.patch new file mode 100644 index 0000000..c336695 --- /dev/null +++ b/rubygem-contracts-0.16.0-0002-Update-spec-to-specify-error-class-to-suppress-RSpec.patch @@ -0,0 +1,73 @@ +From 85c6a4e471f2013079dc5a63c1a6bb84bee9351b Mon Sep 17 00:00:00 2001 +From: PikachuEXE +Date: Mon, 25 Jan 2021 17:26:45 +0800 +Subject: [PATCH 2/5] * Update spec to specify error class to suppress RSpec + warning + +--- + spec/contracts_spec.rb | 6 +++--- + spec/methods_spec.rb | 8 ++++---- + 2 files changed, 7 insertions(+), 7 deletions(-) + +diff --git a/spec/contracts_spec.rb b/spec/contracts_spec.rb +index d37c40e..72c8603 100644 +--- a/spec/contracts_spec.rb ++++ b/spec/contracts_spec.rb +@@ -7,7 +7,7 @@ RSpec.describe "Contracts:" do + it "should fail for insufficient arguments" do + expect do + @o.hello +- end.to raise_error ++ end.to raise_error ArgumentError + end + + it "should fail for insufficient contracts" do +@@ -32,7 +32,7 @@ RSpec.describe "Contracts:" do + 1 + end + end +- end.to raise_error ++ end.to raise_error NameError + end + end + +@@ -696,7 +696,7 @@ RSpec.describe "Contracts:" do + it "should apply the contract to an inherited method" do + c = Child.new + expect { c.double(2) }.to_not raise_error +- expect { c.double("asd") }.to raise_error ++ expect { c.double("asd") }.to raise_error ParamContractError + end + end + +diff --git a/spec/methods_spec.rb b/spec/methods_spec.rb +index 334fb4e..d1b5d47 100644 +--- a/spec/methods_spec.rb ++++ b/spec/methods_spec.rb +@@ -36,19 +36,19 @@ RSpec.describe "Contracts:" do + end + + it "should enforce return value inside block with no other parameter" do +- expect { obj.foo(&:to_s) }.to raise_error ++ expect { obj.foo(&:to_s) }.to raise_error ReturnContractError + end + + it "should enforce return value inside block with other parameter" do +- expect { obj.foo2(2) { |x| x.to_s } }.to raise_error ++ expect { obj.foo2(2) { |x| x.to_s } }.to raise_error ReturnContractError + end + + it "should enforce return value inside lambda with no other parameter" do +- expect { obj.bar lambda { |x| x.to_s } }.to raise_error ++ expect { obj.bar lambda { |x| x.to_s } }.to raise_error ReturnContractError + end + + it "should enforce return value inside lambda with other parameter" do +- expect { obj.bar2(2, lambda { |x| x.to_s }) }.to raise_error ++ expect { obj.bar2(2, lambda { |x| x.to_s }) }.to raise_error ReturnContractError + end + end + end +-- +2.29.2 + diff --git a/rubygem-contracts-0.16.0-0003-Fix-misspellings-in-comments.patch b/rubygem-contracts-0.16.0-0003-Fix-misspellings-in-comments.patch new file mode 100644 index 0000000..8ac5b36 --- /dev/null +++ b/rubygem-contracts-0.16.0-0003-Fix-misspellings-in-comments.patch @@ -0,0 +1,40 @@ +From 989ee11906bb2061b2618bd1d8f128162e143a79 Mon Sep 17 00:00:00 2001 +From: Olle Jonsson +Date: Sun, 24 Sep 2017 19:08:58 +0200 +Subject: [PATCH 3/5] Fix misspellings in comments + + - found using find . | misspellings -f - +--- + lib/contracts/call_with.rb | 2 +- + spec/ruby_version_specific/contracts_spec_2.1.rb | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/lib/contracts/call_with.rb b/lib/contracts/call_with.rb +index 2735d1e..c9336a1 100644 +--- a/lib/contracts/call_with.rb ++++ b/lib/contracts/call_with.rb +@@ -80,7 +80,7 @@ module Contracts + # proc, block, lambda, etc + method.call(*args, &blk) + else +- # original method name referrence ++ # original method name reference + added_block = blk ? lambda { |*params| blk.call(*params) } : nil + method.send_to(this, *args, &added_block) + end +diff --git a/spec/ruby_version_specific/contracts_spec_2.1.rb b/spec/ruby_version_specific/contracts_spec_2.1.rb +index 168cfd0..36b6ede 100644 +--- a/spec/ruby_version_specific/contracts_spec_2.1.rb ++++ b/spec/ruby_version_specific/contracts_spec_2.1.rb +@@ -51,7 +51,7 @@ RSpec.describe "Contracts:" do + end.to raise_error(ContractError) + end + +- it "should fail when passed nil to an optional argument which contract shouldnt accept nil" do ++ it "should fail when passed nil to an optional argument which contract shouldn't accept nil" do + expect do + @o.complicated("a", true, :b, :c, 2.0, e: (1..5), f: nil, g: :d) do |x| + x +-- +2.29.2 + diff --git a/rubygem-contracts-0.16.0-0004-Wrapping-blocks-only-when-there-is-a-Func-check.-bug.patch b/rubygem-contracts-0.16.0-0004-Wrapping-blocks-only-when-there-is-a-Func-check.-bug.patch new file mode 100644 index 0000000..04b1d62 --- /dev/null +++ b/rubygem-contracts-0.16.0-0004-Wrapping-blocks-only-when-there-is-a-Func-check.-bug.patch @@ -0,0 +1,30 @@ +From ab30dab081c4e004812eab00a36c70e5b8e4e29b Mon Sep 17 00:00:00 2001 +From: md-work <> +Date: Thu, 14 Dec 2017 11:37:18 +0100 +Subject: [PATCH 4/5] Wrapping &blocks only when there is a Func check. (bug + 278) + +--- + lib/contracts/call_with.rb | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/lib/contracts/call_with.rb b/lib/contracts/call_with.rb +index c9336a1..9252c79 100644 +--- a/lib/contracts/call_with.rb ++++ b/lib/contracts/call_with.rb +@@ -81,8 +81,10 @@ module Contracts + method.call(*args, &blk) + else + # original method name reference +- added_block = blk ? lambda { |*params| blk.call(*params) } : nil +- method.send_to(this, *args, &added_block) ++ # Don't reassign blk, else Travis CI shows "stack level too deep". ++ target_blk = blk ++ target_blk = lambda { |*params| blk.call(*params) } if blk && blk.is_a?(Contract) ++ method.send_to(this, *args, &target_blk) + end + + unless @ret_validator[result] +-- +2.29.2 + diff --git a/rubygem-contracts-0.16.0-0005-Update-implementation-spec-to-be-3.0-compatible.patch b/rubygem-contracts-0.16.0-0005-Update-implementation-spec-to-be-3.0-compatible.patch new file mode 100644 index 0000000..7d79dac --- /dev/null +++ b/rubygem-contracts-0.16.0-0005-Update-implementation-spec-to-be-3.0-compatible.patch @@ -0,0 +1,387 @@ +From 62ad3fb999287f1495273d4ef41ff6abc28fd278 Mon Sep 17 00:00:00 2001 +From: PikachuEXE +Date: Tue, 26 Jan 2021 17:37:59 +0800 +Subject: [PATCH 5/5] * Update implementation & spec to be 3.0 compatible + +Mainly around the breaking behaviour change about keyword arguments +--- + lib/contracts.rb | 14 ++++----- + lib/contracts/call_with.rb | 31 ++++++++++--------- + lib/contracts/invariants.rb | 10 +++--- + lib/contracts/method_handler.rb | 6 ++-- + lib/contracts/method_reference.rb | 4 +-- + spec/builtin_contracts_spec.rb | 20 +++++------- + spec/contracts_spec.rb | 21 +++++++------ + spec/fixtures/fixtures.rb | 9 ++---- + spec/override_validators_spec.rb | 6 ++-- + .../contracts_spec_2.0.rb | 4 +-- + spec/validators_spec.rb | 2 +- + 11 files changed, 63 insertions(+), 64 deletions(-) + +diff --git a/lib/contracts.rb b/lib/contracts.rb +index baf2acf..f5ae75d 100644 +--- a/lib/contracts.rb ++++ b/lib/contracts.rb +@@ -93,9 +93,9 @@ class Contract < Contracts::Decorator + last_contract = args_contracts.last + penultimate_contract = args_contracts[-2] + @has_options_contract = if @has_proc_contract +- penultimate_contract.is_a?(Hash) || penultimate_contract.is_a?(Contracts::Builtin::KeywordArgs) ++ penultimate_contract.is_a?(Contracts::Builtin::KeywordArgs) + else +- last_contract.is_a?(Hash) || last_contract.is_a?(Contracts::Builtin::KeywordArgs) ++ last_contract.is_a?(Contracts::Builtin::KeywordArgs) + end + # === + +@@ -214,12 +214,12 @@ class Contract < Contracts::Decorator + + # Same thing for when we have named params but didn't pass any in. + # returns true if it appended nil +- def maybe_append_options! args, blk ++ def maybe_append_options! args, kargs, blk + return false unless @has_options_contract +- if @has_proc_contract && (args_contracts[-2].is_a?(Hash) || args_contracts[-2].is_a?(Contracts::Builtin::KeywordArgs)) && !args[-2].is_a?(Hash) +- args.insert(-2, {}) +- elsif (args_contracts[-1].is_a?(Hash) || args_contracts[-1].is_a?(Contracts::Builtin::KeywordArgs)) && !args[-1].is_a?(Hash) +- args << {} ++ if @has_proc_contract && args_contracts[-2].is_a?(Contracts::Builtin::KeywordArgs) ++ args.insert(-2, kargs) ++ elsif args_contracts[-1].is_a?(Contracts::Builtin::KeywordArgs) ++ args << kargs + end + true + end +diff --git a/lib/contracts/call_with.rb b/lib/contracts/call_with.rb +index 9252c79..224b357 100644 +--- a/lib/contracts/call_with.rb ++++ b/lib/contracts/call_with.rb +@@ -1,17 +1,17 @@ + module Contracts + module CallWith +- def call_with(this, *args, &blk) +- call_with_inner(false, this, *args, &blk) ++ def call_with(this, *args, **kargs, &blk) ++ call_with_inner(false, this, *args, **kargs, &blk) + end + +- def call_with_inner(returns, this, *args, &blk) ++ def call_with_inner(returns, this, *args, **kargs, &blk) + args << blk if blk + + # Explicitly append blk=nil if nil != Proc contract violation anticipated + nil_block_appended = maybe_append_block!(args, blk) + + # Explicitly append options={} if Hash contract is present +- maybe_append_options!(args, blk) ++ kargs_appended = maybe_append_options!(args, kargs, blk) + + # Loop forward validating the arguments up to the splat (if there is one) + (@args_contract_index || args.size).times do |i| +@@ -57,14 +57,16 @@ module Contracts + validator = @args_validators[args_contracts.size - 1 - j] + + unless validator && validator[arg] +- return unless Contract.failure_callback(:arg => arg, +- :contract => contract, +- :class => klass, +- :method => method, +- :contracts => self, +- :arg_pos => i-1, +- :total_args => args.size, +- :return_value => false) ++ return unless Contract.failure_callback({ ++ :arg => arg, ++ :contract => contract, ++ :class => klass, ++ :method => method, ++ :contracts => self, ++ :arg_pos => i - 1, ++ :total_args => args.size, ++ :return_value => false, ++ }) + end + + if contract.is_a?(Contracts::Func) +@@ -76,15 +78,16 @@ module Contracts + # If we put the block into args for validating, restore the args + # OR if we added a fake nil at the end because a block wasn't passed in. + args.slice!(-1) if blk || nil_block_appended ++ args.slice!(-1) if kargs_appended + result = if method.respond_to?(:call) + # proc, block, lambda, etc +- method.call(*args, &blk) ++ method.call(*args, **kargs, &blk) + else + # original method name reference + # Don't reassign blk, else Travis CI shows "stack level too deep". + target_blk = blk + target_blk = lambda { |*params| blk.call(*params) } if blk && blk.is_a?(Contract) +- method.send_to(this, *args, &target_blk) ++ method.send_to(this, *args, **kargs, &target_blk) + end + + unless @ret_validator[result] +diff --git a/lib/contracts/invariants.rb b/lib/contracts/invariants.rb +index 56d2d82..215cb89 100644 +--- a/lib/contracts/invariants.rb ++++ b/lib/contracts/invariants.rb +@@ -46,10 +46,12 @@ module Contracts + def check_on(target, method) + return if target.instance_eval(&@condition) + +- self.class.failure_callback(:expected => expected, +- :actual => false, +- :target => target, +- :method => method) ++ self.class.failure_callback({ ++ :expected => expected, ++ :actual => false, ++ :target => target, ++ :method => method, ++ }) + end + + def self.failure_callback(data) +diff --git a/lib/contracts/method_handler.rb b/lib/contracts/method_handler.rb +index fe301cd..714e4e1 100644 +--- a/lib/contracts/method_handler.rb ++++ b/lib/contracts/method_handler.rb +@@ -107,7 +107,7 @@ module Contracts + current_engine = engine + + # We are gonna redefine original method here +- method_reference.make_definition(target) do |*args, &blk| ++ method_reference.make_definition(target) do |*args, **kargs, &blk| + engine = current_engine.nearest_decorated_ancestor + + # If we weren't able to find any ancestor that has decorated methods +@@ -130,14 +130,14 @@ module Contracts + last_error = nil + + decorated_methods.each do |decorated_method| +- result = decorated_method.call_with_inner(true, self, *args, &blk) ++ result = decorated_method.call_with_inner(true, self, *args, **kargs, &blk) + return result unless result.is_a?(ParamContractError) + last_error = result + end + + begin + if ::Contract.failure_callback(last_error.data, false) +- decorated_methods.last.call_with_inner(false, self, *args, &blk) ++ decorated_methods.last.call_with_inner(false, self, *args, **kargs, &blk) + end + rescue expected_error => final_error + raise final_error.to_contract_error +diff --git a/lib/contracts/method_reference.rb b/lib/contracts/method_reference.rb +index 0bc68f8..0c0c03f 100644 +--- a/lib/contracts/method_reference.rb ++++ b/lib/contracts/method_reference.rb +@@ -39,8 +39,8 @@ module Contracts + + # Calls original method on specified `this` argument with + # specified arguments `args` and block `&blk`. +- def send_to(this, *args, &blk) +- this.send(aliased_name, *args, &blk) ++ def send_to(this, *args, **kargs, &blk) ++ this.send(aliased_name, *args, **kargs, &blk) + end + + private +diff --git a/spec/builtin_contracts_spec.rb b/spec/builtin_contracts_spec.rb +index 00cf495..a9f7257 100644 +--- a/spec/builtin_contracts_spec.rb ++++ b/spec/builtin_contracts_spec.rb +@@ -376,10 +376,6 @@ RSpec.describe "Contracts:" do + fails { @o.hash_keywordargs(:hash => nil) } + fails { @o.hash_keywordargs(:hash => 1) } + end +- +- it "should pass if a method is overloaded with non-KeywordArgs" do +- passes { @o.person_keywordargs("name", 10) } +- end + end + + describe "Optional:" do +@@ -405,15 +401,15 @@ RSpec.describe "Contracts:" do + end + + context "given a fulfilled contract" do +- it { expect(@o.gives_max_value(:panda => 1, :bamboo => 2)).to eq(2) } +- it { expect(@o.pretty_gives_max_value(:panda => 1, :bamboo => 2)).to eq(2) } ++ it { expect(@o.gives_max_value({ :panda => 1, :bamboo => 2 })).to eq(2) } ++ it { expect(@o.pretty_gives_max_value({ :panda => 1, :bamboo => 2 })).to eq(2) } + end + + context "given an unfulfilled contract" do +- it { fails { @o.gives_max_value(:panda => "1", :bamboo => "2") } } ++ it { fails { @o.gives_max_value({ :panda => "1", :bamboo => "2" }) } } + it { fails { @o.gives_max_value(nil) } } + it { fails { @o.gives_max_value(1) } } +- it { fails { @o.pretty_gives_max_value(:panda => "1", :bamboo => "2") } } ++ it { fails { @o.pretty_gives_max_value({ :panda => "1", :bamboo => "2" }) } } + end + + describe "#to_s" do +@@ -430,25 +426,25 @@ RSpec.describe "Contracts:" do + describe "StrictHash:" do + context "when given an exact correct input" do + it "does not raise an error" do +- passes { @o.strict_person(:name => "calvin", :age => 10) } ++ passes { @o.strict_person({ :name => "calvin", :age => 10 }) } + end + end + + context "when given an input with correct keys but wrong types" do + it "raises an error" do +- fails { @o.strict_person(:name => "calvin", :age => "10") } ++ fails { @o.strict_person({ :name => "calvin", :age => "10" }) } + end + end + + context "when given an input with missing keys" do + it "raises an error" do +- fails { @o.strict_person(:name => "calvin") } ++ fails { @o.strict_person({ :name => "calvin" }) } + end + end + + context "when given an input with extra keys" do + it "raises an error" do +- fails { @o.strict_person(:name => "calvin", :age => 10, :soft => true) } ++ fails { @o.strict_person({ :name => "calvin", :age => 10, :soft => true }) } + end + end + +diff --git a/spec/contracts_spec.rb b/spec/contracts_spec.rb +index 72c8603..5586415 100644 +--- a/spec/contracts_spec.rb ++++ b/spec/contracts_spec.rb +@@ -349,19 +349,19 @@ RSpec.describe "Contracts:" do + + describe "Hashes" do + it "should pass for exact correct input" do +- expect { @o.person(:name => "calvin", :age => 10) }.to_not raise_error ++ expect { @o.person({ :name => "calvin", :age => 10 }) }.to_not raise_error + end + + it "should pass even if some keys don't have contracts" do +- expect { @o.person(:name => "calvin", :age => 10, :foo => "bar") }.to_not raise_error ++ expect { @o.person({ :name => "calvin", :age => 10, :foo => "bar" }) }.to_not raise_error + end + + it "should fail if a key with a contract on it isn't provided" do +- expect { @o.person(:name => "calvin") }.to raise_error(ContractError) ++ expect { @o.person({ :name => "calvin" }) }.to raise_error(ContractError) + end + + it "should fail for incorrect input" do +- expect { @o.person(:name => 50, :age => 10) }.to raise_error(ContractError) ++ expect { @o.person({ :name => 50, :age => 10 }) }.to raise_error(ContractError) + end + end + +@@ -612,16 +612,19 @@ RSpec.describe "Contracts:" do + + it "should contain to_s representation within a Hash contract" do + expect do +- @o.hash_complex_contracts(:rigged => "bad") ++ @o.hash_complex_contracts({ :rigged => "bad" }) + end.to raise_error(ContractError, not_s(delim "TrueClass or FalseClass")) + end + + it "should contain to_s representation within a nested Hash contract" do + expect do +- @o.nested_hash_complex_contracts(:rigged => true, +- :contents => { +- :kind => 0, +- :total => 42 }) ++ @o.nested_hash_complex_contracts({ ++ :rigged => true, ++ :contents => { ++ :kind => 0, ++ :total => 42, ++ }, ++ }) + end.to raise_error(ContractError, not_s(delim "String or Symbol")) + end + +diff --git a/spec/fixtures/fixtures.rb b/spec/fixtures/fixtures.rb +index b6d2bea..c42722e 100644 +--- a/spec/fixtures/fixtures.rb ++++ b/spec/fixtures/fixtures.rb +@@ -120,16 +120,11 @@ class GenericExample + end + + Contract C::KeywordArgs[:name => String, :age => Fixnum] => nil +- def person_keywordargs(data) +- end +- +- # Testing overloaded method +- Contract String, Fixnum => nil +- def person_keywordargs(name, age) ++ def person_keywordargs(name: "name", age: 10) + end + + Contract C::KeywordArgs[:hash => C::HashOf[Symbol, C::Num]] => nil +- def hash_keywordargs(data) ++ def hash_keywordargs(hash:) + end + + Contract (/foo/) => nil +diff --git a/spec/override_validators_spec.rb b/spec/override_validators_spec.rb +index 293c84c..25af373 100644 +--- a/spec/override_validators_spec.rb ++++ b/spec/override_validators_spec.rb +@@ -30,15 +30,15 @@ RSpec.describe Contract do + obj = klass.new + + expect do +- obj.something(:a => 35, :b => "hello") ++ obj.something({ :a => 35, :b => "hello" }) + end.to raise_error(ContractError) + + expect do +- obj.something( ++ obj.something({ + :a => 35, + :b => "hello", + :it_is_a_hash => true +- ) ++ }) + end.not_to raise_error + end + +diff --git a/spec/ruby_version_specific/contracts_spec_2.0.rb b/spec/ruby_version_specific/contracts_spec_2.0.rb +index 78c5e69..c2b3d69 100644 +--- a/spec/ruby_version_specific/contracts_spec_2.0.rb ++++ b/spec/ruby_version_specific/contracts_spec_2.0.rb +@@ -1,10 +1,10 @@ + class GenericExample +- Contract C::Args[String], { repeat: C::Maybe[C::Num] } => C::ArrayOf[String] ++ Contract C::Args[String], C::KeywordArgs[ repeat: C::Maybe[C::Num] ] => C::ArrayOf[String] + def splat_then_optional_named(*vals, repeat: 2) + vals.map { |v| v * repeat } + end + +- Contract ({foo: C::Nat}) => nil ++ Contract C::KeywordArgs[ foo: C::Nat ] => nil + def nat_test_with_kwarg(foo: 10) + end + +diff --git a/spec/validators_spec.rb b/spec/validators_spec.rb +index 588580e..22dc2a9 100644 +--- a/spec/validators_spec.rb ++++ b/spec/validators_spec.rb +@@ -34,7 +34,7 @@ RSpec.describe "Contract validators" do + + describe "within a hash" do + it "should pass for a matching string" do +- expect { o.hash_containing_foo(:host => "foo.example.org") }.to_not raise_error ++ expect { o.hash_containing_foo({ :host => "foo.example.org" }) }.to_not raise_error + end + end + +-- +2.29.2 + diff --git a/rubygem-contracts.spec b/rubygem-contracts.spec index d029af3..b2da14d 100644 --- a/rubygem-contracts.spec +++ b/rubygem-contracts.spec @@ -2,12 +2,21 @@ Name: rubygem-%{gem_name} Version: 0.16.0 -Release: 9%{?dist} +Release: 10%{?dist} Summary: Contracts for Ruby License: BSD URL: http://egonschiele.github.io/contracts.ruby/ Source0: https://rubygems.org/gems/%{gem_name}-%{version}.gem +# Upstream patches +Patch1: rubygem-contracts-0.16.0-0001-Don-t-use-exceptions-for-control-flow.patch +Patch2: rubygem-contracts-0.16.0-0002-Update-spec-to-specify-error-class-to-suppress-RSpec.patch +Patch3: rubygem-contracts-0.16.0-0003-Fix-misspellings-in-comments.patch +Patch4: rubygem-contracts-0.16.0-0004-Wrapping-blocks-only-when-there-is-a-Func-check.-bug.patch +# Ruby 3.0 Trial Upstream patches +# https://github.com/egonSchiele/contracts.ruby/issues/294 +# https://github.com/egonSchiele/contracts.ruby/pull/295 +Patch5: rubygem-contracts-0.16.0-0005-Update-implementation-spec-to-be-3.0-compatible.patch BuildRequires: ruby(release) BuildRequires: rubygems-devel @@ -32,6 +41,14 @@ Documentation for %{name}. gem unpack %{SOURCE0} %setup -q -D -T -n %{gem_name}-%{version} +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 +%patch4 -p1 +%if 0%{?fedora} >= 34 +%patch5 -p1 +%endif + gem spec %{SOURCE0} -l --ruby > %{gem_name}.gemspec %build @@ -78,6 +95,10 @@ popd %{gem_instdir}/benchmarks/ %changelog +* Sun Jan 31 2021 Mamoru TASAKA - 0.16.0-10 +- Backport some patches from the upstream +- Ruby 3.0: apply the upstream WIP patch for keyword separation + * Wed Jan 27 2021 Fedora Release Engineering - 0.16.0-9 - Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild