diff options
author | Benoit Daloze <eregontp@gmail.com> | 2022-04-25 14:53:54 +0200 |
---|---|---|
committer | Benoit Daloze <eregontp@gmail.com> | 2022-04-25 14:53:54 +0200 |
commit | 45cf4f218728a15eb36d14a6c9912086525f5e3f (patch) | |
tree | 2aa93fadcb904c226f722dde47827098b87a9846 /spec/ruby/core/module/ruby2_keywords_spec.rb | |
parent | 6ae81d49b52563a6720d666a6118ffa6e484f398 (diff) |
Update to ruby/spec@3affe1e
Diffstat (limited to 'spec/ruby/core/module/ruby2_keywords_spec.rb')
-rw-r--r-- | spec/ruby/core/module/ruby2_keywords_spec.rb | 360 |
1 files changed, 232 insertions, 128 deletions
diff --git a/spec/ruby/core/module/ruby2_keywords_spec.rb b/spec/ruby/core/module/ruby2_keywords_spec.rb index 6de3fdec80..80a99e2624 100644 --- a/spec/ruby/core/module/ruby2_keywords_spec.rb +++ b/spec/ruby/core/module/ruby2_keywords_spec.rb @@ -1,215 +1,319 @@ require_relative '../../spec_helper' require_relative 'fixtures/classes' -ruby_version_is "2.7" do - describe "Module#ruby2_keywords" do - it "marks the final hash argument as keyword hash" do - obj = Object.new +describe "Module#ruby2_keywords" do + class << self + ruby2_keywords def mark(*args) + args + end + end - obj.singleton_class.class_exec do - def foo(*a) a.last end - ruby2_keywords :foo + it "marks the final hash argument as keyword hash" do + last = mark(1, 2, a: "a").last + Hash.ruby2_keywords_hash?(last).should == true + end + + it "makes a copy of the hash and only marks the copy as keyword hash" do + obj = Object.new + obj.singleton_class.class_exec do + def regular(*args) + args.last end + end - last = obj.foo(1, 2, a: "a") - Hash.ruby2_keywords_hash?(last).should == true + h = {a: 1} + ruby_version_is "3.0" do + obj.regular(**h).should.equal?(h) end - it "makes a copy of the hash and only marks the copy as keyword hash" do - obj = Object.new - obj.singleton_class.class_exec do - def regular(*args) - args.last - end + last = mark(**h).last + Hash.ruby2_keywords_hash?(last).should == true + Hash.ruby2_keywords_hash?(h).should == false - ruby2_keywords def foo(*args) - args.last - end - end + last2 = mark(**last).last # last is already marked + Hash.ruby2_keywords_hash?(last2).should == true + Hash.ruby2_keywords_hash?(last).should == true + last2.should_not.equal?(last) + Hash.ruby2_keywords_hash?(h).should == false + end - h = {a: 1} - ruby_version_is "3.0" do - obj.regular(**h).should.equal?(h) + it "makes a copy and unmark the Hash when calling a method taking (arg)" do + obj = Object.new + obj.singleton_class.class_exec do + def single(arg) + arg end + end - last = obj.foo(**h) - Hash.ruby2_keywords_hash?(last).should == true - Hash.ruby2_keywords_hash?(h).should == false + h = { a: 1 } + args = mark(**h) + marked = args.last + Hash.ruby2_keywords_hash?(marked).should == true + + after_usage = obj.single(*args) + after_usage.should == h + after_usage.should_not.equal?(h) + after_usage.should_not.equal?(marked) + Hash.ruby2_keywords_hash?(after_usage).should == false + Hash.ruby2_keywords_hash?(marked).should == true + end - last2 = obj.foo(**last) # last is already marked - Hash.ruby2_keywords_hash?(last2).should == true - Hash.ruby2_keywords_hash?(last).should == true - last2.should_not.equal?(last) - Hash.ruby2_keywords_hash?(h).should == false + it "makes a copy and unmark the Hash when calling a method taking (**kw)" do + obj = Object.new + obj.singleton_class.class_exec do + def kwargs(**kw) + kw + end end - it "makes a copy and unmark at the call site when calling with marked *args" do + h = { a: 1 } + args = mark(**h) + marked = args.last + Hash.ruby2_keywords_hash?(marked).should == true + + after_usage = obj.kwargs(*args) + after_usage.should == h + after_usage.should_not.equal?(h) + after_usage.should_not.equal?(marked) + Hash.ruby2_keywords_hash?(after_usage).should == false + Hash.ruby2_keywords_hash?(marked).should == true + end + + ruby_version_is "3.2" do + it "makes a copy and unmark the Hash when calling a method taking (*args)" do obj = Object.new obj.singleton_class.class_exec do - ruby2_keywords def foo(*args) - args - end - - def single(arg) - arg + def splat(*args) + args.last end - def splat(*args) + def splat1(arg, *args) args.last end - def kwargs(**kw) - kw + def proc_call(*args) + -> *a { a.last }.call(*args) end end h = { a: 1 } - args = obj.foo(**h) + args = mark(**h) marked = args.last Hash.ruby2_keywords_hash?(marked).should == true - after_usage = obj.single(*args) + after_usage = obj.splat(*args) after_usage.should == h after_usage.should_not.equal?(h) after_usage.should_not.equal?(marked) Hash.ruby2_keywords_hash?(after_usage).should == false Hash.ruby2_keywords_hash?(marked).should == true - after_usage = obj.splat(*args) + args = mark(1, **h) + marked = args.last + after_usage = obj.splat1(*args) after_usage.should == h after_usage.should_not.equal?(h) after_usage.should_not.equal?(marked) - ruby_bug "#18625", ""..."3.3" do # might be fixed in 3.2 - Hash.ruby2_keywords_hash?(after_usage).should == false - end + Hash.ruby2_keywords_hash?(after_usage).should == false Hash.ruby2_keywords_hash?(marked).should == true - after_usage = obj.kwargs(*args) + args = mark(**h) + marked = args.last + after_usage = obj.proc_call(*args) + after_usage.should == h + after_usage.should_not.equal?(h) + after_usage.should_not.equal?(marked) + Hash.ruby2_keywords_hash?(after_usage).should == false + Hash.ruby2_keywords_hash?(marked).should == true + + args = mark(**h) + marked = args.last + after_usage = obj.send(:splat, *args) after_usage.should == h after_usage.should_not.equal?(h) after_usage.should_not.equal?(marked) Hash.ruby2_keywords_hash?(after_usage).should == false Hash.ruby2_keywords_hash?(marked).should == true end + end - it "applies to the underlying method and applies across aliasing" do + ruby_version_is ""..."3.2" do + # https://bugs.ruby-lang.org/issues/18625 + it "does NOT copy the Hash when calling a method taking (*args)" do obj = Object.new - obj.singleton_class.class_exec do - def foo(*a) a.last end - alias_method :bar, :foo - ruby2_keywords :foo + def splat(*args) + args.last + end - def baz(*a) a.last end - ruby2_keywords :baz - alias_method :bob, :baz + def splat1(arg, *args) + args.last + end + + def proc_call(*args) + -> *a { a.last }.call(*args) + end end - last = obj.foo(1, 2, a: "a") - Hash.ruby2_keywords_hash?(last).should == true + h = { a: 1 } + args = mark(**h) + marked = args.last + Hash.ruby2_keywords_hash?(marked).should == true - last = obj.bar(1, 2, a: "a") - Hash.ruby2_keywords_hash?(last).should == true + after_usage = obj.splat(*args) + after_usage.should == h + after_usage.should_not.equal?(h) + after_usage.should.equal?(marked) # https://bugs.ruby-lang.org/issues/18625 + Hash.ruby2_keywords_hash?(after_usage).should == true # https://bugs.ruby-lang.org/issues/18625 + Hash.ruby2_keywords_hash?(marked).should == true - last = obj.baz(1, 2, a: "a") - Hash.ruby2_keywords_hash?(last).should == true + args = mark(1, **h) + marked = args.last + after_usage = obj.splat1(*args) + after_usage.should == h + after_usage.should_not.equal?(h) + after_usage.should.equal?(marked) # https://bugs.ruby-lang.org/issues/18625 + Hash.ruby2_keywords_hash?(after_usage).should == true # https://bugs.ruby-lang.org/issues/18625 + Hash.ruby2_keywords_hash?(marked).should == true - last = obj.bob(1, 2, a: "a") - Hash.ruby2_keywords_hash?(last).should == true + args = mark(**h) + marked = args.last + after_usage = obj.proc_call(*args) + after_usage.should == h + after_usage.should_not.equal?(h) + after_usage.should.equal?(marked) # https://bugs.ruby-lang.org/issues/18625 + Hash.ruby2_keywords_hash?(after_usage).should == true # https://bugs.ruby-lang.org/issues/18625 + Hash.ruby2_keywords_hash?(marked).should == true + + args = mark(**h) + marked = args.last + after_usage = obj.send(:splat, *args) + after_usage.should == h + after_usage.should_not.equal?(h) + send_copies = RUBY_ENGINE == "ruby" # inconsistent with Proc#call above for CRuby + after_usage.equal?(marked).should == !send_copies + Hash.ruby2_keywords_hash?(after_usage).should == !send_copies + Hash.ruby2_keywords_hash?(marked).should == true end + end - ruby_version_is "2.7" ... "3.0" do - it "fixes delegation warnings when calling a method accepting keywords" do - obj = Object.new + it "applies to the underlying method and applies across aliasing" do + obj = Object.new - obj.singleton_class.class_exec do - def foo(*a) bar(*a) end - def bar(*a, **b) end - end + obj.singleton_class.class_exec do + def foo(*a) a.last end + alias_method :bar, :foo + ruby2_keywords :foo - -> { obj.foo(1, 2, {a: "a"}) }.should complain(/Using the last argument as keyword parameters is deprecated/) + def baz(*a) a.last end + ruby2_keywords :baz + alias_method :bob, :baz + end - obj.singleton_class.class_exec do - ruby2_keywords :foo - end + last = obj.foo(1, 2, a: "a") + Hash.ruby2_keywords_hash?(last).should == true - -> { obj.foo(1, 2, {a: "a"}) }.should_not complain - end - end + last = obj.bar(1, 2, a: "a") + Hash.ruby2_keywords_hash?(last).should == true - it "returns nil" do + last = obj.baz(1, 2, a: "a") + Hash.ruby2_keywords_hash?(last).should == true + + last = obj.bob(1, 2, a: "a") + Hash.ruby2_keywords_hash?(last).should == true + end + + ruby_version_is ""..."3.0" do + it "fixes delegation warnings when calling a method accepting keywords" do obj = Object.new obj.singleton_class.class_exec do - def foo(*a) end + def foo(*a) bar(*a) end + def bar(*a, **b) end + end - ruby2_keywords(:foo).should == nil + -> { obj.foo(1, 2, {a: "a"}) }.should complain(/Using the last argument as keyword parameters is deprecated/) + + obj.singleton_class.class_exec do + ruby2_keywords :foo end + + -> { obj.foo(1, 2, {a: "a"}) }.should_not complain end + end - it "raises NameError when passed not existing method name" do - obj = Object.new + it "returns nil" do + obj = Object.new - -> { - obj.singleton_class.class_exec do - ruby2_keywords :not_existing - end - }.should raise_error(NameError, /undefined method `not_existing'/) + obj.singleton_class.class_exec do + def foo(*a) end + + ruby2_keywords(:foo).should == nil end + end - it "accepts String as well" do - obj = Object.new + it "raises NameError when passed not existing method name" do + obj = Object.new + -> { obj.singleton_class.class_exec do - def foo(*a) a.last end - ruby2_keywords "foo" + ruby2_keywords :not_existing end + }.should raise_error(NameError, /undefined method `not_existing'/) + end - last = obj.foo(1, 2, a: "a") - Hash.ruby2_keywords_hash?(last).should == true + it "accepts String as well" do + obj = Object.new + + obj.singleton_class.class_exec do + def foo(*a) a.last end + ruby2_keywords "foo" end - it "raises TypeError when passed not Symbol or String" do - obj = Object.new + last = obj.foo(1, 2, a: "a") + Hash.ruby2_keywords_hash?(last).should == true + end - -> { - obj.singleton_class.class_exec do - ruby2_keywords Object.new - end - }.should raise_error(TypeError, /is not a symbol nor a string/) - end + it "raises TypeError when passed not Symbol or String" do + obj = Object.new - it "prints warning when a method does not accept argument splat" do - obj = Object.new - def obj.foo(a, b, c) end + -> { + obj.singleton_class.class_exec do + ruby2_keywords Object.new + end + }.should raise_error(TypeError, /is not a symbol nor a string/) + end - -> { - obj.singleton_class.class_exec do - ruby2_keywords :foo - end - }.should complain(/Skipping set of ruby2_keywords flag for/) - end + it "prints warning when a method does not accept argument splat" do + obj = Object.new + def obj.foo(a, b, c) end - it "prints warning when a method accepts keywords" do - obj = Object.new - def obj.foo(a:, b:) end + -> { + obj.singleton_class.class_exec do + ruby2_keywords :foo + end + }.should complain(/Skipping set of ruby2_keywords flag for/) + end - -> { - obj.singleton_class.class_exec do - ruby2_keywords :foo - end - }.should complain(/Skipping set of ruby2_keywords flag for/) - end + it "prints warning when a method accepts keywords" do + obj = Object.new + def obj.foo(a:, b:) end - it "prints warning when a method accepts keyword splat" do - obj = Object.new - def obj.foo(**a) end + -> { + obj.singleton_class.class_exec do + ruby2_keywords :foo + end + }.should complain(/Skipping set of ruby2_keywords flag for/) + end - -> { - obj.singleton_class.class_exec do - ruby2_keywords :foo - end - }.should complain(/Skipping set of ruby2_keywords flag for/) - end + it "prints warning when a method accepts keyword splat" do + obj = Object.new + def obj.foo(**a) end + + -> { + obj.singleton_class.class_exec do + ruby2_keywords :foo + end + }.should complain(/Skipping set of ruby2_keywords flag for/) end end |