active_model_serializers 0.10.0 → 0.10.5

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 (161) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +2 -4
  3. data/.travis.yml +17 -5
  4. data/CHANGELOG.md +112 -2
  5. data/CODE_OF_CONDUCT.md +74 -0
  6. data/Gemfile +5 -2
  7. data/README.md +166 -26
  8. data/Rakefile +3 -3
  9. data/active_model_serializers.gemspec +21 -24
  10. data/appveyor.yml +9 -3
  11. data/docs/README.md +2 -1
  12. data/docs/general/adapters.md +4 -2
  13. data/docs/general/caching.md +7 -1
  14. data/docs/general/configuration_options.md +70 -1
  15. data/docs/general/deserialization.md +1 -1
  16. data/docs/general/fields.md +31 -0
  17. data/docs/general/logging.md +7 -0
  18. data/docs/general/rendering.md +44 -20
  19. data/docs/general/serializers.md +100 -11
  20. data/docs/howto/add_pagination_links.md +15 -16
  21. data/docs/howto/add_relationship_links.md +140 -0
  22. data/docs/howto/add_root_key.md +4 -0
  23. data/docs/howto/grape_integration.md +42 -0
  24. data/docs/howto/outside_controller_use.md +12 -4
  25. data/docs/howto/passing_arbitrary_options.md +2 -2
  26. data/docs/howto/serialize_poro.md +46 -5
  27. data/docs/howto/test.md +2 -0
  28. data/docs/howto/upgrade_from_0_8_to_0_10.md +265 -0
  29. data/docs/integrations/ember-and-json-api.md +64 -32
  30. data/docs/jsonapi/schema.md +1 -1
  31. data/lib/action_controller/serialization.rb +13 -3
  32. data/lib/active_model/serializer/adapter/base.rb +2 -0
  33. data/lib/active_model/serializer/array_serializer.rb +8 -5
  34. data/lib/active_model/serializer/association.rb +19 -4
  35. data/lib/active_model/serializer/belongs_to_reflection.rb +0 -3
  36. data/lib/active_model/serializer/collection_serializer.rb +35 -12
  37. data/lib/active_model/serializer/{associations.rb → concerns/associations.rb} +13 -11
  38. data/lib/active_model/serializer/{attributes.rb → concerns/attributes.rb} +1 -1
  39. data/lib/active_model/serializer/{caching.rb → concerns/caching.rb} +72 -113
  40. data/lib/active_model/serializer/{configuration.rb → concerns/configuration.rb} +25 -1
  41. data/lib/active_model/serializer/{links.rb → concerns/links.rb} +0 -0
  42. data/lib/active_model/serializer/{meta.rb → concerns/meta.rb} +0 -0
  43. data/lib/active_model/serializer/{type.rb → concerns/type.rb} +0 -0
  44. data/lib/active_model/serializer/error_serializer.rb +11 -7
  45. data/lib/active_model/serializer/errors_serializer.rb +25 -20
  46. data/lib/active_model/serializer/has_many_reflection.rb +0 -3
  47. data/lib/active_model/serializer/has_one_reflection.rb +0 -3
  48. data/lib/active_model/serializer/lint.rb +134 -130
  49. data/lib/active_model/serializer/reflection.rb +37 -21
  50. data/lib/active_model/serializer/version.rb +1 -1
  51. data/lib/active_model/serializer.rb +76 -37
  52. data/lib/active_model_serializers/adapter/attributes.rb +3 -66
  53. data/lib/active_model_serializers/adapter/base.rb +39 -39
  54. data/lib/active_model_serializers/adapter/json_api/deserialization.rb +1 -1
  55. data/lib/active_model_serializers/adapter/json_api/link.rb +1 -1
  56. data/lib/active_model_serializers/adapter/json_api/pagination_links.rb +8 -1
  57. data/lib/active_model_serializers/adapter/json_api/relationship.rb +30 -19
  58. data/lib/active_model_serializers/adapter/json_api/resource_identifier.rb +23 -9
  59. data/lib/active_model_serializers/adapter/json_api.rb +44 -43
  60. data/lib/active_model_serializers/adapter.rb +6 -0
  61. data/lib/active_model_serializers/deprecate.rb +1 -2
  62. data/lib/active_model_serializers/deserialization.rb +2 -0
  63. data/lib/active_model_serializers/lookup_chain.rb +80 -0
  64. data/lib/active_model_serializers/model.rb +108 -28
  65. data/lib/active_model_serializers/railtie.rb +3 -1
  66. data/lib/active_model_serializers/register_jsonapi_renderer.rb +44 -31
  67. data/lib/active_model_serializers/serializable_resource.rb +6 -5
  68. data/lib/active_model_serializers/serialization_context.rb +10 -3
  69. data/lib/active_model_serializers/test/schema.rb +2 -2
  70. data/lib/active_model_serializers.rb +15 -0
  71. data/lib/generators/rails/resource_override.rb +1 -1
  72. data/lib/generators/rails/serializer_generator.rb +4 -4
  73. data/lib/grape/active_model_serializers.rb +7 -5
  74. data/lib/grape/formatters/active_model_serializers.rb +19 -2
  75. data/lib/grape/helpers/active_model_serializers.rb +1 -0
  76. data/test/action_controller/adapter_selector_test.rb +14 -5
  77. data/test/action_controller/explicit_serializer_test.rb +5 -4
  78. data/test/action_controller/json/include_test.rb +106 -27
  79. data/test/action_controller/json_api/errors_test.rb +8 -9
  80. data/test/action_controller/json_api/fields_test.rb +66 -0
  81. data/test/action_controller/json_api/linked_test.rb +29 -24
  82. data/test/action_controller/json_api/pagination_test.rb +19 -19
  83. data/test/action_controller/json_api/transform_test.rb +11 -3
  84. data/test/action_controller/lookup_proc_test.rb +49 -0
  85. data/test/action_controller/namespace_lookup_test.rb +232 -0
  86. data/test/action_controller/serialization_scope_name_test.rb +12 -6
  87. data/test/action_controller/serialization_test.rb +12 -9
  88. data/test/active_model_serializers/json_pointer_test.rb +15 -13
  89. data/test/active_model_serializers/model_test.rb +137 -4
  90. data/test/active_model_serializers/railtie_test_isolated.rb +12 -7
  91. data/test/active_model_serializers/register_jsonapi_renderer_test_isolated.rb +161 -0
  92. data/test/active_model_serializers/serialization_context_test_isolated.rb +23 -10
  93. data/test/active_model_serializers/test/schema_test.rb +3 -2
  94. data/test/adapter/attributes_test.rb +40 -0
  95. data/test/adapter/json/collection_test.rb +14 -0
  96. data/test/adapter/json/has_many_test.rb +10 -2
  97. data/test/adapter/json/transform_test.rb +15 -15
  98. data/test/adapter/json_api/collection_test.rb +4 -3
  99. data/test/adapter/json_api/errors_test.rb +17 -19
  100. data/test/adapter/json_api/fields_test.rb +12 -3
  101. data/test/adapter/json_api/has_many_test.rb +49 -20
  102. data/test/adapter/json_api/include_data_if_sideloaded_test.rb +183 -0
  103. data/test/adapter/json_api/json_api_test.rb +5 -7
  104. data/test/adapter/json_api/linked_test.rb +33 -12
  105. data/test/adapter/json_api/links_test.rb +4 -2
  106. data/test/adapter/json_api/pagination_links_test.rb +35 -8
  107. data/test/adapter/json_api/relationship_test.rb +309 -73
  108. data/test/adapter/json_api/resource_identifier_test.rb +27 -2
  109. data/test/adapter/json_api/resource_meta_test.rb +3 -3
  110. data/test/adapter/json_api/transform_test.rb +263 -253
  111. data/test/adapter/json_api/type_test.rb +1 -1
  112. data/test/adapter/json_test.rb +8 -7
  113. data/test/adapter/null_test.rb +1 -2
  114. data/test/adapter/polymorphic_test.rb +5 -5
  115. data/test/adapter_test.rb +1 -1
  116. data/test/benchmark/app.rb +1 -1
  117. data/test/benchmark/benchmarking_support.rb +1 -1
  118. data/test/benchmark/bm_active_record.rb +81 -0
  119. data/test/benchmark/bm_adapter.rb +38 -0
  120. data/test/benchmark/bm_caching.rb +16 -16
  121. data/test/benchmark/bm_lookup_chain.rb +83 -0
  122. data/test/benchmark/bm_transform.rb +21 -10
  123. data/test/benchmark/controllers.rb +16 -17
  124. data/test/benchmark/fixtures.rb +72 -72
  125. data/test/cache_test.rb +235 -69
  126. data/test/collection_serializer_test.rb +25 -12
  127. data/test/fixtures/active_record.rb +45 -10
  128. data/test/fixtures/poro.rb +124 -181
  129. data/test/generators/serializer_generator_test.rb +23 -5
  130. data/test/grape_test.rb +170 -56
  131. data/test/lint_test.rb +1 -1
  132. data/test/logger_test.rb +13 -11
  133. data/test/serializable_resource_test.rb +18 -22
  134. data/test/serializers/association_macros_test.rb +3 -2
  135. data/test/serializers/associations_test.rb +132 -36
  136. data/test/serializers/attribute_test.rb +5 -3
  137. data/test/serializers/attributes_test.rb +1 -1
  138. data/test/serializers/caching_configuration_test_isolated.rb +6 -6
  139. data/test/serializers/fieldset_test.rb +1 -1
  140. data/test/serializers/meta_test.rb +12 -6
  141. data/test/serializers/options_test.rb +17 -6
  142. data/test/serializers/read_attribute_for_serialization_test.rb +3 -3
  143. data/test/serializers/root_test.rb +1 -1
  144. data/test/serializers/serialization_test.rb +2 -2
  145. data/test/serializers/serializer_for_test.rb +12 -10
  146. data/test/serializers/serializer_for_with_namespace_test.rb +88 -0
  147. data/test/support/isolated_unit.rb +5 -2
  148. data/test/support/rails5_shims.rb +8 -2
  149. data/test/support/rails_app.rb +2 -9
  150. data/test/support/serialization_testing.rb +23 -5
  151. data/test/test_helper.rb +13 -0
  152. metadata +104 -38
  153. data/.rubocop_todo.yml +0 -167
  154. data/docs/ARCHITECTURE.md +0 -126
  155. data/lib/active_model/serializer/include_tree.rb +0 -111
  156. data/lib/active_model_serializers/key_transform.rb +0 -70
  157. data/test/active_model_serializers/key_transform_test.rb +0 -263
  158. data/test/adapter/json_api/relationships_test.rb +0 -199
  159. data/test/include_tree/from_include_args_test.rb +0 -26
  160. data/test/include_tree/from_string_test.rb +0 -94
  161. data/test/include_tree/include_args_to_hash_test.rb +0 -64
data/test/lint_test.rb CHANGED
@@ -30,7 +30,7 @@ module ActiveModel
30
30
  def errors
31
31
  end
32
32
 
33
- def self.human_attribute_name(attr, options = {})
33
+ def self.human_attribute_name(_, _ = {})
34
34
  end
35
35
 
36
36
  def self.lookup_ancestors
data/test/logger_test.rb CHANGED
@@ -1,18 +1,20 @@
1
1
  require 'test_helper'
2
2
 
3
- class ActiveModelSerializers::LoggerTest < ActiveSupport::TestCase
4
- def test_logger_is_set_to_action_controller_logger_when_initializer_runs
5
- assert_equal $action_controller_logger, ActionController::Base.logger # rubocop:disable Style/GlobalVars
6
- end
3
+ module ActiveModelSerializers
4
+ class LoggerTest < ActiveSupport::TestCase
5
+ def test_logger_is_set_to_action_controller_logger_when_initializer_runs
6
+ assert_equal $action_controller_logger, ActionController::Base.logger # rubocop:disable Style/GlobalVars
7
+ end
7
8
 
8
- def test_logger_can_be_set
9
- original_logger = ActiveModelSerializers.logger
10
- logger = Logger.new(STDOUT)
9
+ def test_logger_can_be_set
10
+ original_logger = ActiveModelSerializers.logger
11
+ logger = Logger.new(STDOUT)
11
12
 
12
- ActiveModelSerializers.logger = logger
13
+ ActiveModelSerializers.logger = logger
13
14
 
14
- assert_equal ActiveModelSerializers.logger, logger
15
- ensure
16
- ActiveModelSerializers.logger = original_logger
15
+ assert_equal ActiveModelSerializers.logger, logger
16
+ ensure
17
+ ActiveModelSerializers.logger = original_logger
18
+ end
17
19
  end
18
20
  end
@@ -3,7 +3,7 @@ require 'test_helper'
3
3
  module ActiveModelSerializers
4
4
  class SerializableResourceTest < ActiveSupport::TestCase
5
5
  def setup
6
- @resource = Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' })
6
+ @resource = Profile.new(name: 'Name 1', description: 'Description 1', comments: 'Comments 1')
7
7
  @serializer = ProfileSerializer.new(@resource)
8
8
  @adapter = ActiveModelSerializers::Adapter.create(@serializer)
9
9
  @serializable_resource = SerializableResource.new(@resource)
@@ -32,11 +32,11 @@ module ActiveModelSerializers
32
32
  end
33
33
 
34
34
  def test_use_adapter_with_adapter_option
35
- assert SerializableResource.new(@resource, { adapter: 'json' }).use_adapter?
35
+ assert SerializableResource.new(@resource, adapter: 'json').use_adapter?
36
36
  end
37
37
 
38
38
  def test_use_adapter_with_adapter_option_as_false
39
- refute SerializableResource.new(@resource, { adapter: false }).use_adapter?
39
+ refute SerializableResource.new(@resource, adapter: false).use_adapter?
40
40
  end
41
41
 
42
42
  class SerializableResourceErrorsTest < Minitest::Test
@@ -45,15 +45,13 @@ module ActiveModelSerializers
45
45
  resource = ModelWithErrors.new
46
46
  resource.errors.add(:name, 'must be awesome')
47
47
  serializable_resource = ActiveModelSerializers::SerializableResource.new(
48
- resource, {
49
- serializer: ActiveModel::Serializer::ErrorSerializer,
50
- adapter: :json_api
51
- })
52
- expected_response_document =
53
- { :errors =>
54
- [
55
- { :source => { :pointer => '/data/attributes/name' }, :detail => 'must be awesome' }
56
- ]
48
+ resource, serializer: ActiveModel::Serializer::ErrorSerializer,
49
+ adapter: :json_api
50
+ )
51
+ expected_response_document = {
52
+ errors: [
53
+ { source: { pointer: '/data/attributes/name' }, detail: 'must be awesome' }
54
+ ]
57
55
  }
58
56
  assert_equal serializable_resource.as_json(options), expected_response_document
59
57
  end
@@ -65,16 +63,14 @@ module ActiveModelSerializers
65
63
  resource.errors.add(:title, 'must be amazing')
66
64
  resources << ModelWithErrors.new
67
65
  serializable_resource = SerializableResource.new(
68
- resources, {
69
- serializer: ActiveModel::Serializer::ErrorsSerializer,
70
- each_serializer: ActiveModel::Serializer::ErrorSerializer,
71
- adapter: :json_api
72
- })
73
- expected_response_document =
74
- { :errors =>
75
- [
76
- { :source => { :pointer => '/data/attributes/title' }, :detail => 'must be amazing' }
77
- ]
66
+ resources, serializer: ActiveModel::Serializer::ErrorsSerializer,
67
+ each_serializer: ActiveModel::Serializer::ErrorSerializer,
68
+ adapter: :json_api
69
+ )
70
+ expected_response_document = {
71
+ errors: [
72
+ { source: { pointer: '/data/attributes/title' }, detail: 'must be amazing' }
73
+ ]
78
74
  }
79
75
  assert_equal serializable_resource.as_json(options), expected_response_document
80
76
  end
@@ -3,7 +3,8 @@ require 'test_helper'
3
3
  module ActiveModel
4
4
  class Serializer
5
5
  class AssociationMacrosTest < ActiveSupport::TestCase
6
- AuthorSummarySerializer = Class.new
6
+ class AuthorSummarySerializer < ActiveModel::Serializer; end
7
+
7
8
  class AssociationsTestSerializer < Serializer
8
9
  belongs_to :author, serializer: AuthorSummarySerializer
9
10
  has_many :comments
@@ -11,7 +12,7 @@ module ActiveModel
11
12
  end
12
13
 
13
14
  def before_setup
14
- @reflections = AssociationsTestSerializer._reflections
15
+ @reflections = AssociationsTestSerializer._reflections.values
15
16
  end
16
17
 
17
18
  def test_has_one_defines_reflection
@@ -1,16 +1,19 @@
1
1
  require 'test_helper'
2
-
3
2
  module ActiveModel
4
3
  class Serializer
5
4
  class AssociationsTest < ActiveSupport::TestCase
5
+ class ModelWithoutSerializer < ::Model
6
+ attributes :id, :name
7
+ end
8
+
6
9
  def setup
7
10
  @author = Author.new(name: 'Steve K.')
8
11
  @author.bio = nil
9
12
  @author.roles = []
10
- @blog = Blog.new({ name: 'AMS Blog' })
11
- @post = Post.new({ title: 'New Post', body: 'Body' })
12
- @tag = Tag.new({ name: '#hashtagged' })
13
- @comment = Comment.new({ id: 1, body: 'ZOMG A COMMENT' })
13
+ @blog = Blog.new(name: 'AMS Blog')
14
+ @post = Post.new(title: 'New Post', body: 'Body')
15
+ @tag = ModelWithoutSerializer.new(id: 'tagid', name: '#hashtagged')
16
+ @comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
14
17
  @post.comments = [@comment]
15
18
  @post.tags = [@tag]
16
19
  @post.blog = @blog
@@ -19,7 +22,7 @@ module ActiveModel
19
22
  @post.author = @author
20
23
  @author.posts = [@post]
21
24
 
22
- @post_serializer = PostSerializer.new(@post, { custom_options: true })
25
+ @post_serializer = PostSerializer.new(@post, custom_options: true)
23
26
  @author_serializer = AuthorSerializer.new(@author)
24
27
  @comment_serializer = CommentSerializer.new(@comment)
25
28
  end
@@ -32,13 +35,13 @@ module ActiveModel
32
35
 
33
36
  case key
34
37
  when :posts
35
- assert_equal({ include_data: true }, options)
38
+ assert_equal true, options.fetch(:include_data)
36
39
  assert_kind_of(ActiveModelSerializers.config.collection_serializer, serializer)
37
40
  when :bio
38
- assert_equal({ include_data: true }, options)
41
+ assert_equal true, options.fetch(:include_data)
39
42
  assert_nil serializer
40
43
  when :roles
41
- assert_equal({ include_data: true }, options)
44
+ assert_equal true, options.fetch(:include_data)
42
45
  assert_kind_of(ActiveModelSerializers.config.collection_serializer, serializer)
43
46
  else
44
47
  flunk "Unknown association: #{key}"
@@ -47,14 +50,18 @@ module ActiveModel
47
50
  end
48
51
 
49
52
  def test_has_many_with_no_serializer
50
- PostWithTagsSerializer.new(@post).associations.each do |association|
53
+ post_serializer_class = Class.new(ActiveModel::Serializer) do
54
+ attributes :id
55
+ has_many :tags
56
+ end
57
+ post_serializer_class.new(@post).associations.each do |association|
51
58
  key = association.key
52
59
  serializer = association.serializer
53
60
  options = association.options
54
61
 
55
62
  assert_equal :tags, key
56
63
  assert_nil serializer
57
- assert_equal [{ name: '#hashtagged' }].to_json, options[:virtual_value].to_json
64
+ assert_equal [{ id: 'tagid', name: '#hashtagged' }].to_json, options[:virtual_value].to_json
58
65
  end
59
66
  end
60
67
 
@@ -63,7 +70,13 @@ module ActiveModel
63
70
  .associations
64
71
  .detect { |assoc| assoc.key == :comments }
65
72
 
66
- assert association.serializer.first.custom_options[:custom_options]
73
+ comment_serializer = association.serializer.first
74
+ class << comment_serializer
75
+ def custom_options
76
+ instance_options
77
+ end
78
+ end
79
+ assert comment_serializer.custom_options.fetch(:custom_options)
67
80
  end
68
81
 
69
82
  def test_belongs_to
@@ -80,7 +93,7 @@ module ActiveModel
80
93
  flunk "Unknown association: #{key}"
81
94
  end
82
95
 
83
- assert_equal({ include_data: true }, association.options)
96
+ assert_equal true, association.options.fetch(:include_data)
84
97
  end
85
98
  end
86
99
 
@@ -104,13 +117,13 @@ module ActiveModel
104
117
  end
105
118
 
106
119
  assert(
107
- PostSerializer._reflections.all? do |reflection|
108
- inherited_klass._reflections.include?(reflection)
120
+ PostSerializer._reflections.values.all? do |reflection|
121
+ inherited_klass._reflections.values.include?(reflection)
109
122
  end
110
123
  )
111
124
 
112
125
  assert(
113
- inherited_klass._reflections.any? do |reflection|
126
+ inherited_klass._reflections.values.any? do |reflection|
114
127
  reflection.name == :top_comments
115
128
  end
116
129
  )
@@ -143,12 +156,12 @@ module ActiveModel
143
156
  )
144
157
  actual = serializable(post, adapter: :attributes, serializer: InlineAssociationTestPostSerializer).as_json
145
158
  expected = {
146
- :comments => [
147
- { :id => 1, :contents => 'first comment' },
148
- { :id => 2, :contents => 'last comment' }
159
+ comments: [
160
+ { id: 1, contents: 'first comment' },
161
+ { id: 2, contents: 'last comment' }
149
162
  ],
150
- :last_comments => [
151
- { :id => 2, :contents => 'last comment' }
163
+ last_comments: [
164
+ { id: 2, contents: 'last comment' }
152
165
  ]
153
166
  }
154
167
 
@@ -160,18 +173,20 @@ module ActiveModel
160
173
 
161
174
  class NamespacedResourcesTest < ActiveSupport::TestCase
162
175
  class ResourceNamespace
163
- Post = Class.new(::Model)
164
- Comment = Class.new(::Model)
165
- Author = Class.new(::Model)
166
- Description = Class.new(::Model)
176
+ class Post < ::Model
177
+ associations :comments, :author, :description
178
+ end
179
+ class Comment < ::Model; end
180
+ class Author < ::Model; end
181
+ class Description < ::Model; end
167
182
  class PostSerializer < ActiveModel::Serializer
168
183
  has_many :comments
169
184
  belongs_to :author
170
185
  has_one :description
171
186
  end
172
- CommentSerializer = Class.new(ActiveModel::Serializer)
173
- AuthorSerializer = Class.new(ActiveModel::Serializer)
174
- DescriptionSerializer = Class.new(ActiveModel::Serializer)
187
+ class CommentSerializer < ActiveModel::Serializer; end
188
+ class AuthorSerializer < ActiveModel::Serializer; end
189
+ class DescriptionSerializer < ActiveModel::Serializer; end
175
190
  end
176
191
 
177
192
  def setup
@@ -201,17 +216,19 @@ module ActiveModel
201
216
  end
202
217
 
203
218
  class NestedSerializersTest < ActiveSupport::TestCase
204
- Post = Class.new(::Model)
205
- Comment = Class.new(::Model)
206
- Author = Class.new(::Model)
207
- Description = Class.new(::Model)
219
+ class Post < ::Model
220
+ associations :comments, :author, :description
221
+ end
222
+ class Comment < ::Model; end
223
+ class Author < ::Model; end
224
+ class Description < ::Model; end
208
225
  class PostSerializer < ActiveModel::Serializer
209
226
  has_many :comments
210
- CommentSerializer = Class.new(ActiveModel::Serializer)
227
+ class CommentSerializer < ActiveModel::Serializer; end
211
228
  belongs_to :author
212
- AuthorSerializer = Class.new(ActiveModel::Serializer)
229
+ class AuthorSerializer < ActiveModel::Serializer; end
213
230
  has_one :description
214
- DescriptionSerializer = Class.new(ActiveModel::Serializer)
231
+ class DescriptionSerializer < ActiveModel::Serializer; end
215
232
  end
216
233
 
217
234
  def setup
@@ -241,7 +258,10 @@ module ActiveModel
241
258
 
242
259
  # rubocop:disable Metrics/AbcSize
243
260
  def test_conditional_associations
244
- model = ::Model.new(true: true, false: false)
261
+ model = Class.new(::Model) do
262
+ attributes :true, :false
263
+ associations :association
264
+ end.new(true: true, false: false)
245
265
 
246
266
  scenarios = [
247
267
  { options: { if: :true }, included: true },
@@ -290,6 +310,82 @@ module ActiveModel
290
310
  assert_match(/:if should be a Symbol, String or Proc/, exception.message)
291
311
  end
292
312
  end
313
+
314
+ class InheritedSerializerTest < ActiveSupport::TestCase
315
+ class PostSerializer < ActiveModel::Serializer
316
+ belongs_to :author
317
+ has_many :comments
318
+ belongs_to :blog
319
+ end
320
+
321
+ class InheritedPostSerializer < PostSerializer
322
+ belongs_to :author, polymorphic: true
323
+ has_many :comments, key: :reviews
324
+ end
325
+
326
+ class AuthorSerializer < ActiveModel::Serializer
327
+ has_many :posts
328
+ has_many :roles
329
+ has_one :bio
330
+ end
331
+
332
+ class InheritedAuthorSerializer < AuthorSerializer
333
+ has_many :roles, polymorphic: true
334
+ has_one :bio, polymorphic: true
335
+ end
336
+
337
+ def setup
338
+ @author = Author.new(name: 'Steve K.')
339
+ @post = Post.new(title: 'New Post', body: 'Body')
340
+ @post_serializer = PostSerializer.new(@post)
341
+ @author_serializer = AuthorSerializer.new(@author)
342
+ @inherited_post_serializer = InheritedPostSerializer.new(@post)
343
+ @inherited_author_serializer = InheritedAuthorSerializer.new(@author)
344
+ @author_associations = @author_serializer.associations.to_a
345
+ @inherited_author_associations = @inherited_author_serializer.associations.to_a
346
+ @post_associations = @post_serializer.associations.to_a
347
+ @inherited_post_associations = @inherited_post_serializer.associations.to_a
348
+ end
349
+
350
+ test 'an author serializer must have [posts,roles,bio] associations' do
351
+ expected = [:posts, :roles, :bio].sort
352
+ result = @author_serializer.associations.map(&:name).sort
353
+ assert_equal(result, expected)
354
+ end
355
+
356
+ test 'a post serializer must have [author,comments,blog] associations' do
357
+ expected = [:author, :comments, :blog].sort
358
+ result = @post_serializer.associations.map(&:name).sort
359
+ assert_equal(result, expected)
360
+ end
361
+
362
+ test 'a serializer inheriting from another serializer can redefine has_many and has_one associations' do
363
+ expected = [:roles, :bio].sort
364
+ result = (@inherited_author_associations - @author_associations).map(&:name).sort
365
+ assert_equal(result, expected)
366
+ end
367
+
368
+ test 'a serializer inheriting from another serializer can redefine belongs_to associations' do
369
+ assert_equal [:author, :comments, :blog], @post_associations.map(&:name)
370
+ assert_equal [:author, :comments, :blog, :comments], @inherited_post_associations.map(&:name)
371
+
372
+ refute @post_associations.detect { |assoc| assoc.name == :author }.options.key?(:polymorphic)
373
+ assert_equal true, @inherited_post_associations.detect { |assoc| assoc.name == :author }.options.fetch(:polymorphic)
374
+
375
+ refute @post_associations.detect { |assoc| assoc.name == :comments }.options.key?(:key)
376
+ original_comment_assoc, new_comments_assoc = @inherited_post_associations.select { |assoc| assoc.name == :comments }
377
+ refute original_comment_assoc.options.key?(:key)
378
+ assert_equal :reviews, new_comments_assoc.options.fetch(:key)
379
+
380
+ assert_equal @post_associations.detect { |assoc| assoc.name == :blog }, @inherited_post_associations.detect { |assoc| assoc.name == :blog }
381
+ end
382
+
383
+ test 'a serializer inheriting from another serializer can have an additional association with the same name but with different key' do
384
+ expected = [:author, :comments, :blog, :reviews].sort
385
+ result = @inherited_post_serializer.associations.map { |a| a.options.fetch(:key, a.name) }.sort
386
+ assert_equal(result, expected)
387
+ end
388
+ end
293
389
  end
294
390
  end
295
391
  end
@@ -22,7 +22,7 @@ module ActiveModel
22
22
  inherited_klass = Class.new(AlternateBlogSerializer)
23
23
  blog_serializer = inherited_klass.new(@blog)
24
24
  adapter = ActiveModelSerializers::Adapter::Attributes.new(blog_serializer)
25
- assert_equal({ :id => 1, :title => 'AMS Hints' }, adapter.serializable_hash)
25
+ assert_equal({ id: 1, title: 'AMS Hints' }, adapter.serializable_hash)
26
26
  end
27
27
 
28
28
  def test_multiple_calls_with_the_same_attribute
@@ -81,7 +81,7 @@ module ActiveModel
81
81
  assert_equal('custom', hash[:blog][:id])
82
82
  end
83
83
 
84
- PostWithVirtualAttribute = Class.new(::Model)
84
+ class PostWithVirtualAttribute < ::Model; attributes :first_name, :last_name end
85
85
  class PostWithVirtualAttributeSerializer < ActiveModel::Serializer
86
86
  attribute :name do
87
87
  "#{object.first_name} #{object.last_name}"
@@ -98,7 +98,9 @@ module ActiveModel
98
98
 
99
99
  # rubocop:disable Metrics/AbcSize
100
100
  def test_conditional_associations
101
- model = ::Model.new(true: true, false: false)
101
+ model = Class.new(::Model) do
102
+ attributes :true, :false, :attribute
103
+ end.new(true: true, false: false)
102
104
 
103
105
  scenarios = [
104
106
  { options: { if: :true }, included: true },
@@ -4,7 +4,7 @@ module ActiveModel
4
4
  class Serializer
5
5
  class AttributesTest < ActiveSupport::TestCase
6
6
  def setup
7
- @profile = Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' })
7
+ @profile = Profile.new(name: 'Name 1', description: 'Description 1', comments: 'Comments 1')
8
8
  @profile_serializer = ProfileSerializer.new(@profile)
9
9
  @comment = Comment.new(id: 1, body: 'ZOMG!!', date: '2015')
10
10
  @serializer_klass = Class.new(CommentSerializer)
@@ -69,9 +69,9 @@ class CachingConfigurationTest < ActiveSupport::TestCase
69
69
  end
70
70
 
71
71
  test 'the non-cached serializer cache_store is nil' do
72
- assert_equal nil, @non_cached_serializer._cache
73
- assert_equal nil, @non_cached_serializer.cache_store
74
- assert_equal nil, @non_cached_serializer._cache
72
+ assert_nil @non_cached_serializer._cache
73
+ assert_nil @non_cached_serializer.cache_store
74
+ assert_nil @non_cached_serializer._cache
75
75
  end
76
76
 
77
77
  test 'the non-cached serializer does not have cache_enabled?' do
@@ -136,9 +136,9 @@ class CachingConfigurationTest < ActiveSupport::TestCase
136
136
  end
137
137
 
138
138
  test 'the non-cached serializer cache_store is nil' do
139
- assert_equal nil, @non_cached_serializer._cache
140
- assert_equal nil, @non_cached_serializer.cache_store
141
- assert_equal nil, @non_cached_serializer._cache
139
+ assert_nil @non_cached_serializer._cache
140
+ assert_nil @non_cached_serializer.cache_store
141
+ assert_nil @non_cached_serializer._cache
142
142
  end
143
143
 
144
144
  test 'the non-cached serializer does not have cache_enabled?' do
@@ -5,7 +5,7 @@ module ActiveModel
5
5
  class FieldsetTest < ActiveSupport::TestCase
6
6
  def test_fieldset_with_hash
7
7
  fieldset = ActiveModel::Serializer::Fieldset.new('post' => %w(id title), 'comment' => ['body'])
8
- expected = { :post => [:id, :title], :comment => [:body] }
8
+ expected = { post: [:id, :title], comment: [:body] }
9
9
 
10
10
  assert_equal(expected, fieldset.fields)
11
11
  end
@@ -15,7 +15,8 @@ module ActiveModel
15
15
  @blog,
16
16
  adapter: :json,
17
17
  serializer: AlternateBlogSerializer,
18
- meta: { total: 10 }).as_json
18
+ meta: { total: 10 }
19
+ ).as_json
19
20
  expected = {
20
21
  blog: {
21
22
  id: 1,
@@ -65,7 +66,8 @@ module ActiveModel
65
66
  @blog,
66
67
  adapter: :attributes,
67
68
  serializer: AlternateBlogSerializer,
68
- meta: { total: 10 }).as_json
69
+ meta: { total: 10 }
70
+ ).as_json
69
71
  expected = {
70
72
  id: 1,
71
73
  title: 'AMS Hints'
@@ -79,7 +81,8 @@ module ActiveModel
79
81
  adapter: :json,
80
82
  serializer: AlternateBlogSerializer,
81
83
  meta: { total: 10 },
82
- meta_key: 'haha_meta').as_json
84
+ meta_key: 'haha_meta'
85
+ ).as_json
83
86
  expected = {
84
87
  blog: {
85
88
  id: 1,
@@ -98,7 +101,8 @@ module ActiveModel
98
101
  adapter: :json_api,
99
102
  serializer: AlternateBlogSerializer,
100
103
  meta: { total: 10 },
101
- meta_key: 'haha_meta').as_json
104
+ meta_key: 'haha_meta'
105
+ ).as_json
102
106
  expected = {
103
107
  data: {
104
108
  id: '1',
@@ -148,7 +152,8 @@ module ActiveModel
148
152
  actual = ActiveModelSerializers::SerializableResource.new(
149
153
  [@blog],
150
154
  adapter: :attributes,
151
- meta: { total: 10 }).as_json
155
+ meta: { total: 10 }
156
+ ).as_json
152
157
  expected = [{
153
158
  id: 1,
154
159
  name: 'AMS Hints',
@@ -170,7 +175,8 @@ module ActiveModel
170
175
  [@blog],
171
176
  adapter: :json,
172
177
  meta: { total: 10 },
173
- meta_key: 'haha_meta').as_json
178
+ meta_key: 'haha_meta'
179
+ ).as_json
174
180
  expected = {
175
181
  blogs: [{
176
182
  id: 1,
@@ -3,18 +3,29 @@ require 'test_helper'
3
3
  module ActiveModel
4
4
  class Serializer
5
5
  class OptionsTest < ActiveSupport::TestCase
6
- def setup
7
- @profile = Profile.new(name: 'Name 1', description: 'Description 1')
6
+ class ModelWithOptions < ActiveModelSerializers::Model
7
+ attributes :name, :description
8
+ end
9
+ class ModelWithOptionsSerializer < ActiveModel::Serializer
10
+ attributes :name, :description
11
+
12
+ def arguments_passed_in?
13
+ instance_options[:my_options] == :accessible
14
+ end
15
+ end
16
+
17
+ setup do
18
+ @model_with_options = ModelWithOptions.new(name: 'Name 1', description: 'Description 1')
8
19
  end
9
20
 
10
21
  def test_options_are_accessible
11
- @profile_serializer = ProfileSerializer.new(@profile, my_options: :accessible)
12
- assert @profile_serializer.arguments_passed_in?
22
+ model_with_options_serializer = ModelWithOptionsSerializer.new(@model_with_options, my_options: :accessible)
23
+ assert model_with_options_serializer.arguments_passed_in?
13
24
  end
14
25
 
15
26
  def test_no_option_is_passed_in
16
- @profile_serializer = ProfileSerializer.new(@profile)
17
- refute @profile_serializer.arguments_passed_in?
27
+ model_with_options_serializer = ModelWithOptionsSerializer.new(@model_with_options)
28
+ refute model_with_options_serializer.arguments_passed_in?
18
29
  end
19
30
  end
20
31
  end
@@ -5,10 +5,10 @@ module ActiveModel
5
5
  class ReadAttributeForSerializationTest < ActiveSupport::TestCase
6
6
  # https://github.com/rails-api/active_model_serializers/issues/1653
7
7
  class Parent < ActiveModelSerializers::Model
8
- attr_accessor :id
8
+ attributes :id
9
9
  end
10
10
  class Child < Parent
11
- attr_accessor :name
11
+ attributes :name
12
12
  end
13
13
  class ParentSerializer < ActiveModel::Serializer
14
14
  attributes :$id
@@ -30,7 +30,7 @@ module ActiveModel
30
30
 
31
31
  # https://github.com/rails-api/active_model_serializers/issues/1658
32
32
  class ErrorResponse < ActiveModelSerializers::Model
33
- attr_accessor :error
33
+ attributes :error
34
34
  end
35
35
  class ApplicationSerializer < ActiveModel::Serializer
36
36
  attributes :status
@@ -8,7 +8,7 @@ module ActiveModel
8
8
  end
9
9
 
10
10
  def test_overwrite_root
11
- serializer = VirtualValueSerializer.new(@virtual_value, { root: 'smth' })
11
+ serializer = VirtualValueSerializer.new(@virtual_value, root: 'smth')
12
12
  assert_equal('smth', serializer.json_key)
13
13
  end
14
14
 
@@ -2,10 +2,10 @@ module ActiveModel
2
2
  class Serializer
3
3
  class SerializationTest < ActiveSupport::TestCase
4
4
  class Blog < ActiveModelSerializers::Model
5
- attr_accessor :id, :name, :authors
5
+ attributes :id, :name, :authors
6
6
  end
7
7
  class Author < ActiveModelSerializers::Model
8
- attr_accessor :id, :name
8
+ attributes :id, :name
9
9
  end
10
10
  class BlogSerializer < ActiveModel::Serializer
11
11
  attributes :id