active_model_serializers 0.10.0 → 0.10.7
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 +6 -5
- data/.travis.yml +30 -21
- data/CHANGELOG.md +172 -2
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +23 -4
- data/README.md +166 -28
- data/Rakefile +3 -32
- data/active_model_serializers.gemspec +22 -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 +125 -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 +13 -3
- data/lib/active_model/serializer/adapter/base.rb +2 -0
- data/lib/active_model/serializer/array_serializer.rb +8 -5
- data/lib/active_model/serializer/association.rb +62 -10
- data/lib/active_model/serializer/belongs_to_reflection.rb +4 -3
- data/lib/active_model/serializer/collection_serializer.rb +39 -13
- data/lib/active_model/serializer/{caching.rb → concerns/caching.rb} +82 -115
- data/lib/active_model/serializer/error_serializer.rb +11 -7
- data/lib/active_model/serializer/errors_serializer.rb +25 -20
- data/lib/active_model/serializer/has_many_reflection.rb +3 -3
- data/lib/active_model/serializer/has_one_reflection.rb +1 -4
- data/lib/active_model/serializer/lazy_association.rb +95 -0
- data/lib/active_model/serializer/lint.rb +134 -130
- data/lib/active_model/serializer/reflection.rb +127 -67
- data/lib/active_model/serializer/version.rb +1 -1
- data/lib/active_model/serializer.rb +297 -79
- data/lib/active_model_serializers/adapter/attributes.rb +3 -66
- data/lib/active_model_serializers/adapter/base.rb +39 -39
- data/lib/active_model_serializers/adapter/json_api/deserialization.rb +2 -2
- data/lib/active_model_serializers/adapter/json_api/link.rb +1 -1
- data/lib/active_model_serializers/adapter/json_api/pagination_links.rb +47 -21
- data/lib/active_model_serializers/adapter/json_api/relationship.rb +75 -23
- data/lib/active_model_serializers/adapter/json_api/resource_identifier.rb +39 -10
- data/lib/active_model_serializers/adapter/json_api.rb +71 -57
- data/lib/active_model_serializers/adapter.rb +6 -0
- data/lib/active_model_serializers/deprecate.rb +1 -2
- data/lib/active_model_serializers/deserialization.rb +2 -0
- data/lib/active_model_serializers/lookup_chain.rb +80 -0
- data/lib/active_model_serializers/model.rb +109 -28
- data/lib/active_model_serializers/railtie.rb +3 -1
- data/lib/active_model_serializers/register_jsonapi_renderer.rb +44 -31
- data/lib/active_model_serializers/serializable_resource.rb +6 -5
- data/lib/active_model_serializers/serialization_context.rb +10 -3
- data/lib/active_model_serializers/test/schema.rb +2 -2
- data/lib/active_model_serializers.rb +16 -1
- data/lib/generators/rails/resource_override.rb +1 -1
- data/lib/generators/rails/serializer_generator.rb +4 -4
- data/lib/grape/active_model_serializers.rb +7 -5
- data/lib/grape/formatters/active_model_serializers.rb +19 -2
- data/lib/grape/helpers/active_model_serializers.rb +1 -0
- data/lib/tasks/rubocop.rake +53 -0
- data/test/action_controller/adapter_selector_test.rb +14 -5
- data/test/action_controller/explicit_serializer_test.rb +5 -4
- data/test/action_controller/json/include_test.rb +106 -27
- data/test/action_controller/json_api/deserialization_test.rb +1 -1
- data/test/action_controller/json_api/errors_test.rb +8 -9
- data/test/action_controller/json_api/fields_test.rb +66 -0
- data/test/action_controller/json_api/linked_test.rb +29 -24
- data/test/action_controller/json_api/pagination_test.rb +31 -23
- data/test/action_controller/json_api/transform_test.rb +11 -3
- data/test/action_controller/lookup_proc_test.rb +49 -0
- data/test/action_controller/namespace_lookup_test.rb +232 -0
- data/test/action_controller/serialization_scope_name_test.rb +12 -6
- data/test/action_controller/serialization_test.rb +12 -9
- data/test/active_model_serializers/json_pointer_test.rb +15 -13
- data/test/active_model_serializers/model_test.rb +137 -4
- data/test/active_model_serializers/railtie_test_isolated.rb +12 -7
- data/test/active_model_serializers/register_jsonapi_renderer_test_isolated.rb +161 -0
- data/test/active_model_serializers/serialization_context_test_isolated.rb +23 -10
- data/test/active_model_serializers/test/schema_test.rb +3 -2
- data/test/adapter/attributes_test.rb +40 -0
- data/test/adapter/json/collection_test.rb +14 -0
- data/test/adapter/json/has_many_test.rb +10 -2
- data/test/adapter/json/transform_test.rb +15 -15
- data/test/adapter/json_api/collection_test.rb +4 -3
- data/test/adapter/json_api/errors_test.rb +17 -19
- data/test/adapter/json_api/fields_test.rb +12 -3
- data/test/adapter/json_api/has_many_test.rb +49 -20
- data/test/adapter/json_api/include_data_if_sideloaded_test.rb +213 -0
- data/test/adapter/json_api/json_api_test.rb +5 -7
- data/test/adapter/json_api/linked_test.rb +33 -12
- data/test/adapter/json_api/links_test.rb +4 -2
- data/test/adapter/json_api/pagination_links_test.rb +53 -13
- data/test/adapter/json_api/parse_test.rb +1 -1
- data/test/adapter/json_api/relationship_test.rb +309 -73
- data/test/adapter/json_api/resource_meta_test.rb +3 -3
- data/test/adapter/json_api/transform_test.rb +263 -253
- data/test/adapter/json_api/type_test.rb +168 -36
- data/test/adapter/json_test.rb +8 -7
- data/test/adapter/null_test.rb +1 -2
- data/test/adapter/polymorphic_test.rb +52 -5
- data/test/adapter_test.rb +1 -1
- data/test/benchmark/app.rb +1 -1
- data/test/benchmark/benchmarking_support.rb +1 -1
- data/test/benchmark/bm_active_record.rb +81 -0
- data/test/benchmark/bm_adapter.rb +38 -0
- data/test/benchmark/bm_caching.rb +16 -16
- data/test/benchmark/bm_lookup_chain.rb +83 -0
- data/test/benchmark/bm_transform.rb +21 -10
- data/test/benchmark/controllers.rb +16 -17
- data/test/benchmark/fixtures.rb +72 -72
- data/test/cache_test.rb +235 -69
- data/test/collection_serializer_test.rb +31 -14
- data/test/fixtures/active_record.rb +45 -10
- data/test/fixtures/poro.rb +124 -181
- data/test/generators/serializer_generator_test.rb +23 -5
- data/test/grape_test.rb +170 -56
- data/test/lint_test.rb +1 -1
- data/test/logger_test.rb +13 -11
- data/test/serializable_resource_test.rb +18 -22
- data/test/serializers/association_macros_test.rb +3 -2
- data/test/serializers/associations_test.rb +222 -49
- data/test/serializers/attribute_test.rb +5 -3
- data/test/serializers/attributes_test.rb +1 -1
- data/test/serializers/caching_configuration_test_isolated.rb +6 -6
- data/test/serializers/fieldset_test.rb +1 -1
- data/test/serializers/meta_test.rb +12 -6
- data/test/serializers/options_test.rb +17 -6
- data/test/serializers/read_attribute_for_serialization_test.rb +3 -3
- data/test/serializers/reflection_test.rb +427 -0
- data/test/serializers/root_test.rb +1 -1
- data/test/serializers/serialization_test.rb +2 -2
- data/test/serializers/serializer_for_test.rb +12 -10
- data/test/serializers/serializer_for_with_namespace_test.rb +88 -0
- data/test/support/isolated_unit.rb +9 -4
- data/test/support/rails5_shims.rb +8 -2
- data/test/support/rails_app.rb +2 -9
- data/test/support/serialization_testing.rb +31 -5
- data/test/test_helper.rb +13 -0
- metadata +130 -71
- 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
|
@@ -15,7 +15,8 @@ module ActiveModel
|
|
|
15
15
|
@blog,
|
|
16
16
|
adapter: :json,
|
|
17
17
|
serializer: AlternateBlogSerializer,
|
|
18
|
-
meta: { total: 10 }
|
|
18
|
+
meta: { total: 10 }
|
|
19
|
+
).as_json
|
|
19
20
|
expected = {
|
|
20
21
|
blog: {
|
|
21
22
|
id: 1,
|
|
@@ -65,7 +66,8 @@ module ActiveModel
|
|
|
65
66
|
@blog,
|
|
66
67
|
adapter: :attributes,
|
|
67
68
|
serializer: AlternateBlogSerializer,
|
|
68
|
-
meta: { total: 10 }
|
|
69
|
+
meta: { total: 10 }
|
|
70
|
+
).as_json
|
|
69
71
|
expected = {
|
|
70
72
|
id: 1,
|
|
71
73
|
title: 'AMS Hints'
|
|
@@ -79,7 +81,8 @@ module ActiveModel
|
|
|
79
81
|
adapter: :json,
|
|
80
82
|
serializer: AlternateBlogSerializer,
|
|
81
83
|
meta: { total: 10 },
|
|
82
|
-
meta_key: 'haha_meta'
|
|
84
|
+
meta_key: 'haha_meta'
|
|
85
|
+
).as_json
|
|
83
86
|
expected = {
|
|
84
87
|
blog: {
|
|
85
88
|
id: 1,
|
|
@@ -98,7 +101,8 @@ module ActiveModel
|
|
|
98
101
|
adapter: :json_api,
|
|
99
102
|
serializer: AlternateBlogSerializer,
|
|
100
103
|
meta: { total: 10 },
|
|
101
|
-
meta_key: 'haha_meta'
|
|
104
|
+
meta_key: 'haha_meta'
|
|
105
|
+
).as_json
|
|
102
106
|
expected = {
|
|
103
107
|
data: {
|
|
104
108
|
id: '1',
|
|
@@ -148,7 +152,8 @@ module ActiveModel
|
|
|
148
152
|
actual = ActiveModelSerializers::SerializableResource.new(
|
|
149
153
|
[@blog],
|
|
150
154
|
adapter: :attributes,
|
|
151
|
-
meta: { total: 10 }
|
|
155
|
+
meta: { total: 10 }
|
|
156
|
+
).as_json
|
|
152
157
|
expected = [{
|
|
153
158
|
id: 1,
|
|
154
159
|
name: 'AMS Hints',
|
|
@@ -170,7 +175,8 @@ module ActiveModel
|
|
|
170
175
|
[@blog],
|
|
171
176
|
adapter: :json,
|
|
172
177
|
meta: { total: 10 },
|
|
173
|
-
meta_key: 'haha_meta'
|
|
178
|
+
meta_key: 'haha_meta'
|
|
179
|
+
).as_json
|
|
174
180
|
expected = {
|
|
175
181
|
blogs: [{
|
|
176
182
|
id: 1,
|
|
@@ -3,18 +3,29 @@ require 'test_helper'
|
|
|
3
3
|
module ActiveModel
|
|
4
4
|
class Serializer
|
|
5
5
|
class OptionsTest < ActiveSupport::TestCase
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
class ModelWithOptions < ActiveModelSerializers::Model
|
|
7
|
+
attributes :name, :description
|
|
8
|
+
end
|
|
9
|
+
class ModelWithOptionsSerializer < ActiveModel::Serializer
|
|
10
|
+
attributes :name, :description
|
|
11
|
+
|
|
12
|
+
def arguments_passed_in?
|
|
13
|
+
instance_options[:my_options] == :accessible
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
setup do
|
|
18
|
+
@model_with_options = ModelWithOptions.new(name: 'Name 1', description: 'Description 1')
|
|
8
19
|
end
|
|
9
20
|
|
|
10
21
|
def test_options_are_accessible
|
|
11
|
-
|
|
12
|
-
assert
|
|
22
|
+
model_with_options_serializer = ModelWithOptionsSerializer.new(@model_with_options, my_options: :accessible)
|
|
23
|
+
assert model_with_options_serializer.arguments_passed_in?
|
|
13
24
|
end
|
|
14
25
|
|
|
15
26
|
def test_no_option_is_passed_in
|
|
16
|
-
|
|
17
|
-
refute
|
|
27
|
+
model_with_options_serializer = ModelWithOptionsSerializer.new(@model_with_options)
|
|
28
|
+
refute model_with_options_serializer.arguments_passed_in?
|
|
18
29
|
end
|
|
19
30
|
end
|
|
20
31
|
end
|
|
@@ -5,10 +5,10 @@ module ActiveModel
|
|
|
5
5
|
class ReadAttributeForSerializationTest < ActiveSupport::TestCase
|
|
6
6
|
# https://github.com/rails-api/active_model_serializers/issues/1653
|
|
7
7
|
class Parent < ActiveModelSerializers::Model
|
|
8
|
-
|
|
8
|
+
attributes :id
|
|
9
9
|
end
|
|
10
10
|
class Child < Parent
|
|
11
|
-
|
|
11
|
+
attributes :name
|
|
12
12
|
end
|
|
13
13
|
class ParentSerializer < ActiveModel::Serializer
|
|
14
14
|
attributes :$id
|
|
@@ -30,7 +30,7 @@ module ActiveModel
|
|
|
30
30
|
|
|
31
31
|
# https://github.com/rails-api/active_model_serializers/issues/1658
|
|
32
32
|
class ErrorResponse < ActiveModelSerializers::Model
|
|
33
|
-
|
|
33
|
+
attributes :error
|
|
34
34
|
end
|
|
35
35
|
class ApplicationSerializer < ActiveModel::Serializer
|
|
36
36
|
attributes :status
|
|
@@ -0,0 +1,427 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
module ActiveModel
|
|
3
|
+
class Serializer
|
|
4
|
+
class ReflectionTest < ActiveSupport::TestCase
|
|
5
|
+
class Blog < ActiveModelSerializers::Model
|
|
6
|
+
attributes :id
|
|
7
|
+
end
|
|
8
|
+
class BlogSerializer < ActiveModel::Serializer
|
|
9
|
+
type 'blog'
|
|
10
|
+
attributes :id
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
setup do
|
|
14
|
+
@expected_meta = { id: 1 }
|
|
15
|
+
@expected_links = { self: 'no_uri_validation' }
|
|
16
|
+
@empty_links = {}
|
|
17
|
+
model_attributes = { blog: Blog.new(@expected_meta) }
|
|
18
|
+
@model = Class.new(ActiveModelSerializers::Model) do
|
|
19
|
+
attributes(*model_attributes.keys)
|
|
20
|
+
|
|
21
|
+
def self.name
|
|
22
|
+
'TestModel'
|
|
23
|
+
end
|
|
24
|
+
end.new(model_attributes)
|
|
25
|
+
@instance_options = {}
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def evaluate_association_value(association)
|
|
29
|
+
association.lazy_association.eval_reflection_block
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# TODO: Remaining tests
|
|
33
|
+
# test_reflection_value_block_with_scope
|
|
34
|
+
# test_reflection_value_uses_serializer_instance_method
|
|
35
|
+
# test_reflection_excluded_eh_blank_is_false
|
|
36
|
+
# test_reflection_excluded_eh_if
|
|
37
|
+
# test_reflection_excluded_eh_unless
|
|
38
|
+
# test_evaluate_condition_symbol_serializer_method
|
|
39
|
+
# test_evaluate_condition_string_serializer_method
|
|
40
|
+
# test_evaluate_condition_proc
|
|
41
|
+
# test_evaluate_condition_proc_yields_serializer
|
|
42
|
+
# test_evaluate_condition_other
|
|
43
|
+
# test_options_key
|
|
44
|
+
# test_options_polymorphic
|
|
45
|
+
# test_options_serializer
|
|
46
|
+
# test_options_virtual_value
|
|
47
|
+
# test_options_namespace
|
|
48
|
+
|
|
49
|
+
def test_reflection_value
|
|
50
|
+
serializer_class = Class.new(ActiveModel::Serializer) do
|
|
51
|
+
has_one :blog
|
|
52
|
+
end
|
|
53
|
+
serializer_instance = serializer_class.new(@model, @instance_options)
|
|
54
|
+
|
|
55
|
+
# Get Reflection
|
|
56
|
+
reflection = serializer_class._reflections.fetch(:blog)
|
|
57
|
+
|
|
58
|
+
# Assert
|
|
59
|
+
assert_nil reflection.block
|
|
60
|
+
assert_equal Serializer.config.include_data_default, reflection.options.fetch(:include_data_setting)
|
|
61
|
+
assert_equal true, reflection.options.fetch(:include_data_setting)
|
|
62
|
+
|
|
63
|
+
include_slice = :does_not_matter
|
|
64
|
+
assert_equal @model.blog, reflection.send(:value, serializer_instance, include_slice)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def test_reflection_value_block
|
|
68
|
+
serializer_class = Class.new(ActiveModel::Serializer) do
|
|
69
|
+
has_one :blog do
|
|
70
|
+
object.blog
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
serializer_instance = serializer_class.new(@model, @instance_options)
|
|
74
|
+
|
|
75
|
+
# Get Reflection
|
|
76
|
+
reflection = serializer_class._reflections.fetch(:blog)
|
|
77
|
+
|
|
78
|
+
# Assert
|
|
79
|
+
assert_respond_to reflection.block, :call
|
|
80
|
+
assert_equal Serializer.config.include_data_default, reflection.options.fetch(:include_data_setting)
|
|
81
|
+
assert_equal true, reflection.options.fetch(:include_data_setting)
|
|
82
|
+
|
|
83
|
+
include_slice = :does_not_matter
|
|
84
|
+
assert_equal @model.blog, reflection.send(:value, serializer_instance, include_slice)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def test_reflection_value_block_with_explicit_include_data_true
|
|
88
|
+
serializer_class = Class.new(ActiveModel::Serializer) do
|
|
89
|
+
has_one :blog do
|
|
90
|
+
include_data true
|
|
91
|
+
object.blog
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
serializer_instance = serializer_class.new(@model, @instance_options)
|
|
95
|
+
|
|
96
|
+
# Get Reflection
|
|
97
|
+
reflection = serializer_class._reflections.fetch(:blog)
|
|
98
|
+
|
|
99
|
+
# Assert
|
|
100
|
+
assert_respond_to reflection.block, :call
|
|
101
|
+
assert_equal Serializer.config.include_data_default, reflection.options.fetch(:include_data_setting)
|
|
102
|
+
assert_equal true, reflection.options.fetch(:include_data_setting)
|
|
103
|
+
|
|
104
|
+
include_slice = :does_not_matter
|
|
105
|
+
assert_equal @model.blog, reflection.send(:value, serializer_instance, include_slice)
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def test_reflection_value_block_with_include_data_false_mutates_the_reflection_include_data
|
|
109
|
+
serializer_class = Class.new(ActiveModel::Serializer) do
|
|
110
|
+
has_one :blog do
|
|
111
|
+
include_data false
|
|
112
|
+
object.blog
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
serializer_instance = serializer_class.new(@model, @instance_options)
|
|
116
|
+
|
|
117
|
+
# Get Reflection
|
|
118
|
+
reflection = serializer_class._reflections.fetch(:blog)
|
|
119
|
+
|
|
120
|
+
# Assert
|
|
121
|
+
assert_respond_to reflection.block, :call
|
|
122
|
+
assert_equal true, reflection.options.fetch(:include_data_setting)
|
|
123
|
+
include_slice = :does_not_matter
|
|
124
|
+
assert_nil reflection.send(:value, serializer_instance, include_slice)
|
|
125
|
+
assert_equal false, reflection.options.fetch(:include_data_setting)
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def test_reflection_value_block_with_include_data_if_sideloaded_included_mutates_the_reflection_include_data
|
|
129
|
+
serializer_class = Class.new(ActiveModel::Serializer) do
|
|
130
|
+
has_one :blog do
|
|
131
|
+
include_data :if_sideloaded
|
|
132
|
+
object.blog
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
serializer_instance = serializer_class.new(@model, @instance_options)
|
|
136
|
+
|
|
137
|
+
# Get Reflection
|
|
138
|
+
reflection = serializer_class._reflections.fetch(:blog)
|
|
139
|
+
|
|
140
|
+
# Assert
|
|
141
|
+
assert_respond_to reflection.block, :call
|
|
142
|
+
assert_equal true, reflection.options.fetch(:include_data_setting)
|
|
143
|
+
include_slice = {}
|
|
144
|
+
assert_nil reflection.send(:value, serializer_instance, include_slice)
|
|
145
|
+
assert_equal :if_sideloaded, reflection.options.fetch(:include_data_setting)
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def test_reflection_value_block_with_include_data_if_sideloaded_excluded_mutates_the_reflection_include_data
|
|
149
|
+
serializer_class = Class.new(ActiveModel::Serializer) do
|
|
150
|
+
has_one :blog do
|
|
151
|
+
include_data :if_sideloaded
|
|
152
|
+
object.blog
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
serializer_instance = serializer_class.new(@model, @instance_options)
|
|
156
|
+
|
|
157
|
+
# Get Reflection
|
|
158
|
+
reflection = serializer_class._reflections.fetch(:blog)
|
|
159
|
+
|
|
160
|
+
# Assert
|
|
161
|
+
assert_respond_to reflection.block, :call
|
|
162
|
+
assert_equal true, reflection.options.fetch(:include_data_setting)
|
|
163
|
+
include_slice = { blog: :does_not_matter }
|
|
164
|
+
assert_equal @model.blog, reflection.send(:value, serializer_instance, include_slice)
|
|
165
|
+
assert_equal :if_sideloaded, reflection.options.fetch(:include_data_setting)
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def test_reflection_block_with_link_mutates_the_reflection_links
|
|
169
|
+
serializer_class = Class.new(ActiveModel::Serializer) do
|
|
170
|
+
has_one :blog do
|
|
171
|
+
link :self, 'no_uri_validation'
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
serializer_instance = serializer_class.new(@model, @instance_options)
|
|
175
|
+
|
|
176
|
+
# Get Reflection
|
|
177
|
+
reflection = serializer_class._reflections.fetch(:blog)
|
|
178
|
+
assert_equal @empty_links, reflection.options.fetch(:links)
|
|
179
|
+
|
|
180
|
+
# Build Association
|
|
181
|
+
association = reflection.build_association(serializer_instance, @instance_options)
|
|
182
|
+
|
|
183
|
+
# Assert association links empty when not yet evaluated
|
|
184
|
+
assert_equal @empty_links, reflection.options.fetch(:links)
|
|
185
|
+
assert_equal @empty_links, association.links
|
|
186
|
+
|
|
187
|
+
evaluate_association_value(association)
|
|
188
|
+
|
|
189
|
+
assert_equal @expected_links, association.links
|
|
190
|
+
assert_equal @expected_links, reflection.options.fetch(:links)
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
def test_reflection_block_with_link_block_mutates_the_reflection_links
|
|
194
|
+
serializer_class = Class.new(ActiveModel::Serializer) do
|
|
195
|
+
has_one :blog do
|
|
196
|
+
link :self do
|
|
197
|
+
'no_uri_validation'
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
serializer_instance = serializer_class.new(@model, @instance_options)
|
|
202
|
+
|
|
203
|
+
# Get Reflection
|
|
204
|
+
reflection = serializer_class._reflections.fetch(:blog)
|
|
205
|
+
assert_equal @empty_links, reflection.options.fetch(:links)
|
|
206
|
+
|
|
207
|
+
# Build Association
|
|
208
|
+
association = reflection.build_association(serializer_instance, @instance_options)
|
|
209
|
+
|
|
210
|
+
# Assert association links empty when not yet evaluated
|
|
211
|
+
assert_equal @empty_links, association.links
|
|
212
|
+
|
|
213
|
+
evaluate_association_value(association)
|
|
214
|
+
|
|
215
|
+
# Assert before instance_eval link
|
|
216
|
+
link = association.links.fetch(:self)
|
|
217
|
+
assert_respond_to link, :call
|
|
218
|
+
assert_respond_to reflection.options.fetch(:links).fetch(:self), :call
|
|
219
|
+
|
|
220
|
+
# Assert after instance_eval link
|
|
221
|
+
assert_equal @expected_links.fetch(:self), reflection.instance_eval(&link)
|
|
222
|
+
assert_respond_to reflection.options.fetch(:links).fetch(:self), :call
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
def test_reflection_block_with_meta_mutates_the_reflection_meta
|
|
226
|
+
serializer_class = Class.new(ActiveModel::Serializer) do
|
|
227
|
+
has_one :blog do
|
|
228
|
+
meta(id: object.blog.id)
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
serializer_instance = serializer_class.new(@model, @instance_options)
|
|
232
|
+
|
|
233
|
+
# Get Reflection
|
|
234
|
+
reflection = serializer_class._reflections.fetch(:blog)
|
|
235
|
+
assert_nil reflection.options.fetch(:meta)
|
|
236
|
+
|
|
237
|
+
# Build Association
|
|
238
|
+
association = reflection.build_association(serializer_instance, @instance_options)
|
|
239
|
+
|
|
240
|
+
evaluate_association_value(association)
|
|
241
|
+
|
|
242
|
+
assert_equal @expected_meta, association.meta
|
|
243
|
+
assert_equal @expected_meta, reflection.options.fetch(:meta)
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
def test_reflection_block_with_meta_block_mutates_the_reflection_meta
|
|
247
|
+
serializer_class = Class.new(ActiveModel::Serializer) do
|
|
248
|
+
has_one :blog do
|
|
249
|
+
meta do
|
|
250
|
+
{ id: object.blog.id }
|
|
251
|
+
end
|
|
252
|
+
end
|
|
253
|
+
end
|
|
254
|
+
serializer_instance = serializer_class.new(@model, @instance_options)
|
|
255
|
+
|
|
256
|
+
# Get Reflection
|
|
257
|
+
reflection = serializer_class._reflections.fetch(:blog)
|
|
258
|
+
assert_nil reflection.options.fetch(:meta)
|
|
259
|
+
|
|
260
|
+
# Build Association
|
|
261
|
+
association = reflection.build_association(serializer_instance, @instance_options)
|
|
262
|
+
# Assert before instance_eval meta
|
|
263
|
+
|
|
264
|
+
evaluate_association_value(association)
|
|
265
|
+
|
|
266
|
+
assert_respond_to association.meta, :call
|
|
267
|
+
assert_respond_to reflection.options.fetch(:meta), :call
|
|
268
|
+
|
|
269
|
+
# Assert after instance_eval meta
|
|
270
|
+
assert_equal @expected_meta, reflection.instance_eval(&association.meta)
|
|
271
|
+
assert_respond_to reflection.options.fetch(:meta), :call
|
|
272
|
+
assert_respond_to association.meta, :call
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
# rubocop:disable Metrics/AbcSize
|
|
276
|
+
def test_reflection_block_with_meta_in_link_block_mutates_the_reflection_meta
|
|
277
|
+
serializer_class = Class.new(ActiveModel::Serializer) do
|
|
278
|
+
has_one :blog do
|
|
279
|
+
link :self do
|
|
280
|
+
meta(id: object.blog.id)
|
|
281
|
+
'no_uri_validation'
|
|
282
|
+
end
|
|
283
|
+
end
|
|
284
|
+
end
|
|
285
|
+
serializer_instance = serializer_class.new(@model, @instance_options)
|
|
286
|
+
|
|
287
|
+
# Get Reflection
|
|
288
|
+
reflection = serializer_class._reflections.fetch(:blog)
|
|
289
|
+
assert_nil reflection.options.fetch(:meta)
|
|
290
|
+
assert_equal @empty_links, reflection.options.fetch(:links)
|
|
291
|
+
|
|
292
|
+
# Build Association
|
|
293
|
+
association = reflection.build_association(serializer_instance, @instance_options)
|
|
294
|
+
# Assert before instance_eval link meta
|
|
295
|
+
assert_nil association.meta
|
|
296
|
+
assert_nil reflection.options.fetch(:meta)
|
|
297
|
+
|
|
298
|
+
evaluate_association_value(association)
|
|
299
|
+
|
|
300
|
+
link = association.links.fetch(:self)
|
|
301
|
+
assert_respond_to link, :call
|
|
302
|
+
assert_respond_to reflection.options.fetch(:links).fetch(:self), :call
|
|
303
|
+
assert_nil reflection.options.fetch(:meta)
|
|
304
|
+
|
|
305
|
+
# Assert after instance_eval link
|
|
306
|
+
assert_equal 'no_uri_validation', reflection.instance_eval(&link)
|
|
307
|
+
assert_equal @expected_meta, reflection.options.fetch(:meta)
|
|
308
|
+
assert_equal @expected_meta, association.meta
|
|
309
|
+
end
|
|
310
|
+
# rubocop:enable Metrics/AbcSize
|
|
311
|
+
|
|
312
|
+
# rubocop:disable Metrics/AbcSize
|
|
313
|
+
def test_reflection_block_with_meta_block_in_link_block_mutates_the_reflection_meta
|
|
314
|
+
serializer_class = Class.new(ActiveModel::Serializer) do
|
|
315
|
+
has_one :blog do
|
|
316
|
+
link :self do
|
|
317
|
+
meta do
|
|
318
|
+
{ id: object.blog.id }
|
|
319
|
+
end
|
|
320
|
+
'no_uri_validation'
|
|
321
|
+
end
|
|
322
|
+
end
|
|
323
|
+
end
|
|
324
|
+
serializer_instance = serializer_class.new(@model, @instance_options)
|
|
325
|
+
|
|
326
|
+
# Get Reflection
|
|
327
|
+
reflection = serializer_class._reflections.fetch(:blog)
|
|
328
|
+
assert_nil reflection.options.fetch(:meta)
|
|
329
|
+
|
|
330
|
+
# Build Association
|
|
331
|
+
association = reflection.build_association(serializer_instance, @instance_options)
|
|
332
|
+
assert_nil association.meta
|
|
333
|
+
assert_nil reflection.options.fetch(:meta)
|
|
334
|
+
|
|
335
|
+
# Assert before instance_eval link
|
|
336
|
+
|
|
337
|
+
evaluate_association_value(association)
|
|
338
|
+
|
|
339
|
+
link = association.links.fetch(:self)
|
|
340
|
+
assert_nil reflection.options.fetch(:meta)
|
|
341
|
+
assert_respond_to link, :call
|
|
342
|
+
assert_respond_to association.links.fetch(:self), :call
|
|
343
|
+
|
|
344
|
+
# Assert after instance_eval link
|
|
345
|
+
assert_equal 'no_uri_validation', reflection.instance_eval(&link)
|
|
346
|
+
assert_respond_to association.links.fetch(:self), :call
|
|
347
|
+
# Assert before instance_eval link meta
|
|
348
|
+
assert_respond_to reflection.options.fetch(:meta), :call
|
|
349
|
+
assert_respond_to association.meta, :call
|
|
350
|
+
|
|
351
|
+
# Assert after instance_eval link meta
|
|
352
|
+
assert_equal @expected_meta, reflection.instance_eval(&reflection.options.fetch(:meta))
|
|
353
|
+
assert_respond_to association.meta, :call
|
|
354
|
+
end
|
|
355
|
+
# rubocop:enable Metrics/AbcSize
|
|
356
|
+
|
|
357
|
+
def test_no_href_in_vanilla_reflection
|
|
358
|
+
serializer_class = Class.new(ActiveModel::Serializer) do
|
|
359
|
+
has_one :blog do
|
|
360
|
+
link :self do
|
|
361
|
+
href 'no_uri_validation'
|
|
362
|
+
end
|
|
363
|
+
end
|
|
364
|
+
end
|
|
365
|
+
serializer_instance = serializer_class.new(@model, @instance_options)
|
|
366
|
+
|
|
367
|
+
# Get Reflection
|
|
368
|
+
reflection = serializer_class._reflections.fetch(:blog)
|
|
369
|
+
assert_equal @empty_links, reflection.options.fetch(:links)
|
|
370
|
+
|
|
371
|
+
# Build Association
|
|
372
|
+
association = reflection.build_association(serializer_instance, @instance_options)
|
|
373
|
+
# Assert before instance_eval link
|
|
374
|
+
|
|
375
|
+
evaluate_association_value(association)
|
|
376
|
+
|
|
377
|
+
link = association.links.fetch(:self)
|
|
378
|
+
assert_respond_to link, :call
|
|
379
|
+
|
|
380
|
+
# Assert after instance_eval link
|
|
381
|
+
exception = assert_raise(NoMethodError) do
|
|
382
|
+
reflection.instance_eval(&link)
|
|
383
|
+
end
|
|
384
|
+
assert_match(/undefined method `href'/, exception.message)
|
|
385
|
+
end
|
|
386
|
+
|
|
387
|
+
# rubocop:disable Metrics/AbcSize
|
|
388
|
+
def test_mutating_reflection_block_is_not_thread_safe
|
|
389
|
+
serializer_class = Class.new(ActiveModel::Serializer) do
|
|
390
|
+
has_one :blog do
|
|
391
|
+
meta(id: object.blog.id)
|
|
392
|
+
end
|
|
393
|
+
end
|
|
394
|
+
model1_meta = @expected_meta
|
|
395
|
+
# Evaluate reflection meta for model with id 1
|
|
396
|
+
serializer_instance = serializer_class.new(@model, @instance_options)
|
|
397
|
+
reflection = serializer_class._reflections.fetch(:blog)
|
|
398
|
+
assert_nil reflection.options.fetch(:meta)
|
|
399
|
+
association = reflection.build_association(serializer_instance, @instance_options)
|
|
400
|
+
|
|
401
|
+
evaluate_association_value(association)
|
|
402
|
+
|
|
403
|
+
assert_equal model1_meta, association.meta
|
|
404
|
+
assert_equal model1_meta, reflection.options.fetch(:meta)
|
|
405
|
+
|
|
406
|
+
model2_meta = @expected_meta.merge(id: 2)
|
|
407
|
+
# Evaluate reflection meta for model with id 2
|
|
408
|
+
@model.blog.id = 2
|
|
409
|
+
assert_equal 2, @model.blog.id # sanity check
|
|
410
|
+
serializer_instance = serializer_class.new(@model, @instance_options)
|
|
411
|
+
reflection = serializer_class._reflections.fetch(:blog)
|
|
412
|
+
|
|
413
|
+
# WARN: Thread-safety issue
|
|
414
|
+
# Before the reflection is evaluated, it has the value from the previous evaluation
|
|
415
|
+
assert_equal model1_meta, reflection.options.fetch(:meta)
|
|
416
|
+
|
|
417
|
+
association = reflection.build_association(serializer_instance, @instance_options)
|
|
418
|
+
|
|
419
|
+
evaluate_association_value(association)
|
|
420
|
+
|
|
421
|
+
assert_equal model2_meta, association.meta
|
|
422
|
+
assert_equal model2_meta, reflection.options.fetch(:meta)
|
|
423
|
+
end
|
|
424
|
+
# rubocop:enable Metrics/AbcSize
|
|
425
|
+
end
|
|
426
|
+
end
|
|
427
|
+
end
|
|
@@ -2,10 +2,10 @@ module ActiveModel
|
|
|
2
2
|
class Serializer
|
|
3
3
|
class SerializationTest < ActiveSupport::TestCase
|
|
4
4
|
class Blog < ActiveModelSerializers::Model
|
|
5
|
-
|
|
5
|
+
attributes :id, :name, :authors
|
|
6
6
|
end
|
|
7
7
|
class Author < ActiveModelSerializers::Model
|
|
8
|
-
|
|
8
|
+
attributes :id, :name
|
|
9
9
|
end
|
|
10
10
|
class BlogSerializer < ActiveModel::Serializer
|
|
11
11
|
attributes :id
|
|
@@ -28,8 +28,8 @@ module ActiveModel
|
|
|
28
28
|
|
|
29
29
|
class SerializerTest < ActiveSupport::TestCase
|
|
30
30
|
module ResourceNamespace
|
|
31
|
-
Post
|
|
32
|
-
Comment
|
|
31
|
+
class Post < ::Model; end
|
|
32
|
+
class Comment < ::Model; end
|
|
33
33
|
|
|
34
34
|
class PostSerializer < ActiveModel::Serializer
|
|
35
35
|
class CommentSerializer < ActiveModel::Serializer
|
|
@@ -41,10 +41,12 @@ module ActiveModel
|
|
|
41
41
|
end
|
|
42
42
|
|
|
43
43
|
class CustomProfile
|
|
44
|
-
def serializer_class
|
|
44
|
+
def serializer_class
|
|
45
|
+
ProfileSerializer
|
|
46
|
+
end
|
|
45
47
|
end
|
|
46
48
|
|
|
47
|
-
Tweet
|
|
49
|
+
class Tweet < ::Model; end
|
|
48
50
|
TweetSerializer = Class.new
|
|
49
51
|
|
|
50
52
|
def setup
|
|
@@ -57,7 +59,7 @@ module ActiveModel
|
|
|
57
59
|
|
|
58
60
|
def test_serializer_for_non_ams_serializer
|
|
59
61
|
serializer = ActiveModel::Serializer.serializer_for(@tweet)
|
|
60
|
-
|
|
62
|
+
assert_nil serializer
|
|
61
63
|
end
|
|
62
64
|
|
|
63
65
|
def test_serializer_for_existing_serializer
|
|
@@ -69,12 +71,12 @@ module ActiveModel
|
|
|
69
71
|
serializer = with_serializer_lookup_disabled do
|
|
70
72
|
ActiveModel::Serializer.serializer_for(@profile)
|
|
71
73
|
end
|
|
72
|
-
|
|
74
|
+
assert_nil serializer
|
|
73
75
|
end
|
|
74
76
|
|
|
75
77
|
def test_serializer_for_not_existing_serializer
|
|
76
78
|
serializer = ActiveModel::Serializer.serializer_for(@model)
|
|
77
|
-
|
|
79
|
+
assert_nil serializer
|
|
78
80
|
end
|
|
79
81
|
|
|
80
82
|
def test_serializer_inherited_serializer
|
|
@@ -86,7 +88,7 @@ module ActiveModel
|
|
|
86
88
|
serializer = with_serializer_lookup_disabled do
|
|
87
89
|
ActiveModel::Serializer.serializer_for(@my_profile)
|
|
88
90
|
end
|
|
89
|
-
|
|
91
|
+
assert_nil serializer
|
|
90
92
|
end
|
|
91
93
|
|
|
92
94
|
def test_serializer_custom_serializer
|
|
@@ -112,7 +114,7 @@ module ActiveModel
|
|
|
112
114
|
serializer = with_serializer_lookup_disabled do
|
|
113
115
|
ActiveModel::Serializer.serializer_for(post)
|
|
114
116
|
end
|
|
115
|
-
|
|
117
|
+
assert_nil serializer
|
|
116
118
|
end
|
|
117
119
|
|
|
118
120
|
def test_serializer_for_nested_resource
|
|
@@ -126,7 +128,7 @@ module ActiveModel
|
|
|
126
128
|
serializer = with_serializer_lookup_disabled do
|
|
127
129
|
ResourceNamespace::PostSerializer.serializer_for(comment)
|
|
128
130
|
end
|
|
129
|
-
|
|
131
|
+
assert_nil serializer
|
|
130
132
|
end
|
|
131
133
|
end
|
|
132
134
|
end
|