diff options
Diffstat (limited to 'spec/ruby/core/proc/shared')
-rw-r--r-- | spec/ruby/core/proc/shared/call.rb | 96 | ||||
-rw-r--r-- | spec/ruby/core/proc/shared/call_arguments.rb | 7 | ||||
-rw-r--r-- | spec/ruby/core/proc/shared/dup.rb | 10 | ||||
-rw-r--r-- | spec/ruby/core/proc/shared/equal.rb | 100 | ||||
-rw-r--r-- | spec/ruby/core/proc/shared/to_s.rb | 27 |
5 files changed, 240 insertions, 0 deletions
diff --git a/spec/ruby/core/proc/shared/call.rb b/spec/ruby/core/proc/shared/call.rb new file mode 100644 index 0000000000..11355537b0 --- /dev/null +++ b/spec/ruby/core/proc/shared/call.rb @@ -0,0 +1,96 @@ +require File.expand_path('../../fixtures/common', __FILE__) + +describe :proc_call, shared: true do + it "invokes self" do + Proc.new { "test!" }.send(@method).should == "test!" + lambda { "test!" }.send(@method).should == "test!" + proc { "test!" }.send(@method).should == "test!" + end + + it "sets self's parameters to the given values" do + Proc.new { |a, b| a + b }.send(@method, 1, 2).should == 3 + Proc.new { |*args| args }.send(@method, 1, 2, 3, 4).should == [1, 2, 3, 4] + Proc.new { |_, *args| args }.send(@method, 1, 2, 3).should == [2, 3] + + lambda { |a, b| a + b }.send(@method, 1, 2).should == 3 + lambda { |*args| args }.send(@method, 1, 2, 3, 4).should == [1, 2, 3, 4] + lambda { |_, *args| args }.send(@method, 1, 2, 3).should == [2, 3] + + proc { |a, b| a + b }.send(@method, 1, 2).should == 3 + proc { |*args| args }.send(@method, 1, 2, 3, 4).should == [1, 2, 3, 4] + proc { |_, *args| args }.send(@method, 1, 2, 3).should == [2, 3] + end +end + + +describe :proc_call_on_proc_new, shared: true do + it "replaces missing arguments with nil" do + Proc.new { |a, b| [a, b] }.send(@method).should == [nil, nil] + Proc.new { |a, b| [a, b] }.send(@method, 1).should == [1, nil] + end + + it "silently ignores extra arguments" do + Proc.new { |a, b| a + b }.send(@method, 1, 2, 5).should == 3 + end + + it "auto-explodes a single Array argument" do + p = Proc.new { |a, b| [a, b] } + p.send(@method, 1, 2).should == [1, 2] + p.send(@method, [1, 2]).should == [1, 2] + p.send(@method, [1, 2, 3]).should == [1, 2] + p.send(@method, [1, 2, 3], 4).should == [[1, 2, 3], 4] + end +end + +describe :proc_call_on_proc_or_lambda, shared: true do + it "ignores excess arguments when self is a proc" do + a = proc {|x| x}.send(@method, 1, 2) + a.should == 1 + + a = proc {|x| x}.send(@method, 1, 2, 3) + a.should == 1 + end + + it "will call #to_ary on argument and return self if return is nil" do + argument = ProcSpecs::ToAryAsNil.new + result = proc { |x, _| x }.send(@method, argument) + result.should == argument + end + + it "substitutes nil for missing arguments when self is a proc" do + proc {|x,y| [x,y]}.send(@method).should == [nil,nil] + + a = proc {|x,y| [x, y]}.send(@method, 1) + a.should == [1,nil] + end + + it "raises an ArgumentError on excess arguments when self is a lambda" do + lambda { + lambda {|x| x}.send(@method, 1, 2) + }.should raise_error(ArgumentError) + + lambda { + lambda {|x| x}.send(@method, 1, 2, 3) + }.should raise_error(ArgumentError) + end + + it "raises an ArgumentError on missing arguments when self is a lambda" do + lambda { + lambda {|x| x}.send(@method) + }.should raise_error(ArgumentError) + + lambda { + lambda {|x,y| [x,y]}.send(@method, 1) + }.should raise_error(ArgumentError) + end + + it "treats a single Array argument as a single argument when self is a lambda" do + lambda { |a| a }.send(@method, [1, 2]).should == [1, 2] + lambda { |a, b| [a, b] }.send(@method, [1, 2], 3).should == [[1,2], 3] + end + + it "treats a single Array argument as a single argument when self is a proc" do + proc { |a| a }.send(@method, [1, 2]).should == [1, 2] + proc { |a, b| [a, b] }.send(@method, [1, 2], 3).should == [[1,2], 3] + end +end diff --git a/spec/ruby/core/proc/shared/call_arguments.rb b/spec/ruby/core/proc/shared/call_arguments.rb new file mode 100644 index 0000000000..2e510b194e --- /dev/null +++ b/spec/ruby/core/proc/shared/call_arguments.rb @@ -0,0 +1,7 @@ +describe :proc_call_block_args, shared: true do + it "can receive block arguments" do + Proc.new {|&b| b.send(@method)}.send(@method) {1 + 1}.should == 2 + lambda {|&b| b.send(@method)}.send(@method) {1 + 1}.should == 2 + proc {|&b| b.send(@method)}.send(@method) {1 + 1}.should == 2 + end +end diff --git a/spec/ruby/core/proc/shared/dup.rb b/spec/ruby/core/proc/shared/dup.rb new file mode 100644 index 0000000000..fb6fff299d --- /dev/null +++ b/spec/ruby/core/proc/shared/dup.rb @@ -0,0 +1,10 @@ +describe :proc_dup, shared: true do + it "returns a copy of self" do + a = lambda { "hello" } + b = a.send(@method) + + a.should_not equal(b) + + a.call.should == b.call + end +end diff --git a/spec/ruby/core/proc/shared/equal.rb b/spec/ruby/core/proc/shared/equal.rb new file mode 100644 index 0000000000..c2735ffb2f --- /dev/null +++ b/spec/ruby/core/proc/shared/equal.rb @@ -0,0 +1,100 @@ +require File.expand_path('../../../../spec_helper', __FILE__) +require File.expand_path('../../fixtures/common', __FILE__) + +describe :proc_equal, shared: true do + it "is a public method" do + Proc.should have_public_instance_method(@method, false) + end + + it "returns true if self and other are the same object" do + p = proc { :foo } + p.send(@method, p).should be_true + + p = Proc.new { :foo } + p.send(@method, p).should be_true + + p = lambda { :foo } + p.send(@method, p).should be_true + end + + it "returns true if other is a dup of the original" do + p = proc { :foo } + p.send(@method, p.dup).should be_true + + p = Proc.new { :foo } + p.send(@method, p.dup).should be_true + + p = lambda { :foo } + p.send(@method, p.dup).should be_true + end + + # identical here means the same method invocation. + it "returns false when bodies are the same but capture env is not identical" do + a = ProcSpecs.proc_for_1 + b = ProcSpecs.proc_for_1 + + a.send(@method, b).should be_false + end + + it "returns true if both procs have the same body and environment" do + p = proc { :foo } + p2 = proc { :foo } + p.send(@method, p2).should be_true + end + + it "returns true if both lambdas with the same body and environment" do + x = lambda { :foo } + x2 = lambda { :foo } + x.send(@method, x2).should be_true + end + + it "returns true if both different kinds of procs with the same body and env" do + p = lambda { :foo } + p2 = proc { :foo } + p.send(@method, p2).should be_true + + x = proc { :bar } + x2 = lambda { :bar } + x.send(@method, x2).should be_true + end + + it "returns false if other is not a Proc" do + p = proc { :foo } + p.send(@method, []).should be_false + + p = Proc.new { :foo } + p.send(@method, Object.new).should be_false + + p = lambda { :foo } + p.send(@method, :foo).should be_false + end + + it "returns false if self and other are both procs but have different bodies" do + p = proc { :bar } + p2 = proc { :foo } + p.send(@method, p2).should be_false + end + + it "returns false if self and other are both lambdas but have different bodies" do + p = lambda { :foo } + p2 = lambda { :bar } + p.send(@method, p2).should be_false + end +end + +describe :proc_equal_undefined, shared: true do + it "is not defined" do + Proc.should_not have_instance_method(@method, false) + end + + it "returns false if other is a dup of the original" do + p = proc { :foo } + p.send(@method, p.dup).should be_false + + p = Proc.new { :foo } + p.send(@method, p.dup).should be_false + + p = lambda { :foo } + p.send(@method, p.dup).should be_false + end +end diff --git a/spec/ruby/core/proc/shared/to_s.rb b/spec/ruby/core/proc/shared/to_s.rb new file mode 100644 index 0000000000..c3f82a73f3 --- /dev/null +++ b/spec/ruby/core/proc/shared/to_s.rb @@ -0,0 +1,27 @@ +describe :proc_to_s, shared: true do + describe "for a proc created with Proc.new" do + it "returns a description optionally including file and line number" do + Proc.new { "hello" }.send(@method).should =~ /^#<Proc:([^ ]*?)(@([^ ]*)\/to_s\.rb:4)?>$/ + end + end + + describe "for a proc created with lambda" do + it "returns a description including '(lambda)' and optionally including file and line number" do + lambda { "hello" }.send(@method).should =~ /^#<Proc:([^ ]*?)(@([^ ]*)\/to_s\.rb:10)? \(lambda\)>$/ + end + end + + describe "for a proc created with proc" do + it "returns a description optionally including file and line number" do + proc { "hello" }.send(@method).should =~ /^#<Proc:([^ ]*?)(@([^ ]*)\/to_s\.rb:16)?>$/ + end + end + + describe "for a proc created with UnboundMethod#to_proc" do + it "returns a description including '(lambda)' and optionally including file and line number" do + def hello; end + + method("hello").to_proc.send(@method).should =~ /^#<Proc:([^ ]*?)(@([^ ]*)\/to_s\.rb:22)? \(lambda\)>$/ + end + end +end |