therubyrhino 1.73.0 → 1.73.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|