therubyrhino 2.0.1 → 2.0.2
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/History.txt +12 -0
- data/README.rdoc +30 -0
- data/lib/rhino.rb +21 -3
- data/lib/rhino/context.rb +68 -10
- data/lib/rhino/deprecations.rb +7 -18
- data/lib/rhino/rhino_ext.rb +27 -2
- data/lib/rhino/ruby.rb +8 -4
- data/lib/rhino/version.rb +1 -1
- data/spec/rhino/context_spec.rb +41 -0
- data/spec/rhino/rhino_ext_spec.rb +68 -13
- data/spec/rhino/ruby_spec.rb +25 -26
- data/spec/rhino/wormhole_spec.rb +2 -2
- data/spec/spec_helper.rb +21 -1
- metadata +130 -124
data/History.txt
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
=== 2.0.2 2012-12-05
|
2
|
+
|
3
|
+
* handle Rhino's 64K code generation (method) limit on the fly (#23)
|
4
|
+
* correct explicit Ruby equality == and eql? (JRuby 1.7.1 compat)
|
5
|
+
* allow to set javascript version programatically - globally also allow
|
6
|
+
reading it from system properties by default
|
7
|
+
* allow to set optimization level globally also allow reading it from
|
8
|
+
system properties by default
|
9
|
+
* make sure Ruby function wrapper has (Ruby) #call semantics just like
|
10
|
+
JavaScript functions exposed into the Ruby side
|
11
|
+
* function's return value should be converted to Ruby (Ruby #call style)
|
12
|
+
|
1
13
|
=== 2.0.1 2012-08-24
|
2
14
|
|
3
15
|
* JSError improvement to preserve nested Ruby error message
|
data/README.rdoc
CHANGED
@@ -176,6 +176,36 @@ methods "defined in their classes" are exposed by default e.g.
|
|
176
176
|
cxt.eval("b.a()") # => 'TypeError: undefined property 'a' is not a function'
|
177
177
|
end
|
178
178
|
|
179
|
+
==== Using a custom Rhino version
|
180
|
+
|
181
|
+
Officially supported versions of Rhino's _js.jar_ are packaged separately as
|
182
|
+
*therubyrhino_jar* gem. Make sure you're using the latest gem version if you
|
183
|
+
feel like missing something available with Rhino. For experimenters the jar can
|
184
|
+
be overriden by defining a +Rhino::JAR_PATH+ before +require 'rhino'+ e.g. :
|
185
|
+
|
186
|
+
module Rhino
|
187
|
+
JAR_PATH = File.expand_path('lib/rhino/build/rhino1_7R5pre/js.jar')
|
188
|
+
end
|
189
|
+
# ...
|
190
|
+
require 'rhino'
|
191
|
+
|
192
|
+
==== Context customizations
|
193
|
+
|
194
|
+
Just like the JVM packaged Rhino scripting engine, therubyrhino gem supports
|
195
|
+
specifying JavaScript context properies (optimization level and language version)
|
196
|
+
using system properties e.g. to force interpreted mode :
|
197
|
+
|
198
|
+
jruby -J-Drhino.opt.level=-1 -rtherubyrhino -S ...
|
199
|
+
|
200
|
+
You might also set these programatically as a default for all created contexts :
|
201
|
+
|
202
|
+
Rhino::Context.default_optimization_level = 1
|
203
|
+
Rhino::Context.default_javascript_version = 1.6
|
204
|
+
|
205
|
+
Or using plain old JAVA_OPTS e.g. when setting JavaScript version :
|
206
|
+
|
207
|
+
-Drhino.js.version=1.7
|
208
|
+
|
179
209
|
== Rhino
|
180
210
|
|
181
211
|
Rhino is currently maintained at https://github.com/mozilla/rhino
|
data/lib/rhino.rb
CHANGED
@@ -4,8 +4,8 @@ module Rhino
|
|
4
4
|
|
5
5
|
# allow for rhino.jar overrides for "experimental" jrubyists
|
6
6
|
# fallback to rhino/jar_path provided therubyrhino_jar gem :
|
7
|
-
require 'rhino/jar_path' unless
|
8
|
-
load
|
7
|
+
require 'rhino/jar_path' unless const_defined?(:JAR_PATH)
|
8
|
+
load JAR_PATH
|
9
9
|
|
10
10
|
# This module contains all the native Rhino objects implemented in Java
|
11
11
|
# e.g. Rhino::JS::NativeObject # => org.mozilla.javascript.NativeObject
|
@@ -16,7 +16,7 @@ module Rhino
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
-
@@implementation_version = nil
|
19
|
+
@@implementation_version = nil # :nodoc
|
20
20
|
# Helper to resolve what version of Rhino's .jar we're really using.
|
21
21
|
def self.implementation_version
|
22
22
|
@@implementation_version ||= begin
|
@@ -33,6 +33,24 @@ module Rhino
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
+
@@silence = java.lang.Boolean.getBoolean('rhino.silence') # :nodoc
|
37
|
+
# Should we be silent - no warnings will be printed.
|
38
|
+
def self.silence?; @@silence; end
|
39
|
+
# Silence ! (... or I kill you)
|
40
|
+
def self.silence!; @@silence = true; end
|
41
|
+
|
42
|
+
@@warnings = {} # :nodoc
|
43
|
+
|
44
|
+
def self.warn(msg) # :nodoc
|
45
|
+
return if silence?
|
46
|
+
# only print out deprecations once (even when non-silent)
|
47
|
+
if msg[0, 13] == '[DEPRECATION]'
|
48
|
+
return nil if @@warnings[msg]
|
49
|
+
@@warnings[msg] = true
|
50
|
+
end
|
51
|
+
super # Kernel.warn
|
52
|
+
end
|
53
|
+
|
36
54
|
end
|
37
55
|
|
38
56
|
require 'rhino/version'
|
data/lib/rhino/context.rb
CHANGED
@@ -58,6 +58,24 @@ module Rhino
|
|
58
58
|
@@default_factory = factory
|
59
59
|
end
|
60
60
|
|
61
|
+
@@default_optimization_level = java.lang.Integer.getInteger('rhino.opt.level')
|
62
|
+
def self.default_optimization_level
|
63
|
+
@@default_optimization_level
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.default_optimization_level=(level)
|
67
|
+
@@default_optimization_level = level
|
68
|
+
end
|
69
|
+
|
70
|
+
@@default_javascript_version = java.lang.System.getProperty('rhino.js.version')
|
71
|
+
def self.default_javascript_version
|
72
|
+
@@default_javascript_version
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.default_javascript_version=(version)
|
76
|
+
@@default_javascript_version = version
|
77
|
+
end
|
78
|
+
|
61
79
|
attr_reader :scope
|
62
80
|
|
63
81
|
# Create a new javascript environment for executing javascript and ruby code.
|
@@ -82,6 +100,12 @@ module Rhino
|
|
82
100
|
end
|
83
101
|
end
|
84
102
|
end
|
103
|
+
if optimization_level = options[:optimization_level] || self.class.default_optimization_level
|
104
|
+
self.optimization_level = optimization_level
|
105
|
+
end
|
106
|
+
if javascript_version = options[:javascript_version] || self.class.default_javascript_version
|
107
|
+
self.javascript_version = javascript_version
|
108
|
+
end
|
85
109
|
yield(self) if block_given?
|
86
110
|
end
|
87
111
|
|
@@ -191,16 +215,17 @@ module Rhino
|
|
191
215
|
|
192
216
|
# Get the JS interpreter version.
|
193
217
|
# Returns a number e.g. 1.7, nil if unknown and 0 for default.
|
194
|
-
def
|
218
|
+
def javascript_version
|
195
219
|
case const_value = @native.getLanguageVersion
|
196
220
|
when -1 then nil # VERSION_UNKNOWN
|
197
221
|
when 0 then 0 # VERSION_DEFAULT
|
198
222
|
else const_value / 100.0 # VERSION_1_1 (1.1 = 110 / 100)
|
199
223
|
end
|
200
224
|
end
|
225
|
+
alias :version :javascript_version
|
201
226
|
|
202
227
|
# Sets interpreter mode a.k.a. JS language version e.g. 1.7 (if supported).
|
203
|
-
def
|
228
|
+
def javascript_version=(version)
|
204
229
|
const = version.to_s.gsub('.', '_').upcase
|
205
230
|
const = "VERSION_#{const}" if const[0, 7] != 'VERSION'
|
206
231
|
if JS::Context.constants.find { |c| c.to_s == const }
|
@@ -212,26 +237,59 @@ module Rhino
|
|
212
237
|
nil
|
213
238
|
end
|
214
239
|
end
|
240
|
+
alias :version= :javascript_version=
|
215
241
|
|
216
242
|
# Enter this context for operations.
|
217
|
-
# Some methods such as eval() will fail unless
|
243
|
+
# Some methods such as eval() will fail unless the context is open.
|
218
244
|
def open(&block)
|
219
245
|
do_open(&block)
|
220
246
|
rescue JS::RhinoException => e
|
247
|
+
if code_generation_error?(e)
|
248
|
+
warn "[INFO] Rhino byte-code generation failed forcing #{@native} into interpreted mode"
|
249
|
+
self.optimization_level = -1
|
250
|
+
retry
|
251
|
+
end
|
221
252
|
raise Rhino::JSError.new(e)
|
222
253
|
end
|
223
254
|
|
224
255
|
private
|
225
256
|
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
end
|
257
|
+
def do_open # :nodoc
|
258
|
+
factory.enterContext(@native)
|
259
|
+
begin
|
260
|
+
yield self
|
261
|
+
ensure
|
262
|
+
factory.exit
|
233
263
|
end
|
264
|
+
end
|
234
265
|
|
266
|
+
CODE_GENERATION_ERROR_MESSAGE = 'generated bytecode for method exceeds 64K limit' # :nodoc
|
267
|
+
|
268
|
+
CODE_GENERATION_TRACE_CLASS_NAME = 'org.mozilla.javascript.optimizer.Codegen' # :nodoc
|
269
|
+
CODE_GENERATION_TRACE_METHOD_NAME = 'reportClassFileFormatException' # :nodoc
|
270
|
+
# at org.mozilla.javascript.optimizer.Codegen.reportClassFileFormatException
|
271
|
+
|
272
|
+
def code_generation_error?(exception) # :nodoc
|
273
|
+
if ( exception.is_a?(NativeException) rescue nil ) # JRuby 1.6 wrapping
|
274
|
+
exception = exception.cause
|
275
|
+
end
|
276
|
+
if exception.class == Rhino::JS::EvaluatorException
|
277
|
+
if exception.message.index(CODE_GENERATION_ERROR_MESSAGE)
|
278
|
+
return true
|
279
|
+
end
|
280
|
+
# NOTE: unfortunately Rhino localizes the error messages!
|
281
|
+
# and the ClassFileFormatException is not kept as a cause
|
282
|
+
class_name = CODE_GENERATION_TRACE_CLASS_NAME
|
283
|
+
method_name = CODE_GENERATION_TRACE_METHOD_NAME
|
284
|
+
for trace in exception.getStackTrace()
|
285
|
+
if class_name == trace.class_name && method_name == trace.method_name
|
286
|
+
return true
|
287
|
+
end
|
288
|
+
end
|
289
|
+
end
|
290
|
+
false
|
291
|
+
end
|
292
|
+
|
235
293
|
end
|
236
294
|
|
237
295
|
class IOReader < java.io.Reader # :nodoc:
|
data/lib/rhino/deprecations.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
|
2
2
|
module Rhino
|
3
3
|
|
4
|
-
@@stub_class = Class.new(Object)
|
4
|
+
@@stub_class = Class.new(Object) # :nodoc
|
5
5
|
|
6
|
-
def self.const_missing(name)
|
6
|
+
def self.const_missing(name) # :nodoc
|
7
7
|
case name.to_s
|
8
8
|
when 'J' then
|
9
9
|
warn "[DEPRECATION] `Rhino::J` is deprecated, use `Rhino::JS` instead."
|
@@ -21,30 +21,19 @@ module Rhino
|
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
-
|
25
|
-
|
26
|
-
def self.warn(msg)
|
27
|
-
# only print out deprecation warnings once
|
28
|
-
if msg[0, 13] == '[DEPRECATION]'
|
29
|
-
return nil if @@warnings[msg]
|
30
|
-
@@warnings[msg] = true
|
31
|
-
end
|
32
|
-
super # Kernel.warn
|
33
|
-
end
|
34
|
-
|
35
|
-
module To
|
24
|
+
module To # :nodoc
|
36
25
|
|
37
26
|
extend self
|
38
27
|
|
39
|
-
#
|
28
|
+
# #deprecated use {Rhino#to_ruby} instead
|
40
29
|
def self.ruby(object)
|
41
|
-
|
30
|
+
warn "[DEPRECATION] `Rhino::To.ruby` is deprecated, use `Rhino.to_ruby` instead."
|
42
31
|
to_ruby(object)
|
43
32
|
end
|
44
33
|
|
45
|
-
#
|
34
|
+
# #deprecated use {Rhino#to_javascript} instead
|
46
35
|
def self.javascript(object, scope = nil)
|
47
|
-
|
36
|
+
warn "[DEPRECATION] `Rhino::To.javascript` is deprecated, use `Rhino.to_javascript` instead."
|
48
37
|
to_javascript(object, scope)
|
49
38
|
end
|
50
39
|
|
data/lib/rhino/rhino_ext.rb
CHANGED
@@ -80,6 +80,14 @@ class Java::OrgMozillaJavascript::ScriptableObject
|
|
80
80
|
hash
|
81
81
|
end
|
82
82
|
|
83
|
+
def ==(other)
|
84
|
+
equivalentValues(other) == true # JS ==
|
85
|
+
end
|
86
|
+
|
87
|
+
def eql?(other)
|
88
|
+
self.class == other.class && self.==(other)
|
89
|
+
end
|
90
|
+
|
83
91
|
# Convert this javascript object into a json string.
|
84
92
|
def to_json(*args)
|
85
93
|
to_h.to_json(*args)
|
@@ -91,7 +99,7 @@ class Java::OrgMozillaJavascript::ScriptableObject
|
|
91
99
|
def inspect
|
92
100
|
toString
|
93
101
|
end
|
94
|
-
|
102
|
+
|
95
103
|
# Delegate methods to JS object if possible when called from Ruby.
|
96
104
|
def method_missing(name, *args)
|
97
105
|
name_str = name.to_s
|
@@ -147,6 +155,22 @@ class Java::OrgMozillaJavascript::NativeObject
|
|
147
155
|
ScriptableObject.putProperty(self, key.to_s, Rhino.to_javascript(value, scope))
|
148
156
|
end
|
149
157
|
|
158
|
+
def ==(other)
|
159
|
+
return true if super
|
160
|
+
if other.is_a?(Hash) || other.is_a?(java.util.Map)
|
161
|
+
for key, val in other
|
162
|
+
return false if self[key] != val
|
163
|
+
end
|
164
|
+
return true
|
165
|
+
end
|
166
|
+
false
|
167
|
+
end
|
168
|
+
|
169
|
+
# NOTE: need to re-implement this as JRuby 1.7.1 seems to be not routing to super
|
170
|
+
def eql?(other) # :nodoc
|
171
|
+
self.class == other.class && self.==(other)
|
172
|
+
end
|
173
|
+
|
150
174
|
end
|
151
175
|
|
152
176
|
# The base class for all JavaScript function objects.
|
@@ -165,7 +189,8 @@ class Java::OrgMozillaJavascript::BaseFunction
|
|
165
189
|
# calling as a (var) stored function - no this === undefined "use strict"
|
166
190
|
# TODO can't pass Undefined.instance as this - it's not a Scriptable !?
|
167
191
|
this = Rhino::JS::ScriptRuntime.getGlobal(context)
|
168
|
-
|
192
|
+
js_args = Rhino.args_to_javascript(args, scope)
|
193
|
+
Rhino.to_ruby __call__(context, scope, this, js_args)
|
169
194
|
rescue Rhino::JS::JavaScriptException => e
|
170
195
|
raise Rhino::JSError.new(e)
|
171
196
|
ensure
|
data/lib/rhino/ruby.rb
CHANGED
@@ -176,7 +176,11 @@ module Rhino
|
|
176
176
|
|
177
177
|
# override Object BaseFunction#call(Context context, Scriptable scope,
|
178
178
|
# Scriptable thisObj, Object[] args)
|
179
|
-
def call(
|
179
|
+
def call(*args)
|
180
|
+
unless args.first.is_a?(JS::Context)
|
181
|
+
return super # assume a Ruby #call
|
182
|
+
end
|
183
|
+
_, scope, this, args = *args # Java Function#call dispatch
|
180
184
|
args = args.to_a # java.lang.Object[] -> Array
|
181
185
|
# JS function style :
|
182
186
|
if ( arity = @callable.arity ) != -1 # (a1, *a).arity == -2
|
@@ -268,8 +272,8 @@ module Rhino
|
|
268
272
|
|
269
273
|
end
|
270
274
|
|
271
|
-
RubyObject = Ruby::Object
|
272
|
-
RubyFunction = Ruby::Function
|
273
|
-
RubyConstructor = Ruby::Constructor
|
275
|
+
RubyObject = Ruby::Object # :nodoc
|
276
|
+
RubyFunction = Ruby::Function # :nodoc
|
277
|
+
RubyConstructor = Ruby::Constructor # :nodoc
|
274
278
|
|
275
279
|
end
|
data/lib/rhino/version.rb
CHANGED
data/spec/rhino/context_spec.rb
CHANGED
@@ -140,4 +140,45 @@ describe Rhino::Context do
|
|
140
140
|
}.should raise_error(Rhino::RunawayScriptError)
|
141
141
|
end
|
142
142
|
|
143
|
+
it "allows to set (default) optimization level" do
|
144
|
+
context = Rhino::Context.new :optimization_level => 2
|
145
|
+
context.eval %Q{ for (var i = 0; i < 42; i++) Number(i).toString(); }
|
146
|
+
context.optimization_level.should == 2
|
147
|
+
begin
|
148
|
+
Rhino::Context.default_optimization_level = 3
|
149
|
+
context = Rhino::Context.new
|
150
|
+
context.eval %Q{ for (var i = 0; i < 42; i++) Number(i).toString(); }
|
151
|
+
context.optimization_level.should == 3
|
152
|
+
ensure
|
153
|
+
Rhino::Context.default_optimization_level = nil
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
it "allows to set (default) language version" do
|
158
|
+
context = Rhino::Context.new :javascript_version => '1.6'
|
159
|
+
context.javascript_version.should == 1.6
|
160
|
+
begin
|
161
|
+
Rhino::Context.default_javascript_version = '1.5'
|
162
|
+
context = Rhino::Context.new
|
163
|
+
context.javascript_version.should == 1.5
|
164
|
+
ensure
|
165
|
+
Rhino::Context.default_javascript_version = nil
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
it "handles code generation error when 'generated bytecode for method exceeds 64K limit'" do
|
170
|
+
context = Rhino::Context.new
|
171
|
+
|
172
|
+
big_script = ''
|
173
|
+
10000.times { |i| big_script << "var s#{i} = '#{i}';\n" }
|
174
|
+
10000.times { |i| big_script << "var n#{i} = +#{i} ;\n" }
|
175
|
+
|
176
|
+
lambda {
|
177
|
+
context.eval big_script
|
178
|
+
}.should_not raise_error
|
179
|
+
|
180
|
+
context.eval('( s9999 )').should == '9999'
|
181
|
+
context.eval('( n9999 )').should == +9999
|
182
|
+
end
|
183
|
+
|
143
184
|
end
|
@@ -87,14 +87,14 @@ describe "NativeObject (scoped)" do
|
|
87
87
|
|
88
88
|
before do
|
89
89
|
factory = Rhino::JS::ContextFactory.new
|
90
|
-
context, scope = nil, nil
|
90
|
+
@context, @scope = nil, nil
|
91
91
|
factory.call do |ctx|
|
92
|
-
context = ctx
|
93
|
-
scope = context.initStandardObjects(nil, false)
|
92
|
+
@context = ctx
|
93
|
+
@scope = @context.initStandardObjects(nil, false)
|
94
94
|
end
|
95
|
-
factory.enterContext(context)
|
95
|
+
factory.enterContext(@context)
|
96
96
|
|
97
|
-
@object = context.newObject(scope)
|
97
|
+
@object = @context.newObject(@scope)
|
98
98
|
end
|
99
99
|
|
100
100
|
after do
|
@@ -104,7 +104,7 @@ describe "NativeObject (scoped)" do
|
|
104
104
|
it_should_behave_like 'ScriptableObject'
|
105
105
|
|
106
106
|
it 'routes rhino methods' do
|
107
|
-
@object.prototype.
|
107
|
+
@object.prototype.should_not be nil
|
108
108
|
@object.getTypeOf.should == 'object'
|
109
109
|
end
|
110
110
|
|
@@ -128,6 +128,35 @@ describe "NativeObject (scoped)" do
|
|
128
128
|
@object.foo.should == 42
|
129
129
|
end
|
130
130
|
|
131
|
+
it 'is == to an empty Hash / Map' do
|
132
|
+
( @object == {} ).should be true
|
133
|
+
( @object == java.util.HashMap.new ).should be true
|
134
|
+
end
|
135
|
+
|
136
|
+
it 'is === to an empty Hash' do
|
137
|
+
( @object === {} ).should be true
|
138
|
+
end
|
139
|
+
|
140
|
+
it 'is not eql? to an empty Hash / Map' do
|
141
|
+
( @object.eql?( {} ) ).should be false
|
142
|
+
( @object.eql?( java.util.HashMap.new ) ).should be false
|
143
|
+
end
|
144
|
+
|
145
|
+
it 'is eql? to another native object' do
|
146
|
+
object = @context.newObject(scope)
|
147
|
+
( @object.eql?( object ) ).should be true
|
148
|
+
( object.eql?( @object ) ).should be true
|
149
|
+
( @object == object ).should be true
|
150
|
+
( object === @object ).should be true
|
151
|
+
end
|
152
|
+
|
153
|
+
it 'native objects with same values are equal' do
|
154
|
+
obj1 = @context.evaluateString @scope, "( { ferko: 'suska', answer: 42 } )", '<eval>', 0, nil
|
155
|
+
obj2 = @context.evaluateString @scope, "var obj = {}; obj['answer'] = 42; obj.ferko = 'suska'; obj", '<eval>', 0, nil
|
156
|
+
( obj1 == obj2 ).should be true
|
157
|
+
( obj1.eql?( obj2 ) ).should be true
|
158
|
+
end
|
159
|
+
|
131
160
|
end
|
132
161
|
|
133
162
|
describe "NativeFunction" do
|
@@ -158,10 +187,22 @@ describe "NativeFunction" do
|
|
158
187
|
|
159
188
|
it_should_behave_like 'ScriptableObject'
|
160
189
|
|
161
|
-
it 'is callable' do
|
190
|
+
it 'is (Ruby) callable' do
|
162
191
|
# NOTE: no implicit or bound this thus this === global
|
163
192
|
@object.call.should == '[object global]'
|
164
193
|
end
|
194
|
+
|
195
|
+
it 'is (Ruby) callable passing arguments' do
|
196
|
+
js = "( function foo(arg) { return 'foo' + arg; } )"
|
197
|
+
foo = @context.evaluateString(@scope, js, '<eval>', 0, nil)
|
198
|
+
foo.call(42).should == 'foo42'
|
199
|
+
end
|
200
|
+
|
201
|
+
it 'is (Ruby) callable converting result' do
|
202
|
+
js = "( function foo(arg) { return [ 1, 2, arg ]; } )"
|
203
|
+
foo = @context.evaluateString(@scope, js, '<eval>', 0, nil)
|
204
|
+
foo.call('x').should == [ 1, 2, 'x' ]
|
205
|
+
end
|
165
206
|
|
166
207
|
it 'might be bind and called' do
|
167
208
|
@object.bind(@object).should be_a(Rhino::JS::Function)
|
@@ -208,14 +249,14 @@ describe "NativeFunction (constructor)" do
|
|
208
249
|
|
209
250
|
before do
|
210
251
|
factory = Rhino::JS::ContextFactory.new
|
211
|
-
context, scope = nil, nil
|
252
|
+
@context, @scope = nil, nil
|
212
253
|
factory.call do |ctx|
|
213
|
-
context = ctx
|
214
|
-
scope = context.initStandardObjects(nil, false)
|
254
|
+
@context = ctx
|
255
|
+
@scope = @context.initStandardObjects(nil, false)
|
215
256
|
end
|
216
|
-
factory.enterContext(context)
|
257
|
+
factory.enterContext(@context)
|
217
258
|
|
218
|
-
@object = Rhino::JS::ScriptableObject.getProperty(context.newObject(scope), 'constructor')
|
259
|
+
@object = Rhino::JS::ScriptableObject.getProperty(@context.newObject(@scope), 'constructor')
|
219
260
|
@object.instance_eval do
|
220
261
|
def to_h_properties
|
221
262
|
h = {
|
@@ -248,7 +289,21 @@ describe "NativeFunction (constructor)" do
|
|
248
289
|
it_should_behave_like 'ScriptableObject'
|
249
290
|
|
250
291
|
it 'is constructable' do
|
251
|
-
@object.new.should
|
292
|
+
@object.new.should be_a Rhino::JS::NativeObject
|
252
293
|
end
|
253
294
|
|
295
|
+
it 'is not equal to an empty Hash' do
|
296
|
+
( @object == {} ).should be false
|
297
|
+
( @object === {} ).should be false
|
298
|
+
( @object.eql?( {} ) ).should be false
|
299
|
+
end
|
300
|
+
|
301
|
+
it 'empty functions are not considered equal' do
|
302
|
+
fn1 = @context.evaluateString @scope, "( function() {} )", '<eval>', 0, nil
|
303
|
+
fn2 = @context.evaluateString @scope, "var f = function() {}", '<eval>', 0, nil
|
304
|
+
( fn1 == fn2 ).should be false
|
305
|
+
( fn1 === fn2 ).should be false
|
306
|
+
( fn1.eql?( fn2 ) ).should be false
|
307
|
+
end
|
308
|
+
|
254
309
|
end
|
data/spec/rhino/ruby_spec.rb
CHANGED
@@ -172,13 +172,23 @@ describe Rhino::Ruby::Function do
|
|
172
172
|
end
|
173
173
|
|
174
174
|
it_should_behave_like Rhino::Ruby::Scriptable
|
175
|
+
|
176
|
+
it "is (JavaScript) callable as a function" do
|
177
|
+
rb_function = Rhino::Ruby::Function.wrap 'foo'.method(:upcase)
|
178
|
+
this = nil; args = nil
|
179
|
+
rb_function.call(context, scope, this, args).should == 'FOO'
|
180
|
+
end
|
175
181
|
|
176
|
-
it
|
177
|
-
rb_function = Rhino::Ruby::Function.wrap
|
178
|
-
|
179
|
-
rb_function.call(context, scope, this, args).should == 'foo'
|
182
|
+
it 'is Ruby callable' do
|
183
|
+
rb_function = Rhino::Ruby::Function.wrap 'foo'.method(:upcase)
|
184
|
+
rb_function.call.should == 'FOO'
|
180
185
|
end
|
181
186
|
|
187
|
+
it 'is Ruby callable passing arguments' do
|
188
|
+
rb_function = Rhino::Ruby::Function.wrap 'foo'.method(:scan)
|
189
|
+
rb_function.call('o').should == ['o', 'o']
|
190
|
+
end
|
191
|
+
|
182
192
|
it "args get converted before delegating a ruby function call" do
|
183
193
|
klass = Class.new(Object) do
|
184
194
|
def foo(array)
|
@@ -186,7 +196,7 @@ describe Rhino::Ruby::Function do
|
|
186
196
|
end
|
187
197
|
end
|
188
198
|
rb_function = Rhino::Ruby::Function.wrap method = klass.new.method(:foo)
|
189
|
-
|
199
|
+
this = nil
|
190
200
|
args = [ '1'.to_java, java.lang.String.new('2') ].to_java
|
191
201
|
args = [ Rhino::JS::NativeArray.new(args) ].to_java
|
192
202
|
rb_function.call(context, scope, this, args).should be(true)
|
@@ -199,7 +209,7 @@ describe Rhino::Ruby::Function do
|
|
199
209
|
end
|
200
210
|
end
|
201
211
|
rb_function = Rhino::Ruby::Function.wrap method = klass.new.method(:foo)
|
202
|
-
|
212
|
+
this = nil; args = [].to_java
|
203
213
|
rb_function.call(context, scope, this, args).should be_a(Rhino::JS::NativeArray)
|
204
214
|
end
|
205
215
|
|
@@ -209,8 +219,8 @@ describe Rhino::Ruby::Function do
|
|
209
219
|
a1
|
210
220
|
end
|
211
221
|
end
|
212
|
-
rb_function = Rhino::Ruby::Function.wrap
|
213
|
-
|
222
|
+
rb_function = Rhino::Ruby::Function.wrap klass.new.method(:foo)
|
223
|
+
this = nil
|
214
224
|
|
215
225
|
args = [ 1.to_java, 2.to_java, 3.to_java ].to_java; js_return = nil
|
216
226
|
lambda { js_return = rb_function.call(context, scope, this, args) }.should_not raise_error
|
@@ -224,7 +234,7 @@ describe Rhino::Ruby::Function do
|
|
224
234
|
end
|
225
235
|
end
|
226
236
|
rb_function = Rhino::Ruby::Function.wrap klass.new.method(:foo)
|
227
|
-
|
237
|
+
this = nil
|
228
238
|
|
229
239
|
args = [ 1.to_java ].to_java; js_return = nil
|
230
240
|
lambda { js_return = rb_function.call(context, scope, this, args) }.should_not raise_error
|
@@ -242,7 +252,7 @@ describe Rhino::Ruby::Function do
|
|
242
252
|
end
|
243
253
|
end
|
244
254
|
rb_function = Rhino::Ruby::Function.wrap klass.new.method(:foo)
|
245
|
-
|
255
|
+
this = nil
|
246
256
|
|
247
257
|
args = [ ].to_java; js_return = nil
|
248
258
|
lambda { js_return = rb_function.call(context, scope, this, args) }.should_not raise_error
|
@@ -292,22 +302,11 @@ describe Rhino::Ruby::Function do
|
|
292
302
|
|
293
303
|
describe 'with scope' do
|
294
304
|
|
295
|
-
before
|
296
|
-
|
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
|
305
|
+
before { context_factory.enterContext(context) }
|
306
|
+
after { Rhino::JS::Context.exit }
|
308
307
|
|
309
308
|
it "sets up correct prototype" do
|
310
|
-
rb_function = Rhino::Ruby::Function.wrap 'foo'.method(:concat),
|
309
|
+
rb_function = Rhino::Ruby::Function.wrap 'foo'.method(:concat), scope
|
311
310
|
rb_function.getPrototype.should_not be(nil)
|
312
311
|
rb_function.getPrototype.should be_a(Rhino::JS::Function)
|
313
312
|
end
|
@@ -338,7 +337,7 @@ describe Rhino::Ruby::Constructor do
|
|
338
337
|
|
339
338
|
it "is callable as a function" do
|
340
339
|
rb_new = Rhino::Ruby::Constructor.wrap Foo
|
341
|
-
|
340
|
+
this = nil; args = nil
|
342
341
|
rb_new.call(context, scope, this, args).should be_a(Rhino::Ruby::Object)
|
343
342
|
rb_new.call(context, scope, this, args).unwrap.should be_a(Foo)
|
344
343
|
end
|
@@ -398,7 +397,7 @@ describe Rhino::Ruby::Exception do
|
|
398
397
|
end
|
399
398
|
end
|
400
399
|
rb_function = Rhino::Ruby::Function.wrap klass.new.method(:foo)
|
401
|
-
|
400
|
+
this = nil; args = [ 42.to_java ].to_java
|
402
401
|
begin
|
403
402
|
rb_function.call(context, scope, this, args)
|
404
403
|
rescue java.lang.Exception => e
|
data/spec/rhino/wormhole_spec.rb
CHANGED
@@ -168,12 +168,12 @@ describe Rhino::To do
|
|
168
168
|
it "converts procs and methods into native functions" do
|
169
169
|
Rhino.to_javascript(lambda {|lhs,rhs| lhs * rhs}).tap do |f|
|
170
170
|
f.should be_kind_of(Rhino::JS::Function)
|
171
|
-
f.call(
|
171
|
+
f.call(context, scope, nil, [7, 6].to_java).should be(42)
|
172
172
|
end
|
173
173
|
|
174
174
|
Rhino.to_javascript("foo,bar,baz".method(:split)).tap do |f|
|
175
175
|
f.should be_kind_of(Rhino::JS::Function)
|
176
|
-
Rhino.to_ruby(f.call(
|
176
|
+
Rhino.to_ruby(f.call(context, scope, nil, [','].to_java)).should == ['foo', 'bar', 'baz']
|
177
177
|
end
|
178
178
|
end
|
179
179
|
|
data/spec/spec_helper.rb
CHANGED
@@ -10,6 +10,26 @@ module RedJS
|
|
10
10
|
Error = Rhino::JSError
|
11
11
|
end
|
12
12
|
|
13
|
+
module Rhino
|
14
|
+
module SpecHelpers
|
15
|
+
|
16
|
+
def context_factory
|
17
|
+
@context_factory ||= Rhino::JS::ContextFactory.new
|
18
|
+
end
|
19
|
+
|
20
|
+
def context
|
21
|
+
@context || context_factory.call { |ctx| @context = ctx }
|
22
|
+
@context
|
23
|
+
end
|
24
|
+
|
25
|
+
def scope
|
26
|
+
context.initStandardObjects(nil, false)
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
13
32
|
RSpec.configure do |config|
|
14
|
-
config.filter_run_excluding :compat => /(0.5.0)|(0.6.0)/
|
33
|
+
config.filter_run_excluding :compat => /(0.5.0)|(0.6.0)/ # RedJS
|
34
|
+
config.include Rhino::SpecHelpers
|
15
35
|
end
|
metadata
CHANGED
@@ -1,142 +1,148 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: therubyrhino
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
prerelease:
|
5
|
-
version: 2.0.
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 2.0.2
|
6
6
|
platform: ruby
|
7
|
-
authors:
|
8
|
-
- Charles Lowell
|
9
|
-
autorequire:
|
7
|
+
authors:
|
8
|
+
- Charles Lowell
|
9
|
+
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
12
|
+
|
13
|
+
date: 2012-12-05 00:00:00 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: therubyrhino_jar
|
17
|
+
version_requirements: &id001 !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
19
|
+
requirements:
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 1.7.3
|
23
|
+
requirement: *id001
|
24
|
+
prerelease: false
|
25
|
+
type: :runtime
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: rake
|
28
|
+
version_requirements: &id002 !ruby/object:Gem::Requirement
|
29
|
+
none: false
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: "0"
|
34
|
+
requirement: *id002
|
35
|
+
prerelease: false
|
36
|
+
type: :development
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: rspec
|
39
|
+
version_requirements: &id003 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ~>
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: "2.10"
|
45
|
+
requirement: *id003
|
46
|
+
prerelease: false
|
47
|
+
type: :development
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: mocha
|
50
|
+
version_requirements: &id004 !ruby/object:Gem::Requirement
|
51
|
+
none: false
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: "0"
|
56
|
+
requirement: *id004
|
57
|
+
prerelease: false
|
58
|
+
type: :development
|
59
|
+
- !ruby/object:Gem::Dependency
|
60
|
+
name: jruby-openssl
|
61
|
+
version_requirements: &id005 !ruby/object:Gem::Requirement
|
62
|
+
none: false
|
63
|
+
requirements:
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: "0"
|
67
|
+
requirement: *id005
|
68
|
+
prerelease: false
|
69
|
+
type: :development
|
69
70
|
description: Call javascript code and manipulate javascript objects from ruby. Call ruby code and manipulate ruby objects from javascript.
|
70
71
|
email: cowboyd@thefrontside.net
|
71
72
|
executables: []
|
73
|
+
|
72
74
|
extensions: []
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
- .
|
78
|
-
-
|
79
|
-
-
|
80
|
-
-
|
81
|
-
-
|
82
|
-
-
|
83
|
-
- lib/rhino
|
84
|
-
- lib/rhino/
|
85
|
-
- lib/rhino/
|
86
|
-
- lib/rhino/
|
87
|
-
- lib/rhino/
|
88
|
-
- lib/rhino/
|
89
|
-
- lib/rhino/ruby
|
90
|
-
- lib/rhino/ruby/
|
91
|
-
- lib/rhino/ruby/
|
92
|
-
- lib/rhino/
|
93
|
-
- lib/rhino/
|
94
|
-
-
|
95
|
-
- spec/rhino/
|
96
|
-
- spec/rhino/
|
97
|
-
- spec/rhino/
|
98
|
-
- spec/rhino/
|
99
|
-
- spec/rhino/integration/
|
100
|
-
- spec/rhino/integration/
|
101
|
-
- spec/rhino/integration/
|
102
|
-
- spec/rhino/integration/loop
|
103
|
-
- spec/rhino/integration/loop/
|
104
|
-
- spec/rhino/
|
105
|
-
- spec/rhino/
|
106
|
-
- spec/rhino/
|
107
|
-
- spec/rhino/
|
108
|
-
- spec/rhino/
|
109
|
-
- spec/
|
110
|
-
-
|
75
|
+
|
76
|
+
extra_rdoc_files:
|
77
|
+
- README.rdoc
|
78
|
+
files:
|
79
|
+
- .gitignore
|
80
|
+
- .travis.yml
|
81
|
+
- Gemfile
|
82
|
+
- History.txt
|
83
|
+
- README.rdoc
|
84
|
+
- Rakefile
|
85
|
+
- lib/rhino.rb
|
86
|
+
- lib/rhino/context.rb
|
87
|
+
- lib/rhino/deprecations.rb
|
88
|
+
- lib/rhino/error.rb
|
89
|
+
- lib/rhino/object.rb
|
90
|
+
- lib/rhino/rhino_ext.rb
|
91
|
+
- lib/rhino/ruby.rb
|
92
|
+
- lib/rhino/ruby/access.rb
|
93
|
+
- lib/rhino/ruby/attribute_access.rb
|
94
|
+
- lib/rhino/ruby/default_access.rb
|
95
|
+
- lib/rhino/version.rb
|
96
|
+
- lib/rhino/wormhole.rb
|
97
|
+
- spec/rhino/access_spec.rb
|
98
|
+
- spec/rhino/context_spec.rb
|
99
|
+
- spec/rhino/deprecations_spec.rb
|
100
|
+
- spec/rhino/error_spec.rb
|
101
|
+
- spec/rhino/integration/bar.js
|
102
|
+
- spec/rhino/integration/foo.js
|
103
|
+
- spec/rhino/integration/index.js
|
104
|
+
- spec/rhino/integration/loop.js
|
105
|
+
- spec/rhino/integration/loop/element1.js
|
106
|
+
- spec/rhino/integration/loop/element2.js
|
107
|
+
- spec/rhino/integration_spec.rb
|
108
|
+
- spec/rhino/redjs_spec.rb
|
109
|
+
- spec/rhino/rhino_ext_spec.rb
|
110
|
+
- spec/rhino/ruby_spec.rb
|
111
|
+
- spec/rhino/wormhole_spec.rb
|
112
|
+
- spec/spec_helper.rb
|
113
|
+
- therubyrhino.gemspec
|
111
114
|
homepage: http://github.com/cowboyd/therubyrhino
|
112
115
|
licenses: []
|
113
|
-
|
116
|
+
|
117
|
+
post_install_message:
|
114
118
|
rdoc_options: []
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
- - ! '>='
|
120
|
-
- !ruby/object:Gem::Version
|
121
|
-
segments:
|
122
|
-
- 0
|
123
|
-
hash: 2
|
124
|
-
version: '0'
|
119
|
+
|
120
|
+
require_paths:
|
121
|
+
- lib
|
122
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
125
123
|
none: false
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
124
|
+
requirements:
|
125
|
+
- - ">="
|
126
|
+
- !ruby/object:Gem::Version
|
127
|
+
hash: 2
|
128
|
+
segments:
|
129
|
+
- 0
|
130
|
+
version: "0"
|
131
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
134
132
|
none: false
|
133
|
+
requirements:
|
134
|
+
- - ">="
|
135
|
+
- !ruby/object:Gem::Version
|
136
|
+
hash: 2
|
137
|
+
segments:
|
138
|
+
- 0
|
139
|
+
version: "0"
|
135
140
|
requirements: []
|
141
|
+
|
136
142
|
rubyforge_project: therubyrhino
|
137
|
-
rubygems_version: 1.8.
|
138
|
-
signing_key:
|
143
|
+
rubygems_version: 1.8.24
|
144
|
+
signing_key:
|
139
145
|
specification_version: 3
|
140
146
|
summary: Embed the Rhino JavaScript interpreter into JRuby
|
141
147
|
test_files: []
|
142
|
-
|
148
|
+
|