diff --git a/lib/rabl-fast-json.rb b/lib/rabl-fast-json.rb index 0f29c9c..0fcadee 100644 --- a/lib/rabl-fast-json.rb +++ b/lib/rabl-fast-json.rb @@ -5,7 +5,6 @@ require 'active_support/json' require 'active_support/core_ext/class/attribute_accessors' require 'rabl-fast-json/version' -require 'rabl-fast-json/helpers' require 'rabl-fast-json/template' require 'rabl-fast-json/compiler' diff --git a/lib/rabl-fast-json/compiler.rb b/lib/rabl-fast-json/compiler.rb index 5e3c4fe..a8422d1 100644 --- a/lib/rabl-fast-json/compiler.rb +++ b/lib/rabl-fast-json/compiler.rb @@ -4,8 +4,6 @@ module RablFastJson # representing data structure # class Compiler - include Helpers - def initialize @glue_count = 0 end @@ -49,7 +47,7 @@ module RablFastJson # def collection(data, options = {}) object(data) - @template.root_name = options[:root] if root_given?(options) + @template.root_name = options[:root] if options[:root] end # @@ -82,8 +80,8 @@ module RablFastJson # def child(name_or_data, options = {}, &block) data, name = extract_data_and_name(name_or_data) - name = options[:root] if root_given?(options) - if partial_given?(options) + name = options[:root] if options[:root] + if options[:partial] template = Library.instance.get(options[:partial]) @template[name] = template.merge!(:_data => data) else diff --git a/lib/rabl-fast-json/helpers.rb b/lib/rabl-fast-json/helpers.rb deleted file mode 100644 index e105b67..0000000 --- a/lib/rabl-fast-json/helpers.rb +++ /dev/null @@ -1,11 +0,0 @@ -module RablFastJson - module Helpers - def root_given?(options) #:nodoc: - options[:root].present? - end - - def partial_given?(options) #:nodoc: - options[:partial].present? - end - end -end \ No newline at end of file diff --git a/lib/rabl-fast-json/library.rb b/lib/rabl-fast-json/library.rb index 10565e0..62b511e 100644 --- a/lib/rabl-fast-json/library.rb +++ b/lib/rabl-fast-json/library.rb @@ -4,8 +4,6 @@ module RablFastJson class Library include Singleton - attr_accessor :view_renderer - def initialize @cached_templates = {} end @@ -31,7 +29,7 @@ module RablFastJson def get(path) template = @cached_templates[path] - return template unless template.nil? + return template if template t = @lookup_context.find_template(path, [], false) get_compiled_template(path, t.source) end diff --git a/lib/rabl-fast-json/renderers/base.rb b/lib/rabl-fast-json/renderers/base.rb index 5709580..aa7235a 100644 --- a/lib/rabl-fast-json/renderers/base.rb +++ b/lib/rabl-fast-json/renderers/base.rb @@ -74,6 +74,10 @@ module RablFastJson collection.map { |o| render_resource(o, source) } end + # + # Allow to use partial inside of node blocks (they are evaluated at) + # rendering time. + # def partial(template_path, options = {}) raise "No object was given to partial" unless options[:object] object = options[:object] diff --git a/test/cache_templates_test.rb b/test/cache_templates_test.rb index 288c668..3d792df 100644 --- a/test/cache_templates_test.rb +++ b/test/cache_templates_test.rb @@ -18,10 +18,10 @@ class CacheTemplatesTest < ActiveSupport::TestCase test "cached templates should not be modifiable in place" do ActionController::Base.stub(:perform_caching).and_return(true) - t = @library.get_compiled_template('some/path', "") - assert_nil t.context - t.context = "foobar" - assert_nil @library.get_compiled_template('some/path', "").context + @library.get_compiled_template('some/path', "") + t = @library.get_compiled_template('some/path', "attribute :id") + + assert_equal({}, t.source) end test "don't cache templates cache_templates is enabled but perform_caching is not active" do diff --git a/test/compiler_test.rb b/test/compiler_test.rb index 862d3d4..c9b550f 100644 --- a/test/compiler_test.rb +++ b/test/compiler_test.rb @@ -11,6 +11,40 @@ class CompilerTest < ActiveSupport::TestCase assert_instance_of RablFastJson::CompiledTemplate, @compiler.compile_source("") end + test "object set data for the template" do + t = @compiler.compile_source(%{ object :@user }) + assert_equal :@user, t.data + assert_equal({}, t.source) + 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 + assert_equal({}, t.source) + end + + test "collection set the data for the template" do + t = @compiler.compile_source(%{ collection :@user }) + assert_equal :@user, t.data + assert_equal({}, t.source) + end + + test "collection property can define root name" do + t = @compiler.compile_source(%{ collection :@user => :users }) + assert_equal :@user, t.data + assert_equal :users, t.root_name + assert_equal({}, t.source) + end + + test "collection property can define root name via options" do + t = @compiler.compile_source(%{ collection :@user, :root => :users }) + assert_equal :@user, t.data + assert_equal :users, t.root_name + end + + # Compilation + test "simple attributes are compiled to hash" do t = @compiler.compile_source(%{ attributes :id, :name }) assert_equal({ :id => :id, :name => :name}, t.source) @@ -57,11 +91,10 @@ class CompilerTest < ActiveSupport::TestCase end test "child with succint partial notation" do - @view_renderer = mock() - @view_renderer.stub_chain(:lookup_context, :find_template).with('users/base', [], false).and_return( - mock(:source => %{ attribute :id })) + mock_template = RablFastJson::CompiledTemplate.new + mock_template.source = { :id => :id } RablFastJson::Library.reset_instance - RablFastJson::Library.instance.view_renderer = @view_renderer + RablFastJson::Library.instance.stub(:get).with('users/base').and_return(mock_template) t = @compiler.compile_source(%{child(:user, :partial => 'users/base') }) assert_equal( {:user => { :_data => :user, :id => :id } }, t.source) @@ -84,38 +117,6 @@ class CompilerTest < ActiveSupport::TestCase }, t.source) end - test "object set data for the template" do - t = @compiler.compile_source(%{ object :@user }) - assert_equal :@user, t.data - assert_equal({}, t.source) - 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 - assert_equal({}, t.source) - end - - test "collection set the data for the template" do - t = @compiler.compile_source(%{ collection :@user }) - assert_equal :@user, t.data - assert_equal({}, t.source) - end - - test "collection property can define root name" do - t = @compiler.compile_source(%{ collection :@user => :users }) - assert_equal :@user, t.data - assert_equal :users, t.root_name - assert_equal({}, t.source) - end - - test "collection property can define root name via options" do - t = @compiler.compile_source(%{ collection :@user, :root => :users }) - assert_equal :@user, t.data - assert_equal :users, t.root_name - end - test "extends use other template source as itself" do template = mock('template', :source => { :id => :id }) RablFastJson::Library.reset_instance diff --git a/test/deep_nesting_test.rb b/test/deep_nesting_test.rb index 3c3e87c..2dca67a 100644 --- a/test/deep_nesting_test.rb +++ b/test/deep_nesting_test.rb @@ -21,15 +21,11 @@ class DeepNestingTest < ActiveSupport::TestCase @user.stub(:posts).and_return([@post]) @user.stub(:respond_to?).with(:each).and_return(false) - @view_renderer = mock() - @view_renderer.stub_chain(:lookup_context, :find_template).with('comments/show', [], false).and_return( - mock(:source => %{ object :@comment\n attribute :content })) - @context = Context.new @context.stub(:instance_variable_get).with(:@user).and_return(@user) - @context.stub(:instance_variable_get).with(:@view_renderer).and_return(@view_renderer) @context.stub(:instance_variable_get).with(:@virtual_path).and_return('users/show') @context.stub(:instance_variable_get).with(:@_assigns).and_return({}) + @context.stub(:lookup_context).and_return(mock(:find_template => mock(:source => %{ object :@comment\n attribute :content }))) end test "compile and render deep nesting template" do diff --git a/test/non_restful_response_test.rb b/test/non_restful_response_test.rb index 8eadfcd..d0a7e83 100644 --- a/test/non_restful_response_test.rb +++ b/test/non_restful_response_test.rb @@ -3,18 +3,18 @@ require 'test_helper' class NonRestfulResponseTest < ActiveSupport::TestCase setup do RablFastJson::Library.reset_instance - + @user = User.new(1, 'foo', 'male') @user.stub_chain(:posts, :count).and_return(10) @user.stub(:respond_to?).with(:each).and_return(false) - + @context = Context.new @context.stub(:instance_variable_get).with(:@user).and_return(@user) - @context.stub(:instance_variable_get).with(:@view_renderer).and_return(mock()) @context.stub(:instance_variable_get).with(:@virtual_path).and_return('user/show') @context.stub(:instance_variable_get).with(:@_assigns).and_return({'user' => @user}) + @context.stub(:lookup_context) end - + test "compile and render non restful resource" do source = %{ object false @@ -23,13 +23,13 @@ class NonRestfulResponseTest < ActiveSupport::TestCase attributes :id, :name end } - + assert_equal(ActiveSupport::JSON.encode({ :post_count => 10, :user => { :id => 1, :name => 'foo' } - }), RablFastJson::Library.instance.get_rendered_template(source, @context)) + }), RablFastJson::Library.instance.get_rendered_template(source, @context)) end end \ No newline at end of file diff --git a/test/compiled_template_test.rb b/test/renderers/json_renderer_test.rb similarity index 66% rename from test/compiled_template_test.rb rename to test/renderers/json_renderer_test.rb index 3ad7ec1..4c25e8a 100644 --- a/test/compiled_template_test.rb +++ b/test/renderers/json_renderer_test.rb @@ -1,76 +1,80 @@ require 'test_helper' -class TestCompiledTemplate < ActiveSupport::TestCase +class TestJsonRenderer < ActiveSupport::TestCase setup do - @context = Context.new @data = User.new(1, 'foobar', 'male') @data.stub(:respond_to?).with(:each).and_return(false) + + @context = Context.new @context.stub(:instance_variable_get).with(:@data).and_return(@data) @context.stub(:instance_variable_get).with(:@_assigns).and_return({}) + @template = RablFastJson::CompiledTemplate.new - @template.context = @context @template.data = :@data end def render_json_output - RablFastJson::Renderers::JSON.new(@context).render(@template) + RablFastJson::Renderers::JSON.new(@context).render(@template).to_s end test "render object wth empty template" do @template.source = {} - assert_equal({}, @template.render) + assert_equal %q({}), render_json_output end test "render collection with empty template" do @context.stub(:instance_variable_get).with(:@data).and_return([@data]) @template.source = {} - assert_equal([{}], @template.render) + assert_equal %q([{}]), render_json_output end test "render single object attributes" do @template.source = { :id => :id, :name => :name } - assert_equal({ :id => 1, :name => 'foobar'}, @template.render) + assert_equal %q({"id":1,"name":"foobar"}), render_json_output end - test "render object as a child" do + test "render child with object association" do + @data.stub(:address).and_return(mock(:city => 'Paris')) + @template.source = { :address => { :_data => :address, :city => :city } } + assert_equal %q({"address":{"city":"Paris"}}), render_json_output + end + + test "render child with arbitrary data source" do @template.source = { :author => { :_data => :@data, :name => :name } } - assert_equal({ :author => { :name => 'foobar' } }, @template.render) + assert_equal %q({"author":{"name":"foobar"}}), render_json_output end test "render glued attributes from single object" do @template.source = { :_glue0 => { :_data => :@data, :name => :name } } - assert_equal({ :name => 'foobar' }, @template.render) + assert_equal %q({"name":"foobar"}), render_json_output end test "render collection with attributes" do @data = [User.new(1, 'foo', 'male'), User.new(2, 'bar', 'female')] @context.stub(:instance_variable_get).with(:@data).and_return(@data) @template.source = { :uid => :id, :name => :name, :gender => :sex } - assert_equal([ - { :uid => 1, :name => 'foo', :gender => 'male'}, - { :uid => 2, :name => 'bar', :gender => 'female'} - ], @template.render) + assert_equal %q([{"uid":1,"name":"foo","gender":"male"},{"uid":2,"name":"bar","gender":"female"}]), render_json_output end test "render node property" do - proc = lambda { |object| object.sex } - @template.source = { :sex => proc } - assert_equal({ :sex => 'male' }, @template.render) + proc = lambda { |object| object.name } + @template.source = { :name => proc } + assert_equal %q({"name":"foobar"}), render_json_output end test "render node property with true condition" do condition = lambda { |u| true } proc = lambda { |object| object.name } @template.source = { :name => [condition, proc] } - assert_equal({ :name => 'foobar' }, @template.render) + assert_equal %q({"name":"foobar"}), render_json_output end test "render node property with false condition" do condition = lambda { |u| false } proc = lambda { |object| object.name } @template.source = { :name => [condition, proc] } - assert_equal({}, @template.render) + assert_equal %q({}), render_json_output end test "partial should be evaluated at rendering time" do @@ -80,27 +84,27 @@ class TestCompiledTemplate < ActiveSupport::TestCase # Stub Library#get t = RablFastJson::CompiledTemplate.new - t.source, t.context = { :name => :name }, @context + t.source = { :name => :name } RablFastJson::Library.reset_instance RablFastJson::Library.instance.should_receive(:get).with('users/base').and_return(t) @template.data = false @template.source = { :user => ->(s) { partial('users/base', :object => @user) } } - assert_equal({ :user => { :name => 'foobar' } }, @template.render) + assert_equal %q({"user":{"name":"foobar"}}), render_json_output end - test "partial with nil values should raise an error" do + test "partial with no values should raise an error" do @template.data = false @template.source = { :user => ->(s) { partial('users/base') } } - assert_raises(RuntimeError) { @template.render } + assert_raises(RuntimeError) { render_json_output } end test "partial with empty values should not raise an error" do @template.data = false @template.source = { :users => ->(s) { partial('users/base', :object => []) } } - assert_equal({ :users => [] }, @template.render) + assert_equal %q({"users":[]}), render_json_output end end \ No newline at end of file diff --git a/test/test_helper.rb b/test/test_helper.rb index f315ce5..c9f4c64 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -35,16 +35,11 @@ class Context def initialize @_assigns = {} - @virtual_path = '/users' end - def set_assign(key, value) - @_assigns[key] = value - end - - def get_assign(key) - @_assigns[key] + def params + {} end end - + User = Struct.new(:id, :name, :sex) \ No newline at end of file