1
0
Fork 0
mirror of https://github.com/rubyjs/mini_racer synced 2023-03-27 23:21:28 -04:00

allow attaching on undefined nested objects

context.attach("foo.bar.foo", proc{"bar"})
context.eval("foo.bar.foo()") => "bar"
This commit is contained in:
Sam 2016-05-19 13:11:39 +10:00
parent 87e0e1ba09
commit 3545eafd95
3 changed files with 39 additions and 5 deletions

View file

@ -428,6 +428,7 @@ static VALUE rb_external_function_notify_v8(VALUE self) {
VALUE parent = rb_iv_get(self, "@parent");
VALUE name = rb_iv_get(self, "@name");
VALUE parent_object = rb_iv_get(self, "@parent_object");
VALUE parent_object_eval = rb_iv_get(self, "@parent_object_eval");
bool parse_error = false;
bool attach_error = false;
@ -456,8 +457,8 @@ static VALUE rb_external_function_notify_v8(VALUE self) {
context->Global()->Set(v8_str, FunctionTemplate::New(context_info->isolate, ruby_callback, external)->GetFunction());
} else {
Local<String> eval = String::NewFromUtf8(context_info->isolate, RSTRING_PTR(parent_object),
NewStringType::kNormal, (int)RSTRING_LEN(parent_object)).ToLocalChecked();
Local<String> eval = String::NewFromUtf8(context_info->isolate, RSTRING_PTR(parent_object_eval),
NewStringType::kNormal, (int)RSTRING_LEN(parent_object_eval)).ToLocalChecked();
MaybeLocal<Script> parsed_script = Script::Compile(context, eval);
if (parsed_script.IsEmpty()) {

View file

@ -52,7 +52,27 @@ module MiniRacer
parent_object, _ , @name = name.rpartition(".")
@callback = callback
@parent = parent
@parent_object = parent_object.empty? ? nil : parent_object
@parent_object_eval = nil
@parent_object = nil
unless parent_object.empty?
@parent_object = parent_object
@parent_object_eval = ""
prev = ""
first = true
parent_object.split(".").each do |obj|
prev << obj
if first
@parent_object_eval << "if (typeof #{prev} === 'undefined') { #{prev} = {} };\n"
else
@parent_object_eval << "#{prev} = #{prev} || {};\n"
end
prev << "."
first = false
end
@parent_object_eval << "#{parent_object};"
end
notify_v8
end
end

View file

@ -141,18 +141,31 @@ raise FooError, "I like foos"
def test_attached_on_object
context = MiniRacer::Context.new
context.eval("var minion = {}")
context.attach("minion.speak", proc{"banana"})
assert_equal "banana", context.eval("minion.speak()")
end
def test_attached_on_nested_object
context = MiniRacer::Context.new
context.eval("var minion = {kevin: {}}")
context.attach("minion.kevin.speak", proc{"banana"})
assert_equal "banana", context.eval("minion.kevin.speak()")
end
def test_attach_error
context = MiniRacer::Context.new
context.eval("minion = 2")
assert_raises do
begin
context.attach("minion.kevin.speak", proc{"banana"})
rescue => e
assert_equal MiniRacer::ParseError, e.class
assert_match(/expecting minion.kevin/, e.message)
raise
end
end
end
def test_load
context = MiniRacer::Context.new
context.load(File.dirname(__FILE__) + "/file.js")