therubyrhino 1.73.0 → 1.73.1
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/rhino.rb +27 -9
- data/lib/rhino/context.rb +127 -100
- data/lib/rhino/deprecations.rb +52 -0
- data/lib/rhino/error.rb +44 -0
- data/lib/rhino/object.rb +10 -1
- data/lib/rhino/rhino_ext.rb +237 -0
- data/lib/rhino/ruby.rb +225 -0
- data/lib/rhino/ruby/access.rb +8 -0
- data/lib/rhino/ruby/attribute_access.rb +55 -0
- data/lib/rhino/ruby/default_access.rb +54 -0
- data/lib/rhino/version.rb +1 -1
- data/lib/rhino/wormhole.rb +63 -57
- data/spec/rhino/access_spec.rb +69 -0
- data/spec/rhino/context_spec.rb +24 -10
- data/spec/rhino/deprecations_spec.rb +41 -0
- data/spec/rhino/error_spec.rb +38 -0
- data/spec/rhino/rhino_ext_spec.rb +234 -0
- data/spec/rhino/ruby_spec.rb +390 -0
- data/spec/rhino/wormhole_spec.rb +99 -78
- data/spec/spec_helper.rb +1 -0
- data/therubyrhino.gemspec +1 -0
- metadata +26 -8
- data/lib/rhino/java.rb +0 -24
- data/lib/rhino/native_function.rb +0 -29
- data/lib/rhino/native_object.rb +0 -71
- data/lib/rhino/ruby_function.rb +0 -14
- data/lib/rhino/ruby_object.rb +0 -71
@@ -0,0 +1,55 @@
|
|
1
|
+
module Rhino
|
2
|
+
module Ruby
|
3
|
+
module AttributeAccess
|
4
|
+
|
5
|
+
def self.has(object, name, scope)
|
6
|
+
if object.respond_to?(name.to_s) ||
|
7
|
+
object.respond_to?("#{name}=") # might have a writer but no reader
|
8
|
+
return true
|
9
|
+
end
|
10
|
+
# try [](name) method :
|
11
|
+
if object.respond_to?(:'[]') && object.method(:'[]').arity == 1
|
12
|
+
return true if object[name]
|
13
|
+
end
|
14
|
+
yield
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.get(object, name, scope)
|
18
|
+
if object.respond_to?(name_s = name.to_s)
|
19
|
+
method = object.method(name_s)
|
20
|
+
if method.arity == 0 && # check if it is an attr_reader
|
21
|
+
( object.respond_to?("#{name}=") || object.instance_variables.include?("@#{name}") )
|
22
|
+
begin
|
23
|
+
return Rhino.to_javascript(method.call, scope)
|
24
|
+
rescue => e
|
25
|
+
raise Rhino::Ruby.wrap_error(e)
|
26
|
+
end
|
27
|
+
else
|
28
|
+
return Function.wrap(method.unbind)
|
29
|
+
end
|
30
|
+
elsif object.respond_to?("#{name}=")
|
31
|
+
return nil # it does have the property but is non readable
|
32
|
+
end
|
33
|
+
# try [](name) method :
|
34
|
+
if object.respond_to?(:'[]') && object.method(:'[]').arity == 1
|
35
|
+
if value = object[name]
|
36
|
+
return Rhino.to_javascript(value, scope)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
yield
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.put(object, name, value)
|
43
|
+
if object.respond_to?(set_name = "#{name}=")
|
44
|
+
return object.send(set_name, Rhino.to_ruby(value))
|
45
|
+
end
|
46
|
+
# try []=(name, value) method :
|
47
|
+
if object.respond_to?(:'[]=') && object.method(:'[]=').arity == 2
|
48
|
+
return object[name] = Rhino.to_ruby(value)
|
49
|
+
end
|
50
|
+
yield
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Rhino
|
2
|
+
module Ruby
|
3
|
+
module DefaultAccess
|
4
|
+
|
5
|
+
def self.has(object, name, scope)
|
6
|
+
if object.respond_to?(name.to_s) ||
|
7
|
+
object.respond_to?("#{name}=")
|
8
|
+
return true
|
9
|
+
end
|
10
|
+
# try [](name) method :
|
11
|
+
if object.respond_to?(:'[]') && object.method(:'[]').arity == 1
|
12
|
+
return true if object[name]
|
13
|
+
end
|
14
|
+
yield
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.get(object, name, scope)
|
18
|
+
if object.respond_to?(name_s = name.to_s)
|
19
|
+
method = object.method(name_s)
|
20
|
+
if method.arity == 0
|
21
|
+
begin
|
22
|
+
return Rhino.to_javascript(method.call, scope)
|
23
|
+
rescue => e
|
24
|
+
raise Rhino::Ruby.wrap_error(e)
|
25
|
+
end
|
26
|
+
else
|
27
|
+
return Function.wrap(method.unbind)
|
28
|
+
end
|
29
|
+
elsif object.respond_to?("#{name}=")
|
30
|
+
return nil
|
31
|
+
end
|
32
|
+
# try [](name) method :
|
33
|
+
if object.respond_to?(:'[]') && object.method(:'[]').arity == 1
|
34
|
+
if value = object[name]
|
35
|
+
return Rhino.to_javascript(value, scope)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
yield
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.put(object, name, value)
|
42
|
+
if object.respond_to?(set_name = "#{name}=")
|
43
|
+
return object.send(set_name, Rhino.to_ruby(value))
|
44
|
+
end
|
45
|
+
# try []=(name, value) method :
|
46
|
+
if object.respond_to?(:'[]=') && object.method(:'[]=').arity == 2
|
47
|
+
return object[name] = Rhino.to_ruby(value)
|
48
|
+
end
|
49
|
+
yield
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
data/lib/rhino/version.rb
CHANGED
data/lib/rhino/wormhole.rb
CHANGED
@@ -1,81 +1,87 @@
|
|
1
1
|
|
2
2
|
module Rhino
|
3
3
|
module To
|
4
|
-
JS_UNDEF = [J::Scriptable::NOT_FOUND, J::Undefined]
|
5
4
|
|
6
|
-
|
7
|
-
|
8
|
-
def ruby(object)
|
5
|
+
def to_ruby(object)
|
9
6
|
case object
|
10
|
-
when
|
11
|
-
when
|
12
|
-
when
|
13
|
-
when
|
14
|
-
|
15
|
-
when J::Function then j2r(object) {|o| NativeFunction.new(o)}
|
16
|
-
when J::Scriptable then j2r(object) {|o| NativeObject.new(o)}
|
17
|
-
else object
|
7
|
+
when JS::Scriptable::NOT_FOUND, JS::Undefined then nil
|
8
|
+
when JS::Wrapper then object.unwrap
|
9
|
+
when JS::NativeArray then array_to_ruby(object)
|
10
|
+
when JS::NativeDate then Time.at(object.getJSTimeValue / 1000)
|
11
|
+
else object
|
18
12
|
end
|
19
13
|
end
|
20
14
|
|
21
|
-
def
|
15
|
+
def to_javascript(object, scope = nil)
|
22
16
|
case object
|
23
|
-
when
|
24
|
-
when
|
25
|
-
when
|
26
|
-
when
|
27
|
-
when
|
28
|
-
when
|
29
|
-
when
|
30
|
-
|
17
|
+
when NilClass then object
|
18
|
+
when String, Numeric then object
|
19
|
+
when TrueClass, FalseClass then object
|
20
|
+
when JS::Scriptable then object
|
21
|
+
when Array then array_to_javascript(object, scope)
|
22
|
+
when Hash then hash_to_javascript(object, scope)
|
23
|
+
when Time then time_to_javascript(object, scope)
|
24
|
+
when Method, UnboundMethod then Ruby::Function.wrap(object, scope)
|
25
|
+
when Proc then Ruby::Function.wrap(object, scope)
|
26
|
+
when Class then Ruby::Constructor.wrap(object, scope)
|
27
|
+
else RubyObject.wrap(object, scope)
|
31
28
|
end
|
32
29
|
end
|
33
30
|
|
34
|
-
def
|
35
|
-
|
31
|
+
def args_to_ruby(args)
|
32
|
+
args.map { |arg| to_ruby(arg) }
|
36
33
|
end
|
37
|
-
|
38
|
-
def
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
34
|
+
|
35
|
+
def args_to_javascript(args, scope = nil)
|
36
|
+
args.map { |arg| to_javascript(arg, scope) }.to_java
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def array_to_ruby(js_array)
|
42
|
+
js_array.length.times.map { |i| to_ruby( js_array.get(i, js_array) ) }
|
43
43
|
end
|
44
44
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
@@j2r = {}
|
49
|
-
def j2r(value)
|
50
|
-
key = value.object_id
|
51
|
-
if ref = @@j2r[key]
|
52
|
-
if peer = ref.get()
|
53
|
-
return peer
|
45
|
+
def array_to_javascript(rb_array, scope = nil)
|
46
|
+
if scope && context = JS::Context.getCurrentContext
|
47
|
+
context.newArray(scope, rb_array.to_java)
|
54
48
|
else
|
55
|
-
|
56
|
-
return j2r(value) {|o| yield o}
|
57
|
-
end
|
58
|
-
else
|
59
|
-
yield(value).tap do |peer|
|
60
|
-
@@j2r[key] = java.lang.ref.WeakReference.new(peer)
|
49
|
+
JS::NativeArray.new(rb_array.to_java)
|
61
50
|
end
|
62
51
|
end
|
63
|
-
end
|
64
52
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
53
|
+
def hash_to_javascript(rb_hash, scope = nil)
|
54
|
+
js_object =
|
55
|
+
if scope && context = JS::Context.getCurrentContext
|
56
|
+
context.newObject(scope)
|
57
|
+
else
|
58
|
+
JS::NativeObject.new
|
59
|
+
end
|
60
|
+
# JS::NativeObject implements Map put it's #put does :
|
61
|
+
# throw new UnsupportedOperationException(); thus no []=
|
62
|
+
rb_hash.each_pair do |key, val|
|
63
|
+
js_val = to_javascript(val, scope)
|
64
|
+
JS::ScriptableObject.putProperty(js_object, key.to_s, js_val)
|
73
65
|
end
|
74
|
-
|
75
|
-
|
76
|
-
|
66
|
+
js_object
|
67
|
+
end
|
68
|
+
|
69
|
+
def time_to_javascript(time, scope = nil)
|
70
|
+
millis = time.to_f * 1000
|
71
|
+
if scope && context = JS::Context.getCurrentContext
|
72
|
+
JS::ScriptRuntime.newObject(context, scope, 'Date', [ millis ].to_java)
|
73
|
+
else
|
74
|
+
# the pure reflection way - god I love Java's private :
|
75
|
+
js_klass = JS::NativeObject.java_class
|
76
|
+
new = js_klass.getDeclaredConstructor
|
77
|
+
new.setAccessible(true)
|
78
|
+
js_date = new.newInstance
|
79
|
+
date = js_klass.getDeclaredField(:date)
|
80
|
+
date.setAccessible(true)
|
81
|
+
date.setDouble(js_date, millis)
|
82
|
+
js_date
|
77
83
|
end
|
78
84
|
end
|
79
|
-
|
85
|
+
|
80
86
|
end
|
81
87
|
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require File.expand_path('../spec_helper', File.dirname(__FILE__))
|
2
|
+
|
3
|
+
describe Rhino::Ruby::AttributeAccess do
|
4
|
+
|
5
|
+
before(:all) do
|
6
|
+
Rhino::Ruby::Scriptable.access = Rhino::Ruby::AttributeAccess
|
7
|
+
end
|
8
|
+
|
9
|
+
after(:all) do
|
10
|
+
Rhino::Ruby::Scriptable.access = nil
|
11
|
+
end
|
12
|
+
|
13
|
+
class Meh
|
14
|
+
|
15
|
+
attr_reader :anAttr0
|
16
|
+
attr_accessor :the_attr_1
|
17
|
+
|
18
|
+
def initialize
|
19
|
+
@anAttr0 = nil
|
20
|
+
@the_attr_1 = 'attr_1'
|
21
|
+
@an_attr_2 = 'attr_2'
|
22
|
+
end
|
23
|
+
|
24
|
+
def theMethod0; @theMethod0; end
|
25
|
+
|
26
|
+
def a_method1; 1; end
|
27
|
+
|
28
|
+
def the_method_2; '2'; end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
it "gets methods and instance variables" do
|
33
|
+
rb_object = Rhino::Ruby::Object.wrap Meh.new
|
34
|
+
|
35
|
+
rb_object.get('anAttr0', nil).should be_nil
|
36
|
+
rb_object.get('the_attr_1', nil).should == 'attr_1'
|
37
|
+
rb_object.get('an_attr_2', nil).should be(Rhino::JS::Scriptable::NOT_FOUND) # no reader
|
38
|
+
|
39
|
+
[ 'theMethod0', 'a_method1', 'the_method_2' ].each do |name|
|
40
|
+
rb_object.get(name, nil).should be_a(Rhino::Ruby::Function)
|
41
|
+
end
|
42
|
+
|
43
|
+
rb_object.get('non-existent-method', nil).should be(Rhino::JS::Scriptable::NOT_FOUND)
|
44
|
+
end
|
45
|
+
|
46
|
+
it "has methods and instance variables" do
|
47
|
+
rb_object = Rhino::Ruby::Object.wrap Meh.new
|
48
|
+
|
49
|
+
rb_object.has('anAttr0', nil).should be_true
|
50
|
+
rb_object.has('the_attr_1', nil).should be_true
|
51
|
+
rb_object.has('an_attr_2', nil).should be_false # no reader nor writer
|
52
|
+
|
53
|
+
[ 'theMethod0', 'a_method1', 'the_method_2' ].each do |name|
|
54
|
+
rb_object.has(name, nil).should be_true
|
55
|
+
end
|
56
|
+
|
57
|
+
rb_object.has('non-existent-method', nil).should be_false
|
58
|
+
end
|
59
|
+
|
60
|
+
it "puts using attr writer" do
|
61
|
+
start = mock('start')
|
62
|
+
start.expects(:put).never
|
63
|
+
rb_object = Rhino::Ruby::Object.wrap Meh.new
|
64
|
+
|
65
|
+
rb_object.put('the_attr_1', start, 42)
|
66
|
+
rb_object.the_attr_1.should == 42
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
data/spec/rhino/context_spec.rb
CHANGED
@@ -1,12 +1,10 @@
|
|
1
|
-
require File.dirname(__FILE__)
|
2
|
-
|
3
|
-
include Rhino
|
1
|
+
require File.expand_path('../spec_helper', File.dirname(__FILE__))
|
4
2
|
|
5
3
|
describe Rhino::Context do
|
6
4
|
|
7
5
|
describe "Initalizing Standard Javascript Objects" do
|
8
6
|
it "provides the standard objects without java integration by default" do
|
9
|
-
Context.open do |cxt|
|
7
|
+
Rhino::Context.open do |cxt|
|
10
8
|
cxt["Object"].should_not be_nil
|
11
9
|
cxt["Math"].should_not be_nil
|
12
10
|
cxt["String"].should_not be_nil
|
@@ -19,7 +17,7 @@ describe Rhino::Context do
|
|
19
17
|
end
|
20
18
|
|
21
19
|
it "provides unsealed standard object by default" do
|
22
|
-
Context.open do |cxt|
|
20
|
+
Rhino::Context.open do |cxt|
|
23
21
|
cxt.eval("Object.foop = 'blort'")
|
24
22
|
cxt["Object"]['foop'].should == 'blort'
|
25
23
|
end
|
@@ -27,15 +25,15 @@ describe Rhino::Context do
|
|
27
25
|
|
28
26
|
it "allows you to scope the context to an object" do
|
29
27
|
class MyScope
|
30
|
-
def foo;
|
28
|
+
def foo(*args); args && 'bar'; end
|
31
29
|
end
|
32
|
-
Context.open(:with => MyScope.new) do |ctx|
|
30
|
+
Rhino::Context.open(:with => MyScope.new) do |ctx|
|
33
31
|
ctx.eval("foo()").should == 'bar'
|
34
32
|
end
|
35
33
|
end
|
36
34
|
|
37
35
|
it "allows you to seal the standard objects so that they cannot be modified" do
|
38
|
-
Context.open(:sealed => true) do |cxt|
|
36
|
+
Rhino::Context.open(:sealed => true) do |cxt|
|
39
37
|
lambda {
|
40
38
|
cxt.eval("Object.foop = 'blort'")
|
41
39
|
}.should raise_error(Rhino::JSError)
|
@@ -47,9 +45,25 @@ describe Rhino::Context do
|
|
47
45
|
end
|
48
46
|
|
49
47
|
it "allows java integration to be turned on when initializing standard objects" do
|
50
|
-
Context.open(:java => true) do |cxt|
|
51
|
-
|
48
|
+
Rhino::Context.open(:java => true) do |cxt|
|
49
|
+
cxt["Packages"].should_not be_nil
|
52
50
|
end
|
53
51
|
end
|
54
52
|
end
|
53
|
+
|
54
|
+
it "should get default interpreter version" do
|
55
|
+
context = Rhino::Context.new
|
56
|
+
|
57
|
+
context.version.should == 0
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should set interpreter version" do
|
61
|
+
context = Rhino::Context.new
|
62
|
+
context.version = 1.6
|
63
|
+
context.version.should == 1.6
|
64
|
+
|
65
|
+
context.version = '1.7'
|
66
|
+
context.version.should == 1.7
|
67
|
+
end
|
68
|
+
|
55
69
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require File.expand_path('../spec_helper', File.dirname(__FILE__))
|
2
|
+
|
3
|
+
require 'stringio'
|
4
|
+
|
5
|
+
describe 'deprecations' do
|
6
|
+
|
7
|
+
stderr = $stderr
|
8
|
+
|
9
|
+
before do
|
10
|
+
$stderr = StringIO.new
|
11
|
+
end
|
12
|
+
|
13
|
+
after do
|
14
|
+
$stderr = stderr
|
15
|
+
end
|
16
|
+
|
17
|
+
it "To ruby 42" do
|
18
|
+
Rhino::To.ruby(42).should == 42
|
19
|
+
end
|
20
|
+
|
21
|
+
it "To javascript 42" do
|
22
|
+
Rhino::To.javascript(42).should == 42
|
23
|
+
end
|
24
|
+
|
25
|
+
it "J constant still works" do
|
26
|
+
lambda { Rhino::J::Scriptable }.should_not raise_error
|
27
|
+
end
|
28
|
+
|
29
|
+
it "NativeObject constant exists" do
|
30
|
+
lambda { Rhino::NativeObject }.should_not raise_error
|
31
|
+
end
|
32
|
+
|
33
|
+
it "NativeFunction constant exists" do
|
34
|
+
lambda { Rhino::NativeFunction }.should_not raise_error
|
35
|
+
end
|
36
|
+
|
37
|
+
it "JavascriptError returns JSError" do
|
38
|
+
lambda { Rhino::JavascriptError.should be(Rhino::JSError) }.should_not raise_error
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|