Skip to content

Commit

Permalink
Stub out the Node runtime
Browse files Browse the repository at this point in the history
  • Loading branch information
sstephenson committed Feb 7, 2011
1 parent 6ba90fc commit 80b3aa3
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 21 deletions.
4 changes: 4 additions & 0 deletions lib/execjs.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
module ExecJS
class Error < ::StandardError; end
class RuntimeError < Error; end
class ProgramError < Error; end

autoload :Runtimes, "execjs/runtimes"
end
20 changes: 20 additions & 0 deletions lib/execjs/runtimes/node.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
(function(program, execJS) { execJS(program) })(function() { #{source}
}, function(program) {
var output, print = function(string) {
process.stdout.write('' + string);
};
try {
result = program();
if (typeof result == 'undefined' && result !== null) {
print('["ok"]');
} else {
try {
print(JSON.stringify(['ok', result]));
} catch (err) {
print('["err"]');
}
}
} catch (err) {
print(JSON.stringify(['err', '' + err]));
}
});
72 changes: 52 additions & 20 deletions lib/execjs/runtimes/node.rb
Original file line number Diff line number Diff line change
@@ -1,26 +1,58 @@
require "json"
require "tempfile"

module ExecJS
module Runtimes
class Node
module Node
extend self

def exec(source)
compile_to_tempfile(source) do |file|
extract_result(exec_runtime("node #{file.path}"))
end
end

def eval(source)
if /\S/ =~ source
exec("return eval(#{"(#{source})".to_json})")
end
end

protected
def compile_to_tempfile(source)
tempfile = Tempfile.open("execjs")
tempfile.write compile(source)
tempfile.close
yield tempfile
ensure
tempfile.close!
end

def compile(source)
wrapper.sub('#{source}', source)
end

def wrapper
@wrapper ||= IO.read(File.expand_path('../node.js', __FILE__))
end

def exec_runtime(command)
output = `#{command} 2>&1`
if $?.success?
output
else
raise RuntimeError, output
end
end

def extract_result(output)
status, value = output.empty? ? [] : JSON.parse(output)
if status == "ok"
value
else
raise ProgramError, value
end
end
end
end
end

__END__
(function(program, execJS) { execJS(program) })(function() { #{source}
}, function(program) {
var result, output;
try {
result = program();
try {
output = JSON.stringify(result);
sys.print('ok ');
sys.print(output);
} catch (err) {
sys.print('err');
}
} catch (err) {
sys.print('err ');
sys.print(err);
}
});
2 changes: 1 addition & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,5 @@ ExecJS supports these runtimes:
A short example:

require "execjs"
ExecJS.exec "'red yellow blue'.split('')"
ExecJS.eval "'red yellow blue'.split('')"
# => ["red", "yellow", "blue"]
44 changes: 44 additions & 0 deletions test/test_node_runtime.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
require "execjs"
require "test/unit"

class TestNodeRuntime < Test::Unit::TestCase
def setup
@runtime = ExecJS::Runtimes::Node
end

def test_exec
assert_nil @runtime.exec("1")
assert_nil @runtime.exec("return")
assert_nil @runtime.exec("return null")
assert_nil @runtime.exec("return function() {}")
assert_equal 0, @runtime.exec("return 0")
assert_equal true, @runtime.exec("return true")
assert_equal [1, 2], @runtime.exec("return [1, 2]")
assert_equal "hello", @runtime.exec("return 'hello'")
assert_equal({"a"=>1,"b"=>2}, @runtime.exec("return {a:1,b:2}"))
end

def test_eval
assert_nil @runtime.eval("")
assert_nil @runtime.eval(" ")
assert_nil @runtime.eval("null")
assert_nil @runtime.eval("function() {}")
assert_equal 0, @runtime.eval("0")
assert_equal true, @runtime.eval("true")
assert_equal [1, 2], @runtime.eval("[1, 2]")
assert_equal "hello", @runtime.eval("'hello'")
assert_equal({"a"=>1,"b"=>2}, @runtime.eval("{a:1,b:2}"))
end

def test_syntax_error
assert_raise ExecJS::RuntimeError do
@runtime.exec(")")
end
end

def test_thrown_exception
assert_raise ExecJS::ProgramError do
@runtime.exec("throw 'hello'")
end
end
end

0 comments on commit 80b3aa3

Please sign in to comment.