lib/boojs.rb in boojs-0.0.20 vs lib/boojs.rb in boojs-0.0.21
- old
+ new
@@ -1,35 +1,72 @@
require 'tempfile'
require 'securerandom'
require 'greenletters'
require "net/http"
require "uri"
+require "open3"
+require 'therubyracer'
module BooJS
def self.verify str
- phantom = Phantomjs.path
-
#Create tmp file
tmp = Tempfile.new(SecureRandom.hex)
- tmp.puts %{
- phantom.onError = function(msg, trace) {
- console.log("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%");
- console.log("PhantomJS Error");
- console.log("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%");
- console.log(msg);
- trace.forEach(function(t) {
- console.log(t.file + ': line ' + t.line );
- })
- console.log("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%");
- phantom.exit(1);
+ path = tmp.path
+ tmp.close!
+ File.open path, "w" do |f|
+ f.puts %{
+ phantom.onError = function(msg, trace) {
+ console.log("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%");
+ console.log("PhantomJS Error");
+ console.log("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%");
+ console.log(msg);
+ trace.forEach(function(t) {
+ console.log(t.file + ': line ' + t.line );
+ })
+ console.log("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%");
+ phantom.exit(1);
+ }
}
- }
- tmp.puts str
- tmp.puts "phantom.exit(0)"
- tmp.close
+ f.puts str
+ f.puts "phantom.exit(0)"
+ end
- system("phantomjs #{tmp.path} 2>&1") or raise "Verifying failed"
+ begin
+ #Do we have a syntax error?
+ @syntax_error = false
+ Timeout.timeout(8) do
+ Open3.popen3 "#{$phantomjs_path} #{path}" do |_, out, err, _|
+ begin
+ loop do
+ rr, ww = select([out, err], []); e = rr[0]
+
+ #PhantomJS wrote to stderr
+ r = e.readline
+ if r =~ /SyntaxError/
+ @syntax_error = true
+ raise "syntax_error" #Break out
+ end
+ end
+ ensure
+ Process.kill 9, p.pid
+ end
+ end
+ end
+ rescue => e
+ end
+
+ #PhantomJS does not support syntax checking, so we use V8 to do that
+ return 0 unless @syntax_error
+ begin
+ ctx = V8::Context.new
+ ctx.load path
+ rescue V8::Error => e
+ matches = e.message.match(/.*? at (?<path>.*?):(?<line>.*?):.*?$/)
+ dump_lines matches[:path], matches[:line].to_i, 10
+ end
+
+ return 1
end
#Optionally, accept code to inject and a command to run
#If the command is nil, this is not executed as a oneshot
def self.pipe(str=nil, cmd=nil, will_timeout=false)
@@ -129,28 +166,28 @@
# 3| console.log("hello world");
# 4| console.log("hello world again"]; <-------- [optional msg]
# 5| var x = 4;
# 6| var y = 3;
# -----------------------------------------------
- def dump_lines fn, center_num, n_expand, msg=nil
+ def self.dump_lines fn, center_num, n_expand, msg=nil
f = File.open(fn)
range = (center_num-n_expand)..(center_num+n_expand)
- puts "------------------------------------------------------------"
- puts "#{File.basename(fn)}:#{center_num}"
- puts "------------------------------------------------------------"
+ $stderr.puts "------------------------------------------------------------"
+ $stderr.puts "#{File.basename(fn)}:#{center_num}"
+ $stderr.puts "------------------------------------------------------------"
f.each_line.with_index do |line, index|
line.strip!
if range.include? index
if index == center_num
- puts "#{index}| #{line} <------ " + (msg ? "[#{msg}]" : "")
+ $stderr.puts "#{index}| #{line} <------ " + (msg ? "[#{msg}]" : "")
else
- puts "#{index}| #{line}"
+ $stderr.puts "#{index}| #{line}"
end
end
end
- puts "------------------------------------------------------------"
+ $stderr.puts "------------------------------------------------------------"
end
end
#You can not use stdin readLine from PhantomJS because it blocks. This is a workaround where
#commands are queued via the built-in server and then evaluated asynchronously via setInterval.
@@ -177,10 +214,10 @@
if (__async_stdin_queue.length == 0) {
return;
}
var str = __async_stdin_queue.pop()
- eval(str);
+ eval.call(window, str);
}
setInterval(__async_stdin_dequeue, 50);
}
end
end