active_model_serializers 0.8.3 → 0.10.0

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 (232) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE.md +29 -0
  3. data/.github/PULL_REQUEST_TEMPLATE.md +15 -0
  4. data/.gitignore +17 -0
  5. data/.rubocop.yml +104 -0
  6. data/.rubocop_todo.yml +167 -0
  7. data/.simplecov +110 -0
  8. data/.travis.yml +39 -24
  9. data/CHANGELOG.md +465 -6
  10. data/CONTRIBUTING.md +105 -0
  11. data/Gemfile +50 -1
  12. data/{MIT-LICENSE.txt → MIT-LICENSE} +3 -2
  13. data/README.md +102 -590
  14. data/Rakefile +93 -8
  15. data/active_model_serializers.gemspec +65 -23
  16. data/appveyor.yml +24 -0
  17. data/bin/bench +171 -0
  18. data/bin/bench_regression +316 -0
  19. data/bin/serve_benchmark +39 -0
  20. data/docs/ARCHITECTURE.md +126 -0
  21. data/docs/README.md +40 -0
  22. data/docs/STYLE.md +58 -0
  23. data/docs/general/adapters.md +245 -0
  24. data/docs/general/caching.md +52 -0
  25. data/docs/general/configuration_options.md +100 -0
  26. data/docs/general/deserialization.md +100 -0
  27. data/docs/general/getting_started.md +133 -0
  28. data/docs/general/instrumentation.md +40 -0
  29. data/docs/general/key_transforms.md +40 -0
  30. data/docs/general/logging.md +14 -0
  31. data/docs/general/rendering.md +255 -0
  32. data/docs/general/serializers.md +372 -0
  33. data/docs/how-open-source-maintained.jpg +0 -0
  34. data/docs/howto/add_pagination_links.md +139 -0
  35. data/docs/howto/add_root_key.md +51 -0
  36. data/docs/howto/outside_controller_use.md +58 -0
  37. data/docs/howto/passing_arbitrary_options.md +27 -0
  38. data/docs/howto/serialize_poro.md +32 -0
  39. data/docs/howto/test.md +152 -0
  40. data/docs/integrations/ember-and-json-api.md +112 -0
  41. data/docs/integrations/grape.md +19 -0
  42. data/docs/jsonapi/errors.md +56 -0
  43. data/docs/jsonapi/schema/schema.json +366 -0
  44. data/docs/jsonapi/schema.md +151 -0
  45. data/docs/rfcs/0000-namespace.md +106 -0
  46. data/docs/rfcs/template.md +15 -0
  47. data/lib/action_controller/serialization.rb +31 -36
  48. data/lib/active_model/serializable_resource.rb +11 -0
  49. data/lib/active_model/serializer/adapter/attributes.rb +15 -0
  50. data/lib/active_model/serializer/adapter/base.rb +16 -0
  51. data/lib/active_model/serializer/adapter/json.rb +15 -0
  52. data/lib/active_model/serializer/adapter/json_api.rb +15 -0
  53. data/lib/active_model/serializer/adapter/null.rb +15 -0
  54. data/lib/active_model/serializer/adapter.rb +24 -0
  55. data/lib/active_model/serializer/array_serializer.rb +9 -0
  56. data/lib/active_model/serializer/association.rb +19 -0
  57. data/lib/active_model/serializer/associations.rb +87 -220
  58. data/lib/active_model/serializer/attribute.rb +25 -0
  59. data/lib/active_model/serializer/attributes.rb +82 -0
  60. data/lib/active_model/serializer/belongs_to_reflection.rb +10 -0
  61. data/lib/active_model/serializer/caching.rb +333 -0
  62. data/lib/active_model/serializer/collection_reflection.rb +7 -0
  63. data/lib/active_model/serializer/collection_serializer.rb +64 -0
  64. data/lib/active_model/serializer/configuration.rb +35 -0
  65. data/lib/active_model/serializer/error_serializer.rb +10 -0
  66. data/lib/active_model/serializer/errors_serializer.rb +27 -0
  67. data/lib/active_model/serializer/field.rb +90 -0
  68. data/lib/active_model/serializer/fieldset.rb +31 -0
  69. data/lib/active_model/serializer/has_many_reflection.rb +10 -0
  70. data/lib/active_model/serializer/has_one_reflection.rb +10 -0
  71. data/lib/active_model/serializer/include_tree.rb +111 -0
  72. data/lib/active_model/serializer/links.rb +35 -0
  73. data/lib/active_model/serializer/lint.rb +146 -0
  74. data/lib/active_model/serializer/meta.rb +29 -0
  75. data/lib/active_model/serializer/null.rb +17 -0
  76. data/lib/active_model/serializer/reflection.rb +147 -0
  77. data/lib/active_model/serializer/singular_reflection.rb +7 -0
  78. data/lib/active_model/serializer/type.rb +25 -0
  79. data/lib/active_model/{serializers → serializer}/version.rb +1 -1
  80. data/lib/active_model/serializer.rb +158 -481
  81. data/lib/active_model_serializers/adapter/attributes.rb +76 -0
  82. data/lib/active_model_serializers/adapter/base.rb +83 -0
  83. data/lib/active_model_serializers/adapter/json.rb +21 -0
  84. data/lib/active_model_serializers/adapter/json_api/deserialization.rb +213 -0
  85. data/lib/active_model_serializers/adapter/json_api/error.rb +96 -0
  86. data/lib/active_model_serializers/adapter/json_api/jsonapi.rb +49 -0
  87. data/lib/active_model_serializers/adapter/json_api/link.rb +83 -0
  88. data/lib/active_model_serializers/adapter/json_api/meta.rb +37 -0
  89. data/lib/active_model_serializers/adapter/json_api/pagination_links.rb +62 -0
  90. data/lib/active_model_serializers/adapter/json_api/relationship.rb +52 -0
  91. data/lib/active_model_serializers/adapter/json_api/resource_identifier.rb +37 -0
  92. data/lib/active_model_serializers/adapter/json_api.rb +516 -0
  93. data/lib/active_model_serializers/adapter/null.rb +9 -0
  94. data/lib/active_model_serializers/adapter.rb +92 -0
  95. data/lib/active_model_serializers/callbacks.rb +55 -0
  96. data/lib/active_model_serializers/deprecate.rb +55 -0
  97. data/lib/active_model_serializers/deserialization.rb +13 -0
  98. data/lib/active_model_serializers/json_pointer.rb +14 -0
  99. data/lib/active_model_serializers/key_transform.rb +70 -0
  100. data/lib/active_model_serializers/logging.rb +122 -0
  101. data/lib/active_model_serializers/model.rb +49 -0
  102. data/lib/active_model_serializers/railtie.rb +46 -0
  103. data/lib/active_model_serializers/register_jsonapi_renderer.rb +65 -0
  104. data/lib/active_model_serializers/serializable_resource.rb +81 -0
  105. data/lib/active_model_serializers/serialization_context.rb +32 -0
  106. data/lib/active_model_serializers/test/schema.rb +138 -0
  107. data/lib/active_model_serializers/test/serializer.rb +125 -0
  108. data/lib/active_model_serializers/test.rb +7 -0
  109. data/lib/active_model_serializers.rb +32 -89
  110. data/lib/generators/rails/USAGE +6 -0
  111. data/lib/generators/rails/resource_override.rb +10 -0
  112. data/lib/generators/rails/serializer_generator.rb +36 -0
  113. data/lib/generators/rails/templates/serializer.rb.erb +8 -0
  114. data/lib/grape/active_model_serializers.rb +14 -0
  115. data/lib/grape/formatters/active_model_serializers.rb +15 -0
  116. data/lib/grape/helpers/active_model_serializers.rb +16 -0
  117. data/test/action_controller/adapter_selector_test.rb +53 -0
  118. data/test/action_controller/explicit_serializer_test.rb +134 -0
  119. data/test/action_controller/json/include_test.rb +167 -0
  120. data/test/action_controller/json_api/deserialization_test.rb +112 -0
  121. data/test/action_controller/json_api/errors_test.rb +41 -0
  122. data/test/action_controller/json_api/linked_test.rb +197 -0
  123. data/test/action_controller/json_api/pagination_test.rb +116 -0
  124. data/test/action_controller/json_api/transform_test.rb +181 -0
  125. data/test/action_controller/serialization_scope_name_test.rb +229 -0
  126. data/test/action_controller/serialization_test.rb +469 -0
  127. data/test/active_model_serializers/adapter_for_test.rb +208 -0
  128. data/test/active_model_serializers/json_pointer_test.rb +20 -0
  129. data/test/active_model_serializers/key_transform_test.rb +263 -0
  130. data/test/active_model_serializers/logging_test.rb +77 -0
  131. data/test/active_model_serializers/model_test.rb +9 -0
  132. data/test/active_model_serializers/railtie_test_isolated.rb +63 -0
  133. data/test/active_model_serializers/serialization_context_test_isolated.rb +58 -0
  134. data/test/active_model_serializers/test/schema_test.rb +130 -0
  135. data/test/active_model_serializers/test/serializer_test.rb +62 -0
  136. data/test/active_record_test.rb +9 -0
  137. data/test/adapter/deprecation_test.rb +100 -0
  138. data/test/adapter/json/belongs_to_test.rb +45 -0
  139. data/test/adapter/json/collection_test.rb +90 -0
  140. data/test/adapter/json/has_many_test.rb +45 -0
  141. data/test/adapter/json/transform_test.rb +93 -0
  142. data/test/adapter/json_api/belongs_to_test.rb +155 -0
  143. data/test/adapter/json_api/collection_test.rb +95 -0
  144. data/test/adapter/json_api/errors_test.rb +78 -0
  145. data/test/adapter/json_api/fields_test.rb +87 -0
  146. data/test/adapter/json_api/has_many_embed_ids_test.rb +43 -0
  147. data/test/adapter/json_api/has_many_explicit_serializer_test.rb +96 -0
  148. data/test/adapter/json_api/has_many_test.rb +144 -0
  149. data/test/adapter/json_api/has_one_test.rb +80 -0
  150. data/test/adapter/json_api/json_api_test.rb +35 -0
  151. data/test/adapter/json_api/linked_test.rb +392 -0
  152. data/test/adapter/json_api/links_test.rb +93 -0
  153. data/test/adapter/json_api/pagination_links_test.rb +166 -0
  154. data/test/adapter/json_api/parse_test.rb +137 -0
  155. data/test/adapter/json_api/relationship_test.rb +161 -0
  156. data/test/adapter/json_api/relationships_test.rb +199 -0
  157. data/test/adapter/json_api/resource_identifier_test.rb +85 -0
  158. data/test/adapter/json_api/resource_meta_test.rb +100 -0
  159. data/test/adapter/json_api/toplevel_jsonapi_test.rb +82 -0
  160. data/test/adapter/json_api/transform_test.rb +502 -0
  161. data/test/adapter/json_api/type_test.rb +61 -0
  162. data/test/adapter/json_test.rb +45 -0
  163. data/test/adapter/null_test.rb +23 -0
  164. data/test/adapter/polymorphic_test.rb +171 -0
  165. data/test/adapter_test.rb +67 -0
  166. data/test/array_serializer_test.rb +20 -73
  167. data/test/benchmark/app.rb +65 -0
  168. data/test/benchmark/benchmarking_support.rb +67 -0
  169. data/test/benchmark/bm_caching.rb +119 -0
  170. data/test/benchmark/bm_transform.rb +34 -0
  171. data/test/benchmark/config.ru +3 -0
  172. data/test/benchmark/controllers.rb +84 -0
  173. data/test/benchmark/fixtures.rb +219 -0
  174. data/test/cache_test.rb +485 -0
  175. data/test/collection_serializer_test.rb +110 -0
  176. data/test/fixtures/active_record.rb +78 -0
  177. data/test/fixtures/poro.rb +282 -0
  178. data/test/generators/scaffold_controller_generator_test.rb +24 -0
  179. data/test/generators/serializer_generator_test.rb +57 -0
  180. data/test/grape_test.rb +82 -0
  181. data/test/include_tree/from_include_args_test.rb +26 -0
  182. data/test/include_tree/from_string_test.rb +94 -0
  183. data/test/include_tree/include_args_to_hash_test.rb +64 -0
  184. data/test/lint_test.rb +49 -0
  185. data/test/logger_test.rb +18 -0
  186. data/test/poro_test.rb +9 -0
  187. data/test/serializable_resource_test.rb +83 -0
  188. data/test/serializers/association_macros_test.rb +36 -0
  189. data/test/serializers/associations_test.rb +295 -0
  190. data/test/serializers/attribute_test.rb +151 -0
  191. data/test/serializers/attributes_test.rb +52 -0
  192. data/test/serializers/caching_configuration_test_isolated.rb +170 -0
  193. data/test/serializers/configuration_test.rb +32 -0
  194. data/test/serializers/fieldset_test.rb +14 -0
  195. data/test/serializers/meta_test.rb +196 -0
  196. data/test/serializers/options_test.rb +21 -0
  197. data/test/serializers/read_attribute_for_serialization_test.rb +79 -0
  198. data/test/serializers/root_test.rb +21 -0
  199. data/test/serializers/serialization_test.rb +55 -0
  200. data/test/serializers/serializer_for_test.rb +134 -0
  201. data/test/support/custom_schemas/active_model_serializers/test/schema_test/my/index.json +6 -0
  202. data/test/support/isolated_unit.rb +79 -0
  203. data/test/support/rails5_shims.rb +47 -0
  204. data/test/support/rails_app.rb +45 -0
  205. data/test/support/schemas/active_model_serializers/test/schema_test/my/index.json +6 -0
  206. data/test/support/schemas/active_model_serializers/test/schema_test/my/show.json +6 -0
  207. data/test/support/schemas/custom/show.json +7 -0
  208. data/test/support/schemas/hyper_schema.json +93 -0
  209. data/test/support/schemas/render_using_json_api.json +43 -0
  210. data/test/support/schemas/simple_json_pointers.json +10 -0
  211. data/test/support/serialization_testing.rb +53 -0
  212. data/test/test_helper.rb +48 -23
  213. metadata +449 -43
  214. data/DESIGN.textile +0 -586
  215. data/Gemfile.edge +0 -9
  216. data/bench/perf.rb +0 -43
  217. data/cruft.md +0 -19
  218. data/lib/active_model/array_serializer.rb +0 -104
  219. data/lib/active_record/serializer_override.rb +0 -16
  220. data/lib/generators/resource_override.rb +0 -13
  221. data/lib/generators/serializer/USAGE +0 -9
  222. data/lib/generators/serializer/serializer_generator.rb +0 -42
  223. data/lib/generators/serializer/templates/serializer.rb +0 -19
  224. data/test/association_test.rb +0 -592
  225. data/test/caching_test.rb +0 -96
  226. data/test/generators_test.rb +0 -85
  227. data/test/no_serialization_scope_test.rb +0 -34
  228. data/test/serialization_scope_name_test.rb +0 -67
  229. data/test/serialization_test.rb +0 -392
  230. data/test/serializer_support_test.rb +0 -51
  231. data/test/serializer_test.rb +0 -1465
  232. data/test/test_fakes.rb +0 -217
@@ -0,0 +1,282 @@
1
+ verbose = $VERBOSE
2
+ $VERBOSE = nil
3
+ class Model < ActiveModelSerializers::Model
4
+ FILE_DIGEST = Digest::MD5.hexdigest(File.open(__FILE__).read)
5
+
6
+ ### Helper methods, not required to be serializable
7
+
8
+ # Convenience when not adding @attributes readers and writers
9
+ def method_missing(meth, *args)
10
+ if meth.to_s =~ /^(.*)=$/
11
+ attributes[$1.to_sym] = args[0]
12
+ elsif attributes.key?(meth)
13
+ attributes[meth]
14
+ else
15
+ super
16
+ end
17
+ end
18
+
19
+ # required for ActiveModel::AttributeAssignment#_assign_attribute
20
+ # in Rails 5
21
+ def respond_to_missing?(method_name, _include_private = false)
22
+ attributes.key?(method_name.to_s.tr('=', '').to_sym) || super
23
+ end
24
+ end
25
+
26
+ # see
27
+ # https://github.com/rails/rails/blob/4-2-stable/activemodel/lib/active_model/errors.rb
28
+ # The below allows you to do:
29
+ #
30
+ # model = ModelWithErrors.new
31
+ # model.validate! # => ["cannot be nil"]
32
+ # model.errors.full_messages # => ["name cannot be nil"]
33
+ class ModelWithErrors < ::ActiveModelSerializers::Model
34
+ attr_accessor :name
35
+ end
36
+
37
+ class Profile < Model
38
+ end
39
+
40
+ class ProfileSerializer < ActiveModel::Serializer
41
+ attributes :name, :description
42
+
43
+ # TODO: is this used anywhere?
44
+ def arguments_passed_in?
45
+ instance_options[:my_options] == :accessible
46
+ end
47
+ end
48
+
49
+ class ProfilePreviewSerializer < ActiveModel::Serializer
50
+ attributes :name
51
+ end
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
65
+ # Uses a custom non-time-based cache key
66
+ def cache_key
67
+ "#{self.class.name.downcase}/#{self.id}"
68
+ end
69
+ end
70
+
71
+ class Employee < ActiveRecord::Base
72
+ has_many :pictures, as: :imageable
73
+ has_many :object_tags, as: :taggable
74
+ end
75
+
76
+ class ObjectTag < ActiveRecord::Base
77
+ belongs_to :poly_tag
78
+ belongs_to :taggable, polymorphic: true
79
+ end
80
+
81
+ class Picture < ActiveRecord::Base
82
+ belongs_to :imageable, polymorphic: true
83
+ has_many :object_tags, as: :taggable
84
+ end
85
+
86
+ class PolyTag < ActiveRecord::Base
87
+ has_many :object_tags
88
+ end
89
+
90
+ module Spam; end
91
+ Spam::UnrelatedLink = Class.new(Model)
92
+
93
+ PostSerializer = Class.new(ActiveModel::Serializer) do
94
+ cache key: 'post', expires_in: 0.1, skip_digest: true
95
+ attributes :id, :title, :body
96
+
97
+ has_many :comments
98
+ belongs_to :blog
99
+ belongs_to :author
100
+
101
+ def blog
102
+ Blog.new(id: 999, name: 'Custom blog')
103
+ end
104
+
105
+ # TODO: is this used anywhere?
106
+ def custom_options
107
+ instance_options
108
+ end
109
+ end
110
+
111
+ SpammyPostSerializer = Class.new(ActiveModel::Serializer) do
112
+ attributes :id
113
+ has_many :related
114
+ end
115
+
116
+ CommentSerializer = Class.new(ActiveModel::Serializer) do
117
+ cache expires_in: 1.day, skip_digest: true
118
+ attributes :id, :body
119
+
120
+ belongs_to :post
121
+ belongs_to :author
122
+
123
+ def custom_options
124
+ instance_options
125
+ end
126
+ end
127
+
128
+ AuthorSerializer = Class.new(ActiveModel::Serializer) do
129
+ cache key: 'writer', skip_digest: true
130
+ attribute :id
131
+ attribute :name
132
+
133
+ has_many :posts
134
+ has_many :roles
135
+ has_one :bio
136
+ end
137
+
138
+ RoleSerializer = Class.new(ActiveModel::Serializer) do
139
+ cache only: [:name], skip_digest: true
140
+ attributes :id, :name, :description, :slug
141
+
142
+ def slug
143
+ "#{object.name}-#{object.id}"
144
+ end
145
+
146
+ belongs_to :author
147
+ end
148
+
149
+ LikeSerializer = Class.new(ActiveModel::Serializer) do
150
+ attributes :id, :time
151
+
152
+ belongs_to :likeable
153
+ end
154
+
155
+ LocationSerializer = Class.new(ActiveModel::Serializer) do
156
+ cache only: [:place], skip_digest: true
157
+ attributes :id, :lat, :lng
158
+
159
+ belongs_to :place
160
+
161
+ def place
162
+ 'Nowhere'
163
+ end
164
+ end
165
+
166
+ PlaceSerializer = Class.new(ActiveModel::Serializer) do
167
+ attributes :id, :name
168
+
169
+ has_many :locations
170
+ end
171
+
172
+ BioSerializer = Class.new(ActiveModel::Serializer) do
173
+ cache except: [:content], skip_digest: true
174
+ attributes :id, :content, :rating
175
+
176
+ belongs_to :author
177
+ end
178
+
179
+ BlogSerializer = Class.new(ActiveModel::Serializer) do
180
+ cache key: 'blog'
181
+ attributes :id, :name
182
+
183
+ belongs_to :writer
184
+ has_many :articles
185
+ end
186
+
187
+ PaginatedSerializer = Class.new(ActiveModel::Serializer::CollectionSerializer) do
188
+ def json_key
189
+ 'paginated'
190
+ end
191
+ end
192
+
193
+ AlternateBlogSerializer = Class.new(ActiveModel::Serializer) do
194
+ attribute :id
195
+ attribute :name, key: :title
196
+ end
197
+
198
+ CustomBlogSerializer = Class.new(ActiveModel::Serializer) do
199
+ attribute :id
200
+ attribute :special_attribute
201
+
202
+ has_many :articles
203
+ end
204
+
205
+ CommentPreviewSerializer = Class.new(ActiveModel::Serializer) do
206
+ attributes :id
207
+
208
+ belongs_to :post
209
+ end
210
+
211
+ AuthorPreviewSerializer = Class.new(ActiveModel::Serializer) do
212
+ attributes :id
213
+
214
+ has_many :posts
215
+ end
216
+
217
+ PostPreviewSerializer = Class.new(ActiveModel::Serializer) do
218
+ attributes :title, :body, :id
219
+
220
+ has_many :comments, serializer: CommentPreviewSerializer
221
+ belongs_to :author, serializer: AuthorPreviewSerializer
222
+ end
223
+
224
+ PostWithTagsSerializer = Class.new(ActiveModel::Serializer) do
225
+ attributes :id
226
+
227
+ has_many :tags
228
+ end
229
+
230
+ PostWithCustomKeysSerializer = Class.new(ActiveModel::Serializer) do
231
+ attributes :id
232
+
233
+ has_many :comments, key: :reviews
234
+ belongs_to :author, key: :writer
235
+ has_one :blog, key: :site
236
+ end
237
+
238
+ VirtualValueSerializer = Class.new(ActiveModel::Serializer) do
239
+ attributes :id
240
+
241
+ has_many :reviews, virtual_value: [{ type: 'reviews', id: '1' },
242
+ { type: 'reviews', id: '2' }]
243
+ has_one :maker, virtual_value: { type: 'makers', id: '1' }
244
+
245
+ def reviews
246
+ end
247
+
248
+ def maker
249
+ end
250
+ end
251
+
252
+ PolymorphicHasManySerializer = Class.new(ActiveModel::Serializer) do
253
+ attributes :id, :name
254
+ end
255
+
256
+ PolymorphicBelongsToSerializer = Class.new(ActiveModel::Serializer) do
257
+ attributes :id, :title
258
+
259
+ has_one :imageable, serializer: PolymorphicHasManySerializer, polymorphic: true
260
+ end
261
+
262
+ PolymorphicSimpleSerializer = Class.new(ActiveModel::Serializer) do
263
+ attributes :id
264
+ end
265
+
266
+ PolymorphicObjectTagSerializer = Class.new(ActiveModel::Serializer) do
267
+ attributes :id
268
+
269
+ has_many :taggable, serializer: PolymorphicSimpleSerializer, polymorphic: true
270
+ end
271
+
272
+ PolymorphicTagSerializer = Class.new(ActiveModel::Serializer) do
273
+ attributes :id, :phrase
274
+
275
+ has_many :object_tags, serializer: PolymorphicObjectTagSerializer
276
+ end
277
+
278
+ Spam::UnrelatedLinkSerializer = Class.new(ActiveModel::Serializer) do
279
+ cache only: [:id]
280
+ attributes :id
281
+ end
282
+ $VERBOSE = verbose
@@ -0,0 +1,24 @@
1
+ require 'test_helper'
2
+ require 'generators/rails/resource_override'
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
@@ -0,0 +1,57 @@
1
+ require 'test_helper'
2
+ require 'generators/rails/resource_override'
3
+ require 'generators/rails/serializer_generator'
4
+
5
+ class SerializerGeneratorTest < Rails::Generators::TestCase
6
+ destination File.expand_path('../../../tmp/generators', __FILE__)
7
+ setup :prepare_destination
8
+
9
+ tests Rails::Generators::SerializerGenerator
10
+ arguments %w(account name:string description:text business:references)
11
+
12
+ def test_generates_a_serializer
13
+ run_generator
14
+ assert_file 'app/serializers/account_serializer.rb', /class AccountSerializer < ActiveModel::Serializer/
15
+ end
16
+
17
+ def test_generates_a_namespaced_serializer
18
+ run_generator ['admin/account']
19
+ assert_file 'app/serializers/admin/account_serializer.rb', /class Admin::AccountSerializer < ActiveModel::Serializer/
20
+ end
21
+
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
28
+ end
29
+
30
+ def test_uses_given_parent
31
+ Object.const_set(:ApplicationSerializer, Class.new)
32
+ run_generator ['Account', '--parent=MySerializer']
33
+ assert_file 'app/serializers/account_serializer.rb', /class AccountSerializer < MySerializer/
34
+ ensure
35
+ Object.send :remove_const, :ApplicationSerializer
36
+ end
37
+
38
+ def test_generates_attributes_and_associations
39
+ run_generator
40
+ assert_file 'app/serializers/account_serializer.rb' do |serializer|
41
+ assert_match(/^ attributes :id, :name, :description$/, serializer)
42
+ assert_match(/^ has_one :business$/, serializer)
43
+ assert_match(/^end\n*\z/, serializer)
44
+ end
45
+ end
46
+
47
+ def test_with_no_attributes_does_not_add_extra_space
48
+ run_generator ['account']
49
+ assert_file 'app/serializers/account_serializer.rb' do |content|
50
+ if RUBY_PLATFORM =~ /mingw/
51
+ assert_no_match(/\r\n\r\nend/, content)
52
+ else
53
+ assert_no_match(/\n\nend/, content)
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,82 @@
1
+ require 'test_helper'
2
+ require 'grape'
3
+ require 'grape/active_model_serializers'
4
+
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
11
+
12
+ def self.model2
13
+ ARModels::Post.new(id: 2, title: 'Second Dummy Title', body: 'Second Lorem Ipsum')
14
+ end
15
+
16
+ def self.all
17
+ @all ||=
18
+ begin
19
+ model1.save!
20
+ model2.save!
21
+ ARModels::Post.all
22
+ end
23
+ end
24
+ end
25
+
26
+ class GrapeTest < Grape::API
27
+ format :json
28
+ include Grape::ActiveModelSerializers
29
+
30
+ resources :grape do
31
+ get '/render' do
32
+ render Models.model1
33
+ end
34
+
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
39
+
40
+ get '/render_array_with_json_api' do
41
+ posts = Models.all
42
+ render posts, adapter: :json_api
43
+ end
44
+ end
45
+ end
46
+
47
+ def app
48
+ GrapeTest.new
49
+ end
50
+
51
+ def test_formatter_returns_json
52
+ get '/grape/render'
53
+
54
+ post = Models.model1
55
+ serializable_resource = serializable(post)
56
+
57
+ assert last_response.ok?
58
+ assert_equal serializable_resource.to_json, last_response.body
59
+ end
60
+
61
+ def test_render_helper_passes_through_options_correctly
62
+ get '/grape/render_with_json_api'
63
+
64
+ post = Models.model1
65
+ serializable_resource = serializable(post, serializer: ARModels::PostSerializer, adapter: :json_api, meta: { page: 1, total_pages: 2 })
66
+
67
+ assert last_response.ok?
68
+ assert_equal serializable_resource.to_json, last_response.body
69
+ end
70
+
71
+ def test_formatter_handles_arrays
72
+ get '/grape/render_array_with_json_api'
73
+
74
+ posts = Models.all
75
+ serializable_resource = serializable(posts, adapter: :json_api)
76
+
77
+ assert last_response.ok?
78
+ assert_equal serializable_resource.to_json, last_response.body
79
+ ensure
80
+ ARModels::Post.delete_all
81
+ end
82
+ end
@@ -0,0 +1,26 @@
1
+ require 'test_helper'
2
+
3
+ module ActiveModel
4
+ class Serializer
5
+ class IncludeTree
6
+ class FromStringTest < ActiveSupport::TestCase
7
+ def test_simple_array
8
+ input = [:comments, :author]
9
+ actual = ActiveModel::Serializer::IncludeTree.from_include_args(input)
10
+ assert(actual.key?(:author))
11
+ assert(actual.key?(:comments))
12
+ end
13
+
14
+ def test_nested_array
15
+ input = [:comments, posts: [:author, comments: [:author]]]
16
+ actual = ActiveModel::Serializer::IncludeTree.from_include_args(input)
17
+ assert(actual.key?(:posts))
18
+ assert(actual[:posts].key?(:author))
19
+ assert(actual[:posts].key?(:comments))
20
+ assert(actual[:posts][:comments].key?(:author))
21
+ assert(actual.key?(:comments))
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,94 @@
1
+ require 'test_helper'
2
+
3
+ module ActiveModel
4
+ class Serializer
5
+ class IncludeTree
6
+ class FromStringTest < ActiveSupport::TestCase
7
+ def test_single_string
8
+ input = 'author'
9
+ actual = ActiveModel::Serializer::IncludeTree.from_string(input)
10
+ assert(actual.key?(:author))
11
+ end
12
+
13
+ def test_multiple_strings
14
+ input = 'author,comments'
15
+ actual = ActiveModel::Serializer::IncludeTree.from_string(input)
16
+ assert(actual.key?(:author))
17
+ assert(actual.key?(:comments))
18
+ end
19
+
20
+ def test_multiple_strings_with_space
21
+ input = 'author, comments'
22
+ actual = ActiveModel::Serializer::IncludeTree.from_string(input)
23
+ assert(actual.key?(:author))
24
+ assert(actual.key?(:comments))
25
+ end
26
+
27
+ def test_nested_string
28
+ input = 'posts.author'
29
+ actual = ActiveModel::Serializer::IncludeTree.from_string(input)
30
+ assert(actual.key?(:posts))
31
+ assert(actual[:posts].key?(:author))
32
+ end
33
+
34
+ def test_multiple_nested_string
35
+ input = 'posts.author,posts.comments.author,comments'
36
+ actual = ActiveModel::Serializer::IncludeTree.from_string(input)
37
+ assert(actual.key?(:posts))
38
+ assert(actual[:posts].key?(:author))
39
+ assert(actual[:posts].key?(:comments))
40
+ assert(actual[:posts][:comments].key?(:author))
41
+ assert(actual.key?(:comments))
42
+ end
43
+
44
+ def test_toplevel_star_string
45
+ input = '*'
46
+ actual = ActiveModel::Serializer::IncludeTree.from_string(input)
47
+ assert(actual.key?(:comments))
48
+ end
49
+
50
+ def test_nested_star_string
51
+ input = 'posts.*'
52
+ actual = ActiveModel::Serializer::IncludeTree.from_string(input)
53
+ assert(actual.key?(:posts))
54
+ assert(actual[:posts].key?(:comments))
55
+ end
56
+
57
+ def test_nested_star_middle_string
58
+ input = 'posts.*.author'
59
+ actual = ActiveModel::Serializer::IncludeTree.from_string(input)
60
+ assert(actual.key?(:posts))
61
+ assert(actual[:posts].key?(:comments))
62
+ assert(actual[:posts][:comments].key?(:author))
63
+ refute(actual[:posts][:comments].key?(:unspecified))
64
+ end
65
+
66
+ def test_nested_star_lower_precedence_string
67
+ input = 'posts.comments.author,posts.*'
68
+ actual = ActiveModel::Serializer::IncludeTree.from_string(input)
69
+ assert(actual.key?(:posts))
70
+ assert(actual[:posts].key?(:comments))
71
+ assert(actual[:posts][:comments].key?(:author))
72
+ end
73
+
74
+ def test_toplevel_double_star_string
75
+ input = '**'
76
+ actual = ActiveModel::Serializer::IncludeTree.from_string(input)
77
+ assert(actual.key?(:posts))
78
+ assert(actual[:posts].key?(:comments))
79
+ assert(actual[:posts][:comments].key?(:posts))
80
+ end
81
+
82
+ def test_nested_double_star_string
83
+ input = 'comments, posts.**'
84
+ actual = ActiveModel::Serializer::IncludeTree.from_string(input)
85
+ assert(actual.key?(:comments))
86
+ refute(actual[:comments].key?(:author))
87
+ assert(actual.key?(:posts))
88
+ assert(actual[:posts].key?(:comments))
89
+ assert(actual[:posts][:comments].key?(:posts))
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,64 @@
1
+ require 'test_helper'
2
+
3
+ module ActiveModel
4
+ class Serializer
5
+ class IncludeTree
6
+ module Parsing
7
+ class IncludeArgsToHashTest < MiniTest::Test
8
+ def test_include_args_to_hash_from_symbol
9
+ expected = { author: {} }
10
+ input = :author
11
+ actual = Parsing.include_args_to_hash(input)
12
+
13
+ assert_equal(expected, actual)
14
+ end
15
+
16
+ def test_include_args_to_hash_from_array
17
+ expected = { author: {}, comments: {} }
18
+ input = [:author, :comments]
19
+ actual = Parsing.include_args_to_hash(input)
20
+
21
+ assert_equal(expected, actual)
22
+ end
23
+
24
+ def test_include_args_to_hash_from_nested_array
25
+ expected = { author: {}, comments: { author: {} } }
26
+ input = [:author, comments: [:author]]
27
+ actual = Parsing.include_args_to_hash(input)
28
+
29
+ assert_equal(expected, actual)
30
+ end
31
+
32
+ def test_include_args_to_hash_from_array_of_hashes
33
+ expected = {
34
+ author: {},
35
+ blogs: { posts: { contributors: {} } },
36
+ comments: { author: { blogs: { posts: {} } } }
37
+ }
38
+ input = [
39
+ :author,
40
+ blogs: [posts: :contributors],
41
+ comments: { author: { blogs: :posts } }
42
+ ]
43
+ actual = Parsing.include_args_to_hash(input)
44
+
45
+ assert_equal(expected, actual)
46
+ end
47
+
48
+ def test_array_of_string
49
+ expected = {
50
+ comments: { author: {}, attachment: {} }
51
+ }
52
+ input = [
53
+ 'comments.author',
54
+ 'comments.attachment'
55
+ ]
56
+ actual = Parsing.include_args_to_hash(input)
57
+
58
+ assert_equal(expected, actual)
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
data/test/lint_test.rb ADDED
@@ -0,0 +1,49 @@
1
+ require 'test_helper'
2
+
3
+ module ActiveModel
4
+ class Serializer
5
+ class LintTest < ActiveSupport::TestCase
6
+ include ActiveModel::Serializer::Lint::Tests
7
+
8
+ class CompliantResource
9
+ def serializable_hash(options = nil)
10
+ end
11
+
12
+ def read_attribute_for_serialization(name)
13
+ end
14
+
15
+ def as_json(options = nil)
16
+ end
17
+
18
+ def to_json(options = nil)
19
+ end
20
+
21
+ def cache_key
22
+ end
23
+
24
+ def id
25
+ end
26
+
27
+ def updated_at
28
+ end
29
+
30
+ def errors
31
+ end
32
+
33
+ def self.human_attribute_name(attr, options = {})
34
+ end
35
+
36
+ def self.lookup_ancestors
37
+ end
38
+
39
+ def self.model_name
40
+ @_model_name ||= ActiveModel::Name.new(self)
41
+ end
42
+ end
43
+
44
+ def setup
45
+ @resource = CompliantResource.new
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,18 @@
1
+ require 'test_helper'
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
7
+
8
+ def test_logger_can_be_set
9
+ original_logger = ActiveModelSerializers.logger
10
+ logger = Logger.new(STDOUT)
11
+
12
+ ActiveModelSerializers.logger = logger
13
+
14
+ assert_equal ActiveModelSerializers.logger, logger
15
+ ensure
16
+ ActiveModelSerializers.logger = original_logger
17
+ end
18
+ end
data/test/poro_test.rb ADDED
@@ -0,0 +1,9 @@
1
+ require 'test_helper'
2
+
3
+ class PoroTest < ActiveSupport::TestCase
4
+ include ActiveModel::Serializer::Lint::Tests
5
+
6
+ def setup
7
+ @resource = Model.new
8
+ end
9
+ end