diff --git a/lib/rhino/wormhole.rb b/lib/rhino/wormhole.rb index 67d2db6..38ebf45 100644 --- a/lib/rhino/wormhole.rb +++ b/lib/rhino/wormhole.rb @@ -43,10 +43,17 @@ module Rhino end def array_to_javascript(rb_array, scope = nil) + # First convert all array elements to their javascript equivalents and + # then invoke to_java below in order to create a Java array. This allows + # arrays with nested hashes to be converted properly. + converted_rb_array = rb_array.map do |rb_element| + to_javascript(rb_element, scope) + end + if scope && context = JS::Context.getCurrentContext - context.newArray(scope, rb_array.to_java) + context.newArray(scope, converted_rb_array.to_java) else - JS::NativeArray.new(rb_array.to_java) + JS::NativeArray.new(converted_rb_array.to_java) end end diff --git a/spec/rhino/wormhole_spec.rb b/spec/rhino/wormhole_spec.rb index 80e5541..0e55698 100644 --- a/spec/rhino/wormhole_spec.rb +++ b/spec/rhino/wormhole_spec.rb @@ -91,6 +91,46 @@ describe Rhino::To do h.prototype.should be_nil # this is how Rhino works ! end end + + it "converts deeply nested ruby hashes into native objects" do + hash = { + :array => [ + { + :breed => "Pug" + }, + { + :breed => "English Bulldog" + }, + { + :breed => [ + "Pug", + "Beagle" + ] + } + ] + } + + Rhino.to_javascript(hash).tap do |h| + h.should be_kind_of(Rhino::JS::NativeObject) + + a = h.get("array", h) + a.should be_kind_of(Rhino::JS::NativeArray) + + element0 = a.get(0,a) + element0.should be_kind_of(Rhino::JS::NativeObject) + element0.get("breed", element0).should == "Pug" + + element2 = a.get(2,a) + element2.should be_kind_of(Rhino::JS::NativeObject) + + nested_array = element2.get("breed", element2) + nested_array.should be_kind_of(Rhino::JS::NativeArray) + nested_array.get(0,nested_array).should == "Pug" + nested_array.get(1,nested_array).should == "Beagle" + + h.prototype.should be_nil # this is how Rhino works ! + end + end describe "with a scope" do