active_model_serializers 0.8.3 → 0.10.0.rc2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/.travis.yml +18 -20
  4. data/CHANGELOG.md +8 -67
  5. data/CONTRIBUTING.md +31 -0
  6. data/Gemfile +14 -1
  7. data/{MIT-LICENSE.txt → LICENSE.txt} +3 -2
  8. data/README.md +169 -495
  9. data/Rakefile +6 -12
  10. data/active_model_serializers.gemspec +21 -19
  11. data/lib/action_controller/serialization.rb +36 -27
  12. data/lib/active_model/serializer/adapter/flatten_json.rb +12 -0
  13. data/lib/active_model/serializer/adapter/fragment_cache.rb +78 -0
  14. data/lib/active_model/serializer/adapter/json/fragment_cache.rb +15 -0
  15. data/lib/active_model/serializer/adapter/json.rb +50 -0
  16. data/lib/active_model/serializer/adapter/json_api/fragment_cache.rb +23 -0
  17. data/lib/active_model/serializer/adapter/json_api.rb +156 -0
  18. data/lib/active_model/serializer/adapter/null.rb +11 -0
  19. data/lib/active_model/serializer/adapter.rb +96 -0
  20. data/lib/active_model/serializer/array_serializer.rb +35 -0
  21. data/lib/active_model/serializer/configuration.rb +13 -0
  22. data/lib/active_model/serializer/fieldset.rb +40 -0
  23. data/lib/active_model/serializer/railtie.rb +8 -0
  24. data/lib/active_model/{serializers → serializer}/version.rb +1 -1
  25. data/lib/active_model/serializer.rb +177 -440
  26. data/lib/active_model_serializers.rb +10 -86
  27. data/lib/generators/serializer/USAGE +0 -3
  28. data/lib/generators/serializer/resource_override.rb +12 -0
  29. data/lib/generators/serializer/serializer_generator.rb +1 -6
  30. data/lib/generators/serializer/templates/serializer.rb +2 -13
  31. data/test/action_controller/adapter_selector_test.rb +53 -0
  32. data/test/action_controller/explicit_serializer_test.rb +134 -0
  33. data/test/action_controller/json_api_linked_test.rb +179 -0
  34. data/test/action_controller/rescue_from_test.rb +32 -0
  35. data/test/{serialization_scope_name_test.rb → action_controller/serialization_scope_name_test.rb} +7 -11
  36. data/test/action_controller/serialization_test.rb +383 -0
  37. data/test/adapter/fragment_cache_test.rb +27 -0
  38. data/test/adapter/json/belongs_to_test.rb +48 -0
  39. data/test/adapter/json/collection_test.rb +73 -0
  40. data/test/adapter/json/has_many_test.rb +36 -0
  41. data/test/adapter/json_api/belongs_to_test.rb +157 -0
  42. data/test/adapter/json_api/collection_test.rb +96 -0
  43. data/test/adapter/json_api/has_many_embed_ids_test.rb +45 -0
  44. data/test/adapter/json_api/has_many_explicit_serializer_test.rb +98 -0
  45. data/test/adapter/json_api/has_many_test.rb +110 -0
  46. data/test/adapter/json_api/has_one_test.rb +61 -0
  47. data/test/adapter/json_api/linked_test.rb +283 -0
  48. data/test/adapter/json_test.rb +34 -0
  49. data/test/adapter/null_test.rb +25 -0
  50. data/test/adapter_test.rb +43 -0
  51. data/test/array_serializer_test.rb +31 -63
  52. data/test/fixtures/poro.rb +230 -0
  53. data/test/generators/scaffold_controller_generator_test.rb +24 -0
  54. data/test/{generators_test.rb → generators/serializer_generator_test.rb} +2 -36
  55. data/test/serializers/adapter_for_test.rb +50 -0
  56. data/test/serializers/associations_test.rb +127 -0
  57. data/test/serializers/attribute_test.rb +38 -0
  58. data/test/serializers/attributes_test.rb +63 -0
  59. data/test/serializers/cache_test.rb +138 -0
  60. data/test/serializers/configuration_test.rb +15 -0
  61. data/test/serializers/fieldset_test.rb +26 -0
  62. data/test/serializers/meta_test.rb +107 -0
  63. data/test/serializers/options_test.rb +21 -0
  64. data/test/serializers/serializer_for_test.rb +65 -0
  65. data/test/serializers/urls_test.rb +26 -0
  66. data/test/test_helper.rb +28 -16
  67. metadata +109 -43
  68. data/DESIGN.textile +0 -586
  69. data/Gemfile.edge +0 -9
  70. data/bench/perf.rb +0 -43
  71. data/cruft.md +0 -19
  72. data/lib/active_model/array_serializer.rb +0 -104
  73. data/lib/active_model/serializer/associations.rb +0 -233
  74. data/lib/active_record/serializer_override.rb +0 -16
  75. data/lib/generators/resource_override.rb +0 -13
  76. data/test/association_test.rb +0 -592
  77. data/test/caching_test.rb +0 -96
  78. data/test/no_serialization_scope_test.rb +0 -34
  79. data/test/serialization_test.rb +0 -392
  80. data/test/serializer_support_test.rb +0 -51
  81. data/test/serializer_test.rb +0 -1465
  82. data/test/test_fakes.rb +0 -217
@@ -0,0 +1,283 @@
1
+ require 'test_helper'
2
+ module ActiveModel
3
+ class Serializer
4
+ class Adapter
5
+ class JsonApi
6
+ class LinkedTest < Minitest::Test
7
+ def setup
8
+ ActionController::Base.cache_store.clear
9
+ @author1 = Author.new(id: 1, name: 'Steve K.')
10
+ @author2 = Author.new(id: 2, name: 'Tenderlove')
11
+ @bio1 = Bio.new(id: 1, content: 'AMS Contributor')
12
+ @bio2 = Bio.new(id: 2, content: 'Rails Contributor')
13
+ @first_post = Post.new(id: 10, title: 'Hello!!', body: 'Hello, world!!')
14
+ @second_post = Post.new(id: 20, title: 'New Post', body: 'Body')
15
+ @third_post = Post.new(id: 30, title: 'Yet Another Post', body: 'Body')
16
+ @blog = Blog.new({ name: 'AMS Blog' })
17
+ @first_comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
18
+ @second_comment = Comment.new(id: 2, body: 'ZOMG ANOTHER COMMENT')
19
+ @first_post.blog = @blog
20
+ @second_post.blog = @blog
21
+ @third_post.blog = nil
22
+ @first_post.comments = [@first_comment, @second_comment]
23
+ @second_post.comments = []
24
+ @third_post.comments = []
25
+ @first_post.author = @author1
26
+ @second_post.author = @author2
27
+ @third_post.author = @author1
28
+ @first_comment.post = @first_post
29
+ @first_comment.author = nil
30
+ @second_comment.post = @first_post
31
+ @second_comment.author = nil
32
+ @author1.posts = [@first_post, @third_post]
33
+ @author1.bio = @bio1
34
+ @author1.roles = []
35
+ @author2.posts = [@second_post]
36
+ @author2.bio = @bio2
37
+ @author2.roles = []
38
+ @bio1.author = @author1
39
+ @bio2.author = @author2
40
+ end
41
+
42
+ def test_include_multiple_posts_and_linked_array
43
+ serializer = ArraySerializer.new([@first_post, @second_post])
44
+ adapter = ActiveModel::Serializer::Adapter::JsonApi.new(
45
+ serializer,
46
+ include: ['author', 'author.bio', 'comments']
47
+ )
48
+ alt_adapter = ActiveModel::Serializer::Adapter::JsonApi.new(
49
+ serializer,
50
+ include: 'author,author.bio,comments'
51
+ )
52
+
53
+ expected = {
54
+ data: [
55
+ {
56
+ id: "10",
57
+ type: "posts",
58
+ attributes: {
59
+ title: "Hello!!",
60
+ body: "Hello, world!!"
61
+ },
62
+ relationships: {
63
+ comments: { data: [ { type: "comments", id: '1' }, { type: "comments", id: '2' } ] },
64
+ blog: { data: { type: "blogs", id: "999" } },
65
+ author: { data: { type: "authors", id: "1" } }
66
+ }
67
+ },
68
+ {
69
+ id: "20",
70
+ type: "posts",
71
+ attributes: {
72
+ title: "New Post",
73
+ body: "Body"
74
+ },
75
+ relationships: {
76
+ comments: { data: [] },
77
+ blog: { data: { type: "blogs", id: "999" } },
78
+ author: { data: { type: "authors", id: "2" } }
79
+ }
80
+ }
81
+ ],
82
+ included: [
83
+ {
84
+ id: "1",
85
+ type: "comments",
86
+ attributes: {
87
+ body: "ZOMG A COMMENT"
88
+ },
89
+ relationships: {
90
+ post: { data: { type: "posts", id: "10" } },
91
+ author: { data: nil }
92
+ }
93
+ }, {
94
+ id: "2",
95
+ type: "comments",
96
+ attributes: {
97
+ body: "ZOMG ANOTHER COMMENT",
98
+ },
99
+ relationships: {
100
+ post: { data: { type: "posts", id: "10" } },
101
+ author: { data: nil }
102
+ }
103
+ }, {
104
+ id: "1",
105
+ type: "authors",
106
+ attributes: {
107
+ name: "Steve K."
108
+ },
109
+ relationships: {
110
+ posts: { data: [ { type: "posts", id: "10" }, { type: "posts", id: "30" } ] },
111
+ roles: { data: [] },
112
+ bio: { data: { type: "bios", id: "1" } }
113
+ }
114
+ }, {
115
+ id: "1",
116
+ type: "bios",
117
+ attributes: {
118
+ content: "AMS Contributor",
119
+ rating: nil
120
+ },
121
+ relationships: {
122
+ author: { data: { type: "authors", id: "1" } }
123
+ }
124
+ }, {
125
+ id: "2",
126
+ type: "authors",
127
+ attributes: {
128
+ name: "Tenderlove"
129
+ },
130
+ relationships: {
131
+ posts: { data: [ { type: "posts", id:"20" } ] },
132
+ roles: { data: [] },
133
+ bio: { data: { type: "bios", id: "2" } }
134
+ }
135
+ }, {
136
+ id: "2",
137
+ type: "bios",
138
+ attributes: {
139
+ rating: nil,
140
+ content: "Rails Contributor",
141
+ },
142
+ relationships: {
143
+ author: { data: { type: "authors", id: "2" } }
144
+ }
145
+ }
146
+ ]
147
+ }
148
+ assert_equal expected, adapter.serializable_hash
149
+ assert_equal expected, alt_adapter.serializable_hash
150
+ end
151
+
152
+ def test_include_multiple_posts_and_linked
153
+ serializer = BioSerializer.new @bio1
154
+ adapter = ActiveModel::Serializer::Adapter::JsonApi.new(
155
+ serializer,
156
+ include: ['author', 'author.posts']
157
+ )
158
+ alt_adapter = ActiveModel::Serializer::Adapter::JsonApi.new(
159
+ serializer,
160
+ include: 'author,author.posts'
161
+ )
162
+
163
+ expected = [
164
+ {
165
+ id: "1",
166
+ type: "authors",
167
+ attributes: {
168
+ name: "Steve K."
169
+ },
170
+ relationships: {
171
+ posts: { data: [ { type: "posts", id: "10"}, { type: "posts", id: "30" }] },
172
+ roles: { data: [] },
173
+ bio: { data: { type: "bios", id: "1" }}
174
+ }
175
+ }, {
176
+ id: "10",
177
+ type: "posts",
178
+ attributes: {
179
+ title: "Hello!!",
180
+ body: "Hello, world!!"
181
+ },
182
+ relationships: {
183
+ comments: { data: [ { type: "comments", id: "1"}, { type: "comments", id: "2" }] },
184
+ blog: { data: { type: "blogs", id: "999" } },
185
+ author: { data: { type: "authors", id: "1" } }
186
+ }
187
+ }, {
188
+ id: "30",
189
+ type: "posts",
190
+ attributes: {
191
+ title: "Yet Another Post",
192
+ body: "Body"
193
+ },
194
+ relationships: {
195
+ comments: { data: [] },
196
+ blog: { data: { type: "blogs", id: "999" } },
197
+ author: { data: { type: "authors", id: "1" } }
198
+ }
199
+ }
200
+ ]
201
+
202
+ assert_equal expected, adapter.serializable_hash[:included]
203
+ assert_equal expected, alt_adapter.serializable_hash[:included]
204
+ end
205
+
206
+ def test_underscore_model_namespace_for_linked_resource_type
207
+ spammy_post = Post.new(id: 123)
208
+ spammy_post.related = [Spam::UnrelatedLink.new(id: 456)]
209
+ serializer = SpammyPostSerializer.new(spammy_post)
210
+ adapter = ActiveModel::Serializer::Adapter::JsonApi.new(serializer)
211
+ relationships = adapter.serializable_hash[:data][:relationships]
212
+ expected = {
213
+ related: {
214
+ data: [{
215
+ type: 'spam_unrelated_links',
216
+ id: '456'
217
+ }]
218
+ }
219
+ }
220
+ assert_equal expected, relationships
221
+ end
222
+
223
+ def test_multiple_references_to_same_resource
224
+ serializer = ArraySerializer.new([@first_comment, @second_comment])
225
+ adapter = ActiveModel::Serializer::Adapter::JsonApi.new(
226
+ serializer,
227
+ include: ['post']
228
+ )
229
+
230
+ expected = [
231
+ {
232
+ id: "10",
233
+ type: "posts",
234
+ attributes: {
235
+ title: "Hello!!",
236
+ body: "Hello, world!!"
237
+ },
238
+ relationships: {
239
+ comments: {
240
+ data: [{type: "comments", id: "1"}, {type: "comments", id: "2"}]
241
+ },
242
+ blog: {
243
+ data: {type: "blogs", id: "999"}
244
+ },
245
+ author: {
246
+ data: {type: "authors", id: "1"}
247
+ }
248
+ }
249
+ }
250
+ ]
251
+
252
+ assert_equal expected, adapter.serializable_hash[:included]
253
+ end
254
+
255
+ def test_nil_link_with_specified_serializer
256
+ @first_post.author = nil
257
+ serializer = PostPreviewSerializer.new(@first_post)
258
+ adapter = ActiveModel::Serializer::Adapter::JsonApi.new(
259
+ serializer,
260
+ include: ['author']
261
+ )
262
+
263
+ expected = {
264
+ data: {
265
+ id: "10",
266
+ type: "posts",
267
+ attributes: {
268
+ title: "Hello!!",
269
+ body: "Hello, world!!"
270
+ },
271
+ relationships: {
272
+ comments: { data: [ { type: "comments", id: '1' }, { type: "comments", id: '2' } ] },
273
+ author: { data: nil }
274
+ }
275
+ }
276
+ }
277
+ assert_equal expected, adapter.serializable_hash
278
+ end
279
+ end
280
+ end
281
+ end
282
+ end
283
+ end
@@ -0,0 +1,34 @@
1
+ require 'test_helper'
2
+
3
+ module ActiveModel
4
+ class Serializer
5
+ class Adapter
6
+ class JsonTest < Minitest::Test
7
+ def setup
8
+ ActionController::Base.cache_store.clear
9
+ @author = Author.new(id: 1, name: 'Steve K.')
10
+ @post = Post.new(title: 'New Post', body: 'Body')
11
+ @first_comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
12
+ @second_comment = Comment.new(id: 2, body: 'ZOMG ANOTHER COMMENT')
13
+ @post.comments = [@first_comment, @second_comment]
14
+ @first_comment.post = @post
15
+ @second_comment.post = @post
16
+ @post.author = @author
17
+ @blog = Blog.new(id: 1, name: "My Blog!!")
18
+ @post.blog = @blog
19
+
20
+ @serializer = PostSerializer.new(@post)
21
+ @adapter = ActiveModel::Serializer::Adapter::Json.new(@serializer)
22
+ end
23
+
24
+ def test_has_many
25
+ assert_equal([
26
+ {id: 1, body: 'ZOMG A COMMENT'},
27
+ {id: 2, body: 'ZOMG ANOTHER COMMENT'}
28
+ ], @adapter.serializable_hash[:post][:comments])
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+
@@ -0,0 +1,25 @@
1
+ require 'test_helper'
2
+
3
+ module ActiveModel
4
+ class Serializer
5
+ class Adapter
6
+ class NullTest < Minitest::Test
7
+ def setup
8
+ profile = Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' })
9
+ serializer = ProfileSerializer.new(profile)
10
+
11
+ @adapter = Null.new(serializer)
12
+ end
13
+
14
+ def test_serializable_hash
15
+ assert_equal({}, @adapter.serializable_hash)
16
+ end
17
+
18
+ def test_it_returns_empty_json
19
+ assert_equal('{}', @adapter.to_json)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+
@@ -0,0 +1,43 @@
1
+ require 'test_helper'
2
+
3
+ module ActiveModel
4
+ class Serializer
5
+ class AdapterTest < Minitest::Test
6
+ def setup
7
+ profile = Profile.new
8
+ @serializer = ProfileSerializer.new(profile)
9
+ @adapter = ActiveModel::Serializer::Adapter.new(@serializer)
10
+ end
11
+
12
+ def test_serializable_hash_is_abstract_method
13
+ assert_raises(NotImplementedError) do
14
+ @adapter.serializable_hash(only: [:name])
15
+ end
16
+ end
17
+
18
+ def test_serializer
19
+ assert_equal @serializer, @adapter.serializer
20
+ end
21
+
22
+ def test_adapter_class_for_known_adapter
23
+ klass = ActiveModel::Serializer::Adapter.adapter_class(:json_api)
24
+ assert_equal ActiveModel::Serializer::Adapter::JsonApi, klass
25
+ end
26
+
27
+ def test_adapter_class_for_unknown_adapter
28
+ klass = ActiveModel::Serializer::Adapter.adapter_class(:json_simple)
29
+ assert_nil klass
30
+ end
31
+
32
+ def test_create_adapter
33
+ adapter = ActiveModel::Serializer::Adapter.create(@serializer)
34
+ assert_equal ActiveModel::Serializer::Adapter::FlattenJson, adapter.class
35
+ end
36
+
37
+ def test_create_adapter_with_override
38
+ adapter = ActiveModel::Serializer::Adapter.create(@serializer, { adapter: :json_api})
39
+ assert_equal ActiveModel::Serializer::Adapter::JsonApi, adapter.class
40
+ end
41
+ end
42
+ end
43
+ end
@@ -1,75 +1,43 @@
1
- require "test_helper"
2
- require "test_fakes"
1
+ require 'test_helper'
3
2
 
4
- class ArraySerializerTest < ActiveModel::TestCase
3
+ module ActiveModel
4
+ class Serializer
5
+ class ArraySerializerTest < Minitest::Test
6
+ def setup
7
+ @comment = Comment.new
8
+ @post = Post.new
9
+ @serializer = ArraySerializer.new([@comment, @post], {some: :options})
10
+ end
5
11
 
6
- def test_array_items_do_not_have_root
7
- array = [
8
- BasicActiveModel.new(:name => "First model"),
9
- BasicActiveModel.new(:name => "Second model")
10
- ]
11
- expected = { "root" => [
12
- { :name => "First model" },
13
- { :name => "Second model" }
14
- ] }
12
+ def test_respond_to_each
13
+ assert_respond_to @serializer, :each
14
+ end
15
15
 
16
- default_serializer = array.active_model_serializer.new(array, :root => "root")
17
- each_serializer = array.active_model_serializer.new(array, :root => "root", :each_serializer => BasicSerializer)
16
+ def test_each_object_should_be_serialized_with_appropriate_serializer
17
+ serializers = @serializer.to_a
18
18
 
19
- default_json = default_serializer.as_json
20
- each_json = each_serializer.as_json
19
+ assert_kind_of CommentSerializer, serializers.first
20
+ assert_kind_of Comment, serializers.first.object
21
21
 
22
- assert_equal(expected, default_json)
23
- assert_equal(expected, each_json)
24
- end
25
-
26
- # serialize different typed objects
27
- def test_array_serializer
28
- model = Model.new
29
- user = User.new
30
- comments = Comment.new(:title => "Comment1", :id => 1)
31
-
32
- array = [model, user, comments]
33
- serializer = array.active_model_serializer.new(array, :scope => {:scope => true})
34
- assert_equal([
35
- { :model => "Model" },
36
- { :last_name => "Valim", :ok => true, :first_name => "Jose", :scope => true },
37
- { :title => "Comment1" }
38
- ], serializer.as_json)
39
- end
40
-
41
- def test_array_serializer_with_root
42
- comment1 = Comment.new(:title => "Comment1", :id => 1)
43
- comment2 = Comment.new(:title => "Comment2", :id => 2)
22
+ assert_kind_of PostSerializer, serializers.last
23
+ assert_kind_of Post, serializers.last.object
44
24
 
45
- array = [ comment1, comment2 ]
46
-
47
- serializer = array.active_model_serializer.new(array, :root => :comments)
48
-
49
- assert_equal({ :comments => [
50
- { :title => "Comment1" },
51
- { :title => "Comment2" }
52
- ]}, serializer.as_json)
53
- end
54
-
55
- def test_array_serializer_with_hash
56
- hash = {:value => "something"}
57
- array = [hash]
58
- serializer = array.active_model_serializer.new(array, :root => :items)
59
- assert_equal({ :items => [ hash.as_json ]}, serializer.as_json)
60
- end
25
+ assert_equal serializers.last.custom_options[:some], :options
26
+ end
61
27
 
62
- def test_array_serializer_with_specified_seriailizer
63
- post1 = Post.new(:title => "Post1", :author => "Author1", :id => 1)
64
- post2 = Post.new(:title => "Post2", :author => "Author2", :id => 2)
28
+ def test_serializer_option_not_passed_to_each_serializer
29
+ serializers = ArraySerializer.new([@post], {serializer: PostSerializer}).to_a
65
30
 
66
- array = [ post1, post2 ]
31
+ refute serializers.first.custom_options.key?(:serializer)
32
+ end
67
33
 
68
- serializer = array.active_model_serializer.new array, :each_serializer => CustomPostSerializer
34
+ def test_meta_and_meta_key_attr_readers
35
+ meta_content = {meta: "the meta", meta_key: "the meta key"}
36
+ @serializer = ArraySerializer.new([@comment, @post], meta_content)
69
37
 
70
- assert_equal([
71
- { :title => "Post1" },
72
- { :title => "Post2" }
73
- ], serializer.as_json)
38
+ assert_equal @serializer.meta, "the meta"
39
+ assert_equal @serializer.meta_key, "the meta key"
40
+ end
41
+ end
74
42
  end
75
43
  end