Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

284 lines (217 sloc) 7.449 kb
require File.expand_path('../../spec_helper', __FILE__)
# Why so many fixed arg tests? JRuby and I assume other Ruby impls have
# separate call paths for simple fixed arity methods. Testing up to five
# will verify special and generic arity code paths for all impls.
#
# Method naming conventions:
# P - Pre Required Args
# O - Optional Arg
# R - Rest Arg
# Q - Post Required Args (1.9)
describe "Calling a method" do
it "with no arguments is ok" do
def fooP0; 100 end
fooP0.should == 100
end
it "with simple required arguments works" do
def fooP1(a); [a]; end
fooP1(1).should == [1]
def fooP2(a,b); [a,b]; end
fooP2(1,2).should == [1,2]
def fooP3(a,b,c); [a,b,c]; end
fooP3(1,2,3).should == [1,2,3]
def fooP4(a,b,c,d); [a,b,c,d]; end
fooP4(1,2,3,4).should == [1,2,3,4]
def fooP5(a,b,c,d,e); [a,b,c,d,e]; end
fooP5(1,2,3,4,5).should == [1,2,3,4,5]
end
it "works with optional arguments" do
def fooP0O1(a=1); [a]; end
fooP0O1().should == [1]
def fooP1O1(a,b=1); [a,b]; end
fooP1O1(1).should == [1,1]
def fooP2O1(a,b,c=1); [a,b,c]; end
fooP2O1(1,2).should == [1,2,1]
def fooP3O1(a,b,c,d=1); [a,b,c,d]; end
fooP3O1(1,2,3).should == [1,2,3,1]
def fooP4O1(a,b,c,d,e=1); [a,b,c,d,e]; end
fooP4O1(1,2,3,4).should == [1,2,3,4,1]
def fooP0O2(a=1,b=2); [a,b]; end
fooP0O2().should == [1,2]
end
it "works with rest arguments" do
def fooP0R(*r); r; end
fooP0R().should == []
fooP0R(1).should == [1]
fooP0R(1,2).should == [1, 2]
def fooP1R(a, *r); [a, r]; end
fooP1R(1).should == [1, []]
fooP1R(1,2).should == [1, [2]]
def fooP0O1R(a=1, *r); [a, r]; end
fooP0O1R().should == [1, []]
fooP0O1R(2).should == [2, []]
fooP0O1R(2,3).should == [2, [3]]
def fooP1O1R(a, b=1, *r); [a, b, r]; end
fooP1O1R(1).should == [1, 1, []]
fooP1O1R(1,2).should == [1, 2, []]
fooP1O1R(1,2,3).should == [1, 2, [3]]
end
it "with an empty expression is like calling with nil argument" do
def foo(a); a end
foo(()).should be_nil
end
it "with block as block argument is ok" do
def foo(a,&b); [a,yield(b)] end
foo(10) do 200 end.should == [10,200]
foo(10) { 200 }.should == [10,200]
end
it "with block argument converts the block to proc" do
def makeproc(&b) b end
makeproc { "hello" }.call.should == "hello"
makeproc { "hello" }.should be_kind_of(Proc)
# check that converted proc is indeed behaves like proc,
# not like lambda
def proc_caller(&b) b.call end
def enclosing_method
proc_caller { return :break_return_value }
:method_return_value
end
enclosing_method.should == :break_return_value
end
it "with an object that responds to 'to_proc' as a block argument coerces it to a proc" do
x = "my proc"
class << x
def to_proc; Proc.new {|y| self + y}; end
end
def foo(&b); b.call(" called"); end
def foo2; yield(" yielded"); end
foo(&x).should == "my proc called"
foo2(&x).should == "my proc yielded"
end
it "fails with both lambda and block argument" do
def foo(a,&b); [a,yield(b)] end
l = lambda { 300 }
lambda { eval "foo(10, &l){ 42}"}.should raise_error(SyntaxError)
end
it "with same names as existing variables is ok" do
foobar = 100
def foobar; 200; end
foobar.should == 100
foobar().should == 200
end
it "with splat operator * and literal array unpacks params" do
def fooP3(a,b,c); [a,b,c] end
fooP3(*[1,2,3]).should == [1,2,3]
end
it "with splat operator * and referenced array unpacks params" do
def fooP3(a,b,c); [a,b,c] end
a = [1,2,3]
fooP3(*a).should == [1,2,3]
end
it "without parentheses works" do
def fooP3(a,b,c); [a,b,c] end
(fooP3 1,2,3).should == [1,2,3]
end
it "with a space separating method name and parenthesis treats expression in parenthesis as first argument" do
def myfoo(x); x * 2 end
def mybar
# means myfoo((5).to_s)
# NOT (myfoo(5)).to_s
myfoo (5).to_s
end
mybar().should == "55"
end
it "with invalid argument count raises an ArgumentError" do
def fooP3(a,b,c); end
lambda { fooP3 }.should raise_error(ArgumentError)
lambda { fooP3(1,2) }.should raise_error(ArgumentError)
lambda { fooP3(1,2,3,4) }.should raise_error(ArgumentError)
lambda { fooP3((), (), (), ()) }.should raise_error(ArgumentError)
end
# "Allows infinite arguments" is kinda hard to spec
it "allows any number of args beyond required to method with a splat" do
def foo(a, b, *c); [c.size, c.last]; end
a = Array.new(2500) { Object.new }
obj = a[-1]
lambda { foo 1 }.should raise_error(ArgumentError)
res = foo 1, 2
res.first.should == 0
res.last.nil?.should == true
res = foo 1, 2, 3
res.first.should == 1
res.last.should == 3
res = foo 1, 2, 3, *a
res.first.should == 2501
res.last.should equal(obj)
end
it "allows []= form with *args in the [] expanded to individual arguments" do
obj = Class.new do
attr_reader :result
def []=(a, b, c, d); @result = [a,b,c,d]; end
end.new
ary = [2,3]
(obj[1, *ary] = 4).should == 4
obj.result.should == [1,2,3,4]
end
it "allows to pass literal hashes without curly braces as the last parameter" do
def foo(a,b,c); [a,b,c] end
foo('abc', 456, 'rbx' => 'cool', 'specs' => 'fail sometimes', 'oh' => 'weh').should ==
['abc', 456, { 'rbx' => 'cool', 'specs' => 'fail sometimes', 'oh' => 'weh'}]
(foo 'abc', 456, 'rbx' => 'cool', 'specs' => 'fail sometimes', 'oh' => 'weh').should ==
['abc', 456, { 'rbx' => 'cool', 'specs' => 'fail sometimes', 'oh' => 'weh'}]
end
it "allows to literal hashes without curly braces as the only parameter" do
def foo(a); a end
foo(:rbx => :cool, :specs => :fail_sometimes).should ==
{ :rbx => :cool, :specs => :fail_sometimes }
(foo :rbx => :cool, :specs => :fail_sometimes).should ==
{ :rbx => :cool, :specs => :fail_sometimes }
end
end
describe "Calling a private setter method" do
describe "permits self as a receiver" do
module MethodSpecs
class PrivateSetter
attr_reader :foo
attr_writer :foo
private :foo=
def call_self_foo_equals(value)
self.foo = value
end
def call_self_foo_equals_masgn(value)
a, self.foo = 1, value
end
end
end
it "for normal assignment" do
receiver = MethodSpecs::PrivateSetter.new
receiver.call_self_foo_equals(42)
receiver.foo.should == 42
end
it "for multiple assignment" do
receiver = MethodSpecs::PrivateSetter.new
receiver.call_self_foo_equals_masgn(42)
receiver.foo.should == 42
end
end
end
describe "Calling a private getter method" do
it "does not permit self as a receiver" do
module MethodSpecs
class PrivateGetter
attr_reader :foo
private :foo
def call_self_foo
self.foo
end
def call_self_foo_or_equals(value)
self.foo ||= 6
end
end
end
receiver = MethodSpecs::PrivateGetter.new
lambda { receiver.call_self_foo }.should raise_error(NoMethodError)
lambda { receiver.call_self_foo_or_equals(6) }.should raise_error(NoMethodError)
end
end
language_version __FILE__, "method"
Jump to Line
Something went wrong with that request. Please try again.