cm-active_model_serializers 0.10.0.rc1.1

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 (62) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +21 -0
  3. data/.travis.yml +26 -0
  4. data/CHANGELOG.md +8 -0
  5. data/CONTRIBUTING.md +31 -0
  6. data/Gemfile +17 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +326 -0
  9. data/Rakefile +12 -0
  10. data/cm-active_model_serializers.gemspec +26 -0
  11. data/lib/action_controller/serialization.rb +62 -0
  12. data/lib/active_model/serializer.rb +261 -0
  13. data/lib/active_model/serializer/adapter.rb +87 -0
  14. data/lib/active_model/serializer/adapter/fragment_cache.rb +78 -0
  15. data/lib/active_model/serializer/adapter/json.rb +52 -0
  16. data/lib/active_model/serializer/adapter/json/fragment_cache.rb +15 -0
  17. data/lib/active_model/serializer/adapter/json_api.rb +152 -0
  18. data/lib/active_model/serializer/adapter/json_api/fragment_cache.rb +22 -0
  19. data/lib/active_model/serializer/adapter/null.rb +11 -0
  20. data/lib/active_model/serializer/array_serializer.rb +32 -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/version.rb +5 -0
  24. data/lib/active_model_serializers.rb +18 -0
  25. data/lib/generators/serializer/USAGE +6 -0
  26. data/lib/generators/serializer/serializer_generator.rb +37 -0
  27. data/lib/generators/serializer/templates/serializer.rb +8 -0
  28. data/test/action_controller/adapter_selector_test.rb +51 -0
  29. data/test/action_controller/explicit_serializer_test.rb +110 -0
  30. data/test/action_controller/json_api_linked_test.rb +173 -0
  31. data/test/action_controller/serialization_scope_name_test.rb +63 -0
  32. data/test/action_controller/serialization_test.rb +365 -0
  33. data/test/adapter/fragment_cache_test.rb +27 -0
  34. data/test/adapter/json/belongs_to_test.rb +48 -0
  35. data/test/adapter/json/collection_test.rb +73 -0
  36. data/test/adapter/json/has_many_test.rb +36 -0
  37. data/test/adapter/json_api/belongs_to_test.rb +147 -0
  38. data/test/adapter/json_api/collection_test.rb +89 -0
  39. data/test/adapter/json_api/has_many_embed_ids_test.rb +45 -0
  40. data/test/adapter/json_api/has_many_explicit_serializer_test.rb +98 -0
  41. data/test/adapter/json_api/has_many_test.rb +106 -0
  42. data/test/adapter/json_api/has_one_test.rb +59 -0
  43. data/test/adapter/json_api/linked_test.rb +257 -0
  44. data/test/adapter/json_test.rb +34 -0
  45. data/test/adapter/null_test.rb +25 -0
  46. data/test/adapter_test.rb +43 -0
  47. data/test/array_serializer_test.rb +43 -0
  48. data/test/fixtures/poro.rb +213 -0
  49. data/test/serializers/adapter_for_test.rb +50 -0
  50. data/test/serializers/associations_test.rb +127 -0
  51. data/test/serializers/attribute_test.rb +38 -0
  52. data/test/serializers/attributes_test.rb +63 -0
  53. data/test/serializers/cache_test.rb +128 -0
  54. data/test/serializers/configuration_test.rb +15 -0
  55. data/test/serializers/fieldset_test.rb +26 -0
  56. data/test/serializers/generators_test.rb +59 -0
  57. data/test/serializers/meta_test.rb +78 -0
  58. data/test/serializers/options_test.rb +21 -0
  59. data/test/serializers/serializer_for_test.rb +65 -0
  60. data/test/serializers/urls_test.rb +26 -0
  61. data/test/test_helper.rb +38 -0
  62. metadata +195 -0
@@ -0,0 +1,213 @@
1
+ class Model
2
+ def initialize(hash={})
3
+ @attributes = hash
4
+ end
5
+
6
+ def cache_key
7
+ "#{self.class.name.downcase}/#{self.id}-#{self.updated_at}"
8
+ end
9
+
10
+ def updated_at
11
+ @attributes[:updated_at] ||= DateTime.now.to_time.to_i
12
+ end
13
+
14
+ def read_attribute_for_serialization(name)
15
+ if name == :id || name == 'id'
16
+ id
17
+ else
18
+ @attributes[name]
19
+ end
20
+ end
21
+
22
+ def id
23
+ @attributes[:id] || @attributes['id'] || object_id
24
+ end
25
+
26
+ def to_param
27
+ id
28
+ end
29
+
30
+ def method_missing(meth, *args)
31
+ if meth.to_s =~ /^(.*)=$/
32
+ @attributes[$1.to_sym] = args[0]
33
+ elsif @attributes.key?(meth)
34
+ @attributes[meth]
35
+ else
36
+ super
37
+ end
38
+ end
39
+ end
40
+
41
+ class Profile < Model
42
+ end
43
+
44
+ class ProfileSerializer < ActiveModel::Serializer
45
+ attributes :name, :description
46
+
47
+ urls :posts, :comments
48
+
49
+ def arguments_passed_in?
50
+ options[:my_options] == :accessible
51
+ end
52
+ end
53
+
54
+ class ProfilePreviewSerializer < ActiveModel::Serializer
55
+ attributes :name
56
+
57
+ urls :posts, :comments
58
+ end
59
+
60
+ Post = Class.new(Model)
61
+ Like = Class.new(Model)
62
+ Comment = Class.new(Model)
63
+ Author = Class.new(Model)
64
+ Bio = Class.new(Model)
65
+ Blog = Class.new(Model)
66
+ Role = Class.new(Model)
67
+ User = Class.new(Model)
68
+ Location = Class.new(Model)
69
+ Place = Class.new(Model)
70
+
71
+ module Spam; end
72
+ Spam::UnrelatedLink = Class.new(Model)
73
+
74
+ PostSerializer = Class.new(ActiveModel::Serializer) do
75
+ cache key:'post', expires_in: 0.1
76
+ attributes :id, :title, :body
77
+
78
+ has_many :comments
79
+ belongs_to :blog
80
+ belongs_to :author
81
+ url :comments
82
+
83
+ def blog
84
+ Blog.new(id: 999, name: "Custom blog")
85
+ end
86
+
87
+ def custom_options
88
+ options
89
+ end
90
+ end
91
+
92
+ SpammyPostSerializer = Class.new(ActiveModel::Serializer) do
93
+ attributes :id
94
+ has_many :related
95
+
96
+ def self.root_name
97
+ 'posts'
98
+ end
99
+ end
100
+
101
+ CommentSerializer = Class.new(ActiveModel::Serializer) do
102
+ cache expires_in: 1.day
103
+ attributes :id, :body
104
+
105
+ belongs_to :post
106
+ belongs_to :author
107
+
108
+ def custom_options
109
+ options
110
+ end
111
+ end
112
+
113
+ AuthorSerializer = Class.new(ActiveModel::Serializer) do
114
+ cache key:'writer'
115
+ attributes :id, :name
116
+
117
+ has_many :posts, embed: :ids
118
+ has_many :roles, embed: :ids
119
+ has_one :bio
120
+ end
121
+
122
+ RoleSerializer = Class.new(ActiveModel::Serializer) do
123
+ cache only: [:name]
124
+ attributes :id, :name, :description, :slug
125
+
126
+ def slug
127
+ "#{name}-#{id}"
128
+ end
129
+
130
+ belongs_to :author
131
+ end
132
+
133
+ LikeSerializer = Class.new(ActiveModel::Serializer) do
134
+ attributes :id, :time
135
+
136
+ belongs_to :post
137
+ end
138
+
139
+ LocationSerializer = Class.new(ActiveModel::Serializer) do
140
+ cache only: [:place]
141
+ attributes :id, :lat, :lng
142
+
143
+ belongs_to :place
144
+
145
+ def place
146
+ 'Nowhere'
147
+ end
148
+ end
149
+
150
+ PlaceSerializer = Class.new(ActiveModel::Serializer) do
151
+ attributes :id, :name
152
+
153
+ has_many :locations
154
+ end
155
+
156
+ BioSerializer = Class.new(ActiveModel::Serializer) do
157
+ cache except: [:content]
158
+ attributes :id, :content, :rating
159
+
160
+ belongs_to :author
161
+ end
162
+
163
+ BlogSerializer = Class.new(ActiveModel::Serializer) do
164
+ attributes :id, :name
165
+
166
+ belongs_to :writer
167
+ has_many :articles
168
+ end
169
+
170
+ PaginatedSerializer = Class.new(ActiveModel::Serializer::ArraySerializer) do
171
+ def json_key
172
+ 'paginated'
173
+ end
174
+ end
175
+
176
+ AlternateBlogSerializer = Class.new(ActiveModel::Serializer) do
177
+ attribute :id
178
+ attribute :name, key: :title
179
+ end
180
+
181
+ CustomBlogSerializer = Class.new(ActiveModel::Serializer) do
182
+ attribute :id
183
+ attribute :special_attribute
184
+
185
+ has_many :articles
186
+ end
187
+
188
+ CommentPreviewSerializer = Class.new(ActiveModel::Serializer) do
189
+ attributes :id
190
+
191
+ belongs_to :post
192
+ end
193
+
194
+ AuthorPreviewSerializer = Class.new(ActiveModel::Serializer) do
195
+ attributes :id
196
+
197
+ has_many :posts
198
+ end
199
+
200
+ PostPreviewSerializer = Class.new(ActiveModel::Serializer) do
201
+ def self.root_name
202
+ 'posts'
203
+ end
204
+
205
+ attributes :title, :body, :id
206
+
207
+ has_many :comments, serializer: CommentPreviewSerializer
208
+ belongs_to :author, serializer: AuthorPreviewSerializer
209
+ end
210
+
211
+ Spam::UnrelatedLinkSerializer = Class.new(ActiveModel::Serializer) do
212
+ attributes :id
213
+ end
@@ -0,0 +1,50 @@
1
+ module ActiveModel
2
+ class Serializer
3
+ class AdapterForTest < Minitest::Test
4
+ def setup
5
+ @previous_adapter = ActiveModel::Serializer.config.adapter
6
+ end
7
+
8
+ def teardown
9
+ ActiveModel::Serializer.config.adapter = @previous_adapter
10
+ end
11
+
12
+ def test_returns_default_adapter
13
+ adapter = ActiveModel::Serializer.adapter
14
+ assert_equal ActiveModel::Serializer::Adapter::Json, adapter
15
+ end
16
+
17
+ def test_overwrite_adapter_with_symbol
18
+ ActiveModel::Serializer.config.adapter = :null
19
+
20
+ adapter = ActiveModel::Serializer.adapter
21
+ assert_equal ActiveModel::Serializer::Adapter::Null, adapter
22
+ ensure
23
+
24
+ end
25
+
26
+ def test_overwrite_adapter_with_class
27
+ ActiveModel::Serializer.config.adapter = ActiveModel::Serializer::Adapter::Null
28
+
29
+ adapter = ActiveModel::Serializer.adapter
30
+ assert_equal ActiveModel::Serializer::Adapter::Null, adapter
31
+ end
32
+
33
+ def test_raises_exception_if_invalid_symbol_given
34
+ ActiveModel::Serializer.config.adapter = :unknown
35
+
36
+ assert_raises ArgumentError do
37
+ ActiveModel::Serializer.adapter
38
+ end
39
+ end
40
+
41
+ def test_raises_exception_if_it_does_not_know_hot_to_infer_adapter
42
+ ActiveModel::Serializer.config.adapter = 42
43
+
44
+ assert_raises ArgumentError do
45
+ ActiveModel::Serializer.adapter
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,127 @@
1
+ require 'test_helper'
2
+
3
+ module ActiveModel
4
+ class Serializer
5
+ class AssociationsTest < Minitest::Test
6
+ class Model
7
+ def initialize(hash={})
8
+ @attributes = hash
9
+ end
10
+
11
+ def read_attribute_for_serialization(name)
12
+ @attributes[name]
13
+ end
14
+
15
+ def method_missing(meth, *args)
16
+ if meth.to_s =~ /^(.*)=$/
17
+ @attributes[$1.to_sym] = args[0]
18
+ elsif @attributes.key?(meth)
19
+ @attributes[meth]
20
+ else
21
+ super
22
+ end
23
+ end
24
+ end
25
+
26
+ def setup
27
+ @author = Author.new(name: 'Steve K.')
28
+ @author.bio = nil
29
+ @author.roles = []
30
+ @blog = Blog.new({ name: 'AMS Blog' })
31
+ @post = Post.new({ title: 'New Post', body: 'Body' })
32
+ @comment = Comment.new({ id: 1, body: 'ZOMG A COMMENT' })
33
+ @post.comments = [@comment]
34
+ @post.blog = @blog
35
+ @comment.post = @post
36
+ @comment.author = nil
37
+ @post.author = @author
38
+ @author.posts = [@post]
39
+
40
+ @post_serializer = PostSerializer.new(@post, {custom_options: true})
41
+ @author_serializer = AuthorSerializer.new(@author)
42
+ @comment_serializer = CommentSerializer.new(@comment)
43
+ end
44
+
45
+ def test_has_many_and_has_one
46
+ assert_equal(
47
+ { posts: { type: :has_many, association_options: { embed: :ids } },
48
+ roles: { type: :has_many, association_options: { embed: :ids } },
49
+ bio: { type: :has_one, association_options: {} } },
50
+ @author_serializer.class._associations
51
+ )
52
+ @author_serializer.each_association do |name, serializer, options|
53
+ if name == :posts
54
+ assert_equal({embed: :ids}, options)
55
+ assert_kind_of(ActiveModel::Serializer.config.array_serializer, serializer)
56
+ elsif name == :bio
57
+ assert_equal({}, options)
58
+ assert_nil serializer
59
+ elsif name == :roles
60
+ assert_equal({embed: :ids}, options)
61
+ assert_kind_of(ActiveModel::Serializer.config.array_serializer, serializer)
62
+ else
63
+ flunk "Unknown association: #{name}"
64
+ end
65
+ end
66
+ end
67
+
68
+ def test_serializer_options_are_passed_into_associations_serializers
69
+ @post_serializer.each_association do |name, association|
70
+ if name == :comments
71
+ assert association.first.custom_options[:custom_options]
72
+ end
73
+ end
74
+ end
75
+
76
+ def test_belongs_to
77
+ assert_equal(
78
+ { post: { type: :belongs_to, association_options: {} },
79
+ author: { type: :belongs_to, association_options: {} } },
80
+ @comment_serializer.class._associations
81
+ )
82
+ @comment_serializer.each_association do |name, serializer, options|
83
+ if name == :post
84
+ assert_equal({}, options)
85
+ assert_kind_of(PostSerializer, serializer)
86
+ elsif name == :author
87
+ assert_equal({}, options)
88
+ assert_nil serializer
89
+ else
90
+ flunk "Unknown association: #{name}"
91
+ end
92
+ end
93
+ end
94
+
95
+ def test_belongs_to_with_custom_method
96
+ blog_is_present = false
97
+
98
+ @post_serializer.each_association do |name, serializer, options|
99
+ blog_is_present = true if name == :blog
100
+ end
101
+
102
+ assert blog_is_present
103
+ end
104
+
105
+ def test_associations_inheritance
106
+ inherited_klass = Class.new(PostSerializer)
107
+
108
+ assert_equal(PostSerializer._associations, inherited_klass._associations)
109
+ end
110
+
111
+ def test_associations_inheritance_with_new_association
112
+ inherited_klass = Class.new(PostSerializer) do
113
+ has_many :top_comments, serializer: CommentSerializer
114
+ end
115
+ expected_associations = PostSerializer._associations.merge(
116
+ top_comments: {
117
+ type: :has_many,
118
+ association_options: {
119
+ serializer: CommentSerializer
120
+ }
121
+ }
122
+ )
123
+ assert_equal(inherited_klass._associations, expected_associations)
124
+ end
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,38 @@
1
+ require 'test_helper'
2
+
3
+ module ActiveModel
4
+ class Serializer
5
+ class AttributeTest < Minitest::Test
6
+ def setup
7
+ @blog = Blog.new({ id: 1, name: 'AMS Hints' })
8
+ @blog_serializer = AlternateBlogSerializer.new(@blog)
9
+ end
10
+
11
+ def test_attributes_definition
12
+ assert_equal([:id, :title],
13
+ @blog_serializer.class._attributes)
14
+ end
15
+
16
+ def test_json_serializable_hash
17
+ adapter = ActiveModel::Serializer::Adapter::Json.new(@blog_serializer)
18
+ assert_equal({:id=>1, :title=>"AMS Hints"}, adapter.serializable_hash)
19
+ end
20
+
21
+ def test_attribute_inheritance_with_key
22
+ inherited_klass = Class.new(AlternateBlogSerializer)
23
+ blog_serializer = inherited_klass.new(@blog)
24
+ adapter = ActiveModel::Serializer::Adapter::Json.new(blog_serializer)
25
+ assert_equal({:id=>1, :title=>"AMS Hints"}, adapter.serializable_hash)
26
+ end
27
+
28
+ def test_multiple_calls_with_the_same_attribute
29
+ serializer_class = Class.new(ActiveModel::Serializer) do
30
+ attribute :title
31
+ attribute :title
32
+ end
33
+
34
+ assert_equal([:title], serializer_class._attributes)
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,63 @@
1
+ require 'test_helper'
2
+
3
+ module ActiveModel
4
+ class Serializer
5
+ class AttributesTest < Minitest::Test
6
+ def setup
7
+ @profile = Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' })
8
+ @profile_serializer = ProfileSerializer.new(@profile)
9
+ @comment = Comment.new(id: 1, body: "ZOMG!!", date: "2015")
10
+ @serializer_klass = Class.new(CommentSerializer)
11
+ @serializer_klass_with_new_attributes = Class.new(CommentSerializer) do
12
+ attributes :date, :likes
13
+ end
14
+ end
15
+
16
+ def test_attributes_definition
17
+ assert_equal([:name, :description],
18
+ @profile_serializer.class._attributes)
19
+ end
20
+
21
+ def test_attributes_with_fields_option
22
+ assert_equal({name: 'Name 1'},
23
+ @profile_serializer.attributes(fields: [:name]))
24
+ end
25
+
26
+ def test_required_fields
27
+ assert_equal({name: 'Name 1', description: 'Description 1'},
28
+ @profile_serializer.attributes(fields: [:name, :description], required_fields: [:name]))
29
+
30
+ end
31
+
32
+ def test_attributes_inheritance_definition
33
+ assert_equal([:id, :body], @serializer_klass._attributes)
34
+ end
35
+
36
+ def test_attributes_inheritance
37
+ serializer = @serializer_klass.new(@comment)
38
+ assert_equal({id: 1, body: "ZOMG!!"},
39
+ serializer.attributes)
40
+ end
41
+
42
+ def test_attribute_inheritance_with_new_attribute_definition
43
+ assert_equal([:id, :body, :date, :likes], @serializer_klass_with_new_attributes._attributes)
44
+ assert_equal([:id, :body], CommentSerializer._attributes)
45
+ end
46
+
47
+ def test_attribute_inheritance_with_new_attribute
48
+ serializer = @serializer_klass_with_new_attributes.new(@comment)
49
+ assert_equal({id: 1, body: "ZOMG!!", date: "2015", likes: nil},
50
+ serializer.attributes)
51
+ end
52
+
53
+ def test_multiple_calls_with_the_same_attribute
54
+ serializer_class = Class.new(ActiveModel::Serializer) do
55
+ attributes :id, :title
56
+ attributes :id, :title, :title, :body
57
+ end
58
+
59
+ assert_equal([:id, :title, :body], serializer_class._attributes)
60
+ end
61
+ end
62
+ end
63
+ end