Skip to content

Commit 80b3aa3

Browse files
committed
Stub out the Node runtime
1 parent 6ba90fc commit 80b3aa3

File tree

5 files changed

+121
-21
lines changed

5 files changed

+121
-21
lines changed

lib/execjs.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
11
module ExecJS
2+
class Error < ::StandardError; end
3+
class RuntimeError < Error; end
4+
class ProgramError < Error; end
5+
26
autoload :Runtimes, "execjs/runtimes"
37
end

lib/execjs/runtimes/node.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
(function(program, execJS) { execJS(program) })(function() { #{source}
2+
}, function(program) {
3+
var output, print = function(string) {
4+
process.stdout.write('' + string);
5+
};
6+
try {
7+
result = program();
8+
if (typeof result == 'undefined' && result !== null) {
9+
print('["ok"]');
10+
} else {
11+
try {
12+
print(JSON.stringify(['ok', result]));
13+
} catch (err) {
14+
print('["err"]');
15+
}
16+
}
17+
} catch (err) {
18+
print(JSON.stringify(['err', '' + err]));
19+
}
20+
});

lib/execjs/runtimes/node.rb

Lines changed: 52 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,58 @@
1+
require "json"
2+
require "tempfile"
3+
14
module ExecJS
25
module Runtimes
3-
class Node
6+
module Node
7+
extend self
8+
9+
def exec(source)
10+
compile_to_tempfile(source) do |file|
11+
extract_result(exec_runtime("node #{file.path}"))
12+
end
13+
end
14+
15+
def eval(source)
16+
if /\S/ =~ source
17+
exec("return eval(#{"(#{source})".to_json})")
18+
end
19+
end
20+
21+
protected
22+
def compile_to_tempfile(source)
23+
tempfile = Tempfile.open("execjs")
24+
tempfile.write compile(source)
25+
tempfile.close
26+
yield tempfile
27+
ensure
28+
tempfile.close!
29+
end
430

31+
def compile(source)
32+
wrapper.sub('#{source}', source)
33+
end
34+
35+
def wrapper
36+
@wrapper ||= IO.read(File.expand_path('../node.js', __FILE__))
37+
end
38+
39+
def exec_runtime(command)
40+
output = `#{command} 2>&1`
41+
if $?.success?
42+
output
43+
else
44+
raise RuntimeError, output
45+
end
46+
end
47+
48+
def extract_result(output)
49+
status, value = output.empty? ? [] : JSON.parse(output)
50+
if status == "ok"
51+
value
52+
else
53+
raise ProgramError, value
54+
end
55+
end
556
end
657
end
758
end
8-
9-
__END__
10-
(function(program, execJS) { execJS(program) })(function() { #{source}
11-
}, function(program) {
12-
var result, output;
13-
try {
14-
result = program();
15-
try {
16-
output = JSON.stringify(result);
17-
sys.print('ok ');
18-
sys.print(output);
19-
} catch (err) {
20-
sys.print('err');
21-
}
22-
} catch (err) {
23-
sys.print('err ');
24-
sys.print(err);
25-
}
26-
});

readme.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,5 @@ ExecJS supports these runtimes:
1919
A short example:
2020

2121
require "execjs"
22-
ExecJS.exec "'red yellow blue'.split('')"
22+
ExecJS.eval "'red yellow blue'.split('')"
2323
# => ["red", "yellow", "blue"]

test/test_node_runtime.rb

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
require "execjs"
2+
require "test/unit"
3+
4+
class TestNodeRuntime < Test::Unit::TestCase
5+
def setup
6+
@runtime = ExecJS::Runtimes::Node
7+
end
8+
9+
def test_exec
10+
assert_nil @runtime.exec("1")
11+
assert_nil @runtime.exec("return")
12+
assert_nil @runtime.exec("return null")
13+
assert_nil @runtime.exec("return function() {}")
14+
assert_equal 0, @runtime.exec("return 0")
15+
assert_equal true, @runtime.exec("return true")
16+
assert_equal [1, 2], @runtime.exec("return [1, 2]")
17+
assert_equal "hello", @runtime.exec("return 'hello'")
18+
assert_equal({"a"=>1,"b"=>2}, @runtime.exec("return {a:1,b:2}"))
19+
end
20+
21+
def test_eval
22+
assert_nil @runtime.eval("")
23+
assert_nil @runtime.eval(" ")
24+
assert_nil @runtime.eval("null")
25+
assert_nil @runtime.eval("function() {}")
26+
assert_equal 0, @runtime.eval("0")
27+
assert_equal true, @runtime.eval("true")
28+
assert_equal [1, 2], @runtime.eval("[1, 2]")
29+
assert_equal "hello", @runtime.eval("'hello'")
30+
assert_equal({"a"=>1,"b"=>2}, @runtime.eval("{a:1,b:2}"))
31+
end
32+
33+
def test_syntax_error
34+
assert_raise ExecJS::RuntimeError do
35+
@runtime.exec(")")
36+
end
37+
end
38+
39+
def test_thrown_exception
40+
assert_raise ExecJS::ProgramError do
41+
@runtime.exec("throw 'hello'")
42+
end
43+
end
44+
end

0 commit comments

Comments
 (0)