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,38 @@
|
|
|
1
|
+
require File.expand_path('../spec_helper', File.dirname(__FILE__))
|
|
2
|
+
|
|
3
|
+
describe Rhino::JSError do
|
|
4
|
+
|
|
5
|
+
it "works as a StandardError with a message being passed" do
|
|
6
|
+
js_error = Rhino::JSError.new 'an error message'
|
|
7
|
+
lambda { js_error.to_s && js_error.inspect }.should_not raise_error
|
|
8
|
+
|
|
9
|
+
js_error.cause.should be_nil
|
|
10
|
+
js_error.message.should == 'an error message'
|
|
11
|
+
js_error.javascript_backtrace.should be_nil
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it "might wrap a RhinoException wrapped in a NativeException like error" do
|
|
15
|
+
# JRuby's NativeException.new(rhino_e) does not work as it is
|
|
16
|
+
# intended to handle Java exceptions ... no new on the Ruby side
|
|
17
|
+
native_error_class = Class.new(RuntimeError) do
|
|
18
|
+
|
|
19
|
+
def initialize(cause)
|
|
20
|
+
@cause = cause
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def cause
|
|
24
|
+
@cause
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
rhino_e = Rhino::JS::JavaScriptException.new("42".to_java)
|
|
30
|
+
js_error = Rhino::JSError.new native_error_class.new(rhino_e)
|
|
31
|
+
lambda { js_error.to_s && js_error.inspect }.should_not raise_error
|
|
32
|
+
|
|
33
|
+
js_error.cause.should be(rhino_e)
|
|
34
|
+
js_error.message.should == '42'
|
|
35
|
+
js_error.javascript_backtrace.should_not be_nil
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
end
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
require File.expand_path('../spec_helper', File.dirname(__FILE__))
|
|
2
|
+
|
|
3
|
+
shared_examples_for 'ScriptableObject', :shared => true do
|
|
4
|
+
|
|
5
|
+
it "acts like a hash" do
|
|
6
|
+
@object['foo'] = 'bar'
|
|
7
|
+
@object['foo'].should == 'bar'
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
it "might be converted to a hash with string keys" do
|
|
11
|
+
@object[42] = '42'
|
|
12
|
+
@object[:foo] = 'bar'
|
|
13
|
+
expect = @object.respond_to?(:to_h_properties) ? @object.to_h_properties : {}
|
|
14
|
+
@object.to_h.should == expect.merge('42' => '42', 'foo' => 'bar')
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "yields properties with each" do
|
|
18
|
+
@object['1'] = 1
|
|
19
|
+
@object['3'] = 3
|
|
20
|
+
@object['2'] = 2
|
|
21
|
+
@object.each do |key, val|
|
|
22
|
+
case key
|
|
23
|
+
when '1' then val.should == 1
|
|
24
|
+
when '2' then val.should == 2
|
|
25
|
+
when '3' then val.should == 3
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
describe "NativeObject" do
|
|
33
|
+
|
|
34
|
+
before do
|
|
35
|
+
@object = Rhino::JS::NativeObject.new
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it_should_behave_like 'ScriptableObject'
|
|
39
|
+
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
describe "FunctionObject" do
|
|
43
|
+
|
|
44
|
+
before do
|
|
45
|
+
factory = Rhino::JS::ContextFactory.new
|
|
46
|
+
context, scope = nil, nil
|
|
47
|
+
factory.call do |ctx|
|
|
48
|
+
context = ctx
|
|
49
|
+
scope = context.initStandardObjects(nil, false)
|
|
50
|
+
end
|
|
51
|
+
factory.enterContext(context)
|
|
52
|
+
|
|
53
|
+
to_string = java.lang.Object.new.getClass.getMethod(:toString)
|
|
54
|
+
@object = Rhino::JS::FunctionObject.new('to_string', to_string, scope)
|
|
55
|
+
@object.instance_eval do
|
|
56
|
+
def to_h_properties
|
|
57
|
+
{ "arguments"=> nil, "prototype"=> {}, "name"=> "to_string", "arity"=> 0, "length"=> 0 }
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
after do
|
|
63
|
+
Rhino::JS::Context.exit
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
it_should_behave_like 'ScriptableObject'
|
|
67
|
+
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
describe "NativeObject (scoped)" do
|
|
71
|
+
|
|
72
|
+
before do
|
|
73
|
+
factory = Rhino::JS::ContextFactory.new
|
|
74
|
+
context, scope = nil, nil
|
|
75
|
+
factory.call do |ctx|
|
|
76
|
+
context = ctx
|
|
77
|
+
scope = context.initStandardObjects(nil, false)
|
|
78
|
+
end
|
|
79
|
+
factory.enterContext(context)
|
|
80
|
+
|
|
81
|
+
@object = context.newObject(scope)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
after do
|
|
85
|
+
Rhino::JS::Context.exit
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
it_should_behave_like 'ScriptableObject'
|
|
89
|
+
|
|
90
|
+
it 'routes rhino methods' do
|
|
91
|
+
@object.prototype.should == {}
|
|
92
|
+
@object.getTypeOf.should == 'object'
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
it 'raises on missing method' do
|
|
96
|
+
lambda { @object.aMissingMethod }.should raise_error(NoMethodError)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
it 'invokes JS function' do
|
|
100
|
+
@object.hasOwnProperty('foo').should == false
|
|
101
|
+
@object.toLocaleString.should == '[object Object]'
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
it 'puts JS property' do
|
|
105
|
+
@object.has('foo', @object).should == false
|
|
106
|
+
@object.foo = 'bar'
|
|
107
|
+
@object.has('foo', @object).should == true
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
it 'gets JS property' do
|
|
111
|
+
@object.put('foo', @object, 42)
|
|
112
|
+
@object.foo.should == 42
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
describe "NativeFunction" do
|
|
118
|
+
|
|
119
|
+
before do
|
|
120
|
+
factory = Rhino::JS::ContextFactory.new
|
|
121
|
+
@context, @scope = nil, nil
|
|
122
|
+
factory.call do |ctx|
|
|
123
|
+
@context = ctx
|
|
124
|
+
@scope = @context.initStandardObjects(nil, false)
|
|
125
|
+
end
|
|
126
|
+
factory.enterContext(@context)
|
|
127
|
+
|
|
128
|
+
object = @context.newObject(@scope)
|
|
129
|
+
@object = Rhino::JS::ScriptableObject.getProperty(object, 'toString')
|
|
130
|
+
@object.instance_eval do
|
|
131
|
+
def to_h_properties
|
|
132
|
+
{ "arguments"=> nil, "prototype"=> {}, "name"=> "toString", "arity"=> 0, "length"=> 0 }
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
after do
|
|
138
|
+
Rhino::JS::Context.exit
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
it_should_behave_like 'ScriptableObject'
|
|
142
|
+
|
|
143
|
+
it 'is callable' do
|
|
144
|
+
# NOTE: no implicit or bound this thus this === global
|
|
145
|
+
@object.call.should == '[object global]'
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
it 'might be bind and called' do
|
|
149
|
+
@object.bind(@object).should be_a(Rhino::JS::Function)
|
|
150
|
+
@object.bind(@object).call.should == '[object Function]'
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
it 'might be bind to a this context' do
|
|
154
|
+
@object.bind(@object).should be_a(Rhino::JS::Function)
|
|
155
|
+
@object.bind(@object).call.should == '[object Function]'
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
it 'might be bind to a this with args' do
|
|
159
|
+
array = @context.newArray(@scope, [].to_java)
|
|
160
|
+
push = Rhino::JS::ScriptableObject.getProperty(array, 'push')
|
|
161
|
+
|
|
162
|
+
this = @context.newArray(@scope, [ 0 ].to_java)
|
|
163
|
+
push.bind(this, 1, 2).call(3, 4)
|
|
164
|
+
|
|
165
|
+
this.length.should == 5
|
|
166
|
+
5.times { |i| this.get(i, this).should == i }
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
it 'might be applied' do
|
|
170
|
+
an_obj = @context.newObject(@scope)
|
|
171
|
+
@object.apply(an_obj).should == '[object Object]'
|
|
172
|
+
|
|
173
|
+
array = @context.newArray(@scope, [].to_java)
|
|
174
|
+
push = Rhino::JS::ScriptableObject.getProperty(array, 'splice')
|
|
175
|
+
|
|
176
|
+
this = @context.newArray(@scope, [ 0, 3, 4 ].to_java)
|
|
177
|
+
push.apply(this, 1, 0, 1, 2)
|
|
178
|
+
|
|
179
|
+
this.length.should == 5
|
|
180
|
+
5.times { |i| this.get(i, this).should == i }
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
it 'might get method-called' do
|
|
184
|
+
@object.method(:apply).should == @object.method(:methodcall)
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
describe "NativeFunction (constructor)" do
|
|
190
|
+
|
|
191
|
+
before do
|
|
192
|
+
factory = Rhino::JS::ContextFactory.new
|
|
193
|
+
context, scope = nil, nil
|
|
194
|
+
factory.call do |ctx|
|
|
195
|
+
context = ctx
|
|
196
|
+
scope = context.initStandardObjects(nil, false)
|
|
197
|
+
end
|
|
198
|
+
factory.enterContext(context)
|
|
199
|
+
|
|
200
|
+
@object = Rhino::JS::ScriptableObject.getProperty(context.newObject(scope), 'constructor')
|
|
201
|
+
@object.instance_eval do
|
|
202
|
+
def to_h_properties
|
|
203
|
+
{
|
|
204
|
+
"arguments"=>nil, "prototype"=>{}, "name"=>"Object", "arity"=>1, "length"=>1,
|
|
205
|
+
|
|
206
|
+
"getPrototypeOf"=> { "arguments"=>nil, "prototype"=>{}, "name"=>"getPrototypeOf", "arity"=>1, "length"=>1},
|
|
207
|
+
"keys"=>{"arguments"=>nil, "prototype"=>{}, "name"=>"keys", "arity"=>1, "length"=>1},
|
|
208
|
+
"getOwnPropertyNames"=>{"arguments"=>nil, "prototype"=>{}, "name"=>"getOwnPropertyNames", "arity"=>1, "length"=>1},
|
|
209
|
+
"getOwnPropertyDescriptor"=>{"arguments"=>nil, "prototype"=>{}, "name"=>"getOwnPropertyDescriptor", "arity"=>2, "length"=>2},
|
|
210
|
+
"defineProperty"=>{"arguments"=>nil, "prototype"=>{}, "name"=>"defineProperty", "arity"=>3, "length"=>3},
|
|
211
|
+
"isExtensible"=>{"arguments"=>nil, "prototype"=>{}, "name"=>"isExtensible", "arity"=>1, "length"=>1},
|
|
212
|
+
"preventExtensions"=>{"arguments"=>nil, "prototype"=>{}, "name"=>"preventExtensions", "arity"=>1, "length"=>1},
|
|
213
|
+
"defineProperties"=>{"arguments"=>nil, "prototype"=>{}, "name"=>"defineProperties", "arity"=>2, "length"=>2},
|
|
214
|
+
"create"=>{"arguments"=>nil, "prototype"=>{}, "name"=>"create", "arity"=>2, "length"=>2},
|
|
215
|
+
"isSealed"=>{"arguments"=>nil, "prototype"=>{}, "name"=>"isSealed", "arity"=>1, "length"=>1},
|
|
216
|
+
"isFrozen"=>{"arguments"=>nil, "prototype"=>{}, "name"=>"isFrozen", "arity"=>1, "length"=>1},
|
|
217
|
+
"seal"=>{"arguments"=>nil, "prototype"=>{}, "name"=>"seal", "arity"=>1, "length"=>1},
|
|
218
|
+
"freeze"=>{"arguments"=>nil, "prototype"=>{}, "name"=>"freeze", "arity"=>1, "length"=>1}
|
|
219
|
+
}
|
|
220
|
+
end
|
|
221
|
+
end
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
after do
|
|
225
|
+
Rhino::JS::Context.exit
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
it_should_behave_like 'ScriptableObject'
|
|
229
|
+
|
|
230
|
+
it 'is constructable' do
|
|
231
|
+
@object.new.should == {}
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
end
|
|
@@ -0,0 +1,390 @@
|
|
|
1
|
+
require File.expand_path('../spec_helper', File.dirname(__FILE__))
|
|
2
|
+
|
|
3
|
+
shared_examples_for Rhino::Ruby::Scriptable, :shared => true do
|
|
4
|
+
|
|
5
|
+
it "puts, gets and has a read/write attr" do
|
|
6
|
+
start = mock('start')
|
|
7
|
+
start.expects(:put).never
|
|
8
|
+
|
|
9
|
+
@wrapper.unwrap.instance_eval do
|
|
10
|
+
def foo; @foo; end
|
|
11
|
+
def foo=(foo); @foo = foo; end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
@wrapper.put('foo', start, 42)
|
|
15
|
+
@wrapper.has('foo', nil).should == true
|
|
16
|
+
@wrapper.get('foo', nil).should == 42
|
|
17
|
+
@wrapper.unwrap.instance_variable_get(:'@foo').should == 42
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it "puts, gets and has a write only attr" do
|
|
21
|
+
start = mock('start')
|
|
22
|
+
start.expects(:put).never
|
|
23
|
+
|
|
24
|
+
@wrapper.unwrap.instance_eval do
|
|
25
|
+
def foo=(foo); @foo = foo; end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
@wrapper.put('foo', start, 42)
|
|
29
|
+
@wrapper.has('foo', nil).should == true
|
|
30
|
+
@wrapper.get('foo', nil).should be(nil)
|
|
31
|
+
@wrapper.unwrap.instance_variable_get(:'@foo').should == 42
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it "puts, gets and has gets delegated if it acts like a Hash" do
|
|
35
|
+
start = mock('start')
|
|
36
|
+
start.expects(:put).never
|
|
37
|
+
|
|
38
|
+
@wrapper.unwrap.instance_eval do
|
|
39
|
+
def [](name); (@hash ||= {})[name]; end
|
|
40
|
+
def []=(name, value); (@hash ||= {})[name] = value; end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
@wrapper.put('foo', start, 42)
|
|
44
|
+
@wrapper.has('foo', nil).should == true
|
|
45
|
+
@wrapper.get('foo', nil).should == 42
|
|
46
|
+
@wrapper.unwrap.instance_variable_get(:'@hash')['foo'].should == 42
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it "puts, gets and has non-existing property" do
|
|
50
|
+
start = mock('start')
|
|
51
|
+
start.expects(:put).once
|
|
52
|
+
|
|
53
|
+
@wrapper.put('foo', start, 42)
|
|
54
|
+
@wrapper.has('foo', nil).should == false
|
|
55
|
+
@wrapper.get('foo', nil).should be(Rhino::JS::Scriptable::NOT_FOUND)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
describe Rhino::Ruby::Object do
|
|
61
|
+
|
|
62
|
+
before do
|
|
63
|
+
@wrapper = Rhino::Ruby::Object.wrap @object = Object.new
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
it "unwraps a ruby object" do
|
|
67
|
+
@wrapper.unwrap.should be(@object)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
it_should_behave_like Rhino::Ruby::Scriptable
|
|
71
|
+
|
|
72
|
+
class UII < Object
|
|
73
|
+
|
|
74
|
+
attr_reader :reader
|
|
75
|
+
attr_writer :writer
|
|
76
|
+
|
|
77
|
+
def method; nil; end
|
|
78
|
+
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
it "returns the ruby class name" do
|
|
82
|
+
rb_object = Rhino::Ruby::Object.wrap UII.new
|
|
83
|
+
rb_object.getClassName.should == UII.name
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
it "reports being a ruby object on toString" do
|
|
87
|
+
rb_object = Rhino::Ruby::Object.wrap UII.new
|
|
88
|
+
rb_object.toString.should == '[ruby UII]'
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
it "puts a non-existent attr (delegates to start)" do
|
|
92
|
+
start = mock('start')
|
|
93
|
+
start.expects(:put).once
|
|
94
|
+
rb_object = Rhino::Ruby::Object.wrap UII.new
|
|
95
|
+
|
|
96
|
+
rb_object.put('nonExistingAttr', start, 42)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
it "getIds include ruby class methods" do
|
|
100
|
+
rb_object = Rhino::Ruby::Object.wrap UII.new
|
|
101
|
+
|
|
102
|
+
rb_object.getIds.to_a.should include("reader")
|
|
103
|
+
rb_object.getIds.to_a.should include("method")
|
|
104
|
+
rb_object.getIds.to_a.should_not include('writer=')
|
|
105
|
+
rb_object.getIds.to_a.should include("writer")
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
it "getIds include ruby instance methods" do
|
|
109
|
+
rb_object = Rhino::Ruby::Object.wrap object = UII.new
|
|
110
|
+
object.instance_eval do
|
|
111
|
+
def foo; 'foo'; end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
rb_object.getIds.to_a.should include('foo')
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
it "getIds include writers as attr names" do
|
|
118
|
+
rb_object = Rhino::Ruby::Object.wrap object = UII.new
|
|
119
|
+
|
|
120
|
+
rb_object.getIds.to_a.should include('writer')
|
|
121
|
+
rb_object.getIds.to_a.should_not include('writer=')
|
|
122
|
+
|
|
123
|
+
object.instance_eval do
|
|
124
|
+
def foo=(foo)
|
|
125
|
+
'foo'
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
rb_object.getIds.to_a.should include('foo')
|
|
130
|
+
rb_object.getIds.to_a.should_not include('foo=')
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
describe 'with scope' do
|
|
134
|
+
|
|
135
|
+
before do
|
|
136
|
+
factory = Rhino::JS::ContextFactory.new
|
|
137
|
+
context = nil
|
|
138
|
+
factory.call do |ctx|
|
|
139
|
+
context = ctx
|
|
140
|
+
@scope = context.initStandardObjects(nil, false)
|
|
141
|
+
end
|
|
142
|
+
factory.enterContext(context)
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
after do
|
|
146
|
+
Rhino::JS::Context.exit
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
it "sets up correct prototype" do
|
|
150
|
+
rb_object = Rhino::Ruby::Object.wrap UII.new, @scope
|
|
151
|
+
rb_object.getPrototype.should_not be(nil)
|
|
152
|
+
rb_object.getPrototype.should be_a(Rhino::JS::NativeObject)
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
it "is aliased to RubyObject" do
|
|
158
|
+
(!! defined? Rhino::RubyObject).should == true
|
|
159
|
+
Rhino::RubyObject.should be(Rhino::Ruby::Object)
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
describe Rhino::Ruby::Function do
|
|
165
|
+
|
|
166
|
+
before do
|
|
167
|
+
@wrapper = Rhino::Ruby::Function.wrap @method = Object.new.method(:to_s)
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
it "unwraps a ruby method" do
|
|
171
|
+
@wrapper.unwrap.should be(@method)
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
it_should_behave_like Rhino::Ruby::Scriptable
|
|
175
|
+
|
|
176
|
+
it "is callable as a function" do
|
|
177
|
+
rb_function = Rhino::Ruby::Function.wrap method = 'foo'.method(:to_s)
|
|
178
|
+
context = nil; scope = nil; this = nil; args = nil
|
|
179
|
+
rb_function.call(context, scope, this, args).should == 'foo'
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
it "args get converted before delegating a ruby function call" do
|
|
183
|
+
klass = Class.new(Object) do
|
|
184
|
+
def foo(array)
|
|
185
|
+
array.all? { |elem| elem.is_a?(String) }
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
rb_function = Rhino::Ruby::Function.wrap method = klass.new.method(:foo)
|
|
189
|
+
context = nil; scope = nil; this = nil
|
|
190
|
+
args = [ '1'.to_java, java.lang.String.new('2') ].to_java
|
|
191
|
+
args = [ Rhino::JS::NativeArray.new(args) ].to_java
|
|
192
|
+
rb_function.call(context, scope, this, args).should be(true)
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
it "returned value gets converted to javascript" do
|
|
196
|
+
klass = Class.new(Object) do
|
|
197
|
+
def foo
|
|
198
|
+
[ 42 ]
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
rb_function = Rhino::Ruby::Function.wrap method = klass.new.method(:foo)
|
|
202
|
+
context = nil; scope = nil; this = nil; args = [].to_java
|
|
203
|
+
rb_function.call(context, scope, this, args).should be_a(Rhino::JS::NativeArray)
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
it "slices redundant args when delegating call" do
|
|
207
|
+
klass = Class.new(Object) do
|
|
208
|
+
def foo(a1)
|
|
209
|
+
a1
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
rb_function = Rhino::Ruby::Function.wrap method = klass.new.method(:foo)
|
|
213
|
+
context = nil; scope = nil; this = nil
|
|
214
|
+
|
|
215
|
+
args = [ 1.to_java, 2.to_java, 3.to_java ].to_java; js_return = nil
|
|
216
|
+
lambda { js_return = rb_function.call(context, scope, this, args) }.should_not raise_error
|
|
217
|
+
js_return.should == 1
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
it "fills missing args when delegating call" do
|
|
221
|
+
klass = Class.new(Object) do
|
|
222
|
+
def foo(a1, a2)
|
|
223
|
+
[ a1, a2 ]
|
|
224
|
+
end
|
|
225
|
+
end
|
|
226
|
+
rb_function = Rhino::Ruby::Function.wrap klass.new.method(:foo)
|
|
227
|
+
context = nil; scope = nil; this = nil
|
|
228
|
+
|
|
229
|
+
args = [ 1.to_java ].to_java; js_return = nil
|
|
230
|
+
lambda { js_return = rb_function.call(context, scope, this, args) }.should_not raise_error
|
|
231
|
+
js_return.toArray.to_a.should == [ 1, nil ]
|
|
232
|
+
|
|
233
|
+
args = [ ].to_java; js_return = nil
|
|
234
|
+
lambda { js_return = rb_function.call(context, scope, this, args) }.should_not raise_error
|
|
235
|
+
js_return.toArray.to_a.should == [ nil, nil ]
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
it "fills missing args when delegating call that ends with varargs" do
|
|
239
|
+
klass = Class.new(Object) do
|
|
240
|
+
def foo(a1, a2, *args)
|
|
241
|
+
[ a1, a2, args ].flatten
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
rb_function = Rhino::Ruby::Function.wrap klass.new.method(:foo)
|
|
245
|
+
context = nil; scope = nil; this = nil
|
|
246
|
+
|
|
247
|
+
args = [ ].to_java; js_return = nil
|
|
248
|
+
lambda { js_return = rb_function.call(context, scope, this, args) }.should_not raise_error
|
|
249
|
+
js_return.toArray.to_a.should == [ nil, nil ]
|
|
250
|
+
|
|
251
|
+
args = [ 1.to_java ].to_java; js_return = nil
|
|
252
|
+
lambda { js_return = rb_function.call(context, scope, this, args) }.should_not raise_error
|
|
253
|
+
js_return.toArray.to_a.should == [ 1, nil ]
|
|
254
|
+
|
|
255
|
+
args = [ 1.to_java, 2.to_java ].to_java; js_return = nil
|
|
256
|
+
lambda { js_return = rb_function.call(context, scope, this, args) }.should_not raise_error
|
|
257
|
+
js_return.toArray.to_a.should == [ 1, 2 ]
|
|
258
|
+
|
|
259
|
+
args = [ 1.to_java, 2.to_java, 3.to_java ].to_java; js_return = nil
|
|
260
|
+
lambda { js_return = rb_function.call(context, scope, this, args) }.should_not raise_error
|
|
261
|
+
js_return.toArray.to_a.should == [ 1, 2, 3 ]
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
it "returns correct arity and length" do
|
|
265
|
+
klass = Class.new(Object) do
|
|
266
|
+
def foo(a1, a2)
|
|
267
|
+
a1 || a2
|
|
268
|
+
end
|
|
269
|
+
end
|
|
270
|
+
rb_function = Rhino::Ruby::Function.wrap klass.new.method(:foo)
|
|
271
|
+
rb_function.getArity.should == 2
|
|
272
|
+
rb_function.getLength.should == 2
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
it "reports arity and length of 0 for varargs only method" do
|
|
276
|
+
klass = Class.new(Object) do
|
|
277
|
+
def foo(*args); args; end
|
|
278
|
+
end
|
|
279
|
+
rb_function = Rhino::Ruby::Function.wrap klass.new.method(:foo)
|
|
280
|
+
rb_function.getArity.should == 0
|
|
281
|
+
rb_function.getLength.should == 0
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
it "reports correct arity and length for ending varargs" do
|
|
285
|
+
klass = Class.new(Object) do
|
|
286
|
+
def foo(a1, *args); [ a1, args ]; end
|
|
287
|
+
end
|
|
288
|
+
rb_function = Rhino::Ruby::Function.wrap klass.new.method(:foo)
|
|
289
|
+
rb_function.getArity.should == 1
|
|
290
|
+
rb_function.getLength.should == 1
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
describe 'with scope' do
|
|
294
|
+
|
|
295
|
+
before do
|
|
296
|
+
factory = Rhino::JS::ContextFactory.new
|
|
297
|
+
context = nil
|
|
298
|
+
factory.call do |ctx|
|
|
299
|
+
context = ctx
|
|
300
|
+
@scope = context.initStandardObjects(nil, false)
|
|
301
|
+
end
|
|
302
|
+
factory.enterContext(context)
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
after do
|
|
306
|
+
Rhino::JS::Context.exit
|
|
307
|
+
end
|
|
308
|
+
|
|
309
|
+
it "sets up correct prototype" do
|
|
310
|
+
rb_function = Rhino::Ruby::Function.wrap 'foo'.method(:concat), @scope
|
|
311
|
+
rb_function.getPrototype.should_not be(nil)
|
|
312
|
+
rb_function.getPrototype.should be_a(Rhino::JS::Function)
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
it "is aliased to RubyFunction" do
|
|
318
|
+
(!! defined? Rhino::RubyFunction).should == true
|
|
319
|
+
Rhino::RubyFunction.should be(Rhino::Ruby::Function)
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
describe Rhino::Ruby::Constructor do
|
|
325
|
+
|
|
326
|
+
before do
|
|
327
|
+
@wrapper = Rhino::Ruby::Constructor.wrap @class = Class.new(Object)
|
|
328
|
+
end
|
|
329
|
+
|
|
330
|
+
it "unwraps a ruby method" do
|
|
331
|
+
@wrapper.unwrap.should be(@class)
|
|
332
|
+
end
|
|
333
|
+
|
|
334
|
+
it_should_behave_like Rhino::Ruby::Scriptable
|
|
335
|
+
|
|
336
|
+
class Foo < Object
|
|
337
|
+
end
|
|
338
|
+
|
|
339
|
+
it "is callable as a function" do
|
|
340
|
+
rb_new = Rhino::Ruby::Constructor.wrap Foo
|
|
341
|
+
context = nil; scope = nil; this = nil; args = nil
|
|
342
|
+
rb_new.call(context, scope, this, args).should be_a(Rhino::Ruby::Object)
|
|
343
|
+
rb_new.call(context, scope, this, args).unwrap.should be_a(Foo)
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
it "returns correct arity and length" do
|
|
347
|
+
rb_new = Rhino::Ruby::Constructor.wrap Foo
|
|
348
|
+
rb_new.getArity.should == 0
|
|
349
|
+
rb_new.getLength.should == 0
|
|
350
|
+
end
|
|
351
|
+
|
|
352
|
+
it "reports arity and length of 0 for varargs" do
|
|
353
|
+
klass = Class.new do
|
|
354
|
+
def initialize(*args); args; end
|
|
355
|
+
end
|
|
356
|
+
rb_new = Rhino::Ruby::Constructor.wrap klass
|
|
357
|
+
rb_new.getArity.should == 0
|
|
358
|
+
rb_new.getLength.should == 0
|
|
359
|
+
end
|
|
360
|
+
|
|
361
|
+
describe 'with scope' do
|
|
362
|
+
|
|
363
|
+
before do
|
|
364
|
+
factory = Rhino::JS::ContextFactory.new
|
|
365
|
+
context = nil
|
|
366
|
+
factory.call do |ctx|
|
|
367
|
+
context = ctx
|
|
368
|
+
@scope = context.initStandardObjects(nil, false)
|
|
369
|
+
end
|
|
370
|
+
factory.enterContext(context)
|
|
371
|
+
end
|
|
372
|
+
|
|
373
|
+
after do
|
|
374
|
+
Rhino::JS::Context.exit
|
|
375
|
+
end
|
|
376
|
+
|
|
377
|
+
it "has a function prototype" do
|
|
378
|
+
rb_function = Rhino::Ruby::Function.wrap 'foo'.method(:concat), @scope
|
|
379
|
+
rb_function.getPrototype.should_not be(nil)
|
|
380
|
+
rb_function.getPrototype.should be_a(Rhino::JS::Function)
|
|
381
|
+
end
|
|
382
|
+
|
|
383
|
+
end
|
|
384
|
+
|
|
385
|
+
it "is aliased to RubyConstructor" do
|
|
386
|
+
(!! defined? Rhino::RubyConstructor).should == true
|
|
387
|
+
Rhino::RubyConstructor.should be(Rhino::Ruby::Constructor)
|
|
388
|
+
end
|
|
389
|
+
|
|
390
|
+
end
|