cm-active_model_serializers 0.10.0.rc1.1

Sign up to get free protection for your applications and to get access to all the features.
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