1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227
|
require File.expand_path('../../spec_helper', __FILE__)
require File.expand_path('../fixtures/send', __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:
# M - Manditory Args
# O - Optional Arg
# R - Rest Arg
# Q - Post Manditory Args (1.9)
specs = LangSendSpecs
describe "Invoking a method" do
describe "with zero arguments" do
it "requires no arguments passed" do
specs.fooM0.should == 100
end
it "raises ArgumentError if the method has a positive arity" do
lambda {
specs.fooM1
}.should raise_error(ArgumentError)
end
end
describe "with only manditory arguments" do
it "requires exactly the same number of passed values" do
specs.fooM1(1).should == [1]
specs.fooM2(1,2).should == [1,2]
specs.fooM3(1,2,3).should == [1,2,3]
specs.fooM4(1,2,3,4).should == [1,2,3,4]
specs.fooM5(1,2,3,4,5).should == [1,2,3,4,5]
end
it "raises ArgumentError if the methods arity doesn't match" do
lambda {
specs.fooM1(1,2)
}.should raise_error(ArgumentError)
end
end
describe "with optional arguments" do
it "uses the optional argument if none is is passed" do
specs.fooM0O1.should == [1]
end
it "uses the passed argument if available" do
specs.fooM0O1(2).should == [2]
end
it "raises ArgumentError if extra arguments are passed" do
lambda {
specs.fooM0O1(2,3)
}.should raise_error(ArgumentError)
end
end
describe "with manditory and optional arguments" do
it "uses the passed values in left to right order" do
specs.fooM1O1(2).should == [2,1]
end
it "raises an ArgumentError if there are no values for the manditory args" do
lambda {
specs.fooM1O1
}.should raise_error(ArgumentError)
end
it "raises an ArgumentError if too many values are passed" do
lambda {
specs.fooM1O1(1,2,3)
}.should raise_error(ArgumentError)
end
end
describe "with a rest argument" do
it "is an empty array if there are no additional arguments" do
specs.fooM0R().should == []
specs.fooM1R(1).should == [1, []]
end
it "gathers unused arguments" do
specs.fooM0R(1).should == [1]
specs.fooM1R(1,2).should == [1, [2]]
end
end
it "with a block makes it available to yield" do
specs.oneb(10) { 200 }.should == [10,200]
end
it "with a block converts the block to a Proc" do
prc = specs.makeproc { "hello" }
prc.should be_kind_of(Proc)
prc.call.should == "hello"
end
it "with an object as a block uses 'to_proc' for coercion" do
o = LangSendSpecs::ToProc.new(:from_to_proc)
specs.makeproc(&o).call.should == :from_to_proc
specs.yield_now(&o).should == :from_to_proc
end
it "raises a SyntaxError with both a literal block and an object as block" do
lambda {
eval "specs.oneb(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 makes the object the direct arguments" do
a = [1,2,3]
specs.fooM3(*a).should == [1,2,3]
end
it "without parentheses works" do
(specs.fooM3 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
specs.weird_parens().should == "55"
end
ruby_version_is "" ... "1.9" do
describe "allows []=" do
before :each do
@obj = LangSendSpecs::AttrSet.new
end
it "with *args in the [] expanded to individual arguments" do
ary = [2,3]
(@obj[1, *ary] = 4).should == 4
@obj.result.should == [1,2,3,4]
end
it "with multiple *args" do
ary = [2,3]
post = [4,5]
(@obj[1, *ary] = *post).should == [4,5]
@obj.result.should == [1,2,3,[4,5]]
end
it "with multiple *args and unwraps the last splat" do
ary = [2,3]
post = [4]
(@obj[1, *ary] = *post).should == 4
@obj.result.should == [1,2,3,4]
end
it "with a *args and multiple rhs args" do
ary = [2,3]
(@obj[1, *ary] = 4, 5).should == [4,5]
@obj.result.should == [1,2,3,[4,5]]
end
end
end
it "passes literal hashes without curly braces as the last parameter" do
specs.fooM3('abc', 456, 'rbx' => 'cool',
'specs' => 'fail sometimes', 'oh' => 'weh').should == \
['abc', 456, {'rbx' => 'cool', 'specs' => 'fail sometimes', 'oh' => 'weh'}]
end
it "passes a literal hash without curly braces or parens" do
(specs.fooM3 '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
specs.fooM1(:rbx => :cool, :specs => :fail_sometimes).should ==
[{ :rbx => :cool, :specs => :fail_sometimes }]
(specs.fooM1 :rbx => :cool, :specs => :fail_sometimes).should ==
[{ :rbx => :cool, :specs => :fail_sometimes }]
end
describe "when the method is not available" do
it "invokes method_missing" do
o = LangSendSpecs::MethodMissing.new
o.not_there(1,2)
o.message.should == :not_there
o.args.should == [1,2]
end
end
end
describe "Invoking a private setter method" do
describe "permits self as a receiver" do
it "for normal assignment" do
receiver = LangSendSpecs::PrivateSetter.new
receiver.call_self_foo_equals(42)
receiver.foo.should == 42
end
it "for multiple assignment" do
receiver = LangSendSpecs::PrivateSetter.new
receiver.call_self_foo_equals_masgn(42)
receiver.foo.should == 42
end
end
end
describe "Invoking a private getter method" do
it "does not permit self as a receiver" do
receiver = LangSendSpecs::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__, "send"
|