dienashorner 0.1.1 → 0.2.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.
- 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
|