active_model_serializers 0.10.0 → 0.10.3

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 (146) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +2 -4
  3. data/.travis.yml +9 -1
  4. data/CHANGELOG.md +81 -2
  5. data/CODE_OF_CONDUCT.md +74 -0
  6. data/Gemfile +5 -2
  7. data/README.md +24 -24
  8. data/Rakefile +3 -3
  9. data/active_model_serializers.gemspec +20 -24
  10. data/docs/ARCHITECTURE.md +6 -7
  11. data/docs/README.md +2 -0
  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/rendering.md +42 -3
  18. data/docs/general/serializers.md +97 -8
  19. data/docs/howto/add_pagination_links.md +4 -5
  20. data/docs/howto/add_relationship_links.md +137 -0
  21. data/docs/howto/add_root_key.md +4 -0
  22. data/docs/howto/grape_integration.md +42 -0
  23. data/docs/howto/outside_controller_use.md +9 -2
  24. data/docs/howto/passing_arbitrary_options.md +2 -2
  25. data/docs/howto/test.md +2 -0
  26. data/docs/howto/upgrade_from_0_8_to_0_10.md +265 -0
  27. data/docs/integrations/ember-and-json-api.md +64 -32
  28. data/docs/jsonapi/schema.md +1 -1
  29. data/lib/action_controller/serialization.rb +13 -3
  30. data/lib/active_model/serializer/adapter/base.rb +2 -0
  31. data/lib/active_model/serializer/array_serializer.rb +8 -5
  32. data/lib/active_model/serializer/association.rb +19 -4
  33. data/lib/active_model/serializer/belongs_to_reflection.rb +0 -3
  34. data/lib/active_model/serializer/collection_serializer.rb +35 -12
  35. data/lib/active_model/serializer/{associations.rb → concerns/associations.rb} +13 -11
  36. data/lib/active_model/serializer/{attributes.rb → concerns/attributes.rb} +0 -0
  37. data/lib/active_model/serializer/{caching.rb → concerns/caching.rb} +72 -113
  38. data/lib/active_model/serializer/{configuration.rb → concerns/configuration.rb} +25 -1
  39. data/lib/active_model/serializer/{links.rb → concerns/links.rb} +0 -0
  40. data/lib/active_model/serializer/{meta.rb → concerns/meta.rb} +0 -0
  41. data/lib/active_model/serializer/{type.rb → concerns/type.rb} +0 -0
  42. data/lib/active_model/serializer/error_serializer.rb +11 -7
  43. data/lib/active_model/serializer/errors_serializer.rb +25 -20
  44. data/lib/active_model/serializer/has_many_reflection.rb +0 -3
  45. data/lib/active_model/serializer/has_one_reflection.rb +0 -3
  46. data/lib/active_model/serializer/lint.rb +134 -130
  47. data/lib/active_model/serializer/reflection.rb +37 -21
  48. data/lib/active_model/serializer/version.rb +1 -1
  49. data/lib/active_model/serializer.rb +76 -37
  50. data/lib/active_model_serializers/adapter/attributes.rb +3 -66
  51. data/lib/active_model_serializers/adapter/base.rb +38 -38
  52. data/lib/active_model_serializers/adapter/json_api/link.rb +1 -1
  53. data/lib/active_model_serializers/adapter/json_api/pagination_links.rb +8 -1
  54. data/lib/active_model_serializers/adapter/json_api/relationship.rb +30 -19
  55. data/lib/active_model_serializers/adapter/json_api/resource_identifier.rb +23 -9
  56. data/lib/active_model_serializers/adapter/json_api.rb +44 -43
  57. data/lib/active_model_serializers/adapter.rb +6 -0
  58. data/lib/active_model_serializers/deprecate.rb +1 -2
  59. data/lib/active_model_serializers/deserialization.rb +2 -0
  60. data/lib/active_model_serializers/key_transform.rb +4 -0
  61. data/lib/active_model_serializers/lookup_chain.rb +80 -0
  62. data/lib/active_model_serializers/model.rb +4 -2
  63. data/lib/active_model_serializers/railtie.rb +3 -1
  64. data/lib/active_model_serializers/register_jsonapi_renderer.rb +44 -31
  65. data/lib/active_model_serializers/serializable_resource.rb +6 -5
  66. data/lib/active_model_serializers/serialization_context.rb +10 -3
  67. data/lib/active_model_serializers.rb +7 -0
  68. data/lib/generators/rails/serializer_generator.rb +4 -4
  69. data/lib/grape/active_model_serializers.rb +7 -5
  70. data/lib/grape/formatters/active_model_serializers.rb +19 -2
  71. data/lib/grape/helpers/active_model_serializers.rb +1 -0
  72. data/test/action_controller/adapter_selector_test.rb +4 -4
  73. data/test/action_controller/explicit_serializer_test.rb +5 -4
  74. data/test/action_controller/json/include_test.rb +106 -27
  75. data/test/action_controller/json_api/errors_test.rb +6 -7
  76. data/test/action_controller/json_api/fields_test.rb +57 -0
  77. data/test/action_controller/json_api/linked_test.rb +29 -24
  78. data/test/action_controller/json_api/pagination_test.rb +19 -19
  79. data/test/action_controller/json_api/transform_test.rb +3 -3
  80. data/test/action_controller/lookup_proc_test.rb +49 -0
  81. data/test/action_controller/namespace_lookup_test.rb +226 -0
  82. data/test/action_controller/serialization_test.rb +10 -7
  83. data/test/active_model_serializers/json_pointer_test.rb +15 -13
  84. data/test/active_model_serializers/key_transform_test.rb +286 -252
  85. data/test/active_model_serializers/model_test.rb +17 -4
  86. data/test/active_model_serializers/register_jsonapi_renderer_test_isolated.rb +143 -0
  87. data/test/active_model_serializers/serialization_context_test_isolated.rb +23 -10
  88. data/test/adapter/attributes_test.rb +43 -0
  89. data/test/adapter/json/collection_test.rb +14 -0
  90. data/test/adapter/json/transform_test.rb +15 -15
  91. data/test/adapter/json_api/collection_test.rb +4 -3
  92. data/test/adapter/json_api/errors_test.rb +17 -19
  93. data/test/adapter/json_api/fields_test.rb +4 -3
  94. data/test/adapter/json_api/has_many_test.rb +39 -18
  95. data/test/adapter/json_api/include_data_if_sideloaded_test.rb +166 -0
  96. data/test/adapter/json_api/json_api_test.rb +5 -7
  97. data/test/adapter/json_api/linked_test.rb +33 -12
  98. data/test/adapter/json_api/links_test.rb +4 -2
  99. data/test/adapter/json_api/pagination_links_test.rb +35 -8
  100. data/test/adapter/json_api/relationship_test.rb +309 -73
  101. data/test/adapter/json_api/resource_identifier_test.rb +27 -2
  102. data/test/adapter/json_api/resource_meta_test.rb +3 -3
  103. data/test/adapter/json_api/transform_test.rb +255 -253
  104. data/test/adapter/json_api/type_test.rb +1 -1
  105. data/test/adapter/json_test.rb +8 -7
  106. data/test/adapter/null_test.rb +1 -2
  107. data/test/adapter/polymorphic_test.rb +5 -5
  108. data/test/adapter_test.rb +1 -1
  109. data/test/benchmark/app.rb +1 -1
  110. data/test/benchmark/benchmarking_support.rb +1 -1
  111. data/test/benchmark/bm_active_record.rb +81 -0
  112. data/test/benchmark/bm_adapter.rb +38 -0
  113. data/test/benchmark/bm_caching.rb +16 -16
  114. data/test/benchmark/bm_lookup_chain.rb +83 -0
  115. data/test/benchmark/bm_transform.rb +16 -5
  116. data/test/benchmark/controllers.rb +16 -17
  117. data/test/benchmark/fixtures.rb +72 -72
  118. data/test/cache_test.rb +143 -49
  119. data/test/collection_serializer_test.rb +3 -3
  120. data/test/fixtures/poro.rb +52 -48
  121. data/test/generators/serializer_generator_test.rb +22 -5
  122. data/test/grape_test.rb +152 -56
  123. data/test/lint_test.rb +1 -1
  124. data/test/logger_test.rb +13 -11
  125. data/test/serializable_resource_test.rb +18 -22
  126. data/test/serializers/association_macros_test.rb +3 -2
  127. data/test/serializers/associations_test.rb +107 -32
  128. data/test/serializers/attribute_test.rb +2 -2
  129. data/test/serializers/attributes_test.rb +1 -1
  130. data/test/serializers/fieldset_test.rb +1 -1
  131. data/test/serializers/meta_test.rb +12 -6
  132. data/test/serializers/root_test.rb +1 -1
  133. data/test/serializers/serializer_for_test.rb +6 -4
  134. data/test/serializers/serializer_for_with_namespace_test.rb +87 -0
  135. data/test/support/isolated_unit.rb +5 -2
  136. data/test/support/rails5_shims.rb +8 -2
  137. data/test/support/rails_app.rb +0 -9
  138. data/test/support/serialization_testing.rb +23 -5
  139. data/test/test_helper.rb +1 -0
  140. metadata +85 -34
  141. data/.rubocop_todo.yml +0 -167
  142. data/lib/active_model/serializer/include_tree.rb +0 -111
  143. data/test/adapter/json_api/relationships_test.rb +0 -199
  144. data/test/include_tree/from_include_args_test.rb +0 -26
  145. data/test/include_tree/from_string_test.rb +0 -94
  146. data/test/include_tree/include_args_to_hash_test.rb +0 -64
@@ -8,7 +8,7 @@ class Model < ActiveModelSerializers::Model
8
8
  # Convenience when not adding @attributes readers and writers
9
9
  def method_missing(meth, *args)
10
10
  if meth.to_s =~ /^(.*)=$/
11
- attributes[$1.to_sym] = args[0]
11
+ attributes[Regexp.last_match(1).to_sym] = args[0]
12
12
  elsif attributes.key?(meth)
13
13
  attributes[meth]
14
14
  else
@@ -50,21 +50,21 @@ class ProfilePreviewSerializer < ActiveModel::Serializer
50
50
  attributes :name
51
51
  end
52
52
 
53
- Post = Class.new(Model)
54
- Like = Class.new(Model)
55
- Author = Class.new(Model)
56
- Bio = Class.new(Model)
57
- Blog = Class.new(Model)
58
- Role = Class.new(Model)
59
- User = Class.new(Model)
60
- Location = Class.new(Model)
61
- Place = Class.new(Model)
62
- Tag = Class.new(Model)
63
- VirtualValue = Class.new(Model)
64
- Comment = Class.new(Model) do
53
+ class Post < Model; end
54
+ class Like < Model; end
55
+ class Author < Model; end
56
+ class Bio < Model; end
57
+ class Blog < Model; end
58
+ class Role < Model; end
59
+ class User < Model; end
60
+ class Location < Model; end
61
+ class Place < Model; end
62
+ class Tag < Model; end
63
+ class VirtualValue < Model; end
64
+ class Comment < Model
65
65
  # Uses a custom non-time-based cache key
66
66
  def cache_key
67
- "#{self.class.name.downcase}/#{self.id}"
67
+ "#{self.class.name.downcase}/#{id}"
68
68
  end
69
69
  end
70
70
 
@@ -87,10 +87,11 @@ class PolyTag < ActiveRecord::Base
87
87
  has_many :object_tags
88
88
  end
89
89
 
90
- module Spam; end
91
- Spam::UnrelatedLink = Class.new(Model)
90
+ module Spam
91
+ class UnrelatedLink < Model; end
92
+ end
92
93
 
93
- PostSerializer = Class.new(ActiveModel::Serializer) do
94
+ class PostSerializer < ActiveModel::Serializer
94
95
  cache key: 'post', expires_in: 0.1, skip_digest: true
95
96
  attributes :id, :title, :body
96
97
 
@@ -108,12 +109,12 @@ PostSerializer = Class.new(ActiveModel::Serializer) do
108
109
  end
109
110
  end
110
111
 
111
- SpammyPostSerializer = Class.new(ActiveModel::Serializer) do
112
+ class SpammyPostSerializer < ActiveModel::Serializer
112
113
  attributes :id
113
114
  has_many :related
114
115
  end
115
116
 
116
- CommentSerializer = Class.new(ActiveModel::Serializer) do
117
+ class CommentSerializer < ActiveModel::Serializer
117
118
  cache expires_in: 1.day, skip_digest: true
118
119
  attributes :id, :body
119
120
 
@@ -125,7 +126,7 @@ CommentSerializer = Class.new(ActiveModel::Serializer) do
125
126
  end
126
127
  end
127
128
 
128
- AuthorSerializer = Class.new(ActiveModel::Serializer) do
129
+ class AuthorSerializer < ActiveModel::Serializer
129
130
  cache key: 'writer', skip_digest: true
130
131
  attribute :id
131
132
  attribute :name
@@ -135,48 +136,49 @@ AuthorSerializer = Class.new(ActiveModel::Serializer) do
135
136
  has_one :bio
136
137
  end
137
138
 
138
- RoleSerializer = Class.new(ActiveModel::Serializer) do
139
- cache only: [:name], skip_digest: true
140
- attributes :id, :name, :description, :slug
139
+ class RoleSerializer < ActiveModel::Serializer
140
+ cache only: [:name, :slug], skip_digest: true
141
+ attributes :id, :name, :description
142
+ attribute :friendly_id, key: :slug
141
143
 
142
- def slug
144
+ def friendly_id
143
145
  "#{object.name}-#{object.id}"
144
146
  end
145
147
 
146
148
  belongs_to :author
147
149
  end
148
150
 
149
- LikeSerializer = Class.new(ActiveModel::Serializer) do
151
+ class LikeSerializer < ActiveModel::Serializer
150
152
  attributes :id, :time
151
153
 
152
154
  belongs_to :likeable
153
155
  end
154
156
 
155
- LocationSerializer = Class.new(ActiveModel::Serializer) do
156
- cache only: [:place], skip_digest: true
157
+ class LocationSerializer < ActiveModel::Serializer
158
+ cache only: [:address], skip_digest: true
157
159
  attributes :id, :lat, :lng
158
160
 
159
- belongs_to :place
161
+ belongs_to :place, key: :address
160
162
 
161
163
  def place
162
164
  'Nowhere'
163
165
  end
164
166
  end
165
167
 
166
- PlaceSerializer = Class.new(ActiveModel::Serializer) do
168
+ class PlaceSerializer < ActiveModel::Serializer
167
169
  attributes :id, :name
168
170
 
169
171
  has_many :locations
170
172
  end
171
173
 
172
- BioSerializer = Class.new(ActiveModel::Serializer) do
174
+ class BioSerializer < ActiveModel::Serializer
173
175
  cache except: [:content], skip_digest: true
174
176
  attributes :id, :content, :rating
175
177
 
176
178
  belongs_to :author
177
179
  end
178
180
 
179
- BlogSerializer = Class.new(ActiveModel::Serializer) do
181
+ class BlogSerializer < ActiveModel::Serializer
180
182
  cache key: 'blog'
181
183
  attributes :id, :name
182
184
 
@@ -184,50 +186,50 @@ BlogSerializer = Class.new(ActiveModel::Serializer) do
184
186
  has_many :articles
185
187
  end
186
188
 
187
- PaginatedSerializer = Class.new(ActiveModel::Serializer::CollectionSerializer) do
189
+ class PaginatedSerializer < ActiveModel::Serializer::CollectionSerializer
188
190
  def json_key
189
191
  'paginated'
190
192
  end
191
193
  end
192
194
 
193
- AlternateBlogSerializer = Class.new(ActiveModel::Serializer) do
195
+ class AlternateBlogSerializer < ActiveModel::Serializer
194
196
  attribute :id
195
197
  attribute :name, key: :title
196
198
  end
197
199
 
198
- CustomBlogSerializer = Class.new(ActiveModel::Serializer) do
200
+ class CustomBlogSerializer < ActiveModel::Serializer
199
201
  attribute :id
200
202
  attribute :special_attribute
201
203
 
202
204
  has_many :articles
203
205
  end
204
206
 
205
- CommentPreviewSerializer = Class.new(ActiveModel::Serializer) do
207
+ class CommentPreviewSerializer < ActiveModel::Serializer
206
208
  attributes :id
207
209
 
208
210
  belongs_to :post
209
211
  end
210
212
 
211
- AuthorPreviewSerializer = Class.new(ActiveModel::Serializer) do
213
+ class AuthorPreviewSerializer < ActiveModel::Serializer
212
214
  attributes :id
213
215
 
214
216
  has_many :posts
215
217
  end
216
218
 
217
- PostPreviewSerializer = Class.new(ActiveModel::Serializer) do
219
+ class PostPreviewSerializer < ActiveModel::Serializer
218
220
  attributes :title, :body, :id
219
221
 
220
222
  has_many :comments, serializer: CommentPreviewSerializer
221
223
  belongs_to :author, serializer: AuthorPreviewSerializer
222
224
  end
223
225
 
224
- PostWithTagsSerializer = Class.new(ActiveModel::Serializer) do
226
+ class PostWithTagsSerializer < ActiveModel::Serializer
225
227
  attributes :id
226
228
 
227
229
  has_many :tags
228
230
  end
229
231
 
230
- PostWithCustomKeysSerializer = Class.new(ActiveModel::Serializer) do
232
+ class PostWithCustomKeysSerializer < ActiveModel::Serializer
231
233
  attributes :id
232
234
 
233
235
  has_many :comments, key: :reviews
@@ -235,7 +237,7 @@ PostWithCustomKeysSerializer = Class.new(ActiveModel::Serializer) do
235
237
  has_one :blog, key: :site
236
238
  end
237
239
 
238
- VirtualValueSerializer = Class.new(ActiveModel::Serializer) do
240
+ class VirtualValueSerializer < ActiveModel::Serializer
239
241
  attributes :id
240
242
 
241
243
  has_many :reviews, virtual_value: [{ type: 'reviews', id: '1' },
@@ -249,34 +251,36 @@ VirtualValueSerializer = Class.new(ActiveModel::Serializer) do
249
251
  end
250
252
  end
251
253
 
252
- PolymorphicHasManySerializer = Class.new(ActiveModel::Serializer) do
254
+ class PolymorphicHasManySerializer < ActiveModel::Serializer
253
255
  attributes :id, :name
254
256
  end
255
257
 
256
- PolymorphicBelongsToSerializer = Class.new(ActiveModel::Serializer) do
258
+ class PolymorphicBelongsToSerializer < ActiveModel::Serializer
257
259
  attributes :id, :title
258
260
 
259
261
  has_one :imageable, serializer: PolymorphicHasManySerializer, polymorphic: true
260
262
  end
261
263
 
262
- PolymorphicSimpleSerializer = Class.new(ActiveModel::Serializer) do
264
+ class PolymorphicSimpleSerializer < ActiveModel::Serializer
263
265
  attributes :id
264
266
  end
265
267
 
266
- PolymorphicObjectTagSerializer = Class.new(ActiveModel::Serializer) do
268
+ class PolymorphicObjectTagSerializer < ActiveModel::Serializer
267
269
  attributes :id
268
270
 
269
271
  has_many :taggable, serializer: PolymorphicSimpleSerializer, polymorphic: true
270
272
  end
271
273
 
272
- PolymorphicTagSerializer = Class.new(ActiveModel::Serializer) do
274
+ class PolymorphicTagSerializer < ActiveModel::Serializer
273
275
  attributes :id, :phrase
274
276
 
275
277
  has_many :object_tags, serializer: PolymorphicObjectTagSerializer
276
278
  end
277
279
 
278
- Spam::UnrelatedLinkSerializer = Class.new(ActiveModel::Serializer) do
279
- cache only: [:id]
280
- attributes :id
280
+ module Spam
281
+ class UnrelatedLinkSerializer < ActiveModel::Serializer
282
+ cache only: [:id]
283
+ attributes :id
284
+ end
281
285
  end
282
286
  $VERBOSE = verbose
@@ -20,11 +20,10 @@ class SerializerGeneratorTest < Rails::Generators::TestCase
20
20
  end
21
21
 
22
22
  def test_uses_application_serializer_if_one_exists
23
- Object.const_set(:ApplicationSerializer, Class.new)
24
- run_generator
25
- assert_file 'app/serializers/account_serializer.rb', /class AccountSerializer < ApplicationSerializer/
26
- ensure
27
- Object.send :remove_const, :ApplicationSerializer
23
+ stub_safe_constantize(expected: 'ApplicationSerializer') do
24
+ run_generator
25
+ assert_file 'app/serializers/account_serializer.rb', /class AccountSerializer < ApplicationSerializer/
26
+ end
28
27
  end
29
28
 
30
29
  def test_uses_given_parent
@@ -54,4 +53,22 @@ class SerializerGeneratorTest < Rails::Generators::TestCase
54
53
  end
55
54
  end
56
55
  end
56
+
57
+ private
58
+
59
+ def stub_safe_constantize(expected:)
60
+ String.class_eval do
61
+ alias_method :old, :safe_constantize
62
+ end
63
+ String.send(:define_method, :safe_constantize) do
64
+ Class if self == expected
65
+ end
66
+
67
+ yield
68
+ ensure
69
+ String.class_eval do
70
+ alias_method :safe_constantize, :old
71
+ undef_method :old
72
+ end
73
+ end
57
74
  end
data/test/grape_test.rb CHANGED
@@ -1,82 +1,178 @@
1
1
  require 'test_helper'
2
2
  require 'grape'
3
3
  require 'grape/active_model_serializers'
4
+ require 'kaminari'
5
+ require 'kaminari/hooks'
6
+ ::Kaminari::Hooks.init
7
+
8
+ module ActiveModelSerializers
9
+ class GrapeTest < ActiveSupport::TestCase
10
+ include Rack::Test::Methods
11
+ module Models
12
+ def self.model1
13
+ ARModels::Post.new(id: 1, title: 'Dummy Title', body: 'Lorem Ipsum')
14
+ end
4
15
 
5
- class ActiveModelSerializers::GrapeTest < ActiveSupport::TestCase
6
- include Rack::Test::Methods
7
- module Models
8
- def self.model1
9
- ARModels::Post.new(id: 1, title: 'Dummy Title', body: 'Lorem Ipsum')
10
- end
16
+ def self.model2
17
+ ARModels::Post.new(id: 2, title: 'Second Dummy Title', body: 'Second Lorem Ipsum')
18
+ end
19
+
20
+ def self.all
21
+ @all ||=
22
+ begin
23
+ model1.save!
24
+ model2.save!
25
+ ARModels::Post.all
26
+ end
27
+ end
28
+
29
+ def self.reset_all
30
+ ARModels::Post.delete_all
31
+ @all = nil
32
+ end
33
+
34
+ def self.collection_per
35
+ 2
36
+ end
11
37
 
12
- def self.model2
13
- ARModels::Post.new(id: 2, title: 'Second Dummy Title', body: 'Second Lorem Ipsum')
38
+ def self.collection
39
+ @collection ||=
40
+ begin
41
+ Kaminari.paginate_array(
42
+ [
43
+ Profile.new(id: 1, name: 'Name 1', description: 'Description 1', comments: 'Comments 1'),
44
+ Profile.new(id: 2, name: 'Name 2', description: 'Description 2', comments: 'Comments 2'),
45
+ Profile.new(id: 3, name: 'Name 3', description: 'Description 3', comments: 'Comments 3'),
46
+ Profile.new(id: 4, name: 'Name 4', description: 'Description 4', comments: 'Comments 4'),
47
+ Profile.new(id: 5, name: 'Name 5', description: 'Description 5', comments: 'Comments 5')
48
+ ]
49
+ ).page(1).per(collection_per)
50
+ end
51
+ end
14
52
  end
15
53
 
16
- def self.all
17
- @all ||=
18
- begin
19
- model1.save!
20
- model2.save!
21
- ARModels::Post.all
54
+ class GrapeTest < Grape::API
55
+ format :json
56
+ include Grape::ActiveModelSerializers
57
+
58
+ resources :grape do
59
+ get '/render' do
60
+ render Models.model1
22
61
  end
23
- end
24
- end
25
62
 
26
- class GrapeTest < Grape::API
27
- format :json
28
- include Grape::ActiveModelSerializers
63
+ get '/render_with_json_api' do
64
+ post = Models.model1
65
+ render post, meta: { page: 1, total_pages: 2 }, adapter: :json_api
66
+ end
29
67
 
30
- resources :grape do
31
- get '/render' do
32
- render Models.model1
33
- end
68
+ get '/render_array_with_json_api' do
69
+ posts = Models.all
70
+ render posts, adapter: :json_api
71
+ end
34
72
 
35
- get '/render_with_json_api' do
36
- post = Models.model1
37
- render post, meta: { page: 1, total_pages: 2 }, adapter: :json_api
38
- end
73
+ get '/render_collection_with_json_api' do
74
+ posts = Models.collection
75
+ render posts, adapter: :json_api
76
+ end
39
77
 
40
- get '/render_array_with_json_api' do
41
- posts = Models.all
42
- render posts, adapter: :json_api
78
+ get '/render_with_implicit_formatter' do
79
+ Models.model1
80
+ end
81
+
82
+ get '/render_array_with_implicit_formatter' do
83
+ Models.all
84
+ end
85
+
86
+ get '/render_collection_with_implicit_formatter' do
87
+ Models.collection
88
+ end
43
89
  end
44
90
  end
45
- end
46
91
 
47
- def app
48
- GrapeTest.new
49
- end
92
+ def app
93
+ Grape::Middleware::Globals.new(GrapeTest.new)
94
+ end
50
95
 
51
- def test_formatter_returns_json
52
- get '/grape/render'
96
+ def test_formatter_returns_json
97
+ get '/grape/render'
53
98
 
54
- post = Models.model1
55
- serializable_resource = serializable(post)
99
+ post = Models.model1
100
+ serializable_resource = serializable(post)
56
101
 
57
- assert last_response.ok?
58
- assert_equal serializable_resource.to_json, last_response.body
59
- end
102
+ assert last_response.ok?
103
+ assert_equal serializable_resource.to_json, last_response.body
104
+ end
60
105
 
61
- def test_render_helper_passes_through_options_correctly
62
- get '/grape/render_with_json_api'
106
+ def test_render_helper_passes_through_options_correctly
107
+ get '/grape/render_with_json_api'
63
108
 
64
- post = Models.model1
65
- serializable_resource = serializable(post, serializer: ARModels::PostSerializer, adapter: :json_api, meta: { page: 1, total_pages: 2 })
109
+ post = Models.model1
110
+ serializable_resource = serializable(post, serializer: ARModels::PostSerializer, adapter: :json_api, meta: { page: 1, total_pages: 2 })
66
111
 
67
- assert last_response.ok?
68
- assert_equal serializable_resource.to_json, last_response.body
69
- end
112
+ assert last_response.ok?
113
+ assert_equal serializable_resource.to_json, last_response.body
114
+ end
115
+
116
+ def test_formatter_handles_arrays
117
+ get '/grape/render_array_with_json_api'
118
+
119
+ posts = Models.all
120
+ serializable_resource = serializable(posts, adapter: :json_api)
121
+
122
+ assert last_response.ok?
123
+ assert_equal serializable_resource.to_json, last_response.body
124
+ ensure
125
+ Models.reset_all
126
+ end
127
+
128
+ def test_formatter_handles_collections
129
+ get '/grape/render_collection_with_json_api'
130
+ assert last_response.ok?
131
+
132
+ representation = JSON.parse(last_response.body)
133
+ assert representation.include?('data')
134
+ assert representation['data'].count == Models.collection_per
135
+ assert representation.include?('links')
136
+ assert representation['links'].count > 0
137
+ end
138
+
139
+ def test_implicit_formatter
140
+ post = Models.model1
141
+ serializable_resource = serializable(post, adapter: :json_api)
142
+
143
+ with_adapter :json_api do
144
+ get '/grape/render_with_implicit_formatter'
145
+ end
146
+
147
+ assert last_response.ok?
148
+ assert_equal serializable_resource.to_json, last_response.body
149
+ end
70
150
 
71
- def test_formatter_handles_arrays
72
- get '/grape/render_array_with_json_api'
151
+ def test_implicit_formatter_handles_arrays
152
+ posts = Models.all
153
+ serializable_resource = serializable(posts, adapter: :json_api)
73
154
 
74
- posts = Models.all
75
- serializable_resource = serializable(posts, adapter: :json_api)
155
+ with_adapter :json_api do
156
+ get '/grape/render_array_with_implicit_formatter'
157
+ end
158
+
159
+ assert last_response.ok?
160
+ assert_equal serializable_resource.to_json, last_response.body
161
+ ensure
162
+ Models.reset_all
163
+ end
76
164
 
77
- assert last_response.ok?
78
- assert_equal serializable_resource.to_json, last_response.body
79
- ensure
80
- ARModels::Post.delete_all
165
+ def test_implicit_formatter_handles_collections
166
+ with_adapter :json_api do
167
+ get '/grape/render_collection_with_implicit_formatter'
168
+ end
169
+
170
+ representation = JSON.parse(last_response.body)
171
+ assert last_response.ok?
172
+ assert representation.include?('data')
173
+ assert representation['data'].count == Models.collection_per
174
+ assert representation.include?('links')
175
+ assert representation['links'].count > 0
176
+ end
81
177
  end
82
178
  end
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