dienashorner 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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