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
|
@@ -1,20 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'test_helper'
|
|
2
4
|
|
|
3
5
|
module ActiveModel
|
|
4
6
|
class Serializer
|
|
5
7
|
class OptionsTest < ActiveSupport::TestCase
|
|
6
|
-
|
|
7
|
-
|
|
8
|
+
class ModelWithOptions < ActiveModelSerializers::Model
|
|
9
|
+
attributes :name, :description
|
|
10
|
+
end
|
|
11
|
+
class ModelWithOptionsSerializer < ActiveModel::Serializer
|
|
12
|
+
attributes :name, :description
|
|
13
|
+
|
|
14
|
+
def arguments_passed_in?
|
|
15
|
+
instance_options[:my_options] == :accessible
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
setup do
|
|
20
|
+
@model_with_options = ModelWithOptions.new(name: 'Name 1', description: 'Description 1')
|
|
8
21
|
end
|
|
9
22
|
|
|
10
23
|
def test_options_are_accessible
|
|
11
|
-
|
|
12
|
-
assert
|
|
24
|
+
model_with_options_serializer = ModelWithOptionsSerializer.new(@model_with_options, my_options: :accessible)
|
|
25
|
+
assert model_with_options_serializer.arguments_passed_in?
|
|
13
26
|
end
|
|
14
27
|
|
|
15
28
|
def test_no_option_is_passed_in
|
|
16
|
-
|
|
17
|
-
refute
|
|
29
|
+
model_with_options_serializer = ModelWithOptionsSerializer.new(@model_with_options)
|
|
30
|
+
refute model_with_options_serializer.arguments_passed_in?
|
|
18
31
|
end
|
|
19
32
|
end
|
|
20
33
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'test_helper'
|
|
2
4
|
|
|
3
5
|
module ActiveModel
|
|
@@ -5,10 +7,10 @@ module ActiveModel
|
|
|
5
7
|
class ReadAttributeForSerializationTest < ActiveSupport::TestCase
|
|
6
8
|
# https://github.com/rails-api/active_model_serializers/issues/1653
|
|
7
9
|
class Parent < ActiveModelSerializers::Model
|
|
8
|
-
|
|
10
|
+
attributes :id
|
|
9
11
|
end
|
|
10
12
|
class Child < Parent
|
|
11
|
-
|
|
13
|
+
attributes :name
|
|
12
14
|
end
|
|
13
15
|
class ParentSerializer < ActiveModel::Serializer
|
|
14
16
|
attributes :$id
|
|
@@ -30,7 +32,7 @@ module ActiveModel
|
|
|
30
32
|
|
|
31
33
|
# https://github.com/rails-api/active_model_serializers/issues/1658
|
|
32
34
|
class ErrorResponse < ActiveModelSerializers::Model
|
|
33
|
-
|
|
35
|
+
attributes :error
|
|
34
36
|
end
|
|
35
37
|
class ApplicationSerializer < ActiveModel::Serializer
|
|
36
38
|
attributes :status
|
|
@@ -0,0 +1,481 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'test_helper'
|
|
4
|
+
module ActiveModel
|
|
5
|
+
class Serializer
|
|
6
|
+
class ReflectionTest < ActiveSupport::TestCase
|
|
7
|
+
class Blog < ActiveModelSerializers::Model
|
|
8
|
+
attributes :id
|
|
9
|
+
end
|
|
10
|
+
class BlogSerializer < ActiveModel::Serializer
|
|
11
|
+
type 'blog'
|
|
12
|
+
attributes :id
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
setup do
|
|
16
|
+
@expected_meta = { id: 1 }
|
|
17
|
+
@expected_links = { self: 'no_uri_validation' }
|
|
18
|
+
@empty_links = {}
|
|
19
|
+
model_attributes = { blog: Blog.new(@expected_meta) }
|
|
20
|
+
@model = Class.new(ActiveModelSerializers::Model) do
|
|
21
|
+
attributes(*model_attributes.keys)
|
|
22
|
+
|
|
23
|
+
def self.name
|
|
24
|
+
'TestModel'
|
|
25
|
+
end
|
|
26
|
+
end.new(model_attributes)
|
|
27
|
+
@instance_options = {}
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def evaluate_association_value(association)
|
|
31
|
+
association.lazy_association.eval_reflection_block
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# TODO: Remaining tests
|
|
35
|
+
# test_reflection_value_block_with_scope
|
|
36
|
+
# test_reflection_value_uses_serializer_instance_method
|
|
37
|
+
# test_reflection_excluded_eh_blank_is_false
|
|
38
|
+
# test_reflection_excluded_eh_if
|
|
39
|
+
# test_reflection_excluded_eh_unless
|
|
40
|
+
# test_evaluate_condition_symbol_serializer_method
|
|
41
|
+
# test_evaluate_condition_string_serializer_method
|
|
42
|
+
# test_evaluate_condition_proc
|
|
43
|
+
# test_evaluate_condition_proc_yields_serializer
|
|
44
|
+
# test_evaluate_condition_other
|
|
45
|
+
# test_options_key
|
|
46
|
+
# test_options_polymorphic
|
|
47
|
+
# test_options_serializer
|
|
48
|
+
# test_options_virtual_value
|
|
49
|
+
# test_options_namespace
|
|
50
|
+
|
|
51
|
+
def test_reflection_value
|
|
52
|
+
serializer_class = Class.new(ActiveModel::Serializer) do
|
|
53
|
+
has_one :blog
|
|
54
|
+
end
|
|
55
|
+
serializer_instance = serializer_class.new(@model, @instance_options)
|
|
56
|
+
|
|
57
|
+
# Get Reflection
|
|
58
|
+
reflection = serializer_class._reflections.fetch(:blog)
|
|
59
|
+
|
|
60
|
+
# Assert
|
|
61
|
+
assert_nil reflection.block
|
|
62
|
+
assert_equal Serializer.config.include_data_default, reflection.options.fetch(:include_data_setting)
|
|
63
|
+
assert_equal true, reflection.options.fetch(:include_data_setting)
|
|
64
|
+
|
|
65
|
+
include_slice = :does_not_matter
|
|
66
|
+
assert_equal @model.blog, reflection.send(:value, serializer_instance, include_slice)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def test_reflection_value_block
|
|
70
|
+
serializer_class = Class.new(ActiveModel::Serializer) do
|
|
71
|
+
has_one :blog do
|
|
72
|
+
object.blog
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
serializer_instance = serializer_class.new(@model, @instance_options)
|
|
76
|
+
|
|
77
|
+
# Get Reflection
|
|
78
|
+
reflection = serializer_class._reflections.fetch(:blog)
|
|
79
|
+
|
|
80
|
+
# Assert
|
|
81
|
+
assert_respond_to reflection.block, :call
|
|
82
|
+
assert_equal Serializer.config.include_data_default, reflection.options.fetch(:include_data_setting)
|
|
83
|
+
assert_equal true, reflection.options.fetch(:include_data_setting)
|
|
84
|
+
|
|
85
|
+
include_slice = :does_not_matter
|
|
86
|
+
assert_equal @model.blog, reflection.send(:value, serializer_instance, include_slice)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def test_reflection_value_block_with_explicit_include_data_true
|
|
90
|
+
serializer_class = Class.new(ActiveModel::Serializer) do
|
|
91
|
+
has_one :blog do
|
|
92
|
+
include_data true
|
|
93
|
+
object.blog
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
serializer_instance = serializer_class.new(@model, @instance_options)
|
|
97
|
+
|
|
98
|
+
# Get Reflection
|
|
99
|
+
reflection = serializer_class._reflections.fetch(:blog)
|
|
100
|
+
|
|
101
|
+
# Assert
|
|
102
|
+
assert_respond_to reflection.block, :call
|
|
103
|
+
assert_equal Serializer.config.include_data_default, reflection.options.fetch(:include_data_setting)
|
|
104
|
+
assert_equal true, reflection.options.fetch(:include_data_setting)
|
|
105
|
+
|
|
106
|
+
include_slice = :does_not_matter
|
|
107
|
+
assert_equal @model.blog, reflection.send(:value, serializer_instance, include_slice)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def test_reflection_value_block_with_include_data_false_mutates_the_reflection_include_data
|
|
111
|
+
serializer_class = Class.new(ActiveModel::Serializer) do
|
|
112
|
+
has_one :blog do
|
|
113
|
+
include_data false
|
|
114
|
+
object.blog
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
serializer_instance = serializer_class.new(@model, @instance_options)
|
|
118
|
+
|
|
119
|
+
# Get Reflection
|
|
120
|
+
reflection = serializer_class._reflections.fetch(:blog)
|
|
121
|
+
|
|
122
|
+
# Assert
|
|
123
|
+
assert_respond_to reflection.block, :call
|
|
124
|
+
assert_equal true, reflection.options.fetch(:include_data_setting)
|
|
125
|
+
include_slice = :does_not_matter
|
|
126
|
+
assert_nil reflection.send(:value, serializer_instance, include_slice)
|
|
127
|
+
assert_equal false, reflection.options.fetch(:include_data_setting)
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def test_reflection_value_block_with_include_data_if_sideloaded_included_mutates_the_reflection_include_data
|
|
131
|
+
serializer_class = Class.new(ActiveModel::Serializer) do
|
|
132
|
+
has_one :blog do
|
|
133
|
+
include_data :if_sideloaded
|
|
134
|
+
object.blog
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
serializer_instance = serializer_class.new(@model, @instance_options)
|
|
138
|
+
|
|
139
|
+
# Get Reflection
|
|
140
|
+
reflection = serializer_class._reflections.fetch(:blog)
|
|
141
|
+
|
|
142
|
+
# Assert
|
|
143
|
+
assert_respond_to reflection.block, :call
|
|
144
|
+
assert_equal true, reflection.options.fetch(:include_data_setting)
|
|
145
|
+
include_slice = {}
|
|
146
|
+
assert_nil reflection.send(:value, serializer_instance, include_slice)
|
|
147
|
+
assert_equal :if_sideloaded, reflection.options.fetch(:include_data_setting)
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def test_reflection_value_block_with_include_data_if_sideloaded_excluded_mutates_the_reflection_include_data
|
|
151
|
+
serializer_class = Class.new(ActiveModel::Serializer) do
|
|
152
|
+
has_one :blog do
|
|
153
|
+
include_data :if_sideloaded
|
|
154
|
+
object.blog
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
serializer_instance = serializer_class.new(@model, @instance_options)
|
|
158
|
+
|
|
159
|
+
# Get Reflection
|
|
160
|
+
reflection = serializer_class._reflections.fetch(:blog)
|
|
161
|
+
|
|
162
|
+
# Assert
|
|
163
|
+
assert_respond_to reflection.block, :call
|
|
164
|
+
assert_equal true, reflection.options.fetch(:include_data_setting)
|
|
165
|
+
include_slice = { blog: :does_not_matter }
|
|
166
|
+
assert_equal @model.blog, reflection.send(:value, serializer_instance, include_slice)
|
|
167
|
+
assert_equal :if_sideloaded, reflection.options.fetch(:include_data_setting)
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def test_reflection_block_with_link_mutates_the_reflection_links
|
|
171
|
+
serializer_class = Class.new(ActiveModel::Serializer) do
|
|
172
|
+
has_one :blog do
|
|
173
|
+
link :self, 'no_uri_validation'
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
serializer_instance = serializer_class.new(@model, @instance_options)
|
|
177
|
+
|
|
178
|
+
# Get Reflection
|
|
179
|
+
reflection = serializer_class._reflections.fetch(:blog)
|
|
180
|
+
assert_equal @empty_links, reflection.options.fetch(:links)
|
|
181
|
+
|
|
182
|
+
# Build Association
|
|
183
|
+
association = reflection.build_association(serializer_instance, @instance_options)
|
|
184
|
+
|
|
185
|
+
# Assert association links empty when not yet evaluated
|
|
186
|
+
assert_equal @empty_links, reflection.options.fetch(:links)
|
|
187
|
+
assert_equal @empty_links, association.links
|
|
188
|
+
|
|
189
|
+
evaluate_association_value(association)
|
|
190
|
+
|
|
191
|
+
assert_equal @expected_links, association.links
|
|
192
|
+
assert_equal @expected_links, reflection.options.fetch(:links)
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
def test_reflection_block_with_link_block_mutates_the_reflection_links
|
|
196
|
+
serializer_class = Class.new(ActiveModel::Serializer) do
|
|
197
|
+
has_one :blog do
|
|
198
|
+
link :self do
|
|
199
|
+
'no_uri_validation'
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
serializer_instance = serializer_class.new(@model, @instance_options)
|
|
204
|
+
|
|
205
|
+
# Get Reflection
|
|
206
|
+
reflection = serializer_class._reflections.fetch(:blog)
|
|
207
|
+
assert_equal @empty_links, reflection.options.fetch(:links)
|
|
208
|
+
|
|
209
|
+
# Build Association
|
|
210
|
+
association = reflection.build_association(serializer_instance, @instance_options)
|
|
211
|
+
|
|
212
|
+
# Assert association links empty when not yet evaluated
|
|
213
|
+
assert_equal @empty_links, association.links
|
|
214
|
+
|
|
215
|
+
evaluate_association_value(association)
|
|
216
|
+
|
|
217
|
+
# Assert before instance_eval link
|
|
218
|
+
link = association.links.fetch(:self)
|
|
219
|
+
assert_respond_to link, :call
|
|
220
|
+
assert_respond_to reflection.options.fetch(:links).fetch(:self), :call
|
|
221
|
+
|
|
222
|
+
# Assert after instance_eval link
|
|
223
|
+
assert_equal @expected_links.fetch(:self), reflection.instance_eval(&link)
|
|
224
|
+
assert_respond_to reflection.options.fetch(:links).fetch(:self), :call
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
def test_reflection_block_with_meta_mutates_the_reflection_meta
|
|
228
|
+
serializer_class = Class.new(ActiveModel::Serializer) do
|
|
229
|
+
has_one :blog do
|
|
230
|
+
meta(id: object.blog.id)
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
serializer_instance = serializer_class.new(@model, @instance_options)
|
|
234
|
+
|
|
235
|
+
# Get Reflection
|
|
236
|
+
reflection = serializer_class._reflections.fetch(:blog)
|
|
237
|
+
assert_nil reflection.options.fetch(:meta)
|
|
238
|
+
|
|
239
|
+
# Build Association
|
|
240
|
+
association = reflection.build_association(serializer_instance, @instance_options)
|
|
241
|
+
|
|
242
|
+
evaluate_association_value(association)
|
|
243
|
+
|
|
244
|
+
assert_equal @expected_meta, association.meta
|
|
245
|
+
assert_equal @expected_meta, reflection.options.fetch(:meta)
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
def test_reflection_block_with_meta_block_mutates_the_reflection_meta
|
|
249
|
+
serializer_class = Class.new(ActiveModel::Serializer) do
|
|
250
|
+
has_one :blog do
|
|
251
|
+
meta do
|
|
252
|
+
{ id: object.blog.id }
|
|
253
|
+
end
|
|
254
|
+
end
|
|
255
|
+
end
|
|
256
|
+
serializer_instance = serializer_class.new(@model, @instance_options)
|
|
257
|
+
|
|
258
|
+
# Get Reflection
|
|
259
|
+
reflection = serializer_class._reflections.fetch(:blog)
|
|
260
|
+
assert_nil reflection.options.fetch(:meta)
|
|
261
|
+
|
|
262
|
+
# Build Association
|
|
263
|
+
association = reflection.build_association(serializer_instance, @instance_options)
|
|
264
|
+
# Assert before instance_eval meta
|
|
265
|
+
|
|
266
|
+
evaluate_association_value(association)
|
|
267
|
+
|
|
268
|
+
assert_respond_to association.meta, :call
|
|
269
|
+
assert_respond_to reflection.options.fetch(:meta), :call
|
|
270
|
+
|
|
271
|
+
# Assert after instance_eval meta
|
|
272
|
+
assert_equal @expected_meta, reflection.instance_eval(&association.meta)
|
|
273
|
+
assert_respond_to reflection.options.fetch(:meta), :call
|
|
274
|
+
assert_respond_to association.meta, :call
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
# rubocop:disable Metrics/AbcSize
|
|
278
|
+
def test_reflection_block_with_meta_in_link_block_mutates_the_reflection_meta
|
|
279
|
+
serializer_class = Class.new(ActiveModel::Serializer) do
|
|
280
|
+
has_one :blog do
|
|
281
|
+
link :self do
|
|
282
|
+
meta(id: object.blog.id)
|
|
283
|
+
'no_uri_validation'
|
|
284
|
+
end
|
|
285
|
+
end
|
|
286
|
+
end
|
|
287
|
+
serializer_instance = serializer_class.new(@model, @instance_options)
|
|
288
|
+
|
|
289
|
+
# Get Reflection
|
|
290
|
+
reflection = serializer_class._reflections.fetch(:blog)
|
|
291
|
+
assert_nil reflection.options.fetch(:meta)
|
|
292
|
+
assert_equal @empty_links, reflection.options.fetch(:links)
|
|
293
|
+
|
|
294
|
+
# Build Association
|
|
295
|
+
association = reflection.build_association(serializer_instance, @instance_options)
|
|
296
|
+
# Assert before instance_eval link meta
|
|
297
|
+
assert_nil association.meta
|
|
298
|
+
assert_nil reflection.options.fetch(:meta)
|
|
299
|
+
|
|
300
|
+
evaluate_association_value(association)
|
|
301
|
+
|
|
302
|
+
link = association.links.fetch(:self)
|
|
303
|
+
assert_respond_to link, :call
|
|
304
|
+
assert_respond_to reflection.options.fetch(:links).fetch(:self), :call
|
|
305
|
+
assert_nil reflection.options.fetch(:meta)
|
|
306
|
+
|
|
307
|
+
# Assert after instance_eval link
|
|
308
|
+
assert_equal 'no_uri_validation', reflection.instance_eval(&link)
|
|
309
|
+
assert_equal @expected_meta, reflection.options.fetch(:meta)
|
|
310
|
+
assert_equal @expected_meta, association.meta
|
|
311
|
+
end
|
|
312
|
+
# rubocop:enable Metrics/AbcSize
|
|
313
|
+
|
|
314
|
+
# rubocop:disable Metrics/AbcSize
|
|
315
|
+
def test_reflection_block_with_meta_block_in_link_block_mutates_the_reflection_meta
|
|
316
|
+
serializer_class = Class.new(ActiveModel::Serializer) do
|
|
317
|
+
has_one :blog do
|
|
318
|
+
link :self do
|
|
319
|
+
meta do
|
|
320
|
+
{ id: object.blog.id }
|
|
321
|
+
end
|
|
322
|
+
'no_uri_validation'
|
|
323
|
+
end
|
|
324
|
+
end
|
|
325
|
+
end
|
|
326
|
+
serializer_instance = serializer_class.new(@model, @instance_options)
|
|
327
|
+
|
|
328
|
+
# Get Reflection
|
|
329
|
+
reflection = serializer_class._reflections.fetch(:blog)
|
|
330
|
+
assert_nil reflection.options.fetch(:meta)
|
|
331
|
+
|
|
332
|
+
# Build Association
|
|
333
|
+
association = reflection.build_association(serializer_instance, @instance_options)
|
|
334
|
+
assert_nil association.meta
|
|
335
|
+
assert_nil reflection.options.fetch(:meta)
|
|
336
|
+
|
|
337
|
+
# Assert before instance_eval link
|
|
338
|
+
|
|
339
|
+
evaluate_association_value(association)
|
|
340
|
+
|
|
341
|
+
link = association.links.fetch(:self)
|
|
342
|
+
assert_nil reflection.options.fetch(:meta)
|
|
343
|
+
assert_respond_to link, :call
|
|
344
|
+
assert_respond_to association.links.fetch(:self), :call
|
|
345
|
+
|
|
346
|
+
# Assert after instance_eval link
|
|
347
|
+
assert_equal 'no_uri_validation', reflection.instance_eval(&link)
|
|
348
|
+
assert_respond_to association.links.fetch(:self), :call
|
|
349
|
+
# Assert before instance_eval link meta
|
|
350
|
+
assert_respond_to reflection.options.fetch(:meta), :call
|
|
351
|
+
assert_respond_to association.meta, :call
|
|
352
|
+
|
|
353
|
+
# Assert after instance_eval link meta
|
|
354
|
+
assert_equal @expected_meta, reflection.instance_eval(&reflection.options.fetch(:meta))
|
|
355
|
+
assert_respond_to association.meta, :call
|
|
356
|
+
end
|
|
357
|
+
# rubocop:enable Metrics/AbcSize
|
|
358
|
+
|
|
359
|
+
def test_no_href_in_vanilla_reflection
|
|
360
|
+
serializer_class = Class.new(ActiveModel::Serializer) do
|
|
361
|
+
has_one :blog do
|
|
362
|
+
link :self do
|
|
363
|
+
href 'no_uri_validation'
|
|
364
|
+
end
|
|
365
|
+
end
|
|
366
|
+
end
|
|
367
|
+
serializer_instance = serializer_class.new(@model, @instance_options)
|
|
368
|
+
|
|
369
|
+
# Get Reflection
|
|
370
|
+
reflection = serializer_class._reflections.fetch(:blog)
|
|
371
|
+
assert_equal @empty_links, reflection.options.fetch(:links)
|
|
372
|
+
|
|
373
|
+
# Build Association
|
|
374
|
+
association = reflection.build_association(serializer_instance, @instance_options)
|
|
375
|
+
# Assert before instance_eval link
|
|
376
|
+
|
|
377
|
+
evaluate_association_value(association)
|
|
378
|
+
|
|
379
|
+
link = association.links.fetch(:self)
|
|
380
|
+
assert_respond_to link, :call
|
|
381
|
+
|
|
382
|
+
# Assert after instance_eval link
|
|
383
|
+
exception = assert_raise(NoMethodError) do
|
|
384
|
+
reflection.instance_eval(&link)
|
|
385
|
+
end
|
|
386
|
+
assert_match(/undefined method `href'/, exception.message)
|
|
387
|
+
end
|
|
388
|
+
|
|
389
|
+
# rubocop:disable Metrics/AbcSize
|
|
390
|
+
def test_mutating_reflection_block_is_not_thread_safe
|
|
391
|
+
serializer_class = Class.new(ActiveModel::Serializer) do
|
|
392
|
+
has_one :blog do
|
|
393
|
+
meta(id: object.blog.id)
|
|
394
|
+
end
|
|
395
|
+
end
|
|
396
|
+
model1_meta = @expected_meta
|
|
397
|
+
# Evaluate reflection meta for model with id 1
|
|
398
|
+
serializer_instance = serializer_class.new(@model, @instance_options)
|
|
399
|
+
reflection = serializer_class._reflections.fetch(:blog)
|
|
400
|
+
assert_nil reflection.options.fetch(:meta)
|
|
401
|
+
association = reflection.build_association(serializer_instance, @instance_options)
|
|
402
|
+
|
|
403
|
+
evaluate_association_value(association)
|
|
404
|
+
|
|
405
|
+
assert_equal model1_meta, association.meta
|
|
406
|
+
assert_equal model1_meta, reflection.options.fetch(:meta)
|
|
407
|
+
|
|
408
|
+
model2_meta = @expected_meta.merge(id: 2)
|
|
409
|
+
# Evaluate reflection meta for model with id 2
|
|
410
|
+
@model.blog.id = 2
|
|
411
|
+
assert_equal 2, @model.blog.id # sanity check
|
|
412
|
+
serializer_instance = serializer_class.new(@model, @instance_options)
|
|
413
|
+
reflection = serializer_class._reflections.fetch(:blog)
|
|
414
|
+
|
|
415
|
+
# WARN: Thread-safety issue
|
|
416
|
+
# Before the reflection is evaluated, it has the value from the previous evaluation
|
|
417
|
+
assert_equal model1_meta, reflection.options.fetch(:meta)
|
|
418
|
+
|
|
419
|
+
association = reflection.build_association(serializer_instance, @instance_options)
|
|
420
|
+
|
|
421
|
+
evaluate_association_value(association)
|
|
422
|
+
|
|
423
|
+
assert_equal model2_meta, association.meta
|
|
424
|
+
assert_equal model2_meta, reflection.options.fetch(:meta)
|
|
425
|
+
end
|
|
426
|
+
# rubocop:enable Metrics/AbcSize
|
|
427
|
+
end
|
|
428
|
+
class ThreadedReflectionTest < ActiveSupport::TestCase
|
|
429
|
+
class Post < ::Model
|
|
430
|
+
attributes :id, :title, :body
|
|
431
|
+
associations :comments
|
|
432
|
+
end
|
|
433
|
+
class Comment < ::Model
|
|
434
|
+
attributes :id, :body
|
|
435
|
+
associations :post
|
|
436
|
+
end
|
|
437
|
+
class CommentSerializer < ActiveModel::Serializer
|
|
438
|
+
type 'comment'
|
|
439
|
+
attributes :id, :body
|
|
440
|
+
has_one :post
|
|
441
|
+
end
|
|
442
|
+
class PostSerializer < ActiveModel::Serializer
|
|
443
|
+
type 'post'
|
|
444
|
+
attributes :id, :title, :body
|
|
445
|
+
has_many :comments, serializer: CommentSerializer do
|
|
446
|
+
sleep 0.1
|
|
447
|
+
object.comments
|
|
448
|
+
end
|
|
449
|
+
end
|
|
450
|
+
|
|
451
|
+
# per https://github.com/rails-api/active_model_serializers/issues/2270
|
|
452
|
+
def test_concurrent_serialization
|
|
453
|
+
post1 = Post.new(id: 1, title: 'Post 1 Title', body: 'Post 1 Body')
|
|
454
|
+
post1.comments = [Comment.new(id: 1, body: 'Comment on Post 1', post: post1)]
|
|
455
|
+
post2 = Post.new(id: 2, title: 'Post 2 Title', body: 'Post 2 Body')
|
|
456
|
+
post2.comments = [Comment.new(id: 2, body: 'Comment on Post 2', post: post2)]
|
|
457
|
+
serialized_posts = {
|
|
458
|
+
first: Set.new,
|
|
459
|
+
second: Set.new
|
|
460
|
+
}
|
|
461
|
+
t1 = Thread.new do
|
|
462
|
+
10.times do
|
|
463
|
+
serialized_posts[:first] << PostSerializer.new(post1, {}).to_json
|
|
464
|
+
end
|
|
465
|
+
end
|
|
466
|
+
t2 = Thread.new do
|
|
467
|
+
10.times do
|
|
468
|
+
serialized_posts[:second] << PostSerializer.new(post2, {}).to_json
|
|
469
|
+
end
|
|
470
|
+
end
|
|
471
|
+
t1.join
|
|
472
|
+
t2.join
|
|
473
|
+
expected_first_post_serialization = '{"id":1,"title":"Post 1 Title","body":"Post 1 Body","comments":[{"id":1,"body":"Comment on Post 1"}]}'
|
|
474
|
+
expected_second_post_serialization = '{"id":2,"title":"Post 2 Title","body":"Post 2 Body","comments":[{"id":2,"body":"Comment on Post 2"}]}'
|
|
475
|
+
|
|
476
|
+
assert_equal [expected_second_post_serialization], serialized_posts[:second].to_a
|
|
477
|
+
assert_equal [expected_first_post_serialization], serialized_posts[:first].to_a
|
|
478
|
+
end
|
|
479
|
+
end
|
|
480
|
+
end
|
|
481
|
+
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'test_helper'
|
|
2
4
|
|
|
3
5
|
module ActiveModel
|
|
@@ -8,7 +10,7 @@ module ActiveModel
|
|
|
8
10
|
end
|
|
9
11
|
|
|
10
12
|
def test_overwrite_root
|
|
11
|
-
serializer = VirtualValueSerializer.new(@virtual_value,
|
|
13
|
+
serializer = VirtualValueSerializer.new(@virtual_value, root: 'smth')
|
|
12
14
|
assert_equal('smth', serializer.json_key)
|
|
13
15
|
end
|
|
14
16
|
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module ActiveModel
|
|
2
4
|
class Serializer
|
|
3
5
|
class SerializationTest < ActiveSupport::TestCase
|
|
4
6
|
class Blog < ActiveModelSerializers::Model
|
|
5
|
-
|
|
7
|
+
attributes :id, :name, :authors
|
|
6
8
|
end
|
|
7
9
|
class Author < ActiveModelSerializers::Model
|
|
8
|
-
|
|
10
|
+
attributes :id, :name
|
|
9
11
|
end
|
|
10
12
|
class BlogSerializer < ActiveModel::Serializer
|
|
11
13
|
attributes :id
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'test_helper'
|
|
2
4
|
|
|
3
5
|
module ActiveModel
|
|
@@ -28,8 +30,8 @@ module ActiveModel
|
|
|
28
30
|
|
|
29
31
|
class SerializerTest < ActiveSupport::TestCase
|
|
30
32
|
module ResourceNamespace
|
|
31
|
-
Post
|
|
32
|
-
Comment
|
|
33
|
+
class Post < ::Model; end
|
|
34
|
+
class Comment < ::Model; end
|
|
33
35
|
|
|
34
36
|
class PostSerializer < ActiveModel::Serializer
|
|
35
37
|
class CommentSerializer < ActiveModel::Serializer
|
|
@@ -41,10 +43,12 @@ module ActiveModel
|
|
|
41
43
|
end
|
|
42
44
|
|
|
43
45
|
class CustomProfile
|
|
44
|
-
def serializer_class
|
|
46
|
+
def serializer_class
|
|
47
|
+
ProfileSerializer
|
|
48
|
+
end
|
|
45
49
|
end
|
|
46
50
|
|
|
47
|
-
Tweet
|
|
51
|
+
class Tweet < ::Model; end
|
|
48
52
|
TweetSerializer = Class.new
|
|
49
53
|
|
|
50
54
|
def setup
|
|
@@ -57,7 +61,7 @@ module ActiveModel
|
|
|
57
61
|
|
|
58
62
|
def test_serializer_for_non_ams_serializer
|
|
59
63
|
serializer = ActiveModel::Serializer.serializer_for(@tweet)
|
|
60
|
-
|
|
64
|
+
assert_nil serializer
|
|
61
65
|
end
|
|
62
66
|
|
|
63
67
|
def test_serializer_for_existing_serializer
|
|
@@ -69,12 +73,12 @@ module ActiveModel
|
|
|
69
73
|
serializer = with_serializer_lookup_disabled do
|
|
70
74
|
ActiveModel::Serializer.serializer_for(@profile)
|
|
71
75
|
end
|
|
72
|
-
|
|
76
|
+
assert_nil serializer
|
|
73
77
|
end
|
|
74
78
|
|
|
75
79
|
def test_serializer_for_not_existing_serializer
|
|
76
80
|
serializer = ActiveModel::Serializer.serializer_for(@model)
|
|
77
|
-
|
|
81
|
+
assert_nil serializer
|
|
78
82
|
end
|
|
79
83
|
|
|
80
84
|
def test_serializer_inherited_serializer
|
|
@@ -86,7 +90,7 @@ module ActiveModel
|
|
|
86
90
|
serializer = with_serializer_lookup_disabled do
|
|
87
91
|
ActiveModel::Serializer.serializer_for(@my_profile)
|
|
88
92
|
end
|
|
89
|
-
|
|
93
|
+
assert_nil serializer
|
|
90
94
|
end
|
|
91
95
|
|
|
92
96
|
def test_serializer_custom_serializer
|
|
@@ -112,7 +116,7 @@ module ActiveModel
|
|
|
112
116
|
serializer = with_serializer_lookup_disabled do
|
|
113
117
|
ActiveModel::Serializer.serializer_for(post)
|
|
114
118
|
end
|
|
115
|
-
|
|
119
|
+
assert_nil serializer
|
|
116
120
|
end
|
|
117
121
|
|
|
118
122
|
def test_serializer_for_nested_resource
|
|
@@ -126,7 +130,7 @@ module ActiveModel
|
|
|
126
130
|
serializer = with_serializer_lookup_disabled do
|
|
127
131
|
ResourceNamespace::PostSerializer.serializer_for(comment)
|
|
128
132
|
end
|
|
129
|
-
|
|
133
|
+
assert_nil serializer
|
|
130
134
|
end
|
|
131
135
|
end
|
|
132
136
|
end
|