From a820e9774fe327c9756a145506b3e9fbe2e87637 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Fri, 23 Aug 2013 19:17:17 -0300 Subject: [PATCH] Add ArraySerializer's root and meta features --- lib/active_model/array_serializer.rb | 29 +++++- .../array_serializer/meta_test.rb | 53 +++++++++++ .../array_serializer/root_test.rb | 93 +++++++++++++++++++ .../serialize_test.rb} | 5 +- 4 files changed, 176 insertions(+), 4 deletions(-) create mode 100644 test/unit/active_model/array_serializer/meta_test.rb create mode 100644 test/unit/active_model/array_serializer/root_test.rb rename test/unit/active_model/{array_serializer_test.rb => array_serializer/serialize_test.rb} (88%) diff --git a/lib/active_model/array_serializer.rb b/lib/active_model/array_serializer.rb index 6a56262e..a078d0c6 100644 --- a/lib/active_model/array_serializer.rb +++ b/lib/active_model/array_serializer.rb @@ -1,10 +1,23 @@ module ActiveModel class ArraySerializer - def initialize(object, options={}) - @object = object - @options = options + class << self + attr_accessor :_root + + def root(root) + @_root = root + end + alias root= root end + def initialize(object, options={}) + @object = object + @options = options + @root = options[:root] || self.class._root + @meta_key = options[:meta_key] || :meta + @meta = options[@meta_key] + end + attr_accessor :object, :root, :meta_key, :meta + def serializable_array @object.map do |item| serializer = @options[:each_serializer] || Serializer.serializer_for(item) @@ -16,5 +29,15 @@ module ActiveModel end end alias serializable_object serializable_array + + def as_json(options={}) + if root = options[:root] || self.root + hash = { root.to_s => serializable_array } + hash[meta_key.to_s] = meta if meta + hash + else + serializable_array + end + end end end diff --git a/test/unit/active_model/array_serializer/meta_test.rb b/test/unit/active_model/array_serializer/meta_test.rb new file mode 100644 index 00000000..1f3e4ce8 --- /dev/null +++ b/test/unit/active_model/array_serializer/meta_test.rb @@ -0,0 +1,53 @@ +require 'test_helper' +require 'active_model/serializer' + +module ActiveModel + class ArraySerializer + class MetaTest < ActiveModel::TestCase + def setup + @profile1 = Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' }) + @profile2 = Profile.new({ name: 'Name 2', description: 'Description 2', comments: 'Comments 2' }) + @serializer = ArraySerializer.new([@profile1, @profile2], root: 'profiles') + end + + def test_meta + @serializer.meta = { 'total' => 10 } + + assert_equal({ + 'profiles' => [ + { + 'name' => 'Name 1', + 'description' => 'Description 1' + }, { + 'name' => 'Name 2', + 'description' => 'Description 2' + } + ], + 'meta' => { + 'total' => 10 + } + }, @serializer.as_json) + end + + def test_meta_using_meta_key + @serializer.meta_key = :my_meta + @serializer.meta = { 'total' => 10 } + + assert_equal({ + 'profiles' => [ + { + 'name' => 'Name 1', + 'description' => 'Description 1' + }, { + 'name' => 'Name 2', + 'description' => 'Description 2' + } + ], + 'my_meta' => { + 'total' => 10 + } + }, @serializer.as_json) + end + end + end +end diff --git a/test/unit/active_model/array_serializer/root_test.rb b/test/unit/active_model/array_serializer/root_test.rb new file mode 100644 index 00000000..372d1833 --- /dev/null +++ b/test/unit/active_model/array_serializer/root_test.rb @@ -0,0 +1,93 @@ +require 'test_helper' +require 'active_model/serializer' + +module ActiveModel + class ArraySerializer + class RootAsOptionTest < ActiveModel::TestCase + def setup + @old_root = ArraySerializer._root + @profile1 = Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' }) + @profile2 = Profile.new({ name: 'Name 2', description: 'Description 2', comments: 'Comments 2' }) + @serializer = ArraySerializer.new([@profile1, @profile2], root: 'initialize') + end + + def teardown + ArraySerializer._root = @old_root + end + + def test_root_is_not_displayed_using_serializable_array + assert_equal([ + { 'name' => 'Name 1', 'description' => 'Description 1' }, + { 'name' => 'Name 2', 'description' => 'Description 2' } + ], @serializer.serializable_array) + end + + def test_root_using_as_json + assert_equal({ + 'initialize' => [ + { 'name' => 'Name 1', 'description' => 'Description 1' }, + { 'name' => 'Name 2', 'description' => 'Description 2' } + ] + }, @serializer.as_json) + end + + def test_root_as_argument_takes_precedence + assert_equal({ + 'argument' => [ + { 'name' => 'Name 1', 'description' => 'Description 1' }, + { 'name' => 'Name 2', 'description' => 'Description 2' } + ] + }, @serializer.as_json(root: 'argument')) + end + end + + class RootInSerializerTest < ActiveModel::TestCase + def setup + @old_root = ArraySerializer._root + ArraySerializer._root = 'in_serializer' + @profile1 = Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' }) + @profile2 = Profile.new({ name: 'Name 2', description: 'Description 2', comments: 'Comments 2' }) + @serializer = ArraySerializer.new([@profile1, @profile2]) + @rooted_serializer = ArraySerializer.new([@profile1, @profile2], root: :initialize) + end + + def teardown + ArraySerializer._root = @old_root + end + + def test_root_is_not_displayed_using_serializable_hash + assert_equal([ + { 'name' => 'Name 1', 'description' => 'Description 1' }, + { 'name' => 'Name 2', 'description' => 'Description 2' } + ], @serializer.serializable_array) + end + + def test_root_using_as_json + assert_equal({ + 'in_serializer' => [ + { 'name' => 'Name 1', 'description' => 'Description 1' }, + { 'name' => 'Name 2', 'description' => 'Description 2' } + ] + }, @serializer.as_json) + end + + def test_root_in_initializer_takes_precedence + assert_equal({ + 'initialize' => [ + { 'name' => 'Name 1', 'description' => 'Description 1' }, + { 'name' => 'Name 2', 'description' => 'Description 2' } + ] + }, @rooted_serializer.as_json) + end + + def test_root_as_argument_takes_precedence + assert_equal({ + 'argument' => [ + { 'name' => 'Name 1', 'description' => 'Description 1' }, + { 'name' => 'Name 2', 'description' => 'Description 2' } + ] + }, @rooted_serializer.as_json(root: :argument)) + end + end + end +end diff --git a/test/unit/active_model/array_serializer_test.rb b/test/unit/active_model/array_serializer/serialize_test.rb similarity index 88% rename from test/unit/active_model/array_serializer_test.rb rename to test/unit/active_model/array_serializer/serialize_test.rb index 25ede76b..ad7a935a 100644 --- a/test/unit/active_model/array_serializer_test.rb +++ b/test/unit/active_model/array_serializer/serialize_test.rb @@ -3,7 +3,7 @@ require 'active_model/serializer' module ActiveModel class ArraySerializer - class Test < ActiveModel::TestCase + class SerializeTest < ActiveModel::TestCase def setup array = [1, 2, 3] @serializer = ActiveModel::Serializer.serializer_for(array).new(array) @@ -15,6 +15,7 @@ module ActiveModel def test_array_serializer_serializes_simple_objects assert_equal [1, 2, 3], @serializer.serializable_array + assert_equal [1, 2, 3], @serializer.as_json end def test_array_serializer_serializes_models @@ -26,6 +27,7 @@ module ActiveModel {'name' => 'Name 2', 'description' => 'Description 2'}] assert_equal expected, serializer.serializable_array + assert_equal expected, serializer.as_json end def test_array_serializers_each_serializer @@ -37,6 +39,7 @@ module ActiveModel {'name' => 'Name 2', 'description' => 'Description 2'}] assert_equal expected, serializer.serializable_array + assert_equal expected, serializer.as_json end end end