dienashorner 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,199 @@
1
+ require File.expand_path('../spec_helper', File.dirname(__FILE__))
2
+
3
+ describe Nashorn::JSError do
4
+
5
+ it "works as a StandardError with a message being passed" do
6
+ js_error = Nashorn::JSError.new 'an error message'
7
+ lambda { js_error.to_s && js_error.inspect }.should_not raise_error
8
+
9
+ js_error.cause.should be nil
10
+ js_error.message.should == 'an error message'
11
+ js_error.javascript_backtrace.should be nil
12
+ end
13
+
14
+ # it "might wrap a NashornException wrapped in a NativeException like error" do
15
+ # # JRuby's NativeException.new(Nashorn_e) does not work as it is
16
+ # # intended to handle Java exceptions ... no new on the Ruby side
17
+ # native_error_class = Class.new(RuntimeError) do
18
+ # def initialize(cause); @cause = cause end
19
+ # def cause; @cause end
20
+ # end
21
+ #
22
+ # nashorn_e = javax.script.ScriptException.new("42".to_java)
23
+ # js_error = Nashorn::JSError.new native_error_class.new(nashorn_e)
24
+ # lambda { js_error.to_s && js_error.inspect }.should_not raise_error
25
+ #
26
+ # js_error.cause.should be nashorn_e
27
+ # js_error.message.should == '42'
28
+ # js_error.javascript_backtrace.should be nil
29
+ # end
30
+
31
+ it "keeps the thrown javascript object value" do
32
+ begin
33
+ Nashorn::Context.eval "throw { foo: 'bar' }"
34
+ rescue => e
35
+ e.should be_a(Nashorn::JSError)
36
+ e.message.should == e.value.to_s
37
+
38
+ pending
39
+
40
+ puts e.value.inspect
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
45
+
46
+ e.value.should be_a(Nashorn::JS::JSObject)
47
+ e.value['foo'].should == 'bar'
48
+ else
49
+ fail "expected to rescue"
50
+ end
51
+ end
52
+
53
+ it "keeps the thrown javascript string value" do
54
+ begin
55
+ Nashorn::Context.eval "throw 'mehehehe'"
56
+ rescue => e
57
+ e.should be_a(Nashorn::JSError)
58
+ e.value.should == 'mehehehe'
59
+ e.message.should == e.value.to_s
60
+ else
61
+ fail "expected to rescue"
62
+ end
63
+ end
64
+
65
+ it "contains the native error as the cause 42" do
66
+ begin
67
+ Nashorn::Context.eval "throw 42"
68
+ rescue => e # javax.script.ScriptException
69
+ e.cause.should_not be nil
70
+ e.cause.should be_a Java::JdkNashornInternalRuntime::ECMAException
71
+ e.cause.value.should == 42
72
+ e.cause.lineNumber.should == 1
73
+ e.cause.fileName.should == '<eval>'
74
+ else
75
+ fail "expected to rescue"
76
+ end
77
+ end
78
+
79
+ it "has a correct javascript backtrace" do
80
+ begin
81
+ Nashorn::Context.eval "throw 42"
82
+ rescue => e
83
+ #
84
+ e.javascript_backtrace.should be_a Enumerable
85
+ e.javascript_backtrace.size.should >= 1
86
+ e.javascript_backtrace[0].should =~ /.*?<eval>:1/
87
+ e.javascript_backtrace(true).should be_a Enumerable
88
+ e.javascript_backtrace(true).size.should >= 1
89
+ element = e.javascript_backtrace(true)[0]
90
+ element.file_name.should == '<eval>'
91
+ # element.function_name.should be nil
92
+ element.line_number.should == 1
93
+ else
94
+ fail "expected to rescue"
95
+ end
96
+ end
97
+
98
+ it "contains function name in javascript backtrace" do
99
+ begin
100
+ Nashorn::Context.eval "function fortyTwo() { throw 42 }\n fortyTwo()"
101
+ rescue => e
102
+ # ["<<eval>>.fortyTwo(<eval>:1)", "<<eval>>.<program>(<eval>:2)"]
103
+ e.javascript_backtrace.size.should >= 2
104
+ e.javascript_backtrace[0].should =~ /fortyTwo\(<eval>:1\)/
105
+ expect( e.javascript_backtrace.find { |trace| trace.index("<eval>:2") } ).to_not be nil
106
+ else
107
+ fail "expected to rescue"
108
+ end
109
+ end
110
+
111
+ it "backtrace starts with the javascript part" do
112
+ begin
113
+ Nashorn::Context.eval "throw 42"
114
+ rescue => e
115
+ e.backtrace.should be_a Array
116
+ e.backtrace[0].should =~ /.*?<eval>:1/
117
+ e.backtrace[1].should_not be nil
118
+ else
119
+ fail "expected to rescue"
120
+ end
121
+ end
122
+
123
+ it "inspect shows the javascript value" do
124
+ begin
125
+ Nashorn::Context.eval "throw '42'"
126
+ rescue => e
127
+ e.inspect.should == '#<Nashorn::JSError: 42>'
128
+ e.to_s.should == '42'
129
+ else
130
+ fail "expected to rescue"
131
+ end
132
+ end
133
+
134
+ it "wrapps false value correctly" do
135
+ begin
136
+ Nashorn::Context.eval "throw false"
137
+ rescue => e
138
+ e.inspect.should == '#<Nashorn::JSError: false>'
139
+ e.value.should be false
140
+ else
141
+ fail "expected to rescue"
142
+ end
143
+ end
144
+
145
+ it "wrapps null value correctly" do
146
+ begin
147
+ Nashorn::Context.eval "throw null"
148
+ rescue => e
149
+ e.inspect.should == '#<Nashorn::JSError: null>'
150
+ e.value.should be nil
151
+ else
152
+ fail "expected to rescue"
153
+ end
154
+ end
155
+
156
+ it "raises correct error from function#apply" do
157
+ begin
158
+ context = Nashorn::Context.new
159
+ context.eval "function foo() { throw 'bar' }"
160
+ context['foo'].apply(nil)
161
+ rescue => e
162
+ e.should be_a Nashorn::JSError
163
+ e.value.should == 'bar'
164
+ else
165
+ fail "expected to rescue"
166
+ end
167
+ end
168
+
169
+ it "prints info about nested (ruby) error" do
170
+ context = Nashorn::Context.new
171
+ klass = Class.new do
172
+ def hello(arg = 42)
173
+ raise RuntimeError, 'hello' if arg != 42
174
+ end
175
+ end
176
+ context[:Hello] = klass.new
177
+ hi = context.eval "( function hi(arg) { Hello.hello(arg); } )"
178
+ begin
179
+ hi.call(24)
180
+ rescue => e
181
+ e.should be_a Nashorn::JSError
182
+ e.value.should_not be nil
183
+ # Java::JdkNashornInternalObjects::NativeTypeError
184
+ # e.value.should be_a Nashorn::Ruby::Object
185
+ # e.value(true).should be_a RuntimeError # unwraps ruby object
186
+ # prints the original message (beyond [ruby RuntimeError]) :
187
+ e.message.should =~ /TypeError: .* has no such function \"hello\"/
188
+ else
189
+ fail "expected to rescue"
190
+ end
191
+ # Nashorn::JSError:
192
+ # jdk.nashorn.internal.objects.NativeTypeError@52719fb6
193
+ # # <<eval>>.hi(<eval>:1)
194
+ # # <jdk/nashorn/internal/scripts/<eval>>.hi(jdk/nashorn/internal/scripts/<eval>:1)
195
+ # # ./lib/nashorn/ext.rb:157:in `call'
196
+ # # ./spec/nashorn/error_spec.rb:179:in `(root)'
197
+ end
198
+
199
+ end
@@ -0,0 +1,11 @@
1
+ //console.log('bar.js 1');
2
+ var util = require('util');
3
+ //console.log('bar.js 2');
4
+ var Bar = {};
5
+ Bar.puts = function (message) {
6
+ util.puts(message);
7
+ return message;
8
+ };
9
+ //console.log('bar.js 3');
10
+ exports.Bar = Bar;
11
+ //console.log('bar.js 4');
@@ -0,0 +1,7 @@
1
+ //console.log('foo.js 1');
2
+ var Bar = require('./bar').Bar;
3
+ //console.log('foo.js 2 ' + Bar + " : " + Bar.puts);
4
+ Bar.puts('Hello Bar!');
5
+ //console.log('foo.js 3');
6
+ exports.foo = { 'Bar': Bar };
7
+ //console.log('foo.js 4');
@@ -0,0 +1,7 @@
1
+ console.log('./loop');
2
+ require('./loop');
3
+
4
+ ['element1', 'element2'].forEach(function (n) {
5
+ console.log('require(./loop/' + n + ')');
6
+ require('./loop/' + n);
7
+ });
@@ -0,0 +1,3 @@
1
+ console.log('loop/element1 1');
2
+ require('../index');
3
+ console.log('loop/element1 2');
@@ -0,0 +1,8 @@
1
+ console.log('loop/element2 1');
2
+ (function (loop) {
3
+ console.log('loop/element2 2');
4
+ loop.fn2 = function (arg1, arg2) {
5
+ return arg1 + arg2;
6
+ };
7
+ })(require('../loop'));
8
+ console.log('loop/element2 3');
@@ -0,0 +1,3 @@
1
+ Loop = {};
2
+ Loop.toString = function() { return 'Loop'; };
3
+ exports.Loop = Loop;
@@ -0,0 +1,149 @@
1
+ require 'nashorn'
2
+ require 'nashorn/context'
3
+ require 'pathname'
4
+ require 'stringio'
5
+
6
+ puts "Nashorn #{Nashorn::VERSION}"
7
+
8
+ describe 'integration' do
9
+
10
+ it "Less.js: loads (less.rb)" do
11
+ require 'nashorn/rhino/less'
12
+ require 'less'
13
+
14
+ expect( Less.Parser ).to be_a(Nashorn::JS::ScriptObjectMirror)
15
+ # exposes less.tree e.g. for attaching custom functions
16
+ Less.tree.functions['foo'] = lambda { |*args| 'bar' }
17
+ end
18
+
19
+ it "CommonJS: require foo" do # CommonJS
20
+ environment = new_environment(:console => Console)
21
+ environment.native 'util', Util.new(out = StringIO.new)
22
+ exports = environment.require 'foo'
23
+ out.string.should == "Hello Bar!\n"
24
+
25
+ exports.should_not be nil
26
+ exports.foo.should respond_to(:'[]')
27
+ exports.foo['Bar'].should respond_to(:'[]')
28
+ exports.foo['Bar'][:puts].should be_a Nashorn::JS::JSObject # Rhino::JS::Function
29
+ end
30
+
31
+ it "CommonJS: require index/loop" do # CommonJS
32
+ environment = new_environment(:console => Console)
33
+ environment.require 'index'
34
+ environment.context['Loop'].should_not be nil
35
+ end
36
+
37
+ private
38
+
39
+ def new_environment(globals = {})
40
+ context = Nashorn::Context.new
41
+ globals.each { |key, obj| context[key] = obj }
42
+ path = Pathname(__FILE__).dirname.join('integration')
43
+ Env.new(context, :path => path.to_s)
44
+ end
45
+
46
+ class Env # a CommonJS like environment (inspired by commonjs.rb)
47
+
48
+ attr_reader :context, :modules
49
+
50
+ def initialize(context, options = {})
51
+ @context = context
52
+ @paths = [ options[:path] ].flatten.map { |path| Pathname(path) }
53
+ @modules = {}
54
+ end
55
+
56
+ def require(module_id)
57
+ unless mod = modules[module_id]
58
+ filepath = find(module_id) or fail LoadError, "no such module '#{module_id}'"
59
+ js = "( function(module, require, exports) {\n#{File.read(filepath)}\n} )"
60
+ load = context.eval(js, filepath.expand_path.to_s)
61
+ modules[module_id] = mod = Module.new(module_id, self)
62
+ load.call(mod, mod.require_function, mod.exports)
63
+ end
64
+ return mod.exports
65
+ end
66
+
67
+ def native(module_id, impl)
68
+ modules[module_id] = Module::Native.new(impl)
69
+ end
70
+
71
+ def new_object
72
+ context['Object'].new
73
+ end
74
+
75
+ private
76
+
77
+ def find(module_id)
78
+ if loadpath = @paths.find { |path| path.join("#{module_id}.js").exist? }
79
+ loadpath.join("#{module_id}.js")
80
+ end
81
+ end
82
+
83
+ class Module
84
+
85
+ attr_reader :id, :exports
86
+
87
+ def initialize(id, env)
88
+ @id, @env = id, env
89
+ @exports = env.new_object
90
+ @segments = id.split('/')
91
+ end
92
+
93
+ def require_function
94
+ @require_function ||= lambda do |*args|
95
+ this, module_id = *args
96
+ module_id ||= this #backwards compatibility with TRR < 0.10
97
+ @env.require(expand(module_id))
98
+ end
99
+ end
100
+
101
+ private
102
+
103
+ def expand(module_id)
104
+ return module_id unless module_id =~ /(\.|\..)/
105
+ module_id.split('/').inject(@segments[0..-2]) do |path, element|
106
+ path.tap do
107
+ if element == '.'
108
+ # do nothing
109
+ elsif element == '..'
110
+ path.pop
111
+ else
112
+ path.push element
113
+ end
114
+ end
115
+ end.join('/')
116
+ end
117
+
118
+ class Native
119
+
120
+ def initialize(impl); @impl = impl; end
121
+ def exports; @impl; end
122
+
123
+ end
124
+
125
+ end
126
+
127
+ end
128
+
129
+ class Util
130
+
131
+ def initialize(io = STDOUT)
132
+ @io = io
133
+ end
134
+
135
+ def puts(*args)
136
+ args.each { |arg| @io.puts(arg) }
137
+ end
138
+
139
+ end
140
+
141
+ class Console
142
+
143
+ def self.log(*msgs)
144
+ puts msgs.join(', ')
145
+ end
146
+
147
+ end
148
+
149
+ end