From e24aca780dc5ee20092f9f5995eb53fe26a486c0 Mon Sep 17 00:00:00 2001 From: ccocchi Date: Thu, 23 Feb 2012 12:56:45 +0100 Subject: [PATCH] Add compilation to object and glue --- lib/rabl-fast-json/compiler.rb | 27 ++++++++++++++++++++------- lib/rabl-fast-json/template.rb | 2 +- test/compiler_test.rb | 28 ++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 8 deletions(-) diff --git a/lib/rabl-fast-json/compiler.rb b/lib/rabl-fast-json/compiler.rb index ba4c9a6..aa50983 100644 --- a/lib/rabl-fast-json/compiler.rb +++ b/lib/rabl-fast-json/compiler.rb @@ -5,6 +5,7 @@ module RablFastJson def initialize(context, assigns = nil) @context = context + @glue_count = 0 _get_assigns_from_context(assigns) _get_virtual_path_from_context end @@ -32,10 +33,15 @@ module RablFastJson def child(name_or_data, options = {}, &block) return unless block_given? - data, name = extract_name_and_data(name_or_data) - sub_compiler = Compiler.new(@context, @assigns) - sub_template = sub_compiler.compile_block(&block) - @template[name] = sub_template.merge!(:_data => data) + data, name = extract_data_and_name(name_or_data) + _compile_sub_template(name, data, &block) + end + + def glue(data, &block) + return unless block_given? + name = :"_glue#{@glue_count}" + @glue_count += 1 + _compile_sub_template(name, data, &block) end def node(name, options = {}, &block) @@ -48,22 +54,29 @@ module RablFastJson end def object(data) - @data = data + data, name = extract_data_and_name(data) + @template.data, @template.root_name = data, name end protected - def extract_name_and_data(name_or_data) + def extract_data_and_name(name_or_data) case name_or_data when Symbol [name_or_data, name_or_data] when Hash name_or_data.first else - raise "#{name_or_data} is not a valid name for a child association" + name_or_data 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) source = assigns || @context.instance_variable_get(:@_assigns) source.each_pair { |k, v| diff --git a/lib/rabl-fast-json/template.rb b/lib/rabl-fast-json/template.rb index 3205416..a97a572 100644 --- a/lib/rabl-fast-json/template.rb +++ b/lib/rabl-fast-json/template.rb @@ -1,7 +1,7 @@ module RablFastJson class CompiledTemplate - attr_accessor :source + attr_accessor :source, :data, :root_name delegate :[], :[]=, :to => :source diff --git a/test/compiler_test.rb b/test/compiler_test.rb index 1f41616..7b60a45 100644 --- a/test/compiler_test.rb +++ b/test/compiler_test.rb @@ -82,6 +82,34 @@ class CompilerTest < ActiveSupport::TestCase assert_equal({ :author => { :_data => @user, :name => :name } }, t.source) 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 t = @compiler.compile_source(%{ node(:foo) { bar } }) assert_not_nil t.source[:foo]