summaryrefslogtreecommitdiff
path: root/spec/ruby/language/method_spec.rb
diff options
context:
space:
mode:
Diffstat (limited to 'spec/ruby/language/method_spec.rb')
-rw-r--r--spec/ruby/language/method_spec.rb538
1 files changed, 183 insertions, 355 deletions
diff --git a/spec/ruby/language/method_spec.rb b/spec/ruby/language/method_spec.rb
index 9abe4cde20..ca939dbab6 100644
--- a/spec/ruby/language/method_spec.rb
+++ b/spec/ruby/language/method_spec.rb
@@ -1,4 +1,4 @@
-require_relative '../spec_helper'
+require File.expand_path('../../spec_helper', __FILE__)
describe "A method send" do
evaluate <<-ruby do
@@ -40,7 +40,7 @@ describe "A method send" do
x = mock("splat argument")
x.should_receive(:to_a).and_return(1)
- -> { m(*x) }.should raise_error(TypeError)
+ lambda { m(*x) }.should raise_error(TypeError)
end
end
@@ -74,7 +74,7 @@ describe "A method send" do
x = mock("splat argument")
x.should_receive(:to_a).and_return(1)
- -> { m(*x, 2, 3) }.should raise_error(TypeError)
+ lambda { m(*x, 2, 3) }.should raise_error(TypeError)
end
end
@@ -108,7 +108,7 @@ describe "A method send" do
x = mock("splat argument")
x.should_receive(:to_a).and_return(1)
- -> { m(1, *x, 2, 3) }.should raise_error(TypeError)
+ lambda { m(1, *x, 2, 3) }.should raise_error(TypeError)
end
it "copies the splatted array" do
@@ -153,27 +153,7 @@ describe "A method send" do
x = mock("splat argument")
x.should_receive(:to_a).and_return(1)
- -> { m(1, 2, *x) }.should raise_error(TypeError)
- end
- end
-
- context "with a block argument" do
- before :all do
- def m(x)
- if block_given?
- [true, yield(x + 'b')]
- else
- [false]
- end
- end
- end
-
- it "that refers to a proc passes the proc as the block" do
- m('a', &-> y { y + 'c'}).should == [true, 'abc']
- end
-
- it "that is nil passes no block" do
- m('a', &nil).should == [false]
+ lambda { m(1, 2, *x) }.should raise_error(TypeError)
end
end
end
@@ -217,7 +197,7 @@ describe "An element assignment method send" do
x = mock("splat argument")
x.should_receive(:to_a).and_return(1)
- -> { @o[*x] = 1 }.should raise_error(TypeError)
+ lambda { @o[*x] = 1 }.should raise_error(TypeError)
end
end
@@ -255,7 +235,7 @@ describe "An element assignment method send" do
x = mock("splat argument")
x.should_receive(:to_a).and_return(1)
- -> { @o[*x, 2, 3] = 4 }.should raise_error(TypeError)
+ lambda { @o[*x, 2, 3] = 4 }.should raise_error(TypeError)
end
end
@@ -293,7 +273,7 @@ describe "An element assignment method send" do
x = mock("splat argument")
x.should_receive(:to_a).and_return(1)
- -> { @o[1, 2, *x, 3] = 4 }.should raise_error(TypeError)
+ lambda { @o[1, 2, *x, 3] = 4 }.should raise_error(TypeError)
end
end
@@ -331,7 +311,7 @@ describe "An element assignment method send" do
x = mock("splat argument")
x.should_receive(:to_a).and_return(1)
- -> { @o[1, 2, 3, *x] = 4 }.should raise_error(TypeError)
+ lambda { @o[1, 2, 3, *x] = 4 }.should raise_error(TypeError)
end
end
end
@@ -368,7 +348,7 @@ describe "An attribute assignment method send" do
x = mock("splat argument")
x.should_receive(:to_a).and_return(1)
- -> { @o.send :m=, *x, 1 }.should raise_error(TypeError)
+ lambda { @o.send :m=, *x, 1 }.should raise_error(TypeError)
end
end
@@ -403,7 +383,7 @@ describe "An attribute assignment method send" do
x = mock("splat argument")
x.should_receive(:to_a).and_return(1)
- -> { @o.send :m=, *x, 2, 3, 4 }.should raise_error(TypeError)
+ lambda { @o.send :m=, *x, 2, 3, 4 }.should raise_error(TypeError)
end
end
@@ -438,7 +418,7 @@ describe "An attribute assignment method send" do
x = mock("splat argument")
x.should_receive(:to_a).and_return(1)
- -> { @o.send :m=, 1, 2, *x, 3, 4 }.should raise_error(TypeError)
+ lambda { @o.send :m=, 1, 2, *x, 3, 4 }.should raise_error(TypeError)
end
end
@@ -473,7 +453,7 @@ describe "An attribute assignment method send" do
x = mock("splat argument")
x.should_receive(:to_a).and_return(1)
- -> { @o.send :m=, 1, 2, 3, *x, 4 }.should raise_error(TypeError)
+ lambda { @o.send :m=, 1, 2, 3, *x, 4 }.should raise_error(TypeError)
end
end
end
@@ -532,15 +512,6 @@ describe "A method" do
end
evaluate <<-ruby do
- def m() end
- ruby
-
- m().should be_nil
- m(*[]).should be_nil
- m(**{}).should be_nil
- end
-
- evaluate <<-ruby do
def m(*) end
ruby
@@ -556,26 +527,15 @@ describe "A method" do
m().should == []
m(1).should == [1]
m(1, 2, 3).should == [1, 2, 3]
- m(*[]).should == []
- m(**{}).should == []
end
evaluate <<-ruby do
def m(a:) a end
ruby
- -> { m() }.should raise_error(ArgumentError)
+ lambda { m() }.should raise_error(ArgumentError)
m(a: 1).should == 1
- suppress_keyword_warning do
- -> { m("a" => 1, a: 1) }.should raise_error(ArgumentError)
- end
- end
-
- evaluate <<-ruby do
- def m(a:, **kw) [a, kw] end
- ruby
-
- -> { m(b: 1) }.should raise_error(ArgumentError)
+ lambda { m("a" => 1, a: 1) }.should raise_error(ArgumentError)
end
evaluate <<-ruby do
@@ -592,7 +552,7 @@ describe "A method" do
m().should be_nil
m(a: 1, b: 2).should be_nil
- -> { m(1) }.should raise_error(ArgumentError)
+ lambda { m(1) }.should raise_error(ArgumentError)
end
evaluate <<-ruby do
@@ -601,19 +561,7 @@ describe "A method" do
m().should == {}
m(a: 1, b: 2).should == { a: 1, b: 2 }
- m(*[]).should == {}
- m(**{}).should == {}
- suppress_warning {
- eval "m(**{a: 1, b: 2}, **{a: 4, c: 7})"
- }.should == { a: 4, b: 2, c: 7 }
- -> { m(2) }.should raise_error(ArgumentError)
- end
-
- evaluate <<-ruby do
- def m(**k); k end;
- ruby
-
- m("a" => 1).should == { "a" => 1 }
+ lambda { m(2) }.should raise_error(ArgumentError)
end
evaluate <<-ruby do
@@ -652,7 +600,7 @@ describe "A method" do
m(2, 3).should be_nil
m([2, 3, 4], [5, 6]).should be_nil
- -> { m a: 1 }.should raise_error(ArgumentError)
+ lambda { m a: 1 }.should raise_error(ArgumentError)
end
evaluate <<-ruby do
@@ -744,9 +692,7 @@ describe "A method" do
ruby
m(1, b: 2).should == [1, 2]
- suppress_keyword_warning do
- -> { m("a" => 1, b: 2) }.should raise_error(ArgumentError)
- end
+ lambda { m("a" => 1, b: 2) }.should raise_error(ArgumentError)
end
evaluate <<-ruby do
@@ -755,7 +701,7 @@ describe "A method" do
m(2).should == [2, 1]
m(1, b: 2).should == [1, 2]
- -> { m("a" => 1, b: 2) }.should raise_error(ArgumentError)
+ m("a" => 1, b: 2).should == [{"a" => 1, b: 2}, 1]
end
evaluate <<-ruby do
@@ -764,7 +710,7 @@ describe "A method" do
m(1).should == 1
m(1, a: 2, b: 3).should == 1
- -> { m("a" => 1, b: 2) }.should raise_error(ArgumentError)
+ m("a" => 1, b: 2).should == {"a" => 1, b: 2}
end
evaluate <<-ruby do
@@ -773,7 +719,7 @@ describe "A method" do
m(1).should == [1, {}]
m(1, a: 2, b: 3).should == [1, {a: 2, b: 3}]
- -> { m("a" => 1, b: 2) }.should raise_error(ArgumentError)
+ m("a" => 1, b: 2).should == [{"a" => 1, b: 2}, {}]
end
evaluate <<-ruby do
@@ -848,8 +794,8 @@ describe "A method" do
def m(a=1, (*b), (*c)) [a, b, c] end
ruby
- -> { m() }.should raise_error(ArgumentError)
- -> { m(2) }.should raise_error(ArgumentError)
+ lambda { m() }.should raise_error(ArgumentError)
+ lambda { m(2) }.should raise_error(ArgumentError)
m(2, 3).should == [1, [2], [3]]
m(2, [3, 4], [5, 6]).should == [2, [3, 4], [5, 6]]
end
@@ -890,7 +836,7 @@ describe "A method" do
m(b: 2).should == [1, 2]
m(2, b: 1).should == [2, 1]
- -> { m("a" => 1, b: 2) }.should raise_error(ArgumentError)
+ m("a" => 1, b: 2).should == [{"a" => 1}, 2]
end
evaluate <<-ruby do
@@ -900,7 +846,7 @@ describe "A method" do
m().should == [1, 2]
m(2).should == [2, 2]
m(b: 3).should == [1, 3]
- -> { m("a" => 1, b: 2) }.should raise_error(ArgumentError)
+ m("a" => 1, b: 2).should == [{"a" => 1}, 2]
end
evaluate <<-ruby do
@@ -909,7 +855,7 @@ describe "A method" do
m().should == 1
m(2, a: 1, b: 0).should == 2
- m("a" => 1, a: 2).should == 1
+ m("a" => 1, a: 2).should == {"a" => 1}
end
evaluate <<-ruby do
@@ -950,6 +896,151 @@ describe "A method" do
end
evaluate <<-ruby do
+ def m(*, a:) a end
+ ruby
+
+ m(a: 1).should == 1
+ m(1, 2, a: 3).should == 3
+ m("a" => 1, a: 2).should == 2
+ end
+
+ evaluate <<-ruby do
+ def m(*a, b:) [a, b] end
+ ruby
+
+ m(b: 1).should == [[], 1]
+ m(1, 2, b: 3).should == [[1, 2], 3]
+ m("a" => 1, b: 2).should == [[{"a" => 1}], 2]
+ end
+
+ evaluate <<-ruby do
+ def m(*, a: 1) a end
+ ruby
+
+ m().should == 1
+ m(1, 2).should == 1
+ m(a: 2).should == 2
+ m(1, a: 2).should == 2
+ m("a" => 1, a: 2).should == 2
+ end
+
+ evaluate <<-ruby do
+ def m(*a, b: 1) [a, b] end
+ ruby
+
+ m().should == [[], 1]
+ m(1, 2, 3, b: 4).should == [[1, 2, 3], 4]
+ m("a" => 1, b: 2).should == [[{"a" => 1}], 2]
+
+ a = mock("splat")
+ a.should_not_receive(:to_ary)
+ m(*a).should == [[a], 1]
+ end
+
+ evaluate <<-ruby do
+ def m(*, **) end
+ ruby
+
+ m().should be_nil
+ m(a: 1, b: 2).should be_nil
+ m(1, 2, 3, a: 4, b: 5).should be_nil
+
+ h = mock("keyword splat")
+ h.should_receive(:to_hash).and_return({a: 1})
+ m(h).should be_nil
+
+ h = mock("keyword splat")
+ error = RuntimeError.new("error while converting to a hash")
+ h.should_receive(:to_hash).and_raise(error)
+ lambda { m(h) }.should raise_error(error)
+ end
+
+ evaluate <<-ruby do
+ def m(*a, **) a end
+ ruby
+
+ m().should == []
+ m(1, 2, 3, a: 4, b: 5).should == [1, 2, 3]
+ m("a" => 1, a: 1).should == [{"a" => 1}]
+ m(1, **{a: 2}).should == [1]
+
+ h = mock("keyword splat")
+ h.should_receive(:to_hash)
+ lambda { m(**h) }.should raise_error(TypeError)
+ end
+
+ evaluate <<-ruby do
+ def m(*, **k) k end
+ ruby
+
+ m().should == {}
+ m(1, 2, 3, a: 4, b: 5).should == {a: 4, b: 5}
+ m("a" => 1, a: 1).should == {a: 1}
+
+ h = mock("keyword splat")
+ h.should_receive(:to_hash).and_return({a: 1})
+ m(h).should == {a: 1}
+ end
+
+ evaluate <<-ruby do
+ def m(a = nil, **k) [a, k] end
+ ruby
+
+ m().should == [nil, {}]
+ m("a" => 1).should == [{"a" => 1}, {}]
+ m(a: 1).should == [nil, {a: 1}]
+ m("a" => 1, a: 1).should == [{"a" => 1}, {a: 1}]
+ m({ "a" => 1 }, a: 1).should == [{"a" => 1}, {a: 1}]
+ m({a: 1}, {}).should == [{a: 1}, {}]
+
+ h = {"a" => 1, b: 2}
+ m(h).should == [{"a" => 1}, {b: 2}]
+ h.should == {"a" => 1, b: 2}
+
+ h = {"a" => 1}
+ m(h).first.should == h
+
+ h = {}
+ r = m(h)
+ r.first.should be_nil
+ r.last.should == {}
+
+ hh = {}
+ h = mock("keyword splat empty hash")
+ h.should_receive(:to_hash).and_return(hh)
+ r = m(h)
+ r.first.should be_nil
+ r.last.should == {}
+
+ h = mock("keyword splat")
+ h.should_receive(:to_hash).and_return({"a" => 1, a: 2})
+ m(h).should == [{"a" => 1}, {a: 2}]
+ end
+
+ evaluate <<-ruby do
+ def m(*a, **k) [a, k] end
+ ruby
+
+ m().should == [[], {}]
+ m(1).should == [[1], {}]
+ m(a: 1, b: 2).should == [[], {a: 1, b: 2}]
+ m(1, 2, 3, a: 2).should == [[1, 2, 3], {a: 2}]
+
+ m("a" => 1).should == [[{"a" => 1}], {}]
+ m(a: 1).should == [[], {a: 1}]
+ m("a" => 1, a: 1).should == [[{"a" => 1}], {a: 1}]
+ m({ "a" => 1 }, a: 1).should == [[{"a" => 1}], {a: 1}]
+ m({a: 1}, {}).should == [[{a: 1}], {}]
+ m({a: 1}, {"a" => 1}).should == [[{a: 1}, {"a" => 1}], {}]
+
+ bo = BasicObject.new
+ def bo.to_a; [1, 2, 3]; end
+ def bo.to_hash; {:b => 2, :c => 3}; end
+
+ m(*bo, **bo).should == [[1, 2, 3], {:b => 2, :c => 3}]
+ end
+
+ evaluate <<-ruby do
def m(*, &b) b end
ruby
@@ -972,9 +1063,7 @@ describe "A method" do
ruby
m(a: 1, b: 2).should == [1, 2]
- suppress_keyword_warning do
- -> { m("a" => 1, a: 1, b: 2) }.should raise_error(ArgumentError)
- end
+ lambda { m("a" => 1, a: 1, b: 2) }.should raise_error(ArgumentError)
end
evaluate <<-ruby do
@@ -983,9 +1072,7 @@ describe "A method" do
m(a: 1).should == [1, 1]
m(a: 1, b: 2).should == [1, 2]
- suppress_keyword_warning do
- -> { m("a" => 1, a: 1, b: 2) }.should raise_error(ArgumentError)
- end
+ lambda { m("a" => 1, a: 1, b: 2) }.should raise_error(ArgumentError)
end
evaluate <<-ruby do
@@ -994,7 +1081,7 @@ describe "A method" do
m(a: 1).should == 1
m(a: 1, b: 2).should == 1
- m("a" => 1, a: 1, b: 2).should == 1
+ lambda { m("a" => 1, a: 1, b: 2) }.should raise_error(ArgumentError)
end
evaluate <<-ruby do
@@ -1003,7 +1090,7 @@ describe "A method" do
m(a: 1).should == [1, {}]
m(a: 1, b: 2, c: 3).should == [1, {b: 2, c: 3}]
- m("a" => 1, a: 1, b: 2).should == [1, {"a" => 1, b: 2}]
+ lambda { m("a" => 1, a: 1, b: 2) }.should raise_error(ArgumentError)
end
evaluate <<-ruby do
@@ -1101,78 +1188,21 @@ describe "A method" do
end
evaluate <<-ruby do
- def m(a, **nil); a end;
- ruby
-
- m({a: 1}).should == {a: 1}
- m({"a" => 1}).should == {"a" => 1}
-
- -> { m(a: 1) }.should raise_error(ArgumentError, 'no keywords accepted')
- -> { m(**{a: 1}) }.should raise_error(ArgumentError, 'no keywords accepted')
- -> { m("a" => 1) }.should raise_error(ArgumentError, 'no keywords accepted')
- end
-
- evaluate <<-ruby do
def m(a, b = nil, c = nil, d, e: nil, **f)
[a, b, c, d, e, f]
end
- ruby
+ ruby
result = m(1, 2)
result.should == [1, nil, nil, 2, nil, {}]
result = m(1, 2, {foo: :bar})
- result.should == [1, 2, nil, {foo: :bar}, nil, {}]
+ result.should == [1, nil, nil, 2, nil, {foo: :bar}]
result = m(1, {foo: :bar})
result.should == [1, nil, nil, {foo: :bar}, nil, {}]
end
end
-
- context 'when passing an empty keyword splat to a method that does not accept keywords' do
- evaluate <<-ruby do
- def m(*a); a; end
- ruby
-
- h = {}
- m(**h).should == []
- end
- end
-
- context 'when passing an empty keyword splat to a method that does not accept keywords' do
- evaluate <<-ruby do
- def m(a); a; end
- ruby
- h = {}
-
- -> do
- m(**h).should == {}
- end.should raise_error(ArgumentError)
- end
- end
-
- context "raises ArgumentError if passing hash as keyword arguments" do
- evaluate <<-ruby do
- def m(a: nil); a; end
- ruby
-
- options = {a: 1}.freeze
- -> do
- m(options)
- end.should raise_error(ArgumentError)
- end
- end
-
- it "assigns the last Hash to the last optional argument if the Hash contains non-Symbol keys and is not passed as keywords" do
- def m(a = nil, b = {}, v: false)
- [a, b, v]
- end
-
- h = { "key" => "value" }
- m(:a, h).should == [:a, h, false]
- m(:a, h, v: true).should == [:a, h, true]
- m(v: true).should == [nil, {}, true]
- end
end
describe "A method call with a space between method name and parentheses" do
@@ -1193,48 +1223,20 @@ describe "A method call with a space between method name and parentheses" do
end
end
- context "when a single argument is provided" do
- it "assigns a simple expression" do
- args = m (1)
- args.should == [1]
- end
-
- it "assigns an expression consisting of multiple statements" do
- args = m ((0; 1))
- args.should == [1]
- end
-
- it "assigns one single statement, without the need of parentheses" do
+ context "when a single argument provided" do
+ it "assigns it" do
args = m (1 == 1 ? true : false)
args.should == [true]
end
-
- ruby_version_is "3.3" do
- it "supports multiple statements" do
- eval("m (1; 2)").should == [2]
- end
- end
end
- context "when multiple arguments are provided" do
- it "assigns simple expressions" do
- args = m (1), (2)
- args.should == [1, 2]
- end
-
- it "assigns expressions consisting of multiple statements" do
- args = m ((0; 1)), ((2; 3))
- args.should == [1, 3]
- end
- end
-
- context "when the argument looks like an argument list" do
+ context "when 2+ arguments provided" do
it "raises a syntax error" do
- -> {
+ lambda {
eval("m (1, 2)")
}.should raise_error(SyntaxError)
- -> {
+ lambda {
eval("m (1, 2, 3)")
}.should raise_error(SyntaxError)
end
@@ -1292,177 +1294,3 @@ describe "An array-dereference method ([])" do
end
end
end
-
-describe "An endless method definition" do
- context "without arguments" do
- evaluate <<-ruby do
- def m() = 42
- ruby
-
- m.should == 42
- end
-
- context "without parenthesis" do
- evaluate <<-ruby do
- def m = 42
- ruby
-
- m.should == 42
- end
- end
- end
-
- context "with arguments" do
- evaluate <<-ruby do
- def m(a, b) = a + b
- ruby
-
- m(1, 4).should == 5
- end
- end
-
- context "with multiline body" do
- evaluate <<-ruby do
- def m(n) =
- if n > 2
- m(n - 2) + m(n - 1)
- else
- 1
- end
- ruby
-
- m(6).should == 8
- end
- end
-
- # tested more thoroughly in language/delegation_spec.rb
- context "with args forwarding" do
- evaluate <<-ruby do
- def mm(word, num:)
- word * num
- end
-
- def m(...) = mm(...) + mm(...)
- ruby
-
- m("meow", num: 2).should == "meow" * 4
- end
- end
-end
-
-describe "Keyword arguments are now separated from positional arguments" do
- context "when the method has only positional parameters" do
- it "treats incoming keyword arguments as positional for compatibility" do
- def foo(a, b, c, hsh)
- hsh[:key]
- end
-
- foo(1, 2, 3, key: 42).should == 42
- end
- end
-
- context "when the method takes a ** parameter" do
- it "captures the passed literal keyword arguments" do
- def foo(a, b, c, **hsh)
- hsh[:key]
- end
-
- foo(1, 2, 3, key: 42).should == 42
- end
-
- it "captures the passed ** keyword arguments" do
- def foo(a, b, c, **hsh)
- hsh[:key]
- end
-
- h = { key: 42 }
- foo(1, 2, 3, **h).should == 42
- end
-
- it "does not convert a positional Hash to keyword arguments" do
- def foo(a, b, c, **hsh)
- hsh[:key]
- end
-
- -> {
- foo(1, 2, 3, { key: 42 })
- }.should raise_error(ArgumentError, 'wrong number of arguments (given 4, expected 3)')
- end
- end
-
- context "when the method takes a key: parameter" do
- context "when it's called with a positional Hash and no **" do
- it "raises ArgumentError" do
- def foo(a, b, c, key: 1)
- key
- end
-
- -> {
- foo(1, 2, 3, { key: 42 })
- }.should raise_error(ArgumentError, 'wrong number of arguments (given 4, expected 3)')
- end
- end
-
- context "when it's called with **" do
- it "captures the passed keyword arguments" do
- def foo(a, b, c, key: 1)
- key
- end
-
- h = { key: 42 }
- foo(1, 2, 3, **h).should == 42
- end
- end
- end
-end
-
-ruby_version_is "3.1" do
- describe "kwarg with omitted value in a method call" do
- context "accepts short notation 'kwarg' in method call" do
- evaluate <<-ruby do
- def call(*args, **kwargs) = [args, kwargs]
- ruby
-
- a, b, c = 1, 2, 3
- arr, h = eval('call a:')
- h.should == {a: 1}
- arr.should == []
-
- arr, h = eval('call(a:, b:, c:)')
- h.should == {a: 1, b: 2, c: 3}
- arr.should == []
-
- arr, h = eval('call(a:, b: 10, c:)')
- h.should == {a: 1, b: 10, c: 3}
- arr.should == []
- end
- end
-
- context "with methods and local variables" do
- evaluate <<-ruby do
- def call(*args, **kwargs) = [args, kwargs]
-
- def bar
- "baz"
- end
-
- def foo(val)
- call bar:, val:
- end
- ruby
-
- foo(1).should == [[], {bar: "baz", val: 1}]
- end
- end
- end
-
- describe "Inside 'endless' method definitions" do
- it "allows method calls without parenthesis" do
- eval <<-ruby
- def greet(person) = "Hi, ".dup.concat person
- ruby
-
- greet("Homer").should == "Hi, Homer"
- end
- end
-end