Add compilation to object and glue

This commit is contained in:
ccocchi 2012-02-23 12:56:45 +01:00
parent 1997634dfc
commit e24aca780d
3 changed files with 49 additions and 8 deletions

View File

@ -5,6 +5,7 @@ module RablFastJson
def initialize(context, assigns = nil) def initialize(context, assigns = nil)
@context = context @context = context
@glue_count = 0
_get_assigns_from_context(assigns) _get_assigns_from_context(assigns)
_get_virtual_path_from_context _get_virtual_path_from_context
end end
@ -32,10 +33,15 @@ module RablFastJson
def child(name_or_data, options = {}, &block) def child(name_or_data, options = {}, &block)
return unless block_given? return unless block_given?
data, name = extract_name_and_data(name_or_data) data, name = extract_data_and_name(name_or_data)
sub_compiler = Compiler.new(@context, @assigns) _compile_sub_template(name, data, &block)
sub_template = sub_compiler.compile_block(&block) end
@template[name] = sub_template.merge!(:_data => data)
def glue(data, &block)
return unless block_given?
name = :"_glue#{@glue_count}"
@glue_count += 1
_compile_sub_template(name, data, &block)
end end
def node(name, options = {}, &block) def node(name, options = {}, &block)
@ -48,22 +54,29 @@ module RablFastJson
end end
def object(data) def object(data)
@data = data data, name = extract_data_and_name(data)
@template.data, @template.root_name = data, name
end end
protected protected
def extract_name_and_data(name_or_data) def extract_data_and_name(name_or_data)
case name_or_data case name_or_data
when Symbol when Symbol
[name_or_data, name_or_data] [name_or_data, name_or_data]
when Hash when Hash
name_or_data.first name_or_data.first
else else
raise "#{name_or_data} is not a valid name for a child association" name_or_data
end end
end end
def _compile_sub_template(name, data, &block)
compiler = Compiler.new(@context, @assigns)
template = compiler.compile_block(&block)
@template[name] = template.merge!(:_data => data)
end
def _get_assigns_from_context(assigns) def _get_assigns_from_context(assigns)
source = assigns || @context.instance_variable_get(:@_assigns) source = assigns || @context.instance_variable_get(:@_assigns)
source.each_pair { |k, v| source.each_pair { |k, v|

View File

@ -1,7 +1,7 @@
module RablFastJson module RablFastJson
class CompiledTemplate class CompiledTemplate
attr_accessor :source attr_accessor :source, :data, :root_name
delegate :[], :[]=, :to => :source delegate :[], :[]=, :to => :source

View File

@ -82,6 +82,34 @@ class CompilerTest < ActiveSupport::TestCase
assert_equal({ :author => { :_data => @user, :name => :name } }, t.source) assert_equal({ :author => { :_data => @user, :name => :name } }, t.source)
end end
test "glue is compiled as a child but with anonymous name" do
t = @compiler.compile_source(%{ glue @user do attribute :name end })
assert_equal({ :_glue0 => { :_data => @user, :name => :name } }, t.source)
end
test "multiple glue don't come with name collisions" do
t = @compiler.compile_source(%{
glue @user do attribute :name end
glue @user do attribute :foo end
})
assert_equal({
:_glue0 => { :_data => @user, :name => :name},
:_glue1 => { :_data => @user, :foo => :foo}
}, t.source)
end
test "object set data for the template" do
t = @compiler.compile_source(%{ object @user })
assert_equal @user, t.data
end
test "object property can define root name" do
t = @compiler.compile_source(%{ object @user => :author })
assert_equal @user, t.data
assert_equal :author, t.root_name
end
test "node are compiled without evaluating the block" do test "node are compiled without evaluating the block" do
t = @compiler.compile_source(%{ node(:foo) { bar } }) t = @compiler.compile_source(%{ node(:foo) { bar } })
assert_not_nil t.source[:foo] assert_not_nil t.source[:foo]