active_model_serializers 0.8.3 → 0.10.0.rc2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/.travis.yml +18 -20
  4. data/CHANGELOG.md +8 -67
  5. data/CONTRIBUTING.md +31 -0
  6. data/Gemfile +14 -1
  7. data/{MIT-LICENSE.txt → LICENSE.txt} +3 -2
  8. data/README.md +169 -495
  9. data/Rakefile +6 -12
  10. data/active_model_serializers.gemspec +21 -19
  11. data/lib/action_controller/serialization.rb +36 -27
  12. data/lib/active_model/serializer/adapter/flatten_json.rb +12 -0
  13. data/lib/active_model/serializer/adapter/fragment_cache.rb +78 -0
  14. data/lib/active_model/serializer/adapter/json/fragment_cache.rb +15 -0
  15. data/lib/active_model/serializer/adapter/json.rb +50 -0
  16. data/lib/active_model/serializer/adapter/json_api/fragment_cache.rb +23 -0
  17. data/lib/active_model/serializer/adapter/json_api.rb +156 -0
  18. data/lib/active_model/serializer/adapter/null.rb +11 -0
  19. data/lib/active_model/serializer/adapter.rb +96 -0
  20. data/lib/active_model/serializer/array_serializer.rb +35 -0
  21. data/lib/active_model/serializer/configuration.rb +13 -0
  22. data/lib/active_model/serializer/fieldset.rb +40 -0
  23. data/lib/active_model/serializer/railtie.rb +8 -0
  24. data/lib/active_model/{serializers → serializer}/version.rb +1 -1
  25. data/lib/active_model/serializer.rb +177 -440
  26. data/lib/active_model_serializers.rb +10 -86
  27. data/lib/generators/serializer/USAGE +0 -3
  28. data/lib/generators/serializer/resource_override.rb +12 -0
  29. data/lib/generators/serializer/serializer_generator.rb +1 -6
  30. data/lib/generators/serializer/templates/serializer.rb +2 -13
  31. data/test/action_controller/adapter_selector_test.rb +53 -0
  32. data/test/action_controller/explicit_serializer_test.rb +134 -0
  33. data/test/action_controller/json_api_linked_test.rb +179 -0
  34. data/test/action_controller/rescue_from_test.rb +32 -0
  35. data/test/{serialization_scope_name_test.rb → action_controller/serialization_scope_name_test.rb} +7 -11
  36. data/test/action_controller/serialization_test.rb +383 -0
  37. data/test/adapter/fragment_cache_test.rb +27 -0
  38. data/test/adapter/json/belongs_to_test.rb +48 -0
  39. data/test/adapter/json/collection_test.rb +73 -0
  40. data/test/adapter/json/has_many_test.rb +36 -0
  41. data/test/adapter/json_api/belongs_to_test.rb +157 -0
  42. data/test/adapter/json_api/collection_test.rb +96 -0
  43. data/test/adapter/json_api/has_many_embed_ids_test.rb +45 -0
  44. data/test/adapter/json_api/has_many_explicit_serializer_test.rb +98 -0
  45. data/test/adapter/json_api/has_many_test.rb +110 -0
  46. data/test/adapter/json_api/has_one_test.rb +61 -0
  47. data/test/adapter/json_api/linked_test.rb +283 -0
  48. data/test/adapter/json_test.rb +34 -0
  49. data/test/adapter/null_test.rb +25 -0
  50. data/test/adapter_test.rb +43 -0
  51. data/test/array_serializer_test.rb +31 -63
  52. data/test/fixtures/poro.rb +230 -0
  53. data/test/generators/scaffold_controller_generator_test.rb +24 -0
  54. data/test/{generators_test.rb → generators/serializer_generator_test.rb} +2 -36
  55. data/test/serializers/adapter_for_test.rb +50 -0
  56. data/test/serializers/associations_test.rb +127 -0
  57. data/test/serializers/attribute_test.rb +38 -0
  58. data/test/serializers/attributes_test.rb +63 -0
  59. data/test/serializers/cache_test.rb +138 -0
  60. data/test/serializers/configuration_test.rb +15 -0
  61. data/test/serializers/fieldset_test.rb +26 -0
  62. data/test/serializers/meta_test.rb +107 -0
  63. data/test/serializers/options_test.rb +21 -0
  64. data/test/serializers/serializer_for_test.rb +65 -0
  65. data/test/serializers/urls_test.rb +26 -0
  66. data/test/test_helper.rb +28 -16
  67. metadata +109 -43
  68. data/DESIGN.textile +0 -586
  69. data/Gemfile.edge +0 -9
  70. data/bench/perf.rb +0 -43
  71. data/cruft.md +0 -19
  72. data/lib/active_model/array_serializer.rb +0 -104
  73. data/lib/active_model/serializer/associations.rb +0 -233
  74. data/lib/active_record/serializer_override.rb +0 -16
  75. data/lib/generators/resource_override.rb +0 -13
  76. data/test/association_test.rb +0 -592
  77. data/test/caching_test.rb +0 -96
  78. data/test/no_serialization_scope_test.rb +0 -34
  79. data/test/serialization_test.rb +0 -392
  80. data/test/serializer_support_test.rb +0 -51
  81. data/test/serializer_test.rb +0 -1465
  82. data/test/test_fakes.rb +0 -217
@@ -0,0 +1,230 @@
1
+ class Model
2
+ FILE_DIGEST = Digest::MD5.hexdigest(File.open(__FILE__).read)
3
+
4
+ def self.model_name
5
+ @_model_name ||= ActiveModel::Name.new(self)
6
+ end
7
+
8
+ def initialize(hash={})
9
+ @attributes = hash
10
+ end
11
+
12
+ def cache_key
13
+ "#{self.class.name.downcase}/#{self.id}-#{self.updated_at}"
14
+ end
15
+
16
+ def cache_key_with_digest
17
+ "#{cache_key}/#{FILE_DIGEST}"
18
+ end
19
+
20
+ def updated_at
21
+ @attributes[:updated_at] ||= DateTime.now.to_time.to_i
22
+ end
23
+
24
+ def read_attribute_for_serialization(name)
25
+ if name == :id || name == 'id'
26
+ id
27
+ else
28
+ @attributes[name]
29
+ end
30
+ end
31
+
32
+ def id
33
+ @attributes[:id] || @attributes['id'] || object_id
34
+ end
35
+
36
+ def to_param
37
+ id
38
+ end
39
+
40
+ def method_missing(meth, *args)
41
+ if meth.to_s =~ /^(.*)=$/
42
+ @attributes[$1.to_sym] = args[0]
43
+ elsif @attributes.key?(meth)
44
+ @attributes[meth]
45
+ else
46
+ super
47
+ end
48
+ end
49
+ end
50
+
51
+ class Profile < Model
52
+ end
53
+
54
+ class ProfileSerializer < ActiveModel::Serializer
55
+ attributes :name, :description
56
+
57
+ urls :posts, :comments
58
+
59
+ def arguments_passed_in?
60
+ options[:my_options] == :accessible
61
+ end
62
+ end
63
+
64
+ class ProfilePreviewSerializer < ActiveModel::Serializer
65
+ attributes :name
66
+
67
+ urls :posts, :comments
68
+ end
69
+
70
+ Post = Class.new(Model)
71
+ Like = Class.new(Model)
72
+ Comment = Class.new(Model)
73
+ Author = Class.new(Model)
74
+ Bio = Class.new(Model)
75
+ Blog = Class.new(Model)
76
+ Role = Class.new(Model)
77
+ User = Class.new(Model)
78
+ Location = Class.new(Model)
79
+ Place = Class.new(Model)
80
+
81
+ module Spam; end
82
+ Spam::UnrelatedLink = Class.new(Model)
83
+
84
+ PostSerializer = Class.new(ActiveModel::Serializer) do
85
+ cache key:'post', expires_in: 0.1, skip_digest: true
86
+ attributes :id, :title, :body
87
+
88
+ has_many :comments
89
+ belongs_to :blog
90
+ belongs_to :author
91
+ url :comments
92
+
93
+ def blog
94
+ Blog.new(id: 999, name: "Custom blog")
95
+ end
96
+
97
+ def custom_options
98
+ options
99
+ end
100
+ end
101
+
102
+ SpammyPostSerializer = Class.new(ActiveModel::Serializer) do
103
+ attributes :id
104
+ has_many :related
105
+
106
+ def self.root_name
107
+ 'posts'
108
+ end
109
+ end
110
+
111
+ CommentSerializer = Class.new(ActiveModel::Serializer) do
112
+ cache expires_in: 1.day, skip_digest: true
113
+ attributes :id, :body
114
+
115
+ belongs_to :post
116
+ belongs_to :author
117
+
118
+ def custom_options
119
+ options
120
+ end
121
+ end
122
+
123
+ AuthorSerializer = Class.new(ActiveModel::Serializer) do
124
+ cache key:'writer', skip_digest: true
125
+ attributes :id, :name
126
+
127
+ has_many :posts, embed: :ids
128
+ has_many :roles, embed: :ids
129
+ has_one :bio
130
+ end
131
+
132
+ RoleSerializer = Class.new(ActiveModel::Serializer) do
133
+ cache only: [:name], skip_digest: true
134
+ attributes :id, :name, :description, :slug
135
+
136
+ def slug
137
+ "#{name}-#{id}"
138
+ end
139
+
140
+ belongs_to :author
141
+ end
142
+
143
+ LikeSerializer = Class.new(ActiveModel::Serializer) do
144
+ attributes :id, :time
145
+
146
+ belongs_to :post
147
+ end
148
+
149
+ LocationSerializer = Class.new(ActiveModel::Serializer) do
150
+ cache only: [:place], skip_digest: true
151
+ attributes :id, :lat, :lng
152
+
153
+ belongs_to :place
154
+
155
+ def place
156
+ 'Nowhere'
157
+ end
158
+ end
159
+
160
+ PlaceSerializer = Class.new(ActiveModel::Serializer) do
161
+ attributes :id, :name
162
+
163
+ has_many :locations
164
+ end
165
+
166
+ BioSerializer = Class.new(ActiveModel::Serializer) do
167
+ cache except: [:content], skip_digest: true
168
+ attributes :id, :content, :rating
169
+
170
+ belongs_to :author
171
+ end
172
+
173
+ BlogSerializer = Class.new(ActiveModel::Serializer) do
174
+ cache key: 'blog'
175
+ attributes :id, :name
176
+
177
+ belongs_to :writer
178
+ has_many :articles
179
+ end
180
+
181
+ PaginatedSerializer = Class.new(ActiveModel::Serializer::ArraySerializer) do
182
+ def json_key
183
+ 'paginated'
184
+ end
185
+ end
186
+
187
+ AlternateBlogSerializer = Class.new(ActiveModel::Serializer) do
188
+ attribute :id
189
+ attribute :name, key: :title
190
+ end
191
+
192
+ CustomBlogSerializer = Class.new(ActiveModel::Serializer) do
193
+ attribute :id
194
+ attribute :special_attribute
195
+
196
+ has_many :articles
197
+ end
198
+
199
+ CommentPreviewSerializer = Class.new(ActiveModel::Serializer) do
200
+ attributes :id
201
+
202
+ belongs_to :post
203
+ end
204
+
205
+ AuthorPreviewSerializer = Class.new(ActiveModel::Serializer) do
206
+ attributes :id
207
+
208
+ has_many :posts
209
+ end
210
+
211
+ PostPreviewSerializer = Class.new(ActiveModel::Serializer) do
212
+ def self.root_name
213
+ 'posts'
214
+ end
215
+
216
+ attributes :title, :body, :id
217
+
218
+ has_many :comments, serializer: CommentPreviewSerializer
219
+ belongs_to :author, serializer: AuthorPreviewSerializer
220
+ end
221
+
222
+ Spam::UnrelatedLinkSerializer = Class.new(ActiveModel::Serializer) do
223
+ attributes :id
224
+ end
225
+
226
+ RaiseErrorSerializer = Class.new(ActiveModel::Serializer) do
227
+ def json_key
228
+ raise StandardError, 'Intentional error for rescue_from test'
229
+ end
230
+ end
@@ -0,0 +1,24 @@
1
+ require 'test_helper'
2
+ # require 'active_model/serializer/railtie'
3
+
4
+ class ResourceGeneratorTest < Rails::Generators::TestCase
5
+ destination File.expand_path('../../../tmp/generators', __FILE__)
6
+ setup :prepare_destination, :copy_routes
7
+
8
+ tests Rails::Generators::ResourceGenerator
9
+ arguments %w(account)
10
+
11
+ def test_serializer_file_is_generated
12
+ run_generator
13
+
14
+ assert_file 'app/serializers/account_serializer.rb', /class AccountSerializer < ActiveModel::Serializer/
15
+ end
16
+
17
+ private
18
+
19
+ def copy_routes
20
+ config_dir = File.join(destination_root, 'config')
21
+ FileUtils.mkdir_p(config_dir)
22
+ File.write(File.join(config_dir, 'routes.rb'), 'Rails.application.routes.draw { }')
23
+ end
24
+ end
@@ -1,18 +1,8 @@
1
1
  require 'test_helper'
2
-
3
- class Foo < Rails::Application
4
- if Rails.version.to_s.start_with? '4'
5
- config.eager_load = false
6
- config.secret_key_base = 'abc123'
7
- end
8
- end
9
-
10
- Rails.application.load_generators
11
-
12
2
  require 'generators/serializer/serializer_generator'
13
3
 
14
4
  class SerializerGeneratorTest < Rails::Generators::TestCase
15
- destination File.expand_path("../tmp", __FILE__)
5
+ destination File.expand_path("../../../tmp/generators", __FILE__)
16
6
  setup :prepare_destination
17
7
 
18
8
  tests Rails::Generators::SerializerGenerator
@@ -36,30 +26,6 @@ class SerializerGeneratorTest < Rails::Generators::TestCase
36
26
  Object.send :remove_const, :ApplicationSerializer
37
27
  end
38
28
 
39
- def test_serializer_gets_id
40
- run_generator
41
-
42
- assert_file "app/serializers/account_serializer.rb" do |content|
43
- if RUBY_VERSION =~ /1.8/
44
- assert_match /def id/, content
45
- else
46
- assert_no_match /def id/, content
47
- end
48
- end
49
- end
50
-
51
- # def test_uses_namespace_application_serializer_if_one_exists
52
- # Object.const_set(:SerializerNamespace, Module.new)
53
- # SerializerNamespace.const_set(:ApplicationSerializer, Class.new)
54
- # Rails::Generators.namespace = SerializerNamespace
55
- # run_generator
56
- # assert_file "app/serializers/serializer_namespace/account_serializer.rb",
57
- # /module SerializerNamespace\n class AccountSerializer < ApplicationSerializer/
58
- # ensure
59
- # Object.send :remove_const, :SerializerNamespace
60
- # Rails::Generators.namespace = nil
61
- # end
62
-
63
29
  def test_uses_given_parent
64
30
  Object.const_set(:ApplicationSerializer, Class.new)
65
31
  run_generator ["Account", "--parent=MySerializer"]
@@ -72,7 +38,7 @@ class SerializerGeneratorTest < Rails::Generators::TestCase
72
38
  run_generator
73
39
  assert_file "app/serializers/account_serializer.rb" do |serializer|
74
40
  assert_match(/^ attributes :id, :name, :description$/, serializer)
75
- assert_match(/^ has_one :business$/, serializer)
41
+ assert_match(/^ attribute :business$/, serializer)
76
42
  end
77
43
  end
78
44
 
@@ -0,0 +1,50 @@
1
+ module ActiveModel
2
+ class Serializer
3
+ class AdapterForTest < Minitest::Test
4
+ def setup
5
+ @previous_adapter = ActiveModel::Serializer.config.adapter
6
+ end
7
+
8
+ def teardown
9
+ ActiveModel::Serializer.config.adapter = @previous_adapter
10
+ end
11
+
12
+ def test_returns_default_adapter
13
+ adapter = ActiveModel::Serializer.adapter
14
+ assert_equal ActiveModel::Serializer::Adapter::FlattenJson, adapter
15
+ end
16
+
17
+ def test_overwrite_adapter_with_symbol
18
+ ActiveModel::Serializer.config.adapter = :null
19
+
20
+ adapter = ActiveModel::Serializer.adapter
21
+ assert_equal ActiveModel::Serializer::Adapter::Null, adapter
22
+ ensure
23
+
24
+ end
25
+
26
+ def test_overwrite_adapter_with_class
27
+ ActiveModel::Serializer.config.adapter = ActiveModel::Serializer::Adapter::Null
28
+
29
+ adapter = ActiveModel::Serializer.adapter
30
+ assert_equal ActiveModel::Serializer::Adapter::Null, adapter
31
+ end
32
+
33
+ def test_raises_exception_if_invalid_symbol_given
34
+ ActiveModel::Serializer.config.adapter = :unknown
35
+
36
+ assert_raises ArgumentError do
37
+ ActiveModel::Serializer.adapter
38
+ end
39
+ end
40
+
41
+ def test_raises_exception_if_it_does_not_know_hot_to_infer_adapter
42
+ ActiveModel::Serializer.config.adapter = 42
43
+
44
+ assert_raises ArgumentError do
45
+ ActiveModel::Serializer.adapter
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,127 @@
1
+ require 'test_helper'
2
+
3
+ module ActiveModel
4
+ class Serializer
5
+ class AssociationsTest < Minitest::Test
6
+ class Model
7
+ def initialize(hash={})
8
+ @attributes = hash
9
+ end
10
+
11
+ def read_attribute_for_serialization(name)
12
+ @attributes[name]
13
+ end
14
+
15
+ def method_missing(meth, *args)
16
+ if meth.to_s =~ /^(.*)=$/
17
+ @attributes[$1.to_sym] = args[0]
18
+ elsif @attributes.key?(meth)
19
+ @attributes[meth]
20
+ else
21
+ super
22
+ end
23
+ end
24
+ end
25
+
26
+ def setup
27
+ @author = Author.new(name: 'Steve K.')
28
+ @author.bio = nil
29
+ @author.roles = []
30
+ @blog = Blog.new({ name: 'AMS Blog' })
31
+ @post = Post.new({ title: 'New Post', body: 'Body' })
32
+ @comment = Comment.new({ id: 1, body: 'ZOMG A COMMENT' })
33
+ @post.comments = [@comment]
34
+ @post.blog = @blog
35
+ @comment.post = @post
36
+ @comment.author = nil
37
+ @post.author = @author
38
+ @author.posts = [@post]
39
+
40
+ @post_serializer = PostSerializer.new(@post, {custom_options: true})
41
+ @author_serializer = AuthorSerializer.new(@author)
42
+ @comment_serializer = CommentSerializer.new(@comment)
43
+ end
44
+
45
+ def test_has_many_and_has_one
46
+ assert_equal(
47
+ { posts: { type: :has_many, association_options: { embed: :ids } },
48
+ roles: { type: :has_many, association_options: { embed: :ids } },
49
+ bio: { type: :has_one, association_options: {} } },
50
+ @author_serializer.class._associations
51
+ )
52
+ @author_serializer.each_association do |name, serializer, options|
53
+ if name == :posts
54
+ assert_equal({embed: :ids}, options)
55
+ assert_kind_of(ActiveModel::Serializer.config.array_serializer, serializer)
56
+ elsif name == :bio
57
+ assert_equal({}, options)
58
+ assert_nil serializer
59
+ elsif name == :roles
60
+ assert_equal({embed: :ids}, options)
61
+ assert_kind_of(ActiveModel::Serializer.config.array_serializer, serializer)
62
+ else
63
+ flunk "Unknown association: #{name}"
64
+ end
65
+ end
66
+ end
67
+
68
+ def test_serializer_options_are_passed_into_associations_serializers
69
+ @post_serializer.each_association do |name, association|
70
+ if name == :comments
71
+ assert association.first.custom_options[:custom_options]
72
+ end
73
+ end
74
+ end
75
+
76
+ def test_belongs_to
77
+ assert_equal(
78
+ { post: { type: :belongs_to, association_options: {} },
79
+ author: { type: :belongs_to, association_options: {} } },
80
+ @comment_serializer.class._associations
81
+ )
82
+ @comment_serializer.each_association do |name, serializer, options|
83
+ if name == :post
84
+ assert_equal({}, options)
85
+ assert_kind_of(PostSerializer, serializer)
86
+ elsif name == :author
87
+ assert_equal({}, options)
88
+ assert_nil serializer
89
+ else
90
+ flunk "Unknown association: #{name}"
91
+ end
92
+ end
93
+ end
94
+
95
+ def test_belongs_to_with_custom_method
96
+ blog_is_present = false
97
+
98
+ @post_serializer.each_association do |name, serializer, options|
99
+ blog_is_present = true if name == :blog
100
+ end
101
+
102
+ assert blog_is_present
103
+ end
104
+
105
+ def test_associations_inheritance
106
+ inherited_klass = Class.new(PostSerializer)
107
+
108
+ assert_equal(PostSerializer._associations, inherited_klass._associations)
109
+ end
110
+
111
+ def test_associations_inheritance_with_new_association
112
+ inherited_klass = Class.new(PostSerializer) do
113
+ has_many :top_comments, serializer: CommentSerializer
114
+ end
115
+ expected_associations = PostSerializer._associations.merge(
116
+ top_comments: {
117
+ type: :has_many,
118
+ association_options: {
119
+ serializer: CommentSerializer
120
+ }
121
+ }
122
+ )
123
+ assert_equal(inherited_klass._associations, expected_associations)
124
+ end
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,38 @@
1
+ require 'test_helper'
2
+
3
+ module ActiveModel
4
+ class Serializer
5
+ class AttributeTest < Minitest::Test
6
+ def setup
7
+ @blog = Blog.new({ id: 1, name: 'AMS Hints' })
8
+ @blog_serializer = AlternateBlogSerializer.new(@blog)
9
+ end
10
+
11
+ def test_attributes_definition
12
+ assert_equal([:id, :title],
13
+ @blog_serializer.class._attributes)
14
+ end
15
+
16
+ def test_json_serializable_hash
17
+ adapter = ActiveModel::Serializer::Adapter::Json.new(@blog_serializer)
18
+ assert_equal({alternate_blog: { id:1, title:"AMS Hints"}}, adapter.serializable_hash)
19
+ end
20
+
21
+ def test_attribute_inheritance_with_key
22
+ inherited_klass = Class.new(AlternateBlogSerializer)
23
+ blog_serializer = inherited_klass.new(@blog)
24
+ adapter = ActiveModel::Serializer::Adapter::FlattenJson.new(blog_serializer)
25
+ assert_equal({:id=>1, :title=>"AMS Hints"}, adapter.serializable_hash)
26
+ end
27
+
28
+ def test_multiple_calls_with_the_same_attribute
29
+ serializer_class = Class.new(ActiveModel::Serializer) do
30
+ attribute :title
31
+ attribute :title
32
+ end
33
+
34
+ assert_equal([:title], serializer_class._attributes)
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,63 @@
1
+ require 'test_helper'
2
+
3
+ module ActiveModel
4
+ class Serializer
5
+ class AttributesTest < Minitest::Test
6
+ def setup
7
+ @profile = Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' })
8
+ @profile_serializer = ProfileSerializer.new(@profile)
9
+ @comment = Comment.new(id: 1, body: "ZOMG!!", date: "2015")
10
+ @serializer_klass = Class.new(CommentSerializer)
11
+ @serializer_klass_with_new_attributes = Class.new(CommentSerializer) do
12
+ attributes :date, :likes
13
+ end
14
+ end
15
+
16
+ def test_attributes_definition
17
+ assert_equal([:name, :description],
18
+ @profile_serializer.class._attributes)
19
+ end
20
+
21
+ def test_attributes_with_fields_option
22
+ assert_equal({name: 'Name 1'},
23
+ @profile_serializer.attributes(fields: [:name]))
24
+ end
25
+
26
+ def test_required_fields
27
+ assert_equal({name: 'Name 1', description: 'Description 1'},
28
+ @profile_serializer.attributes(fields: [:name, :description], required_fields: [:name]))
29
+
30
+ end
31
+
32
+ def test_attributes_inheritance_definition
33
+ assert_equal([:id, :body], @serializer_klass._attributes)
34
+ end
35
+
36
+ def test_attributes_inheritance
37
+ serializer = @serializer_klass.new(@comment)
38
+ assert_equal({id: 1, body: "ZOMG!!"},
39
+ serializer.attributes)
40
+ end
41
+
42
+ def test_attribute_inheritance_with_new_attribute_definition
43
+ assert_equal([:id, :body, :date, :likes], @serializer_klass_with_new_attributes._attributes)
44
+ assert_equal([:id, :body], CommentSerializer._attributes)
45
+ end
46
+
47
+ def test_attribute_inheritance_with_new_attribute
48
+ serializer = @serializer_klass_with_new_attributes.new(@comment)
49
+ assert_equal({id: 1, body: "ZOMG!!", date: "2015", likes: nil},
50
+ serializer.attributes)
51
+ end
52
+
53
+ def test_multiple_calls_with_the_same_attribute
54
+ serializer_class = Class.new(ActiveModel::Serializer) do
55
+ attributes :id, :title
56
+ attributes :id, :title, :title, :body
57
+ end
58
+
59
+ assert_equal([:id, :title, :body], serializer_class._attributes)
60
+ end
61
+ end
62
+ end
63
+ end