mirror of
https://github.com/rubyjs/therubyrhino
synced 2023-03-27 23:21:34 -04:00
make sure Ruby function wrapper has (Ruby) #call semantics
just like JavaScript functions exposed into the Ruby side have
This commit is contained in:
parent
0a38ab3f0a
commit
82134aecf2
4 changed files with 55 additions and 32 deletions
|
@ -176,7 +176,11 @@ module Rhino
|
||||||
|
|
||||||
# override Object BaseFunction#call(Context context, Scriptable scope,
|
# override Object BaseFunction#call(Context context, Scriptable scope,
|
||||||
# Scriptable thisObj, Object[] args)
|
# Scriptable thisObj, Object[] args)
|
||||||
def call(context, scope, this, args)
|
def call(*args)
|
||||||
|
unless args.first.is_a?(JS::Context)
|
||||||
|
return super # assume a Ruby #call
|
||||||
|
end
|
||||||
|
_, scope, this, args = *args # Java Function#call dispatch
|
||||||
args = args.to_a # java.lang.Object[] -> Array
|
args = args.to_a # java.lang.Object[] -> Array
|
||||||
# JS function style :
|
# JS function style :
|
||||||
if ( arity = @callable.arity ) != -1 # (a1, *a).arity == -2
|
if ( arity = @callable.arity ) != -1 # (a1, *a).arity == -2
|
||||||
|
|
|
@ -172,13 +172,23 @@ describe Rhino::Ruby::Function do
|
||||||
end
|
end
|
||||||
|
|
||||||
it_should_behave_like Rhino::Ruby::Scriptable
|
it_should_behave_like Rhino::Ruby::Scriptable
|
||||||
|
|
||||||
it "is callable as a function" do
|
it "is (JavaScript) callable as a function" do
|
||||||
rb_function = Rhino::Ruby::Function.wrap method = 'foo'.method(:to_s)
|
rb_function = Rhino::Ruby::Function.wrap 'foo'.method(:upcase)
|
||||||
context = nil; scope = nil; this = nil; args = nil
|
this = nil; args = nil
|
||||||
rb_function.call(context, scope, this, args).should == 'foo'
|
rb_function.call(context, scope, this, args).should == 'FOO'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'is Ruby callable' do
|
||||||
|
rb_function = Rhino::Ruby::Function.wrap 'foo'.method(:upcase)
|
||||||
|
rb_function.call.should == 'FOO'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'is Ruby callable passing arguments' do
|
||||||
|
rb_function = Rhino::Ruby::Function.wrap 'foo'.method(:scan)
|
||||||
|
rb_function.call('o').should == ['o', 'o']
|
||||||
|
end
|
||||||
|
|
||||||
it "args get converted before delegating a ruby function call" do
|
it "args get converted before delegating a ruby function call" do
|
||||||
klass = Class.new(Object) do
|
klass = Class.new(Object) do
|
||||||
def foo(array)
|
def foo(array)
|
||||||
|
@ -186,7 +196,7 @@ describe Rhino::Ruby::Function do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
rb_function = Rhino::Ruby::Function.wrap method = klass.new.method(:foo)
|
rb_function = Rhino::Ruby::Function.wrap method = klass.new.method(:foo)
|
||||||
context = nil; scope = nil; this = nil
|
this = nil
|
||||||
args = [ '1'.to_java, java.lang.String.new('2') ].to_java
|
args = [ '1'.to_java, java.lang.String.new('2') ].to_java
|
||||||
args = [ Rhino::JS::NativeArray.new(args) ].to_java
|
args = [ Rhino::JS::NativeArray.new(args) ].to_java
|
||||||
rb_function.call(context, scope, this, args).should be(true)
|
rb_function.call(context, scope, this, args).should be(true)
|
||||||
|
@ -199,7 +209,7 @@ describe Rhino::Ruby::Function do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
rb_function = Rhino::Ruby::Function.wrap method = klass.new.method(:foo)
|
rb_function = Rhino::Ruby::Function.wrap method = klass.new.method(:foo)
|
||||||
context = nil; scope = nil; this = nil; args = [].to_java
|
this = nil; args = [].to_java
|
||||||
rb_function.call(context, scope, this, args).should be_a(Rhino::JS::NativeArray)
|
rb_function.call(context, scope, this, args).should be_a(Rhino::JS::NativeArray)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -209,8 +219,8 @@ describe Rhino::Ruby::Function do
|
||||||
a1
|
a1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
rb_function = Rhino::Ruby::Function.wrap method = klass.new.method(:foo)
|
rb_function = Rhino::Ruby::Function.wrap klass.new.method(:foo)
|
||||||
context = nil; scope = nil; this = nil
|
this = nil
|
||||||
|
|
||||||
args = [ 1.to_java, 2.to_java, 3.to_java ].to_java; js_return = nil
|
args = [ 1.to_java, 2.to_java, 3.to_java ].to_java; js_return = nil
|
||||||
lambda { js_return = rb_function.call(context, scope, this, args) }.should_not raise_error
|
lambda { js_return = rb_function.call(context, scope, this, args) }.should_not raise_error
|
||||||
|
@ -224,7 +234,7 @@ describe Rhino::Ruby::Function do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
rb_function = Rhino::Ruby::Function.wrap klass.new.method(:foo)
|
rb_function = Rhino::Ruby::Function.wrap klass.new.method(:foo)
|
||||||
context = nil; scope = nil; this = nil
|
this = nil
|
||||||
|
|
||||||
args = [ 1.to_java ].to_java; js_return = nil
|
args = [ 1.to_java ].to_java; js_return = nil
|
||||||
lambda { js_return = rb_function.call(context, scope, this, args) }.should_not raise_error
|
lambda { js_return = rb_function.call(context, scope, this, args) }.should_not raise_error
|
||||||
|
@ -242,7 +252,7 @@ describe Rhino::Ruby::Function do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
rb_function = Rhino::Ruby::Function.wrap klass.new.method(:foo)
|
rb_function = Rhino::Ruby::Function.wrap klass.new.method(:foo)
|
||||||
context = nil; scope = nil; this = nil
|
this = nil
|
||||||
|
|
||||||
args = [ ].to_java; js_return = nil
|
args = [ ].to_java; js_return = nil
|
||||||
lambda { js_return = rb_function.call(context, scope, this, args) }.should_not raise_error
|
lambda { js_return = rb_function.call(context, scope, this, args) }.should_not raise_error
|
||||||
|
@ -292,22 +302,11 @@ describe Rhino::Ruby::Function do
|
||||||
|
|
||||||
describe 'with scope' do
|
describe 'with scope' do
|
||||||
|
|
||||||
before do
|
before { context_factory.enterContext(context) }
|
||||||
factory = Rhino::JS::ContextFactory.new
|
after { Rhino::JS::Context.exit }
|
||||||
context = nil
|
|
||||||
factory.call do |ctx|
|
|
||||||
context = ctx
|
|
||||||
@scope = context.initStandardObjects(nil, false)
|
|
||||||
end
|
|
||||||
factory.enterContext(context)
|
|
||||||
end
|
|
||||||
|
|
||||||
after do
|
|
||||||
Rhino::JS::Context.exit
|
|
||||||
end
|
|
||||||
|
|
||||||
it "sets up correct prototype" do
|
it "sets up correct prototype" do
|
||||||
rb_function = Rhino::Ruby::Function.wrap 'foo'.method(:concat), @scope
|
rb_function = Rhino::Ruby::Function.wrap 'foo'.method(:concat), scope
|
||||||
rb_function.getPrototype.should_not be(nil)
|
rb_function.getPrototype.should_not be(nil)
|
||||||
rb_function.getPrototype.should be_a(Rhino::JS::Function)
|
rb_function.getPrototype.should be_a(Rhino::JS::Function)
|
||||||
end
|
end
|
||||||
|
@ -338,7 +337,7 @@ describe Rhino::Ruby::Constructor do
|
||||||
|
|
||||||
it "is callable as a function" do
|
it "is callable as a function" do
|
||||||
rb_new = Rhino::Ruby::Constructor.wrap Foo
|
rb_new = Rhino::Ruby::Constructor.wrap Foo
|
||||||
context = nil; scope = nil; this = nil; args = nil
|
this = nil; args = nil
|
||||||
rb_new.call(context, scope, this, args).should be_a(Rhino::Ruby::Object)
|
rb_new.call(context, scope, this, args).should be_a(Rhino::Ruby::Object)
|
||||||
rb_new.call(context, scope, this, args).unwrap.should be_a(Foo)
|
rb_new.call(context, scope, this, args).unwrap.should be_a(Foo)
|
||||||
end
|
end
|
||||||
|
@ -398,7 +397,7 @@ describe Rhino::Ruby::Exception do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
rb_function = Rhino::Ruby::Function.wrap klass.new.method(:foo)
|
rb_function = Rhino::Ruby::Function.wrap klass.new.method(:foo)
|
||||||
context = nil; scope = nil; this = nil; args = [ 42.to_java ].to_java
|
this = nil; args = [ 42.to_java ].to_java
|
||||||
begin
|
begin
|
||||||
rb_function.call(context, scope, this, args)
|
rb_function.call(context, scope, this, args)
|
||||||
rescue java.lang.Exception => e
|
rescue java.lang.Exception => e
|
||||||
|
|
|
@ -168,12 +168,12 @@ describe Rhino::To do
|
||||||
it "converts procs and methods into native functions" do
|
it "converts procs and methods into native functions" do
|
||||||
Rhino.to_javascript(lambda {|lhs,rhs| lhs * rhs}).tap do |f|
|
Rhino.to_javascript(lambda {|lhs,rhs| lhs * rhs}).tap do |f|
|
||||||
f.should be_kind_of(Rhino::JS::Function)
|
f.should be_kind_of(Rhino::JS::Function)
|
||||||
f.call(nil, nil, nil, [7, 6].to_java).should be(42)
|
f.call(context, scope, nil, [7, 6].to_java).should be(42)
|
||||||
end
|
end
|
||||||
|
|
||||||
Rhino.to_javascript("foo,bar,baz".method(:split)).tap do |f|
|
Rhino.to_javascript("foo,bar,baz".method(:split)).tap do |f|
|
||||||
f.should be_kind_of(Rhino::JS::Function)
|
f.should be_kind_of(Rhino::JS::Function)
|
||||||
Rhino.to_ruby(f.call(nil, nil, nil, [','].to_java)).should == ['foo', 'bar', 'baz']
|
Rhino.to_ruby(f.call(context, scope, nil, [','].to_java)).should == ['foo', 'bar', 'baz']
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,26 @@ module RedJS
|
||||||
Error = Rhino::JSError
|
Error = Rhino::JSError
|
||||||
end
|
end
|
||||||
|
|
||||||
RSpec.configure do |config|
|
module Rhino
|
||||||
config.filter_run_excluding :compat => /(0.5.0)|(0.6.0)/
|
module SpecHelpers
|
||||||
|
|
||||||
|
def context_factory
|
||||||
|
@context_factory ||= Rhino::JS::ContextFactory.new
|
||||||
|
end
|
||||||
|
|
||||||
|
def context
|
||||||
|
@context || context_factory.call { |ctx| @context = ctx }
|
||||||
|
@context
|
||||||
|
end
|
||||||
|
|
||||||
|
def scope
|
||||||
|
context.initStandardObjects(nil, false)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
RSpec.configure do |config|
|
||||||
|
config.filter_run_excluding :compat => /(0.5.0)|(0.6.0)/ # RedJS
|
||||||
|
config.include Rhino::SpecHelpers
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue