dienashorner 0.1.1 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +16 -2
- data/lib/nashorn.rb +3 -0
- data/lib/nashorn/convert.rb +28 -11
- data/lib/nashorn/error.rb +53 -10
- data/lib/nashorn/execjs/load.rb +16 -0
- data/lib/nashorn/execjs/runtime.rb +85 -0
- data/lib/nashorn/ext.rb +41 -26
- data/lib/nashorn/ruby.rb +10 -12
- data/lib/nashorn/version.rb +1 -1
- data/spec/nashorn/access_spec.rb +7 -9
- data/spec/nashorn/error_spec.rb +36 -34
- data/spec/nashorn/test_execjs.rb +374 -0
- data/spec/nashorn_spec.rb +1 -1
- metadata +4 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dd7cd7502f49f9a24841e42881064fce73a09df1
|
4
|
+
data.tar.gz: 3b5f2dc911bf0384853232e290f25405a900786c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 514de8502051b964befd3bb7edd902969f9a15251cbb4042a9be361f07b46a451807da9681e9cb574a24451dcaf967d0e6a3473ae9b83d3997899431185865b4
|
7
|
+
data.tar.gz: ff10758e53b1b206bac06d2104a6041b68ce150b4f353e640a96b92fe7fa24a36aaec12dc927208a6433038e84c44f2bdd79b69496b86b755d1d42cf6442e6c9
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# dia nashorner
|
2
2
|
|
3
|
-
Embed the ~~Mozilla Rhino~~ Nashorn JavaScript interpreter into Ruby.
|
3
|
+
Embed the ~~Mozilla Rhino~~ [Nashorn][0] JavaScript interpreter into Ruby.
|
4
4
|
|
5
5
|
Nashorn JS engine is available with Java 8 installs (try `jjs -v`).
|
6
6
|
|
@@ -147,11 +147,25 @@ Far from being a drop-in replacement although there's `require 'nashorn/rhino'`.
|
|
147
147
|
will simply need to :`require 'nashorn/rhino/less'` before a `require 'less'`.
|
148
148
|
|
149
149
|
|
150
|
+
### ExecJS
|
151
|
+
|
152
|
+
dienashorner gem ships with an [ExecJS][3] compatible runtime, its best to load it
|
153
|
+
(`require 'nashorn/execjs/load'`) before ExecJS's auto-detection takes place :
|
154
|
+
```ruby
|
155
|
+
gem 'execjs', require: false
|
156
|
+
gem 'dienashorner', platform: :jruby, require: [ 'nashorn/execjs/load', 'execjs' ]
|
157
|
+
```
|
158
|
+
|
159
|
+
|
150
160
|
### Nashorn
|
151
161
|
|
152
|
-
Nashorn JavaScript runtime is part of OpenJDK
|
162
|
+
Nashorn JavaScript runtime is part of [OpenJDK][4] (available since 8u40).
|
153
163
|
|
154
164
|
|
155
165
|
## Copyright
|
156
166
|
|
157
167
|
Copyright (c) 2016 Karol Bucek. Apache License v2 (see LICENSE for details).
|
168
|
+
|
169
|
+
[0]: http://www.oracle.com/technetwork/articles/java/jf14-nashorn-2126515.html
|
170
|
+
[3]: https://github.com/rails/execjs
|
171
|
+
[4]: http://openjdk.java.net/projects/nashorn/
|
data/lib/nashorn.rb
CHANGED
@@ -15,6 +15,7 @@ module Nashorn
|
|
15
15
|
include_package 'jdk.nashorn.api.scripting'
|
16
16
|
# include_package 'jdk.nashorn.internal.runtime'
|
17
17
|
ScriptObject = Java::JdkNashornInternalRuntime::ScriptObject rescue nil
|
18
|
+
# Undefined = Java::JdkNashornInternalRuntime::Undefined rescue nil
|
18
19
|
end
|
19
20
|
|
20
21
|
def eval_js(source, options = {})
|
@@ -28,6 +29,8 @@ module Nashorn
|
|
28
29
|
alias_method :eval, :eval_js # Nashorn.eval '"4" + 2'
|
29
30
|
end
|
30
31
|
|
32
|
+
autoload :Context, 'nashorn/context'
|
33
|
+
|
31
34
|
end
|
32
35
|
|
33
36
|
require 'nashorn/version'
|
data/lib/nashorn/convert.rb
CHANGED
@@ -1,11 +1,23 @@
|
|
1
1
|
class << Nashorn
|
2
2
|
|
3
|
+
ScriptObjectMirror = Nashorn::JS::ScriptObjectMirror
|
4
|
+
private_constant :ScriptObjectMirror
|
5
|
+
ScriptObject = Nashorn::JS::ScriptObject
|
6
|
+
private_constant :ScriptObject
|
7
|
+
|
3
8
|
def to_rb(object, unmirror = false)
|
4
9
|
# ConsString for optimized String + operations :
|
5
10
|
return object.toString if object.is_a?(Java::JavaLang::CharSequence)
|
6
11
|
return object.unwrap if object.is_a?(Nashorn::RubyObject)
|
7
12
|
return object.unwrap if object.is_a?(Nashorn::RubyFunction)
|
8
|
-
return nil if
|
13
|
+
return nil if ScriptObjectMirror.isUndefined(object)
|
14
|
+
# NOTE: "correct" Nashorn leaking-out internals :
|
15
|
+
if ScriptObject && object.is_a?(ScriptObject)
|
16
|
+
# BUGY: Java::JavaLang::ClassCastException:
|
17
|
+
# jdk.nashorn.internal.scripts.JO4 cannot be cast to jdk.nashorn.api.scripting.ScriptObjectMirror
|
18
|
+
# jdk.nashorn.api.scripting.ScriptUtils.wrap(jdk/nashorn/api/scripting/ScriptUtils.java:92)
|
19
|
+
# object = Nashorn::JS::ScriptUtils.wrap(object)
|
20
|
+
end
|
9
21
|
return js_mirror_to_rb(object) if unmirror
|
10
22
|
object
|
11
23
|
end
|
@@ -32,22 +44,27 @@ class << Nashorn
|
|
32
44
|
args.map { |arg| to_rb(arg) }
|
33
45
|
end
|
34
46
|
|
35
|
-
def args_to_js(args)
|
36
|
-
args.map { |arg| to_js(arg) }
|
47
|
+
def args_to_js(args, to_java = false)
|
48
|
+
args = args.map { |arg| to_js(arg) }
|
49
|
+
to_java ? args.to_java : args
|
37
50
|
end
|
38
51
|
|
39
|
-
|
40
|
-
|
41
|
-
|
52
|
+
DEEP_UNMIRROR = ENV_JAVA['nashorn.to_rb.unmirror.deep'] &&
|
53
|
+
ENV_JAVA['nashorn.to_rb.unmirror.deep'].length > 0 &&
|
54
|
+
ENV_JAVA['nashorn.to_rb.unmirror.deep'] != 'false'
|
42
55
|
|
43
|
-
def js_mirror_to_rb(object, deep =
|
44
|
-
object = Nashorn::JS::ScriptUtils.unwrap(object)
|
56
|
+
def js_mirror_to_rb(object, deep = DEEP_UNMIRROR)
|
45
57
|
if object.is_a?(Nashorn::JS::JSObject)
|
46
|
-
|
47
|
-
|
58
|
+
if object.isArray
|
59
|
+
return object.raw_values.to_a unless deep
|
60
|
+
object.raw_values.map { |obj| to_rb(obj, true) }
|
61
|
+
end
|
62
|
+
return object if object.isFunction # TODO CallableHash < Hash?
|
48
63
|
# Nashorn::JS::ScriptObjectMirror is already a Map but still :
|
49
64
|
hash = {}
|
50
|
-
|
65
|
+
for key in object.keySet
|
66
|
+
hash[key] = deep ? to_rb(object[key], true) : object[key]
|
67
|
+
end
|
51
68
|
hash
|
52
69
|
else
|
53
70
|
object
|
data/lib/nashorn/error.rb
CHANGED
@@ -8,12 +8,17 @@ module Nashorn
|
|
8
8
|
if value.is_a?(Exception)
|
9
9
|
super "#{value.class.name}: #{value.message}"
|
10
10
|
elsif value.is_a?(JS::ScriptObject) # && @native.to_s.index('Error:')
|
11
|
-
super @native
|
11
|
+
super normalize_message(@native)
|
12
12
|
else
|
13
13
|
super value
|
14
14
|
end
|
15
15
|
else
|
16
|
-
|
16
|
+
if cause = self.cause
|
17
|
+
message = normalize_message(cause)
|
18
|
+
else
|
19
|
+
message = normalize_message(@native)
|
20
|
+
end
|
21
|
+
super message
|
17
22
|
end
|
18
23
|
end
|
19
24
|
|
@@ -30,7 +35,7 @@ module Nashorn
|
|
30
35
|
if @native.respond_to?(:cause) && @native.cause
|
31
36
|
@cause = @native.cause
|
32
37
|
else
|
33
|
-
@native.is_a?(JS::NashornException) ? @native : nil
|
38
|
+
@cause = @native.is_a?(JS::NashornException) ? @native : nil
|
34
39
|
end
|
35
40
|
end
|
36
41
|
|
@@ -51,11 +56,20 @@ module Nashorn
|
|
51
56
|
end
|
52
57
|
|
53
58
|
# Return the thown (native) JavaScript value.
|
54
|
-
def value(unwrap = false)
|
55
|
-
return @value if defined?(@value) && ! unwrap
|
56
|
-
@value = get_thrown unless defined?(@value)
|
57
|
-
return @value.unwrap if unwrap && @value.respond_to?(:unwrap)
|
58
|
-
@value
|
59
|
+
def value(unwrap = nil) # (unwrap = false)
|
60
|
+
# return @value if defined?(@value) && ! unwrap
|
61
|
+
# @value = get_thrown unless defined?(@value)
|
62
|
+
# return @value.unwrap if unwrap && @value.respond_to?(:unwrap)
|
63
|
+
# @value
|
64
|
+
|
65
|
+
return @value if defined?(@value)
|
66
|
+
|
67
|
+
if thrown = get_thrown
|
68
|
+
# NOTE: thrown sometimes leaks a Nashorn::JS::ScriptObject
|
69
|
+
@value = Nashorn.to_rb thrown
|
70
|
+
else
|
71
|
+
@value = thrown
|
72
|
+
end
|
59
73
|
end
|
60
74
|
alias_method :thrown, :value
|
61
75
|
|
@@ -70,10 +84,19 @@ module Nashorn
|
|
70
84
|
|
71
85
|
# Returns the JavaScript back-trace part for this error (the script stack).
|
72
86
|
def javascript_backtrace(raw_elements = false)
|
87
|
+
return @javascript_backtrace if (@javascript_backtrace ||= nil) && ! raw_elements
|
88
|
+
|
73
89
|
return nil unless cause.is_a?(JS::NashornException)
|
74
|
-
|
75
|
-
|
90
|
+
|
91
|
+
return JS::NashornException.getScriptFrames(cause) if raw_elements
|
92
|
+
|
93
|
+
js_backtrace = []
|
94
|
+
js_backtrace << @_trace_trail if defined?(@_trace_trail)
|
95
|
+
|
96
|
+
for element in JS::NashornException.getScriptFrames(cause)
|
97
|
+
js_backtrace << element.to_s # element - ScriptStackElement
|
76
98
|
end
|
99
|
+
@javascript_backtrace = js_backtrace
|
77
100
|
end
|
78
101
|
|
79
102
|
# jdk.nashorn.internal.runtime::ECMAException < NashornException has these :
|
@@ -90,6 +113,14 @@ module Nashorn
|
|
90
113
|
cause.respond_to?(:getColumnNumber) ? cause.getColumnNumber : nil
|
91
114
|
end
|
92
115
|
|
116
|
+
PARSER_EXCEPTION = 'Java::JdkNashornInternalRuntime::ParserException'
|
117
|
+
private_constant :PARSER_EXCEPTION if respond_to?(:private_constant)
|
118
|
+
|
119
|
+
# @private invented for ExceJS
|
120
|
+
def self.parse_error?(error)
|
121
|
+
PARSER_EXCEPTION.eql? error.class.name
|
122
|
+
end
|
123
|
+
|
93
124
|
private
|
94
125
|
|
95
126
|
def get_thrown
|
@@ -100,6 +131,18 @@ module Nashorn
|
|
100
131
|
end
|
101
132
|
end
|
102
133
|
|
134
|
+
def normalize_message(error)
|
135
|
+
# "<eval>:1:1 Expected an operand but found )\n ())\n^"
|
136
|
+
# extract first trace part of message :
|
137
|
+
message = error.message
|
138
|
+
return message unless JSError.parse_error?(error)
|
139
|
+
if match = message.match(/^(.*?\:\d+\:\d+)\s/)
|
140
|
+
@_trace_trail = match[1]
|
141
|
+
return message[@_trace_trail.length + 1..-1]
|
142
|
+
end
|
143
|
+
message
|
144
|
+
end
|
145
|
+
|
103
146
|
end
|
104
147
|
|
105
148
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# load ExecJS with an available Nashorn runtime!
|
2
|
+
|
3
|
+
require 'execjs/runtimes' # only require 'execjs' triggers auto-detect
|
4
|
+
|
5
|
+
module ExecJS
|
6
|
+
if const_defined?(:NashornRuntime)
|
7
|
+
warn "ExecJS::NashornRuntime exists, you probably want to avoid loading #{__FILE__}"
|
8
|
+
end
|
9
|
+
|
10
|
+
require 'nashorn/execjs/runtime'
|
11
|
+
|
12
|
+
unless at = Runtimes.runtimes.find { |runtime| runtime.is_a?(ExecJS::NashornRuntime) }
|
13
|
+
at = Runtimes.runtimes.index(RubyRhino) if const_defined?(:RubyRhino)
|
14
|
+
Runtimes.runtimes.insert (at || 0), ExecJS::NashornRuntime.new
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'execjs/runtime'
|
2
|
+
|
3
|
+
module ExecJS
|
4
|
+
class NashornRuntime < Runtime
|
5
|
+
class Context < Runtime::Context
|
6
|
+
|
7
|
+
def initialize(runtime, source = nil)
|
8
|
+
source = encode(source) if source
|
9
|
+
@nashorn_context = ::Nashorn::Context.new
|
10
|
+
@nashorn_context.eval(source) if source
|
11
|
+
rescue Exception => e
|
12
|
+
raise wrap_error(e)
|
13
|
+
end
|
14
|
+
|
15
|
+
def exec(source, options = nil) # options not used
|
16
|
+
source = encode(source)
|
17
|
+
eval "(function(){#{source}})()", options if /\S/ =~ source
|
18
|
+
end
|
19
|
+
|
20
|
+
def eval(source, options = nil) # options not used
|
21
|
+
source = encode(source)
|
22
|
+
unbox @nashorn_context.eval("(#{source})") if /\S/ =~ source
|
23
|
+
rescue Exception => e
|
24
|
+
raise wrap_error(e)
|
25
|
+
end
|
26
|
+
|
27
|
+
def call(prop, *args)
|
28
|
+
evaled = @nashorn_context.eval(prop)
|
29
|
+
unbox evaled.call(*args)
|
30
|
+
rescue Exception => e
|
31
|
+
raise wrap_error(e)
|
32
|
+
end
|
33
|
+
|
34
|
+
def unbox(value)
|
35
|
+
value = ::Nashorn::to_rb(value, false) # ExecJS likes its own way :
|
36
|
+
|
37
|
+
if value.is_a?(::Nashorn::JS::JSObject)
|
38
|
+
return nil if value.isFunction
|
39
|
+
return value.values.map { |v| unbox(v) } if value.isArray
|
40
|
+
hash = {}; value.each_raw do |key, val|
|
41
|
+
next if val.respond_to?(:isFunction) && val.isFunction
|
42
|
+
hash[key] = unbox(val)
|
43
|
+
end
|
44
|
+
return hash
|
45
|
+
end
|
46
|
+
value
|
47
|
+
end
|
48
|
+
|
49
|
+
def wrap_error(e)
|
50
|
+
return e unless e.is_a?(::Nashorn::JSError)
|
51
|
+
|
52
|
+
error_class = ::Nashorn::JSError.parse_error?(e.cause) ? RuntimeError : ProgramError
|
53
|
+
|
54
|
+
backtrace = e.backtrace
|
55
|
+
|
56
|
+
if js_stack = e.javascript_backtrace
|
57
|
+
backtrace = backtrace - js_stack
|
58
|
+
# ["<<eval>>.<anonymous>(<eval>:1)", "<<eval>>.<program>(<eval>:1)"]
|
59
|
+
js_stack = js_stack.map { |line| line.sub(/\<eval\>\:/, "(execjs):") }
|
60
|
+
backtrace = js_stack + backtrace
|
61
|
+
elsif backtrace
|
62
|
+
backtrace = backtrace.dup; backtrace.unshift('(execjs):1')
|
63
|
+
end
|
64
|
+
|
65
|
+
error = error_class.new e.value ? e.value.to_s : e.message
|
66
|
+
error.set_backtrace(backtrace)
|
67
|
+
error
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
def name
|
73
|
+
'dienashorner (Nashorn)'
|
74
|
+
end
|
75
|
+
|
76
|
+
def available?
|
77
|
+
return false unless defined? JRUBY_VERSION
|
78
|
+
require 'nashorn'
|
79
|
+
true
|
80
|
+
rescue LoadError
|
81
|
+
false
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
end
|
data/lib/nashorn/ext.rb
CHANGED
@@ -1,6 +1,11 @@
|
|
1
1
|
module Nashorn
|
2
2
|
module JS
|
3
3
|
|
4
|
+
AbstractJSObject.module_eval do
|
5
|
+
alias_method :raw_values, :values
|
6
|
+
alias_method :__call__, :call
|
7
|
+
end
|
8
|
+
|
4
9
|
JSObject.module_eval do
|
5
10
|
|
6
11
|
def [](key)
|
@@ -91,8 +96,7 @@ module Nashorn
|
|
91
96
|
else
|
92
97
|
if hasMember(name_str) && property = getMember(name_str)
|
93
98
|
if property.is_a?(JSObject) && property.isFunction
|
94
|
-
|
95
|
-
Nashorn.to_rb property.__call__(self, js_args)
|
99
|
+
Nashorn.to_rb property.__call__(self, *Nashorn.args_to_js(args))
|
96
100
|
else
|
97
101
|
if args.size > 0
|
98
102
|
raise ArgumentError, "can't call '#{name_str}' with args: #{args.inspect} as it's a property"
|
@@ -115,21 +119,7 @@ module Nashorn
|
|
115
119
|
# JavaScript's Function#call but rather as Ruby's Method#call !
|
116
120
|
# Use #apply or #bind before calling to achieve the same effect.
|
117
121
|
def call(*args)
|
118
|
-
this = nil
|
119
|
-
Nashorn.to_rb __call__ this, Nashorn.args_to_js(args)
|
120
|
-
rescue JS::NashornException => e
|
121
|
-
raise Nashorn::JSError.new(e)
|
122
|
-
end
|
123
|
-
|
124
|
-
# bind a JavaScript function into the given (this) context
|
125
|
-
#def bind(this, *args)
|
126
|
-
# args = Nashorn.args_to_js(args)
|
127
|
-
# Rhino::JS::BoundFunction.new(self, Nashorn.to_js(this), args)
|
128
|
-
#end
|
129
|
-
|
130
|
-
# use JavaScript functions constructors from Ruby as `fn.new`
|
131
|
-
def new(*args)
|
132
|
-
newObject Nashorn.args_to_js(args)
|
122
|
+
Nashorn.to_rb __call__ nil, *Nashorn.args_to_js(args) # this = nil
|
133
123
|
rescue JS::NashornException => e
|
134
124
|
raise Nashorn::JSError.new(e)
|
135
125
|
end
|
@@ -140,20 +130,28 @@ module Nashorn
|
|
140
130
|
# NOTE: That #call from Ruby does not have the same semantics as
|
141
131
|
# JavaScript's Function#call but rather as Ruby's Method#call !
|
142
132
|
def apply(this, *args)
|
143
|
-
__call__ Nashorn.to_js(this), Nashorn.args_to_js(args)
|
133
|
+
__call__ Nashorn.to_js(this), *Nashorn.args_to_js(args)
|
144
134
|
rescue JS::NashornException => e
|
145
135
|
raise Nashorn::JSError.new(e)
|
146
136
|
end
|
147
137
|
alias_method :methodcall, :apply # V8::Function compatibility
|
148
138
|
|
149
|
-
|
139
|
+
# bind a JavaScript function into the given (this) context
|
140
|
+
#def bind(this, *args)
|
141
|
+
# args = Nashorn.args_to_js(args)
|
142
|
+
# Rhino::JS::BoundFunction.new(self, Nashorn.to_js(this), args)
|
143
|
+
#end
|
144
|
+
|
145
|
+
# use JavaScript functions constructors from Ruby as `fn.new`
|
146
|
+
def new(*args)
|
147
|
+
newObject *Nashorn.args_to_js(args)
|
148
|
+
rescue JS::NashornException => e
|
149
|
+
raise Nashorn::JSError.new(e)
|
150
|
+
end
|
150
151
|
|
151
|
-
AbstractJSObject.module_eval do
|
152
|
-
alias_method :raw_values, :values
|
153
|
-
alias_method :__call__, :call
|
154
152
|
end
|
155
153
|
|
156
|
-
ScriptObjectMirror.
|
154
|
+
ScriptObjectMirror.class_eval do # implements java.util.Map
|
157
155
|
|
158
156
|
# @private NOTE: duplicated from JSObject
|
159
157
|
def [](key)
|
@@ -169,15 +167,32 @@ module Nashorn
|
|
169
167
|
|
170
168
|
# @private NOTE: duplicated from JSObject
|
171
169
|
def call(*args)
|
172
|
-
this = nil
|
173
|
-
|
170
|
+
# Nashorn.to_rb __call__ nil, *Nashorn.args_to_js(args) # this = nil
|
171
|
+
|
172
|
+
|
173
|
+
#if isFunction
|
174
|
+
# this = Nashorn.to_js args.shift
|
175
|
+
#
|
176
|
+
# puts "calling this = #{this.inspect} args = #{args.inspect}"
|
177
|
+
#
|
178
|
+
# result = __call__(this, Nashorn.args_to_js(args))
|
179
|
+
#else
|
180
|
+
|
181
|
+
#puts "calling args = #{args.inspect} Nashorn.args_to_js(args) #{Nashorn.args_to_js(args).inspect}"
|
182
|
+
|
183
|
+
result = __call__ nil, *Nashorn.args_to_js(args)
|
184
|
+
|
185
|
+
#puts "called result = #{result.inspect} #{result.class}"
|
186
|
+
|
187
|
+
Nashorn.to_rb result
|
188
|
+
#end
|
174
189
|
rescue JS::NashornException => e
|
175
190
|
raise Nashorn::JSError.new(e)
|
176
191
|
end
|
177
192
|
|
178
193
|
# def callMember(this, *args)
|
179
194
|
# this = nil
|
180
|
-
# Nashorn.to_rb __call__ this, Nashorn.args_to_js(args)
|
195
|
+
# Nashorn.to_rb __call__ this, *Nashorn.args_to_js(args)
|
181
196
|
# rescue JS::NashornException => e
|
182
197
|
# raise Nashorn::JSError.new(e)
|
183
198
|
# end
|
data/lib/nashorn/ruby.rb
CHANGED
@@ -269,8 +269,7 @@ module Nashorn
|
|
269
269
|
# Nashorn.to_js(result) # TODO do not convert if java_args ?
|
270
270
|
end
|
271
271
|
|
272
|
-
# make sure redefined :call is aliased not the one "inherited"
|
273
|
-
# JS::BaseFunction#call when invoking __call__ (@see ext.rb)
|
272
|
+
# make sure redefined :call is aliased not the one "inherited" (@see ext.rb)
|
274
273
|
alias_method :__call__, :call
|
275
274
|
|
276
275
|
end
|
@@ -331,22 +330,21 @@ module Nashorn
|
|
331
330
|
# @private
|
332
331
|
class Exception < JS::NashornException
|
333
332
|
|
334
|
-
|
335
|
-
super wrap_value(value)
|
336
|
-
end
|
337
|
-
|
338
|
-
private
|
333
|
+
attr_reader :thrown
|
339
334
|
|
340
|
-
def
|
341
|
-
|
335
|
+
def initialize(error)
|
336
|
+
super error.message, error.is_a?(Java::JavaLang::Throwable) ? error : nil
|
337
|
+
@thrown = error
|
342
338
|
end
|
343
339
|
|
340
|
+
def getThrown; @thrown end
|
341
|
+
|
344
342
|
end
|
345
343
|
|
346
344
|
def self.wrap_error(e, backtrace = nil)
|
347
|
-
|
348
|
-
|
349
|
-
|
345
|
+
js_error = Exception.new(e)
|
346
|
+
js_error.set_backtrace(backtrace) if backtrace
|
347
|
+
js_error
|
350
348
|
end
|
351
349
|
|
352
350
|
end
|
data/lib/nashorn/version.rb
CHANGED
data/spec/nashorn/access_spec.rb
CHANGED
@@ -32,7 +32,7 @@ describe Nashorn::Ruby::AttributeAccess do
|
|
32
32
|
it "gets methods and instance variables" do
|
33
33
|
rb_object = Nashorn::Ruby::Object.wrap Meh.new
|
34
34
|
|
35
|
-
rb_object.get('anAttr0', nil).should
|
35
|
+
rb_object.get('anAttr0', nil).should be nil
|
36
36
|
rb_object.get('the_attr_1', nil).should == 'attr_1'
|
37
37
|
|
38
38
|
# rb_object.get('an_attr_2', nil).should be(Rhino::JS::Scriptable::NOT_FOUND) # no reader
|
@@ -49,23 +49,21 @@ describe Nashorn::Ruby::AttributeAccess do
|
|
49
49
|
it "has methods and instance variables" do
|
50
50
|
rb_object = Nashorn::Ruby::Object.wrap Meh.new
|
51
51
|
|
52
|
-
rb_object.has('anAttr0', nil).should
|
53
|
-
rb_object.has('the_attr_1', nil).should
|
54
|
-
rb_object.has('an_attr_2', nil).should
|
52
|
+
rb_object.has('anAttr0', nil).should be true
|
53
|
+
rb_object.has('the_attr_1', nil).should be true
|
54
|
+
rb_object.has('an_attr_2', nil).should be false # no reader nor writer
|
55
55
|
|
56
56
|
[ 'theMethod0', 'a_method1', 'the_method_2' ].each do |name|
|
57
|
-
rb_object.has(name, nil).should
|
57
|
+
rb_object.has(name, nil).should be true
|
58
58
|
end
|
59
59
|
|
60
|
-
rb_object.has('non-existent-method', nil).should
|
60
|
+
rb_object.has('non-existent-method', nil).should be false
|
61
61
|
end
|
62
62
|
|
63
63
|
it "puts using attr writer" do
|
64
|
-
start = mock('start')
|
65
|
-
start.expects(:put).never
|
66
64
|
rb_object = Nashorn::Ruby::Object.wrap Meh.new
|
67
65
|
|
68
|
-
rb_object.put('the_attr_1',
|
66
|
+
rb_object.put('the_attr_1', 42)
|
69
67
|
rb_object.the_attr_1.should == 42
|
70
68
|
end
|
71
69
|
|
data/spec/nashorn/error_spec.rb
CHANGED
@@ -3,6 +3,8 @@ require File.expand_path('../spec_helper', File.dirname(__FILE__))
|
|
3
3
|
describe Nashorn::JSError do
|
4
4
|
|
5
5
|
it "works as a StandardError with a message being passed" do
|
6
|
+
pending 'currently JSError.new always gets a (nashorn) exception'
|
7
|
+
|
6
8
|
js_error = Nashorn::JSError.new 'an error message'
|
7
9
|
lambda { js_error.to_s && js_error.inspect }.should_not raise_error
|
8
10
|
|
@@ -11,38 +13,40 @@ describe Nashorn::JSError do
|
|
11
13
|
js_error.javascript_backtrace.should be nil
|
12
14
|
end
|
13
15
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
#
|
18
|
-
#
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
16
|
+
it "might wrap a NashornException wrapped in a NativeException like error" do
|
17
|
+
pending 'probably not relevant'
|
18
|
+
|
19
|
+
# JRuby's NativeException.new(Nashorn_e) does not work as it is
|
20
|
+
# intended to handle Java exceptions ... no new on the Ruby side
|
21
|
+
native_error_class = Class.new(RuntimeError) do
|
22
|
+
def initialize(cause); @cause = cause end
|
23
|
+
def cause; @cause end
|
24
|
+
end
|
25
|
+
|
26
|
+
nashorn_e = javax.script.ScriptException.new("42".to_java)
|
27
|
+
js_error = Nashorn::JSError.new native_error_class.new(nashorn_e)
|
28
|
+
lambda { js_error.to_s && js_error.inspect }.should_not raise_error
|
29
|
+
|
30
|
+
js_error.cause.should be nashorn_e
|
31
|
+
js_error.message.should == '42'
|
32
|
+
js_error.javascript_backtrace.should be nil
|
33
|
+
end
|
30
34
|
|
31
35
|
it "keeps the thrown javascript object value" do
|
32
36
|
begin
|
33
37
|
Nashorn::Context.eval "throw { foo: 'bar' }"
|
34
|
-
rescue => e
|
35
|
-
e.should be_a(Nashorn::JSError)
|
36
|
-
e.message.should == e.value.to_s
|
38
|
+
rescue Nashorn::JSError => e
|
37
39
|
|
38
|
-
pending
|
40
|
+
pending 'CAN NOT WORK-AROUND DUE A NASHORN BUG!'
|
39
41
|
|
40
|
-
|
41
|
-
puts e.value.class
|
42
|
-
puts e.value.class.included_modules.inspect
|
43
|
-
puts e.value.class.superclass
|
44
|
-
puts e.value.class.superclass.included_modules.inspect
|
42
|
+
e.message.should == e.value.to_s
|
45
43
|
|
44
|
+
# Java::JdkNashornInternalRuntime::ScriptObject leaks out?!
|
45
|
+
#if Nashorn::JS::ScriptObject
|
46
|
+
# e.value.should be_a(Nashorn::JS::ScriptObject)
|
47
|
+
#else
|
48
|
+
# e.value.should be_a(Nashorn::JS::JSObject)
|
49
|
+
#end
|
46
50
|
e.value.should be_a(Nashorn::JS::JSObject)
|
47
51
|
e.value['foo'].should == 'bar'
|
48
52
|
else
|
@@ -158,8 +162,7 @@ describe Nashorn::JSError do
|
|
158
162
|
context = Nashorn::Context.new
|
159
163
|
context.eval "function foo() { throw 'bar' }"
|
160
164
|
context['foo'].apply(nil)
|
161
|
-
rescue => e
|
162
|
-
e.should be_a Nashorn::JSError
|
165
|
+
rescue Nashorn::JSError => e
|
163
166
|
e.value.should == 'bar'
|
164
167
|
else
|
165
168
|
fail "expected to rescue"
|
@@ -177,14 +180,13 @@ describe Nashorn::JSError do
|
|
177
180
|
hi = context.eval "( function hi(arg) { Hello.hello(arg); } )"
|
178
181
|
begin
|
179
182
|
hi.call(24)
|
180
|
-
rescue => e
|
181
|
-
e.
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
# e.value(true).should be_a RuntimeError # unwraps ruby object
|
183
|
+
rescue Nashorn::JSError => e
|
184
|
+
e.thrown.should_not be nil
|
185
|
+
# NOTE: ... or should it be wrapped?
|
186
|
+
e.value.should be_a Nashorn::Ruby::Object if false
|
187
|
+
e.value(true).should be_a RuntimeError # unwraps ruby object
|
186
188
|
# prints the original message (beyond [ruby RuntimeError]) :
|
187
|
-
e.message.should =~ /
|
189
|
+
e.message.should =~ /hello/
|
188
190
|
else
|
189
191
|
fail "expected to rescue"
|
190
192
|
end
|
@@ -0,0 +1,374 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'minitest/autorun'
|
3
|
+
|
4
|
+
require 'json'
|
5
|
+
|
6
|
+
require 'nashorn/execjs/load'
|
7
|
+
require 'execjs'
|
8
|
+
|
9
|
+
if defined? Minitest::Test
|
10
|
+
Test = Minitest::Test
|
11
|
+
elsif defined? MiniTest::Unit::TestCase
|
12
|
+
Test = MiniTest::Unit::TestCase
|
13
|
+
end
|
14
|
+
|
15
|
+
class TestExecJS < Test
|
16
|
+
# def test_runtime_available
|
17
|
+
# runtime = ExecJS::ExternalRuntime.new(command: "nonexistent")
|
18
|
+
# assert !runtime.available?
|
19
|
+
#
|
20
|
+
# runtime = ExecJS::ExternalRuntime.new(command: "ruby")
|
21
|
+
# assert runtime.available?
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# def test_runtime_assignment
|
25
|
+
# original_runtime = ExecJS.runtime
|
26
|
+
# runtime = ExecJS::ExternalRuntime.new(command: "nonexistent")
|
27
|
+
# assert_raises(ExecJS::RuntimeUnavailable) { ExecJS.runtime = runtime }
|
28
|
+
# assert_equal original_runtime, ExecJS.runtime
|
29
|
+
#
|
30
|
+
# runtime = ExecJS::ExternalRuntime.new(command: "ruby")
|
31
|
+
# ExecJS.runtime = runtime
|
32
|
+
# assert_equal runtime, ExecJS.runtime
|
33
|
+
# ensure
|
34
|
+
# ExecJS.runtime = original_runtime
|
35
|
+
# end
|
36
|
+
|
37
|
+
def test_context_call
|
38
|
+
context = ExecJS.compile("id = function(v) { return v; }")
|
39
|
+
assert_equal "bar", context.call("id", "bar")
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_nested_context_call
|
43
|
+
context = ExecJS.compile("a = {}; a.b = {}; a.b.id = function(v) { return v; }")
|
44
|
+
assert_equal "bar", context.call("a.b.id", "bar")
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_context_call_missing_function
|
48
|
+
context = ExecJS.compile("")
|
49
|
+
assert_raises ExecJS::ProgramError do
|
50
|
+
context.call("missing")
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
{
|
55
|
+
"function() {}" => nil,
|
56
|
+
"0" => 0,
|
57
|
+
"null" => nil,
|
58
|
+
"undefined" => nil,
|
59
|
+
"true" => true,
|
60
|
+
"false" => false,
|
61
|
+
"[1, 2]" => [1, 2],
|
62
|
+
"[1, function() {}]" => [1, nil],
|
63
|
+
"'hello'" => "hello",
|
64
|
+
"'red yellow blue'.split(' ')" => ["red", "yellow", "blue"],
|
65
|
+
"{a:1,b:2}" => {"a"=>1,"b"=>2},
|
66
|
+
"{a:true,b:function (){}}" => {"a"=>true},
|
67
|
+
"'café'" => "café",
|
68
|
+
'"☃"' => "☃",
|
69
|
+
'"\u2603"' => "☃",
|
70
|
+
"'\u{1f604}'".encode("UTF-8") => "\u{1f604}".encode("UTF-8"), # Smiling emoji
|
71
|
+
"'\u{1f1fa}\u{1f1f8}'".encode("UTF-8") => "\u{1f1fa}\u{1f1f8}".encode("UTF-8"), # US flag
|
72
|
+
'"\\\\"' => "\\"
|
73
|
+
}.each_with_index do |(input, output), index|
|
74
|
+
define_method("test_exec_string_#{index}") do
|
75
|
+
assert_equal output, ExecJS.exec("return #{input}")
|
76
|
+
end
|
77
|
+
|
78
|
+
define_method("test_eval_string_#{index}") do
|
79
|
+
assert_equal output, ExecJS.eval(input)
|
80
|
+
end
|
81
|
+
|
82
|
+
define_method("test_compile_return_string_#{index}") do
|
83
|
+
context = ExecJS.compile("var a = #{input};")
|
84
|
+
assert_equal output, context.eval("a")
|
85
|
+
end
|
86
|
+
|
87
|
+
define_method("test_compile_call_string_#{index}") do
|
88
|
+
context = ExecJS.compile("function a() { return #{input}; }")
|
89
|
+
assert_equal output, context.call("a")
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
[
|
94
|
+
nil,
|
95
|
+
true,
|
96
|
+
false,
|
97
|
+
1,
|
98
|
+
3.14,
|
99
|
+
"hello",
|
100
|
+
"\\",
|
101
|
+
"café",
|
102
|
+
"☃",
|
103
|
+
"\u{1f604}".encode("UTF-8"), # Smiling emoji
|
104
|
+
"\u{1f1fa}\u{1f1f8}".encode("UTF-8"), # US flag
|
105
|
+
[1, 2, 3],
|
106
|
+
[1, [2, 3]],
|
107
|
+
[1, [2, [3]]],
|
108
|
+
["red", "yellow", "blue"],
|
109
|
+
{ "a" => 1, "b" => 2},
|
110
|
+
{ "a" => 1, "b" => [2, 3]},
|
111
|
+
{ "a" => true }
|
112
|
+
].each_with_index do |value, index|
|
113
|
+
json_value = JSON.generate(value, quirks_mode: true)
|
114
|
+
|
115
|
+
define_method("test_json_value_#{index}") do
|
116
|
+
assert_equal value, JSON.parse(json_value, quirks_mode: true)
|
117
|
+
end
|
118
|
+
|
119
|
+
define_method("test_exec_value_#{index}") do
|
120
|
+
assert_equal value, ExecJS.exec("return #{json_value}")
|
121
|
+
end
|
122
|
+
|
123
|
+
define_method("test_eval_value_#{index}") do
|
124
|
+
assert_equal value, ExecJS.eval("#{json_value}")
|
125
|
+
end
|
126
|
+
|
127
|
+
define_method("test_strinigfy_value_#{index}") do
|
128
|
+
# context = ExecJS.compile("function json(obj) { return obj || JSON.stringify(obj); }")
|
129
|
+
context = ExecJS.compile("function json(obj) { return JSON.stringify(obj); }")
|
130
|
+
|
131
|
+
puts context.inspect; puts "value = #{value.inspect}"
|
132
|
+
|
133
|
+
assert_equal json_value, context.call("json", value)
|
134
|
+
end
|
135
|
+
|
136
|
+
define_method("test_call_value_#{index}") do
|
137
|
+
context = ExecJS.compile("function id(obj) { return obj; }")
|
138
|
+
assert_equal value, context.call("id", value)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def test_eval_blank
|
143
|
+
assert_nil ExecJS.eval("")
|
144
|
+
assert_nil ExecJS.eval(" ")
|
145
|
+
assert_nil ExecJS.eval(" ")
|
146
|
+
end
|
147
|
+
|
148
|
+
def test_exec_return
|
149
|
+
assert_nil ExecJS.exec("return")
|
150
|
+
end
|
151
|
+
|
152
|
+
def test_exec_no_return
|
153
|
+
assert_nil ExecJS.exec("1")
|
154
|
+
end
|
155
|
+
|
156
|
+
def test_encoding
|
157
|
+
utf8 = Encoding.find('UTF-8')
|
158
|
+
|
159
|
+
assert_equal utf8, ExecJS.exec("return 'hello'").encoding
|
160
|
+
assert_equal utf8, ExecJS.eval("'☃'").encoding
|
161
|
+
|
162
|
+
ascii = "'hello'".encode('US-ASCII')
|
163
|
+
result = ExecJS.eval(ascii)
|
164
|
+
assert_equal "hello", result
|
165
|
+
assert_equal utf8, result.encoding
|
166
|
+
|
167
|
+
assert_raises Encoding::UndefinedConversionError do
|
168
|
+
binary = "\xde\xad\xbe\xef".force_encoding("BINARY")
|
169
|
+
ExecJS.eval(binary)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
def test_encoding_compile
|
174
|
+
utf8 = Encoding.find('UTF-8')
|
175
|
+
|
176
|
+
context = ExecJS.compile("foo = function(v) { return '¶' + v; }".encode("ISO8859-15"))
|
177
|
+
|
178
|
+
assert_equal utf8, context.exec("return foo('hello')").encoding
|
179
|
+
assert_equal utf8, context.eval("foo('☃')").encoding
|
180
|
+
|
181
|
+
ascii = "foo('hello')".encode('US-ASCII')
|
182
|
+
result = context.eval(ascii)
|
183
|
+
assert_equal "¶hello", result
|
184
|
+
assert_equal utf8, result.encoding
|
185
|
+
|
186
|
+
assert_raises Encoding::UndefinedConversionError do
|
187
|
+
binary = "\xde\xad\xbe\xef".force_encoding("BINARY")
|
188
|
+
context.eval(binary)
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
def test_surrogate_pairs
|
193
|
+
# Smiling emoji
|
194
|
+
str = "\u{1f604}".encode("UTF-8")
|
195
|
+
assert_equal 2, ExecJS.eval("'#{str}'.length")
|
196
|
+
assert_equal str, ExecJS.eval("'#{str}'")
|
197
|
+
|
198
|
+
# US flag emoji
|
199
|
+
str = "\u{1f1fa}\u{1f1f8}".encode("UTF-8")
|
200
|
+
assert_equal 4, ExecJS.eval("'#{str}'.length")
|
201
|
+
assert_equal str, ExecJS.eval("'#{str}'")
|
202
|
+
end
|
203
|
+
|
204
|
+
def test_compile_anonymous_function
|
205
|
+
context = ExecJS.compile("foo = function() { return \"bar\"; }")
|
206
|
+
assert_equal "bar", context.exec("return foo()")
|
207
|
+
assert_equal "bar", context.eval("foo()")
|
208
|
+
assert_equal "bar", context.call("foo")
|
209
|
+
end
|
210
|
+
|
211
|
+
def test_compile_named_function
|
212
|
+
context = ExecJS.compile("function foo() { return \"bar\"; }")
|
213
|
+
assert_equal "bar", context.exec("return foo()")
|
214
|
+
assert_equal "bar", context.eval("foo()")
|
215
|
+
assert_equal "bar", context.call("foo")
|
216
|
+
end
|
217
|
+
|
218
|
+
def test_this_is_global_scope
|
219
|
+
assert_equal true, ExecJS.eval("this === (function() {return this})()")
|
220
|
+
assert_equal true, ExecJS.exec("return this === (function() {return this})()")
|
221
|
+
end
|
222
|
+
|
223
|
+
def test_browser_self_is_undefined
|
224
|
+
assert ExecJS.eval("typeof self == 'undefined'")
|
225
|
+
end
|
226
|
+
|
227
|
+
def test_node_global_is_undefined
|
228
|
+
assert ExecJS.eval("typeof global == 'undefined'")
|
229
|
+
end
|
230
|
+
|
231
|
+
def test_commonjs_vars_are_undefined
|
232
|
+
assert ExecJS.eval("typeof module == 'undefined'")
|
233
|
+
assert ExecJS.eval("typeof exports == 'undefined'")
|
234
|
+
assert ExecJS.eval("typeof require == 'undefined'")
|
235
|
+
end
|
236
|
+
|
237
|
+
def test_console_is_undefined
|
238
|
+
assert ExecJS.eval("typeof console == 'undefined'")
|
239
|
+
end
|
240
|
+
|
241
|
+
def test_timers_are_undefined
|
242
|
+
assert ExecJS.eval("typeof setTimeout == 'undefined'")
|
243
|
+
assert ExecJS.eval("typeof setInterval == 'undefined'")
|
244
|
+
assert ExecJS.eval("typeof clearTimeout == 'undefined'")
|
245
|
+
assert ExecJS.eval("typeof clearInterval == 'undefined'")
|
246
|
+
assert ExecJS.eval("typeof setImmediate == 'undefined'")
|
247
|
+
assert ExecJS.eval("typeof clearImmediate == 'undefined'")
|
248
|
+
end
|
249
|
+
|
250
|
+
def test_compile_large_scripts
|
251
|
+
body = "var foo = 'bar';\n" * 100_000
|
252
|
+
assert ExecJS.exec("function foo() {\n#{body}\n};\nreturn true")
|
253
|
+
end
|
254
|
+
|
255
|
+
def test_exec_syntax_error
|
256
|
+
begin
|
257
|
+
ExecJS.exec(")")
|
258
|
+
flunk
|
259
|
+
rescue ExecJS::RuntimeError => e
|
260
|
+
|
261
|
+
#puts "\n\nEXEC: " + e.inspect + "\n #{e.backtrace.join("\n ")}\n"
|
262
|
+
|
263
|
+
assert e
|
264
|
+
assert e.backtrace[0].include?("(execjs):1"), e.backtrace.join("\n")
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
def test_eval_syntax_error
|
269
|
+
begin
|
270
|
+
ExecJS.eval(")")
|
271
|
+
flunk
|
272
|
+
rescue ExecJS::RuntimeError => e
|
273
|
+
assert e
|
274
|
+
assert e.backtrace[0].include?("(execjs):1"), e.backtrace.join("\n")
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
def test_compile_syntax_error
|
279
|
+
begin
|
280
|
+
ExecJS.compile(")")
|
281
|
+
flunk
|
282
|
+
rescue ExecJS::RuntimeError => e
|
283
|
+
assert e
|
284
|
+
assert e.backtrace[0].include?("(execjs):1"), e.backtrace.join("\n")
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
288
|
+
def test_exec_thrown_error
|
289
|
+
begin
|
290
|
+
ExecJS.exec("throw new Error('hello')")
|
291
|
+
flunk
|
292
|
+
rescue ExecJS::ProgramError => e
|
293
|
+
assert e
|
294
|
+
assert e.backtrace[0].include?("(execjs):1"), e.backtrace.join("\n")
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
298
|
+
def test_eval_thrown_error
|
299
|
+
begin
|
300
|
+
ExecJS.eval("(function(){ throw new Error('hello') })()")
|
301
|
+
flunk
|
302
|
+
rescue ExecJS::ProgramError => e
|
303
|
+
assert e
|
304
|
+
assert e.backtrace[0].include?("(execjs):1"), e.backtrace.join("\n")
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
308
|
+
def test_compile_thrown_error
|
309
|
+
begin
|
310
|
+
ExecJS.compile("throw new Error('hello')")
|
311
|
+
flunk
|
312
|
+
rescue ExecJS::ProgramError => e
|
313
|
+
assert e
|
314
|
+
assert e.backtrace[0].include?("(execjs):1"), e.backtrace.join("\n")
|
315
|
+
end
|
316
|
+
end
|
317
|
+
|
318
|
+
def test_exec_thrown_string
|
319
|
+
assert_raises ExecJS::ProgramError do
|
320
|
+
ExecJS.exec("throw 'hello'")
|
321
|
+
end
|
322
|
+
end
|
323
|
+
|
324
|
+
def test_eval_thrown_string
|
325
|
+
assert_raises ExecJS::ProgramError do
|
326
|
+
ExecJS.eval("(function(){ throw 'hello' })()")
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
330
|
+
def test_compile_thrown_string
|
331
|
+
assert_raises ExecJS::ProgramError do
|
332
|
+
ExecJS.compile("throw 'hello'")
|
333
|
+
end
|
334
|
+
end
|
335
|
+
=begin
|
336
|
+
def test_babel
|
337
|
+
skip if ExecJS.runtime.is_a?(ExecJS::RubyRhinoRuntime)
|
338
|
+
|
339
|
+
assert source = File.read(File.expand_path("../fixtures/babel.js", __FILE__))
|
340
|
+
source = <<-JS
|
341
|
+
var self = this;
|
342
|
+
#{source}
|
343
|
+
babel.eval = function(code) {
|
344
|
+
return eval(babel.transform(code)["code"]);
|
345
|
+
}
|
346
|
+
JS
|
347
|
+
context = ExecJS.compile(source)
|
348
|
+
assert_equal 64, context.call("babel.eval", "((x) => x * x)(8)")
|
349
|
+
end
|
350
|
+
|
351
|
+
def test_coffeescript
|
352
|
+
assert source = File.read(File.expand_path("../fixtures/coffee-script.js", __FILE__))
|
353
|
+
context = ExecJS.compile(source)
|
354
|
+
assert_equal 64, context.call("CoffeeScript.eval", "((x) -> x * x)(8)")
|
355
|
+
end
|
356
|
+
|
357
|
+
def test_uglify
|
358
|
+
assert source = File.read(File.expand_path("../fixtures/uglify.js", __FILE__))
|
359
|
+
source = <<-JS
|
360
|
+
#{source}
|
361
|
+
|
362
|
+
function uglify(source) {
|
363
|
+
var ast = UglifyJS.parse(source);
|
364
|
+
var stream = UglifyJS.OutputStream();
|
365
|
+
ast.print(stream);
|
366
|
+
return stream.toString();
|
367
|
+
}
|
368
|
+
JS
|
369
|
+
context = ExecJS.compile(source)
|
370
|
+
assert_equal "function foo(bar){return bar}",
|
371
|
+
context.call("uglify", "function foo(bar) {\n return bar;\n}")
|
372
|
+
end
|
373
|
+
=end
|
374
|
+
end
|
data/spec/nashorn_spec.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dienashorner
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Karol Bucek
|
@@ -58,6 +58,8 @@ files:
|
|
58
58
|
- lib/nashorn/context.rb
|
59
59
|
- lib/nashorn/convert.rb
|
60
60
|
- lib/nashorn/error.rb
|
61
|
+
- lib/nashorn/execjs/load.rb
|
62
|
+
- lib/nashorn/execjs/runtime.rb
|
61
63
|
- lib/nashorn/ext.rb
|
62
64
|
- lib/nashorn/rhino.rb
|
63
65
|
- lib/nashorn/rhino/less.rb
|
@@ -76,6 +78,7 @@ files:
|
|
76
78
|
- spec/nashorn/integration/loop/element2.js
|
77
79
|
- spec/nashorn/integration_spec.rb
|
78
80
|
- spec/nashorn/ruby_spec.rb
|
81
|
+
- spec/nashorn/test_execjs.rb
|
79
82
|
- spec/nashorn_spec.rb
|
80
83
|
- spec/spec_helper.rb
|
81
84
|
homepage: https://github.com/kares/dienashorner
|