active_model_serializers 0.10.0 → 0.10.9
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.
- checksums.yaml +5 -5
- data/.rubocop.yml +10 -5
- data/.travis.yml +41 -21
- data/CHANGELOG.md +200 -2
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +25 -4
- data/README.md +166 -28
- data/Rakefile +5 -32
- data/active_model_serializers.gemspec +23 -25
- data/appveyor.yml +10 -6
- data/bin/rubocop +38 -0
- data/docs/README.md +2 -1
- data/docs/general/adapters.md +35 -11
- data/docs/general/caching.md +7 -1
- data/docs/general/configuration_options.md +86 -1
- data/docs/general/deserialization.md +1 -1
- data/docs/general/fields.md +31 -0
- data/docs/general/getting_started.md +1 -1
- data/docs/general/logging.md +7 -0
- data/docs/general/rendering.md +63 -25
- data/docs/general/serializers.md +137 -14
- data/docs/howto/add_pagination_links.md +16 -17
- data/docs/howto/add_relationship_links.md +140 -0
- data/docs/howto/add_root_key.md +11 -0
- data/docs/howto/grape_integration.md +42 -0
- data/docs/howto/outside_controller_use.md +12 -4
- data/docs/howto/passing_arbitrary_options.md +2 -2
- data/docs/howto/serialize_poro.md +46 -5
- data/docs/howto/test.md +2 -0
- data/docs/howto/upgrade_from_0_8_to_0_10.md +265 -0
- data/docs/integrations/ember-and-json-api.md +67 -32
- data/docs/jsonapi/schema.md +1 -1
- data/lib/action_controller/serialization.rb +15 -3
- data/lib/active_model/serializable_resource.rb +2 -0
- data/lib/active_model/serializer/adapter/attributes.rb +2 -0
- data/lib/active_model/serializer/adapter/base.rb +4 -0
- data/lib/active_model/serializer/adapter/json.rb +2 -0
- data/lib/active_model/serializer/adapter/json_api.rb +2 -0
- data/lib/active_model/serializer/adapter/null.rb +2 -0
- data/lib/active_model/serializer/adapter.rb +2 -0
- data/lib/active_model/serializer/array_serializer.rb +10 -5
- data/lib/active_model/serializer/association.rb +64 -10
- data/lib/active_model/serializer/attribute.rb +2 -0
- data/lib/active_model/serializer/belongs_to_reflection.rb +6 -3
- data/lib/active_model/serializer/collection_serializer.rb +39 -13
- data/lib/active_model/serializer/{caching.rb → concerns/caching.rb} +87 -116
- data/lib/active_model/serializer/error_serializer.rb +13 -7
- data/lib/active_model/serializer/errors_serializer.rb +27 -20
- data/lib/active_model/serializer/field.rb +2 -0
- data/lib/active_model/serializer/fieldset.rb +2 -0
- data/lib/active_model/serializer/has_many_reflection.rb +5 -3
- data/lib/active_model/serializer/has_one_reflection.rb +3 -4
- data/lib/active_model/serializer/lazy_association.rb +99 -0
- data/lib/active_model/serializer/link.rb +23 -0
- data/lib/active_model/serializer/lint.rb +136 -130
- data/lib/active_model/serializer/null.rb +2 -0
- data/lib/active_model/serializer/reflection.rb +132 -67
- data/lib/active_model/serializer/version.rb +3 -1
- data/lib/active_model/serializer.rb +308 -82
- data/lib/active_model_serializers/adapter/attributes.rb +5 -66
- data/lib/active_model_serializers/adapter/base.rb +41 -39
- data/lib/active_model_serializers/adapter/json.rb +2 -0
- data/lib/active_model_serializers/adapter/json_api/deserialization.rb +4 -2
- data/lib/active_model_serializers/adapter/json_api/error.rb +2 -0
- data/lib/active_model_serializers/adapter/json_api/jsonapi.rb +2 -0
- data/lib/active_model_serializers/adapter/json_api/link.rb +3 -1
- data/lib/active_model_serializers/adapter/json_api/meta.rb +2 -0
- data/lib/active_model_serializers/adapter/json_api/pagination_links.rb +49 -21
- data/lib/active_model_serializers/adapter/json_api/relationship.rb +77 -23
- data/lib/active_model_serializers/adapter/json_api/resource_identifier.rb +41 -10
- data/lib/active_model_serializers/adapter/json_api.rb +84 -65
- data/lib/active_model_serializers/adapter/null.rb +2 -0
- data/lib/active_model_serializers/adapter.rb +9 -1
- data/lib/active_model_serializers/callbacks.rb +2 -0
- data/lib/active_model_serializers/deprecate.rb +3 -2
- data/lib/active_model_serializers/deserialization.rb +4 -0
- data/lib/active_model_serializers/json_pointer.rb +2 -0
- data/lib/active_model_serializers/logging.rb +2 -0
- data/lib/active_model_serializers/lookup_chain.rb +82 -0
- data/lib/active_model_serializers/model.rb +111 -28
- data/lib/active_model_serializers/railtie.rb +7 -1
- data/lib/active_model_serializers/register_jsonapi_renderer.rb +46 -31
- data/lib/active_model_serializers/serializable_resource.rb +10 -7
- data/lib/active_model_serializers/serialization_context.rb +12 -3
- data/lib/active_model_serializers/test/schema.rb +4 -2
- data/lib/active_model_serializers/test/serializer.rb +2 -0
- data/lib/active_model_serializers/test.rb +2 -0
- data/lib/active_model_serializers.rb +35 -10
- data/lib/generators/rails/resource_override.rb +3 -1
- data/lib/generators/rails/serializer_generator.rb +6 -4
- data/lib/grape/active_model_serializers.rb +9 -5
- data/lib/grape/formatters/active_model_serializers.rb +21 -2
- data/lib/grape/helpers/active_model_serializers.rb +3 -0
- data/lib/tasks/rubocop.rake +55 -0
- data/test/action_controller/adapter_selector_test.rb +16 -5
- data/test/action_controller/explicit_serializer_test.rb +7 -4
- data/test/action_controller/json/include_test.rb +108 -27
- data/test/action_controller/json_api/deserialization_test.rb +3 -1
- data/test/action_controller/json_api/errors_test.rb +10 -9
- data/test/action_controller/json_api/fields_test.rb +68 -0
- data/test/action_controller/json_api/linked_test.rb +31 -24
- data/test/action_controller/json_api/pagination_test.rb +33 -23
- data/test/action_controller/json_api/transform_test.rb +13 -3
- data/test/action_controller/lookup_proc_test.rb +51 -0
- data/test/action_controller/namespace_lookup_test.rb +234 -0
- data/test/action_controller/serialization_scope_name_test.rb +14 -6
- data/test/action_controller/serialization_test.rb +23 -12
- data/test/active_model_serializers/adapter_for_test.rb +2 -0
- data/test/active_model_serializers/json_pointer_test.rb +17 -13
- data/test/active_model_serializers/logging_test.rb +2 -0
- data/test/active_model_serializers/model_test.rb +139 -4
- data/test/active_model_serializers/railtie_test_isolated.rb +14 -7
- data/test/active_model_serializers/register_jsonapi_renderer_test_isolated.rb +163 -0
- data/test/active_model_serializers/serialization_context_test_isolated.rb +25 -10
- data/test/active_model_serializers/test/schema_test.rb +5 -2
- data/test/active_model_serializers/test/serializer_test.rb +2 -0
- data/test/active_record_test.rb +2 -0
- data/test/adapter/attributes_test.rb +42 -0
- data/test/adapter/deprecation_test.rb +2 -0
- data/test/adapter/json/belongs_to_test.rb +2 -0
- data/test/adapter/json/collection_test.rb +16 -0
- data/test/adapter/json/has_many_test.rb +12 -2
- data/test/adapter/json/transform_test.rb +17 -15
- data/test/adapter/json_api/belongs_to_test.rb +2 -0
- data/test/adapter/json_api/collection_test.rb +6 -3
- data/test/adapter/json_api/errors_test.rb +19 -19
- data/test/adapter/json_api/fields_test.rb +14 -3
- data/test/adapter/json_api/has_many_explicit_serializer_test.rb +2 -0
- data/test/adapter/json_api/has_many_test.rb +51 -20
- data/test/adapter/json_api/has_one_test.rb +2 -0
- data/test/adapter/json_api/include_data_if_sideloaded_test.rb +215 -0
- data/test/adapter/json_api/json_api_test.rb +7 -7
- data/test/adapter/json_api/linked_test.rb +35 -12
- data/test/adapter/json_api/links_test.rb +22 -3
- data/test/adapter/json_api/pagination_links_test.rb +55 -13
- data/test/adapter/json_api/parse_test.rb +3 -1
- data/test/adapter/json_api/relationship_test.rb +311 -73
- data/test/adapter/json_api/resource_meta_test.rb +5 -3
- data/test/adapter/json_api/toplevel_jsonapi_test.rb +2 -0
- data/test/adapter/json_api/transform_test.rb +265 -253
- data/test/adapter/json_api/type_test.rb +170 -36
- data/test/adapter/json_test.rb +10 -7
- data/test/adapter/null_test.rb +3 -2
- data/test/adapter/polymorphic_test.rb +54 -5
- data/test/adapter_test.rb +3 -1
- data/test/array_serializer_test.rb +2 -0
- data/test/benchmark/app.rb +3 -1
- data/test/benchmark/benchmarking_support.rb +3 -1
- data/test/benchmark/bm_active_record.rb +83 -0
- data/test/benchmark/bm_adapter.rb +40 -0
- data/test/benchmark/bm_caching.rb +18 -16
- data/test/benchmark/bm_lookup_chain.rb +85 -0
- data/test/benchmark/bm_transform.rb +23 -10
- data/test/benchmark/controllers.rb +18 -17
- data/test/benchmark/fixtures.rb +74 -72
- data/test/cache_test.rb +301 -69
- data/test/collection_serializer_test.rb +33 -14
- data/test/fixtures/active_record.rb +47 -10
- data/test/fixtures/poro.rb +128 -183
- data/test/generators/scaffold_controller_generator_test.rb +2 -0
- data/test/generators/serializer_generator_test.rb +25 -5
- data/test/grape_test.rb +172 -56
- data/test/lint_test.rb +3 -1
- data/test/logger_test.rb +15 -11
- data/test/poro_test.rb +2 -0
- data/test/serializable_resource_test.rb +20 -22
- data/test/serializers/association_macros_test.rb +5 -2
- data/test/serializers/associations_test.rb +274 -49
- data/test/serializers/attribute_test.rb +7 -3
- data/test/serializers/attributes_test.rb +3 -1
- data/test/serializers/caching_configuration_test_isolated.rb +8 -6
- data/test/serializers/configuration_test.rb +2 -0
- data/test/serializers/fieldset_test.rb +3 -1
- data/test/serializers/meta_test.rb +14 -6
- data/test/serializers/options_test.rb +19 -6
- data/test/serializers/read_attribute_for_serialization_test.rb +5 -3
- data/test/serializers/reflection_test.rb +481 -0
- data/test/serializers/root_test.rb +3 -1
- data/test/serializers/serialization_test.rb +4 -2
- data/test/serializers/serializer_for_test.rb +14 -10
- data/test/serializers/serializer_for_with_namespace_test.rb +90 -0
- data/test/support/isolated_unit.rb +11 -4
- data/test/support/rails5_shims.rb +10 -2
- data/test/support/rails_app.rb +4 -9
- data/test/support/serialization_testing.rb +33 -5
- data/test/test_helper.rb +15 -0
- metadata +126 -46
- data/.rubocop_todo.yml +0 -167
- data/docs/ARCHITECTURE.md +0 -126
- data/lib/active_model/serializer/associations.rb +0 -100
- data/lib/active_model/serializer/attributes.rb +0 -82
- data/lib/active_model/serializer/collection_reflection.rb +0 -7
- data/lib/active_model/serializer/configuration.rb +0 -35
- data/lib/active_model/serializer/include_tree.rb +0 -111
- data/lib/active_model/serializer/links.rb +0 -35
- data/lib/active_model/serializer/meta.rb +0 -29
- data/lib/active_model/serializer/singular_reflection.rb +0 -7
- data/lib/active_model/serializer/type.rb +0 -25
- data/lib/active_model_serializers/key_transform.rb +0 -70
- data/test/active_model_serializers/key_transform_test.rb +0 -263
- data/test/adapter/json_api/has_many_embed_ids_test.rb +0 -43
- data/test/adapter/json_api/relationships_test.rb +0 -199
- data/test/adapter/json_api/resource_identifier_test.rb +0 -85
- data/test/include_tree/from_include_args_test.rb +0 -26
- data/test/include_tree/from_string_test.rb +0 -94
- data/test/include_tree/include_args_to_hash_test.rb +0 -64
data/test/cache_test.rb
CHANGED
|
@@ -1,25 +1,121 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'test_helper'
|
|
2
4
|
require 'tmpdir'
|
|
3
5
|
require 'tempfile'
|
|
4
6
|
|
|
5
7
|
module ActiveModelSerializers
|
|
6
8
|
class CacheTest < ActiveSupport::TestCase
|
|
7
|
-
|
|
8
|
-
|
|
9
|
+
class Article < ::Model
|
|
10
|
+
attributes :title
|
|
11
|
+
# To confirm error is raised when cache_key is not set and cache_key option not passed to cache
|
|
9
12
|
undef_method :cache_key
|
|
10
13
|
end
|
|
14
|
+
class ArticleSerializer < ActiveModel::Serializer
|
|
15
|
+
cache only: [:place], skip_digest: true
|
|
16
|
+
attributes :title
|
|
17
|
+
end
|
|
11
18
|
|
|
12
|
-
|
|
13
|
-
|
|
19
|
+
class Author < ::Model
|
|
20
|
+
attributes :id, :name
|
|
21
|
+
associations :posts, :bio, :roles
|
|
22
|
+
end
|
|
23
|
+
# Instead of a primitive cache key (i.e. a string), this class
|
|
24
|
+
# returns a list of objects that require to be expanded themselves.
|
|
25
|
+
class AuthorWithExpandableCacheElements < Author
|
|
26
|
+
# For the test purposes it's important that #to_s for HasCacheKey differs
|
|
27
|
+
# between instances, hence not a Struct.
|
|
28
|
+
class HasCacheKey
|
|
29
|
+
attr_reader :cache_key
|
|
30
|
+
def initialize(cache_key)
|
|
31
|
+
@cache_key = cache_key
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def to_s
|
|
35
|
+
"HasCacheKey##{object_id}"
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def cache_key
|
|
40
|
+
[
|
|
41
|
+
HasCacheKey.new(name),
|
|
42
|
+
HasCacheKey.new(id)
|
|
43
|
+
]
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
class UncachedAuthor < Author
|
|
47
|
+
# To confirm cache_key is set using updated_at and cache_key option passed to cache
|
|
14
48
|
undef_method :cache_key
|
|
15
49
|
end
|
|
50
|
+
class AuthorSerializer < ActiveModel::Serializer
|
|
51
|
+
cache key: 'writer', skip_digest: true
|
|
52
|
+
attributes :id, :name
|
|
16
53
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
54
|
+
has_many :posts
|
|
55
|
+
has_many :roles
|
|
56
|
+
has_one :bio
|
|
57
|
+
end
|
|
58
|
+
class AuthorSerializerWithCache < ActiveModel::Serializer
|
|
59
|
+
cache
|
|
60
|
+
|
|
61
|
+
attributes :name
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
class Blog < ::Model
|
|
65
|
+
attributes :name
|
|
66
|
+
associations :writer
|
|
67
|
+
end
|
|
68
|
+
class BlogSerializer < ActiveModel::Serializer
|
|
69
|
+
cache key: 'blog'
|
|
70
|
+
attributes :id, :name
|
|
71
|
+
|
|
72
|
+
belongs_to :writer
|
|
20
73
|
end
|
|
21
74
|
|
|
22
|
-
|
|
75
|
+
class Comment < ::Model
|
|
76
|
+
attributes :id, :body
|
|
77
|
+
associations :post, :author
|
|
78
|
+
|
|
79
|
+
# Uses a custom non-time-based cache key
|
|
80
|
+
def cache_key
|
|
81
|
+
"comment/#{id}"
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
class CommentSerializer < ActiveModel::Serializer
|
|
85
|
+
cache expires_in: 1.day, skip_digest: true
|
|
86
|
+
attributes :id, :body
|
|
87
|
+
belongs_to :post
|
|
88
|
+
belongs_to :author
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
class Post < ::Model
|
|
92
|
+
attributes :id, :title, :body
|
|
93
|
+
associations :author, :comments, :blog
|
|
94
|
+
end
|
|
95
|
+
class PostSerializer < ActiveModel::Serializer
|
|
96
|
+
cache key: 'post', expires_in: 0.1, skip_digest: true
|
|
97
|
+
attributes :id, :title, :body
|
|
98
|
+
|
|
99
|
+
has_many :comments
|
|
100
|
+
belongs_to :blog
|
|
101
|
+
belongs_to :author
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
class Role < ::Model
|
|
105
|
+
attributes :name, :description, :special_attribute
|
|
106
|
+
associations :author
|
|
107
|
+
end
|
|
108
|
+
class RoleSerializer < ActiveModel::Serializer
|
|
109
|
+
cache only: [:name, :slug], skip_digest: true
|
|
110
|
+
attributes :id, :name, :description
|
|
111
|
+
attribute :friendly_id, key: :slug
|
|
112
|
+
belongs_to :author
|
|
113
|
+
|
|
114
|
+
def friendly_id
|
|
115
|
+
"#{object.name}-#{object.id}"
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
class InheritedRoleSerializer < RoleSerializer
|
|
23
119
|
cache key: 'inherited_role', only: [:name, :special_attribute]
|
|
24
120
|
attribute :special_attribute
|
|
25
121
|
end
|
|
@@ -27,10 +123,10 @@ module ActiveModelSerializers
|
|
|
27
123
|
setup do
|
|
28
124
|
cache_store.clear
|
|
29
125
|
@comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
|
|
30
|
-
@post = Post.new(title: 'New Post', body: 'Body')
|
|
126
|
+
@post = Post.new(id: 'post', title: 'New Post', body: 'Body')
|
|
31
127
|
@bio = Bio.new(id: 1, content: 'AMS Contributor')
|
|
32
|
-
@author = Author.new(name: 'Joao M. D. Moura')
|
|
33
|
-
@blog = Blog.new(id: 999, name: 'Custom blog', writer: @author
|
|
128
|
+
@author = Author.new(id: 'author', name: 'Joao M. D. Moura')
|
|
129
|
+
@blog = Blog.new(id: 999, name: 'Custom blog', writer: @author)
|
|
34
130
|
@role = Role.new(name: 'Great Author')
|
|
35
131
|
@location = Location.new(lat: '-23.550520', lng: '-46.633309')
|
|
36
132
|
@place = Place.new(name: 'Amazing Place')
|
|
@@ -55,6 +151,65 @@ module ActiveModelSerializers
|
|
|
55
151
|
@blog_serializer = BlogSerializer.new(@blog)
|
|
56
152
|
end
|
|
57
153
|
|
|
154
|
+
def test_expiring_of_cache_at_update_of_record
|
|
155
|
+
original_cache_versioning = :none
|
|
156
|
+
|
|
157
|
+
if ARModels::Author.respond_to?(:cache_versioning)
|
|
158
|
+
original_cache_versioning = ARModels::Author.cache_versioning
|
|
159
|
+
ARModels::Author.cache_versioning = true
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
author = ARModels::Author.create(name: 'Foo')
|
|
163
|
+
author_json = AuthorSerializerWithCache.new(author).as_json
|
|
164
|
+
|
|
165
|
+
assert_equal 'Foo', author_json[:name]
|
|
166
|
+
|
|
167
|
+
author.update_attributes(name: 'Bar')
|
|
168
|
+
author_json = AuthorSerializerWithCache.new(author).as_json
|
|
169
|
+
|
|
170
|
+
expected = 'Bar'
|
|
171
|
+
actual = author_json[:name]
|
|
172
|
+
if ENV['APPVEYOR'] && actual != expected
|
|
173
|
+
skip('Cache expiration tests sometimes fail on Appveyor. FIXME :)')
|
|
174
|
+
else
|
|
175
|
+
assert_equal expected, actual
|
|
176
|
+
end
|
|
177
|
+
ensure
|
|
178
|
+
ARModels::Author.cache_versioning = original_cache_versioning unless original_cache_versioning == :none
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def test_cache_expiration_in_collection_on_update_of_record
|
|
182
|
+
original_cache_versioning = :none
|
|
183
|
+
|
|
184
|
+
if ARModels::Author.respond_to?(:cache_versioning)
|
|
185
|
+
original_cache_versioning = ARModels::Author.cache_versioning
|
|
186
|
+
ARModels::Author.cache_versioning = true
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
foo = 'Foo'
|
|
190
|
+
foo2 = 'Foo2'
|
|
191
|
+
author = ARModels::Author.create(name: foo)
|
|
192
|
+
author2 = ARModels::Author.create(name: foo2)
|
|
193
|
+
author_collection = [author, author, author2]
|
|
194
|
+
|
|
195
|
+
collection_json = render_object_with_cache(author_collection, each_serializer: AuthorSerializerWithCache)
|
|
196
|
+
actual = collection_json
|
|
197
|
+
expected = [{ name: foo }, { name: foo }, { name: foo2 }]
|
|
198
|
+
if ENV['APPVEYOR'] && actual != expected
|
|
199
|
+
skip('Cache expiration tests sometimes fail on Appveyor. FIXME :)')
|
|
200
|
+
else
|
|
201
|
+
assert_equal expected, actual
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
bar = 'Bar'
|
|
205
|
+
author.update!(name: bar)
|
|
206
|
+
|
|
207
|
+
collection_json = render_object_with_cache(author_collection, each_serializer: AuthorSerializerWithCache)
|
|
208
|
+
assert_equal [{ name: bar }, { name: bar }, { name: foo2 }], collection_json
|
|
209
|
+
ensure
|
|
210
|
+
ARModels::Author.cache_versioning = original_cache_versioning unless original_cache_versioning == :none
|
|
211
|
+
end
|
|
212
|
+
|
|
58
213
|
def test_explicit_cache_store
|
|
59
214
|
default_store = Class.new(ActiveModel::Serializer) do
|
|
60
215
|
cache
|
|
@@ -93,7 +248,7 @@ module ActiveModelSerializers
|
|
|
93
248
|
def test_cache_key_definition
|
|
94
249
|
assert_equal('post', @post_serializer.class._cache_key)
|
|
95
250
|
assert_equal('writer', @author_serializer.class._cache_key)
|
|
96
|
-
|
|
251
|
+
assert_nil(@comment_serializer.class._cache_key)
|
|
97
252
|
end
|
|
98
253
|
|
|
99
254
|
def test_cache_key_interpolation_with_updated_at_when_cache_key_is_not_defined_on_object
|
|
@@ -101,14 +256,28 @@ module ActiveModelSerializers
|
|
|
101
256
|
uncached_author_serializer = AuthorSerializer.new(uncached_author)
|
|
102
257
|
|
|
103
258
|
render_object_with_cache(uncached_author)
|
|
104
|
-
key = "#{uncached_author_serializer.class._cache_key}/#{uncached_author_serializer.object.id}-#{uncached_author_serializer.object.updated_at.strftime(
|
|
105
|
-
key = "#{key}/#{adapter.
|
|
259
|
+
key = "#{uncached_author_serializer.class._cache_key}/#{uncached_author_serializer.object.id}-#{uncached_author_serializer.object.updated_at.strftime('%Y%m%d%H%M%S%9N')}"
|
|
260
|
+
key = "#{key}/#{adapter.cache_key}"
|
|
106
261
|
assert_equal(uncached_author_serializer.attributes.to_json, cache_store.fetch(key).to_json)
|
|
107
262
|
end
|
|
108
263
|
|
|
264
|
+
def test_cache_key_expansion
|
|
265
|
+
author = AuthorWithExpandableCacheElements.new(id: 10, name: 'hello')
|
|
266
|
+
same_author = AuthorWithExpandableCacheElements.new(id: 10, name: 'hello')
|
|
267
|
+
diff_author = AuthorWithExpandableCacheElements.new(id: 11, name: 'hello')
|
|
268
|
+
|
|
269
|
+
author_serializer = AuthorSerializer.new(author)
|
|
270
|
+
same_author_serializer = AuthorSerializer.new(same_author)
|
|
271
|
+
diff_author_serializer = AuthorSerializer.new(diff_author)
|
|
272
|
+
adapter = AuthorSerializer.serialization_adapter_instance
|
|
273
|
+
|
|
274
|
+
assert_equal(author_serializer.cache_key(adapter), same_author_serializer.cache_key(adapter))
|
|
275
|
+
refute_equal(author_serializer.cache_key(adapter), diff_author_serializer.cache_key(adapter))
|
|
276
|
+
end
|
|
277
|
+
|
|
109
278
|
def test_default_cache_key_fallback
|
|
110
279
|
render_object_with_cache(@comment)
|
|
111
|
-
key = "#{@comment.cache_key}/#{adapter.
|
|
280
|
+
key = "#{@comment.cache_key}/#{adapter.cache_key}"
|
|
112
281
|
assert_equal(@comment_serializer.attributes.to_json, cache_store.fetch(key).to_json)
|
|
113
282
|
end
|
|
114
283
|
|
|
@@ -117,31 +286,31 @@ module ActiveModelSerializers
|
|
|
117
286
|
e = assert_raises ActiveModel::Serializer::UndefinedCacheKey do
|
|
118
287
|
render_object_with_cache(article)
|
|
119
288
|
end
|
|
120
|
-
assert_match(/ActiveModelSerializers::CacheTest::Article must define #cache_key, or the 'key:' option must be passed into '
|
|
289
|
+
assert_match(/ActiveModelSerializers::CacheTest::Article must define #cache_key, or the 'key:' option must be passed into 'ActiveModelSerializers::CacheTest::ArticleSerializer.cache'/, e.message)
|
|
121
290
|
end
|
|
122
291
|
|
|
123
292
|
def test_cache_options_definition
|
|
124
293
|
assert_equal({ expires_in: 0.1, skip_digest: true }, @post_serializer.class._cache_options)
|
|
125
|
-
|
|
294
|
+
assert_nil(@blog_serializer.class._cache_options)
|
|
126
295
|
assert_equal({ expires_in: 1.day, skip_digest: true }, @comment_serializer.class._cache_options)
|
|
127
296
|
end
|
|
128
297
|
|
|
129
298
|
def test_fragment_cache_definition
|
|
130
|
-
assert_equal([:name], @role_serializer.class._cache_only)
|
|
299
|
+
assert_equal([:name, :slug], @role_serializer.class._cache_only)
|
|
131
300
|
assert_equal([:content], @bio_serializer.class._cache_except)
|
|
132
301
|
end
|
|
133
302
|
|
|
134
303
|
def test_associations_separately_cache
|
|
135
304
|
cache_store.clear
|
|
136
|
-
|
|
137
|
-
|
|
305
|
+
assert_nil(cache_store.fetch(@post.cache_key))
|
|
306
|
+
assert_nil(cache_store.fetch(@comment.cache_key))
|
|
138
307
|
|
|
139
308
|
Timecop.freeze(Time.current) do
|
|
140
309
|
render_object_with_cache(@post)
|
|
141
310
|
|
|
142
|
-
key = "#{@post.cache_key}/#{adapter.
|
|
311
|
+
key = "#{@post.cache_key}/#{adapter.cache_key}"
|
|
143
312
|
assert_equal(@post_serializer.attributes, cache_store.fetch(key))
|
|
144
|
-
key = "#{@comment.cache_key}/#{adapter.
|
|
313
|
+
key = "#{@comment.cache_key}/#{adapter.cache_key}"
|
|
145
314
|
assert_equal(@comment_serializer.attributes, cache_store.fetch(key))
|
|
146
315
|
end
|
|
147
316
|
end
|
|
@@ -152,9 +321,9 @@ module ActiveModelSerializers
|
|
|
152
321
|
render_object_with_cache(@post)
|
|
153
322
|
|
|
154
323
|
# Check if it cached the objects separately
|
|
155
|
-
key = "#{@post.cache_key}/#{adapter.
|
|
324
|
+
key = "#{@post.cache_key}/#{adapter.cache_key}"
|
|
156
325
|
assert_equal(@post_serializer.attributes, cache_store.fetch(key))
|
|
157
|
-
key = "#{@comment.cache_key}/#{adapter.
|
|
326
|
+
key = "#{@comment.cache_key}/#{adapter.cache_key}"
|
|
158
327
|
assert_equal(@comment_serializer.attributes, cache_store.fetch(key))
|
|
159
328
|
|
|
160
329
|
# Simulating update on comments relationship with Post
|
|
@@ -166,9 +335,9 @@ module ActiveModelSerializers
|
|
|
166
335
|
render_object_with_cache(@post)
|
|
167
336
|
|
|
168
337
|
# Check if the the new comment was cached
|
|
169
|
-
key = "#{new_comment.cache_key}/#{adapter.
|
|
338
|
+
key = "#{new_comment.cache_key}/#{adapter.cache_key}"
|
|
170
339
|
assert_equal(new_comment_serializer.attributes, cache_store.fetch(key))
|
|
171
|
-
key = "#{@post.cache_key}/#{adapter.
|
|
340
|
+
key = "#{@post.cache_key}/#{adapter.cache_key}"
|
|
172
341
|
assert_equal(@post_serializer.attributes, cache_store.fetch(key))
|
|
173
342
|
end
|
|
174
343
|
end
|
|
@@ -178,14 +347,14 @@ module ActiveModelSerializers
|
|
|
178
347
|
id: @location.id,
|
|
179
348
|
lat: @location.lat,
|
|
180
349
|
lng: @location.lng,
|
|
181
|
-
|
|
350
|
+
address: 'Nowhere'
|
|
182
351
|
}
|
|
183
352
|
|
|
184
353
|
hash = render_object_with_cache(@location)
|
|
185
354
|
|
|
186
355
|
assert_equal(hash, expected_result)
|
|
187
|
-
key = "#{@location.cache_key}/#{adapter.
|
|
188
|
-
assert_equal({
|
|
356
|
+
key = "#{@location.cache_key}/#{adapter.cache_key}"
|
|
357
|
+
assert_equal({ address: 'Nowhere' }, cache_store.fetch(key))
|
|
189
358
|
end
|
|
190
359
|
|
|
191
360
|
def test_fragment_cache_with_inheritance
|
|
@@ -204,9 +373,9 @@ module ActiveModelSerializers
|
|
|
204
373
|
|
|
205
374
|
# Based on original failing test by @kevintyll
|
|
206
375
|
# rubocop:disable Metrics/AbcSize
|
|
207
|
-
def
|
|
376
|
+
def test_a_serializer_rendered_by_two_adapter_returns_differently_fetch_attributes
|
|
208
377
|
Object.const_set(:Alert, Class.new(ActiveModelSerializers::Model) do
|
|
209
|
-
|
|
378
|
+
attributes :id, :status, :resource, :started_at, :ended_at, :updated_at, :created_at
|
|
210
379
|
end)
|
|
211
380
|
Object.const_set(:UncachedAlertSerializer, Class.new(ActiveModel::Serializer) do
|
|
212
381
|
attributes :id, :status, :resource, :started_at, :ended_at, :updated_at, :created_at
|
|
@@ -225,7 +394,7 @@ module ActiveModelSerializers
|
|
|
225
394
|
created_at: Time.new(2016, 3, 31, 21, 37, 35, 0)
|
|
226
395
|
)
|
|
227
396
|
|
|
228
|
-
|
|
397
|
+
expected_fetch_attributes = {
|
|
229
398
|
id: 1,
|
|
230
399
|
status: 'fail',
|
|
231
400
|
resource: 'resource-1',
|
|
@@ -233,7 +402,7 @@ module ActiveModelSerializers
|
|
|
233
402
|
ended_at: nil,
|
|
234
403
|
updated_at: alert.updated_at,
|
|
235
404
|
created_at: alert.created_at
|
|
236
|
-
}
|
|
405
|
+
}.with_indifferent_access
|
|
237
406
|
expected_cached_jsonapi_attributes = {
|
|
238
407
|
id: '1',
|
|
239
408
|
type: 'alerts',
|
|
@@ -245,15 +414,15 @@ module ActiveModelSerializers
|
|
|
245
414
|
updated_at: alert.updated_at,
|
|
246
415
|
created_at: alert.created_at
|
|
247
416
|
}
|
|
248
|
-
}
|
|
417
|
+
}.with_indifferent_access
|
|
249
418
|
|
|
250
419
|
# Assert attributes are serialized correctly
|
|
251
420
|
serializable_alert = serializable(alert, serializer: AlertSerializer, adapter: :attributes)
|
|
252
|
-
attributes_serialization = serializable_alert.as_json
|
|
253
|
-
assert_equal
|
|
421
|
+
attributes_serialization = serializable_alert.as_json.with_indifferent_access
|
|
422
|
+
assert_equal expected_fetch_attributes, alert.attributes
|
|
254
423
|
assert_equal alert.attributes, attributes_serialization
|
|
255
424
|
attributes_cache_key = serializable_alert.adapter.serializer.cache_key(serializable_alert.adapter)
|
|
256
|
-
assert_equal attributes_serialization, cache_store.fetch(attributes_cache_key)
|
|
425
|
+
assert_equal attributes_serialization, cache_store.fetch(attributes_cache_key).with_indifferent_access
|
|
257
426
|
|
|
258
427
|
serializable_alert = serializable(alert, serializer: AlertSerializer, adapter: :json_api)
|
|
259
428
|
jsonapi_cache_key = serializable_alert.adapter.serializer.cache_key(serializable_alert.adapter)
|
|
@@ -265,7 +434,7 @@ module ActiveModelSerializers
|
|
|
265
434
|
serializable_alert = serializable(alert, serializer: UncachedAlertSerializer, adapter: :json_api)
|
|
266
435
|
assert_equal serializable_alert.as_json, jsonapi_serialization
|
|
267
436
|
|
|
268
|
-
cached_serialization = cache_store.fetch(jsonapi_cache_key)
|
|
437
|
+
cached_serialization = cache_store.fetch(jsonapi_cache_key).with_indifferent_access
|
|
269
438
|
assert_equal expected_cached_jsonapi_attributes, cached_serialization
|
|
270
439
|
ensure
|
|
271
440
|
Object.send(:remove_const, :Alert)
|
|
@@ -276,43 +445,83 @@ module ActiveModelSerializers
|
|
|
276
445
|
|
|
277
446
|
def test_uses_file_digest_in_cache_key
|
|
278
447
|
render_object_with_cache(@blog)
|
|
279
|
-
|
|
448
|
+
file_digest = Digest::MD5.hexdigest(File.open(__FILE__).read)
|
|
449
|
+
key = "#{@blog.cache_key}/#{adapter.cache_key}/#{file_digest}"
|
|
280
450
|
assert_equal(@blog_serializer.attributes, cache_store.fetch(key))
|
|
281
451
|
end
|
|
282
452
|
|
|
283
453
|
def test_cache_digest_definition
|
|
284
|
-
|
|
454
|
+
file_digest = Digest::MD5.hexdigest(File.open(__FILE__).read)
|
|
455
|
+
assert_equal(file_digest, @post_serializer.class._cache_digest)
|
|
285
456
|
end
|
|
286
457
|
|
|
287
458
|
def test_object_cache_keys
|
|
288
459
|
serializable = ActiveModelSerializers::SerializableResource.new([@comment, @comment])
|
|
289
|
-
|
|
460
|
+
include_directive = JSONAPI::IncludeDirective.new('*', allow_wildcard: true)
|
|
290
461
|
|
|
291
|
-
actual = ActiveModel::Serializer.object_cache_keys(serializable.adapter.serializer, serializable.adapter,
|
|
462
|
+
actual = ActiveModel::Serializer.object_cache_keys(serializable.adapter.serializer, serializable.adapter, include_directive)
|
|
292
463
|
|
|
293
464
|
assert_equal 3, actual.size
|
|
294
|
-
|
|
295
|
-
assert actual.any? { |key| key
|
|
296
|
-
|
|
465
|
+
expected_key = "comment/1/#{serializable.adapter.cache_key}"
|
|
466
|
+
assert actual.any? { |key| key == expected_key }, "actual '#{actual}' should include #{expected_key}"
|
|
467
|
+
expected_key = %r{post/post-\d+}
|
|
468
|
+
assert actual.any? { |key| key =~ expected_key }, "actual '#{actual}' should match '#{expected_key}'"
|
|
469
|
+
expected_key = %r{author/author-\d+}
|
|
470
|
+
assert actual.any? { |key| key =~ expected_key }, "actual '#{actual}' should match '#{expected_key}'"
|
|
297
471
|
end
|
|
298
472
|
|
|
299
|
-
|
|
300
|
-
|
|
473
|
+
# rubocop:disable Metrics/AbcSize
|
|
474
|
+
def test_fetch_attributes_from_cache
|
|
475
|
+
serializers = ActiveModel::Serializer::CollectionSerializer.new([@comment, @comment])
|
|
301
476
|
|
|
302
477
|
Timecop.freeze(Time.current) do
|
|
303
478
|
render_object_with_cache(@comment)
|
|
304
479
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
480
|
+
options = {}
|
|
481
|
+
adapter_options = {}
|
|
482
|
+
adapter_instance = ActiveModelSerializers::Adapter::Attributes.new(serializers, adapter_options)
|
|
483
|
+
serializers.serializable_hash(adapter_options, options, adapter_instance)
|
|
484
|
+
cached_attributes = options.fetch(:cached_attributes).with_indifferent_access
|
|
485
|
+
|
|
486
|
+
include_directive = ActiveModelSerializers.default_include_directive
|
|
487
|
+
manual_cached_attributes = ActiveModel::Serializer.cache_read_multi(serializers, adapter_instance, include_directive).with_indifferent_access
|
|
488
|
+
assert_equal manual_cached_attributes, cached_attributes
|
|
308
489
|
|
|
309
|
-
assert_equal cached_attributes["#{@comment.cache_key}/#{
|
|
310
|
-
assert_equal cached_attributes["#{@comment.post.cache_key}/#{
|
|
490
|
+
assert_equal cached_attributes["#{@comment.cache_key}/#{adapter_instance.cache_key}"], Comment.new(id: 1, body: 'ZOMG A COMMENT').attributes
|
|
491
|
+
assert_equal cached_attributes["#{@comment.post.cache_key}/#{adapter_instance.cache_key}"], Post.new(id: 'post', title: 'New Post', body: 'Body').attributes
|
|
311
492
|
|
|
312
493
|
writer = @comment.post.blog.writer
|
|
313
494
|
writer_cache_key = writer.cache_key
|
|
495
|
+
assert_equal cached_attributes["#{writer_cache_key}/#{adapter_instance.cache_key}"], Author.new(id: 'author', name: 'Joao M. D. Moura').attributes
|
|
496
|
+
end
|
|
497
|
+
end
|
|
498
|
+
# rubocop:enable Metrics/AbcSize
|
|
499
|
+
|
|
500
|
+
def test_cache_read_multi_with_fragment_cache_enabled
|
|
501
|
+
post_serializer = Class.new(ActiveModel::Serializer) do
|
|
502
|
+
cache except: [:body]
|
|
503
|
+
end
|
|
314
504
|
|
|
315
|
-
|
|
505
|
+
serializers = ActiveModel::Serializer::CollectionSerializer.new([@post, @post], serializer: post_serializer)
|
|
506
|
+
|
|
507
|
+
Timecop.freeze(Time.current) do
|
|
508
|
+
# Warming up.
|
|
509
|
+
options = {}
|
|
510
|
+
adapter_options = {}
|
|
511
|
+
adapter_instance = ActiveModelSerializers::Adapter::Attributes.new(serializers, adapter_options)
|
|
512
|
+
serializers.serializable_hash(adapter_options, options, adapter_instance)
|
|
513
|
+
|
|
514
|
+
# Should find something with read_multi now
|
|
515
|
+
options = {}
|
|
516
|
+
serializers.serializable_hash(adapter_options, options, adapter_instance)
|
|
517
|
+
cached_attributes = options.fetch(:cached_attributes)
|
|
518
|
+
|
|
519
|
+
include_directive = ActiveModelSerializers.default_include_directive
|
|
520
|
+
manual_cached_attributes = ActiveModel::Serializer.cache_read_multi(serializers, adapter_instance, include_directive)
|
|
521
|
+
|
|
522
|
+
refute_equal 0, cached_attributes.size
|
|
523
|
+
refute_equal 0, manual_cached_attributes.size
|
|
524
|
+
assert_equal manual_cached_attributes, cached_attributes
|
|
316
525
|
end
|
|
317
526
|
end
|
|
318
527
|
|
|
@@ -429,25 +638,53 @@ module ActiveModelSerializers
|
|
|
429
638
|
end
|
|
430
639
|
|
|
431
640
|
def test_fragment_fetch_with_virtual_attributes
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
641
|
+
author = Author.new(name: 'Joao M. D. Moura')
|
|
642
|
+
role = Role.new(name: 'Great Author', description: nil)
|
|
643
|
+
role.author = [author]
|
|
644
|
+
role_serializer = RoleSerializer.new(role)
|
|
645
|
+
adapter_instance = ActiveModelSerializers::Adapter.configured_adapter.new(role_serializer)
|
|
646
|
+
expected_result = {
|
|
647
|
+
id: role.id,
|
|
648
|
+
description: role.description,
|
|
649
|
+
slug: "#{role.name}-#{role.id}",
|
|
650
|
+
name: role.name
|
|
651
|
+
}
|
|
652
|
+
cache_store.clear
|
|
437
653
|
|
|
654
|
+
role_hash = role_serializer.fetch_attributes_fragment(adapter_instance)
|
|
655
|
+
assert_equal(role_hash, expected_result)
|
|
656
|
+
|
|
657
|
+
role.id = 'this has been updated'
|
|
658
|
+
role.name = 'this was cached'
|
|
659
|
+
|
|
660
|
+
role_hash = role_serializer.fetch_attributes_fragment(adapter_instance)
|
|
661
|
+
assert_equal(expected_result.merge(id: role.id), role_hash)
|
|
662
|
+
end
|
|
663
|
+
|
|
664
|
+
def test_fragment_fetch_with_except
|
|
665
|
+
adapter_instance = ActiveModelSerializers::Adapter.configured_adapter.new(@bio_serializer)
|
|
438
666
|
expected_result = {
|
|
439
|
-
id: @
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
name: @role.name
|
|
667
|
+
id: @bio.id,
|
|
668
|
+
rating: nil,
|
|
669
|
+
content: @bio.content
|
|
443
670
|
}
|
|
444
|
-
|
|
671
|
+
cache_store.clear
|
|
672
|
+
|
|
673
|
+
bio_hash = @bio_serializer.fetch_attributes_fragment(adapter_instance)
|
|
674
|
+
assert_equal(expected_result, bio_hash)
|
|
675
|
+
|
|
676
|
+
@bio.content = 'this has been updated'
|
|
677
|
+
@bio.rating = 'this was cached'
|
|
678
|
+
|
|
679
|
+
bio_hash = @bio_serializer.fetch_attributes_fragment(adapter_instance)
|
|
680
|
+
assert_equal(expected_result.merge(content: @bio.content), bio_hash)
|
|
445
681
|
end
|
|
446
682
|
|
|
447
683
|
def test_fragment_fetch_with_namespaced_object
|
|
448
684
|
@spam = Spam::UnrelatedLink.new(id: 'spam-id-1')
|
|
449
685
|
@spam_serializer = Spam::UnrelatedLinkSerializer.new(@spam)
|
|
450
|
-
|
|
686
|
+
adapter_instance = ActiveModelSerializers::Adapter.configured_adapter.new(@spam_serializer)
|
|
687
|
+
@spam_hash = @spam_serializer.fetch_attributes_fragment(adapter_instance)
|
|
451
688
|
expected_result = {
|
|
452
689
|
id: @spam.id
|
|
453
690
|
}
|
|
@@ -476,10 +713,5 @@ module ActiveModelSerializers
|
|
|
476
713
|
def adapter
|
|
477
714
|
@serializable_resource.adapter
|
|
478
715
|
end
|
|
479
|
-
|
|
480
|
-
def cached_serialization(serializer)
|
|
481
|
-
cache_key = serializer.cache_key(adapter)
|
|
482
|
-
cache_store.fetch(cache_key)
|
|
483
|
-
end
|
|
484
716
|
end
|
|
485
717
|
end
|
|
@@ -1,17 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'test_helper'
|
|
2
4
|
|
|
3
5
|
module ActiveModel
|
|
4
6
|
class Serializer
|
|
5
7
|
class CollectionSerializerTest < ActiveSupport::TestCase
|
|
6
|
-
|
|
8
|
+
class SingularModel < ::Model; end
|
|
9
|
+
class SingularModelSerializer < ActiveModel::Serializer
|
|
10
|
+
end
|
|
11
|
+
class HasManyModel < ::Model
|
|
12
|
+
associations :singular_models
|
|
13
|
+
end
|
|
14
|
+
class HasManyModelSerializer < ActiveModel::Serializer
|
|
15
|
+
has_many :singular_models
|
|
16
|
+
|
|
17
|
+
def custom_options
|
|
18
|
+
instance_options
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
class MessagesSerializer < ActiveModel::Serializer
|
|
7
22
|
type 'messages'
|
|
8
23
|
end
|
|
9
24
|
|
|
10
25
|
def setup
|
|
11
|
-
@
|
|
12
|
-
@
|
|
13
|
-
@resource = build_named_collection @
|
|
14
|
-
@serializer = collection_serializer.new(@resource,
|
|
26
|
+
@singular_model = SingularModel.new
|
|
27
|
+
@has_many_model = HasManyModel.new
|
|
28
|
+
@resource = build_named_collection @singular_model, @has_many_model
|
|
29
|
+
@serializer = collection_serializer.new(@resource, some: :options)
|
|
15
30
|
end
|
|
16
31
|
|
|
17
32
|
def collection_serializer
|
|
@@ -34,29 +49,29 @@ module ActiveModel
|
|
|
34
49
|
def test_each_object_should_be_serialized_with_appropriate_serializer
|
|
35
50
|
serializers = @serializer.to_a
|
|
36
51
|
|
|
37
|
-
assert_kind_of
|
|
38
|
-
assert_kind_of
|
|
52
|
+
assert_kind_of SingularModelSerializer, serializers.first
|
|
53
|
+
assert_kind_of SingularModel, serializers.first.object
|
|
39
54
|
|
|
40
|
-
assert_kind_of
|
|
41
|
-
assert_kind_of
|
|
55
|
+
assert_kind_of HasManyModelSerializer, serializers.last
|
|
56
|
+
assert_kind_of HasManyModel, serializers.last.object
|
|
42
57
|
|
|
43
58
|
assert_equal :options, serializers.last.custom_options[:some]
|
|
44
59
|
end
|
|
45
60
|
|
|
46
61
|
def test_serializer_option_not_passed_to_each_serializer
|
|
47
|
-
serializers = collection_serializer.new([@
|
|
62
|
+
serializers = collection_serializer.new([@has_many_model], serializer: HasManyModelSerializer).to_a
|
|
48
63
|
|
|
49
64
|
refute serializers.first.custom_options.key?(:serializer)
|
|
50
65
|
end
|
|
51
66
|
|
|
52
67
|
def test_root_default
|
|
53
|
-
@serializer = collection_serializer.new([@
|
|
68
|
+
@serializer = collection_serializer.new([@singular_model, @has_many_model])
|
|
54
69
|
assert_nil @serializer.root
|
|
55
70
|
end
|
|
56
71
|
|
|
57
72
|
def test_root
|
|
58
73
|
expected = 'custom_root'
|
|
59
|
-
@serializer = collection_serializer.new([@
|
|
74
|
+
@serializer = collection_serializer.new([@singular_model, @has_many_model], root: expected)
|
|
60
75
|
assert_equal expected, @serializer.root
|
|
61
76
|
end
|
|
62
77
|
|
|
@@ -80,12 +95,16 @@ module ActiveModel
|
|
|
80
95
|
resource = []
|
|
81
96
|
resource.define_singleton_method(:name) { nil }
|
|
82
97
|
serializer = collection_serializer.new(resource)
|
|
83
|
-
|
|
98
|
+
assert_raise ArgumentError do
|
|
99
|
+
serializer.json_key
|
|
100
|
+
end
|
|
84
101
|
end
|
|
85
102
|
|
|
86
103
|
def test_json_key_with_resource_without_name_and_no_serializers
|
|
87
104
|
serializer = collection_serializer.new([])
|
|
88
|
-
|
|
105
|
+
assert_raise ArgumentError do
|
|
106
|
+
serializer.json_key
|
|
107
|
+
end
|
|
89
108
|
end
|
|
90
109
|
|
|
91
110
|
def test_json_key_with_empty_resources_with_serializer
|