From ad0ab1bdded9e02f7bc92ed089b5553bbfb91f68 Mon Sep 17 00:00:00 2001 From: Magnus Holm Date: Sat, 2 Jun 2018 21:51:55 +0200 Subject: [PATCH 1/5] Add documentation for the Context methods --- lib/execjs/runtime.rb | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/lib/execjs/runtime.rb b/lib/execjs/runtime.rb index eba424c..822bf5a 100644 --- a/lib/execjs/runtime.rb +++ b/lib/execjs/runtime.rb @@ -9,15 +9,30 @@ module ExecJS def initialize(runtime, source = "", options = {}) end + # Evaluates the +source+ in the context of a function body and returns the + # returned value. + # + # context.exec("return 1") # => 1 + # context.exec("1") # => nil (nothing was returned) def exec(source, options = {}) raise NotImplementedError end + # Evaluates the +source+ as an expression and returns the result. + # + # context.eval("1") # => 1 + # context.eval("return 1") # => Raises SyntaxError def eval(source, options = {}) raise NotImplementedError end - def call(properties, *args) + # Evaluates +source+ as an expression (which should be of type + # +function+), and calls the function with the given arguments. + # The function will be evaluated with the global object as +this+. + # + # context.call("function(a, b) { return a + b }", 1, 1) # => 2 + # context.call("CoffeeScript.compile", "1 + 1") + def call(source, *args) raise NotImplementedError end end From 12afcd26964a3ed49715a2330dc27c478f77269f Mon Sep 17 00:00:00 2001 From: Magnus Holm Date: Sat, 2 Jun 2018 21:52:18 +0200 Subject: [PATCH 2/5] Add more tests for Context#call --- test/test_execjs.rb | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/test/test_execjs.rb b/test/test_execjs.rb index 0ee411f..30d85ec 100644 --- a/test/test_execjs.rb +++ b/test/test_execjs.rb @@ -48,6 +48,31 @@ class TestExecJS < Test assert_equal "bar", context.call("a.b.id", "bar") end + def test_call_with_complex_properties + context = ExecJS.compile("") + assert_equal 2, context.call("function(a, b) { return a + b }", 1, 1) + + context = ExecJS.compile("foo = 1") + assert_equal 2, context.call("(function(bar) { return foo + bar })", 1) + end + + def test_call_with_this + # Make sure that `this` is indeed the global scope + context = ExecJS.compile(<<-EOF) + name = 123; + + function Person(name) { + this.name = name; + } + + Person.prototype.getThis = function() { + return this.name; + } + EOF + + assert_equal 123, context.call("(new Person('Bob')).getThis") + end + def test_context_call_missing_function context = ExecJS.compile("") assert_raises ExecJS::ProgramError do From 58a6c49a667d35bc6e9cc5e6d78aa3b73c3fa7a2 Mon Sep 17 00:00:00 2001 From: Magnus Holm Date: Sat, 2 Jun 2018 21:53:36 +0200 Subject: [PATCH 3/5] Duktape: Follow correct behavior for Context#call --- lib/execjs/duktape_runtime.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/execjs/duktape_runtime.rb b/lib/execjs/duktape_runtime.rb index 8ae42a5..7758fdf 100644 --- a/lib/execjs/duktape_runtime.rb +++ b/lib/execjs/duktape_runtime.rb @@ -26,7 +26,8 @@ module ExecJS end def call(identifier, *args) - @ctx.call_prop(identifier.split("."), *args) + @ctx.exec_string("__execjs_duktape_call = #{identifier}", '(execjs)') + @ctx.call_prop("__execjs_duktape_call", *args) rescue Exception => e raise wrap_error(e) end From a6f6a6cf25f9625bda58e2e5c526ad920eb96184 Mon Sep 17 00:00:00 2001 From: Magnus Holm Date: Sat, 2 Jun 2018 22:02:08 +0200 Subject: [PATCH 4/5] RubyRacer: Force expression in Context#call --- lib/execjs/ruby_racer_runtime.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/execjs/ruby_racer_runtime.rb b/lib/execjs/ruby_racer_runtime.rb index cf8e1a2..682efd5 100644 --- a/lib/execjs/ruby_racer_runtime.rb +++ b/lib/execjs/ruby_racer_runtime.rb @@ -42,7 +42,7 @@ module ExecJS def call(properties, *args) lock do begin - unbox @v8_context.eval(properties).call(*args) + unbox @v8_context.eval("(#{properties})").call(*args) rescue ::V8::JSError => e raise wrap_error(e) end From 412b1e8d7c63c38b559564e2a03614e7caff64d5 Mon Sep 17 00:00:00 2001 From: Magnus Holm Date: Wed, 6 Jun 2018 14:34:19 +0200 Subject: [PATCH 5/5] test_call_with_this: Skip on Rhino This is a known bug in Ruby Rhino --- test/test_execjs.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/test_execjs.rb b/test/test_execjs.rb index 30d85ec..81804a1 100644 --- a/test/test_execjs.rb +++ b/test/test_execjs.rb @@ -57,6 +57,9 @@ class TestExecJS < Test end def test_call_with_this + # Known bug: https://github.com/cowboyd/therubyrhino/issues/39 + skip if ExecJS.runtime.is_a?(ExecJS::RubyRhinoRuntime) + # Make sure that `this` is indeed the global scope context = ExecJS.compile(<<-EOF) name = 123;