Remove non-default serializers

This commit is contained in:
Evgenii Pecherkin 2017-10-23 17:29:28 +04:00 committed by Rafael Mendonça França
parent e360ac1231
commit 3785a57299
10 changed files with 72 additions and 163 deletions

View File

@ -57,10 +57,6 @@ That's it!
ActiveJob supports the following types of arguments by default:
- Standard types (`NilClass`, `String`, `Integer`, `Fixnum`, `Bignum`, `Float`, `BigDecimal`, `TrueClass`, `FalseClass`)
- `Symbol` (`:foo`, `:bar`, ...)
- `ActiveSupport::Duration` (`1.day`, `2.weeks`, ...)
- Classes constants (`ActiveRecord::Base`, `MySpecialService`, ...)
- Struct instances (`Struct.new('Rectangle', :width, :height).new(12, 20)`, ...)
- `Hash`. Keys should be of `String` or `Symbol` type
- `ActiveSupport::HashWithIndifferentAccess`
- `Array`

View File

@ -27,15 +27,11 @@ module ActiveJob
autoload :ArraySerializer
autoload :BaseSerializer
autoload :ClassSerializer
autoload :DurationSerializer
autoload :GlobalIDSerializer
autoload :HashWithIndifferentAccessSerializer
autoload :HashSerializer
autoload :ObjectSerializer
autoload :StandardTypeSerializer
autoload :StructSerializer
autoload :SymbolSerializer
included do
class_attribute :_additional_serializers, instance_accessor: false, instance_predicate: false
@ -46,14 +42,14 @@ module ActiveJob
module ClassMethods
# Returns list of known serializers
def serializers
self._additional_serializers + SERIALIZERS
self._additional_serializers + ActiveJob::Serializers::SERIALIZERS
end
# Adds a new serializer to a list of known serializers
def add_serializers(*serializers)
check_duplicate_serializer_keys!(serializers)
def add_serializers(*new_serializers)
check_duplicate_serializer_keys!(new_serializers)
@_additional_serializers = serializers + @_additional_serializers
self._additional_serializers = new_serializers + self._additional_serializers
end
# Returns a list of reserved keys, which cannot be used as keys for a hash
@ -66,7 +62,7 @@ module ActiveJob
def check_duplicate_serializer_keys!(serializers)
keys_to_add = serializers.select { |s| s.respond_to?(:key) }.map(&:key)
duplicate_keys = reserved_keys & keys_to_add
duplicate_keys = reserved_serializers_keys & keys_to_add
raise ArgumentError.new("Can't add serializers because of keys duplication: #{duplicate_keys}") if duplicate_keys.any?
end
@ -75,21 +71,16 @@ module ActiveJob
# :nodoc:
SERIALIZERS = [
::ActiveJob::Serializers::GlobalIDSerializer,
::ActiveJob::Serializers::DurationSerializer,
::ActiveJob::Serializers::StructSerializer,
::ActiveJob::Serializers::SymbolSerializer,
::ActiveJob::Serializers::ClassSerializer,
::ActiveJob::Serializers::StandardTypeSerializer,
::ActiveJob::Serializers::HashWithIndifferentAccessSerializer,
::ActiveJob::Serializers::HashSerializer,
::ActiveJob::Serializers::ArraySerializer
].freeze
private_constant :SERIALIZERS
class << self
# Returns serialized representative of the passed object.
# Will look up through all known serializers.
# Raises `SerializationError` if it can't find a proper serializer.
# Raises `ActiveJob::SerializationError` if it can't find a proper serializer.
def serialize(argument)
serializer = ::ActiveJob::Base.serializers.detect { |s| s.serialize?(argument) }
raise SerializationError.new("Unsupported argument type: #{argument.class.name}") unless serializer

View File

@ -1,24 +0,0 @@
# frozen_string_literal: true
module ActiveJob
module Serializers
# Provides methods to serialize and deserialize `Class` (`ActiveRecord::Base`, `MySpecialService`, ...)
class ClassSerializer < ObjectSerializer
class << self
def serialize(argument_klass)
{ key => "::#{argument_klass.name}" }
end
def key
"_aj_class"
end
private
def klass
::Class
end
end
end
end
end

View File

@ -1,42 +0,0 @@
# frozen_string_literal: true
module ActiveJob
module Serializers
# Provides methods to serialize and deserialize `ActiveSupport::Duration` (`1.day`, `2.weeks`, ...)
class DurationSerializer < ObjectSerializer
class << self
def serialize(duration)
{
key => duration.value,
parts_key => ::ActiveJob::Serializers.serialize(duration.parts)
}
end
def deserialize(hash)
value = hash[key]
parts = ::ActiveJob::Serializers.deserialize(hash[parts_key])
klass.new(value, parts)
end
def key
"_aj_activesupport_duration"
end
private
def klass
::ActiveSupport::Duration
end
def keys
super.push parts_key
end
def parts_key
"parts"
end
end
end
end
end

View File

@ -1,38 +0,0 @@
# frozen_string_literal: true
module ActiveJob
module Serializers
# Provides methods to serialize and deserialize struct instances
# (`Struct.new('Rectangle', :width, :height).new(12, 20)`)
class StructSerializer < ObjectSerializer
class << self
def serialize(object)
super.merge values_key => ::ActiveJob::Serializers.serialize(object.values)
end
def deserialize(hash)
values = ::ActiveJob::Serializers.deserialize(hash[values_key])
super.new(*values)
end
def key
"_aj_struct"
end
private
def klass
::Struct
end
def keys
super.push values_key
end
def values_key
"values"
end
end
end
end
end

View File

@ -1,28 +0,0 @@
# frozen_string_literal: true
module ActiveJob
module Serializers
# Provides methods to serialize and deserialize `Symbol` (`:foo`, `:bar`, ...)
class SymbolSerializer < ObjectSerializer
class << self
def serialize(symbol)
{ key => symbol.to_s }
end
def deserialize(hash)
hash[key].to_sym
end
def key
"_aj_symbol"
end
private
def klass
::Symbol
end
end
end
end
end

View File

@ -30,7 +30,7 @@ module Rails # :nodoc:
private
def application_job_file_name
@application_job_file_name ||= if mountable_engine?
"app/jobs/#{namespaced_path}/application_job.rb"
"app/jobs/#{namespaced_path}/application_job.rb"
else
"app/jobs/application_job.rb"
end

View File

@ -4,7 +4,6 @@ require "helper"
require "active_job/arguments"
require "models/person"
require "active_support/core_ext/hash/indifferent_access"
require "active_support/duration"
require "jobs/kwargs_job"
class ArgumentSerializationTest < ActiveSupport::TestCase
@ -14,7 +13,6 @@ class ArgumentSerializationTest < ActiveSupport::TestCase
[ nil, 1, 1.0, 1_000_000_000_000_000_000_000,
"a", true, false, BigDecimal.new(5),
:a, self, 1.day,
[ 1, "a" ],
{ "a" => 1 }
].each do |arg|
@ -23,7 +21,7 @@ class ArgumentSerializationTest < ActiveSupport::TestCase
end
end
[ Object.new, Person.find("5").to_gid ].each do |arg|
[ :a, Object.new, self, Person.find("5").to_gid ].each do |arg|
test "does not serialize #{arg.class}" do
assert_raises ActiveJob::SerializationError do
ActiveJob::Arguments.serialize [ arg ]
@ -35,10 +33,6 @@ class ArgumentSerializationTest < ActiveSupport::TestCase
end
end
test "serializes Struct" do
assert_arguments_unchanged Struct.new("Rectangle", :width, :height).new(10, 15)
end
test "should convert records to Global IDs" do
assert_arguments_roundtrip [@person]
end

View File

@ -0,0 +1,64 @@
# frozen_string_literal: true
require "helper"
require "active_job/serializers"
class SerializersTest < ActiveSupport::TestCase
class DummyValueObject
attr_accessor :value
def initialize(value)
@value = value
end
end
class DummySerializer < ActiveJob::Serializers::ObjectSerializer
class << self
def serialize(object)
{ key => object.value }
end
def deserialize(hash)
DummyValueObject.new(hash[key])
end
def key
"_dummy_serializer"
end
private
def klass
DummyValueObject
end
end
end
setup do
@value_object = DummyValueObject.new 123
ActiveJob::Base._additional_serializers = []
end
test "can't serialize unknown object" do
assert_raises ActiveJob::SerializationError do
ActiveJob::Serializers.serialize @value_object
end
end
test "won't deserialize unknown hash" do
hash = { "_dummy_serializer" => 123, "_aj_symbol_keys" => [] }
assert ActiveJob::Serializers.deserialize(hash), hash.except("_aj_symbol_keys")
end
test "adds new serializer" do
ActiveJob::Base.add_serializers DummySerializer
assert ActiveJob::Base.serializers.include?(DummySerializer)
end
test "can't add serializer with the same key twice" do
ActiveJob::Base.add_serializers DummySerializer
assert_raises ArgumentError do
ActiveJob::Base.add_serializers DummySerializer
end
end
end

View File

@ -345,10 +345,6 @@ Supported types for arguments
ActiveJob supports the following types of arguments by default:
- Basic types (`NilClass`, `String`, `Integer`, `Fixnum`, `Bignum`, `Float`, `BigDecimal`, `TrueClass`, `FalseClass`)
- `Symbol` (`:foo`, `:bar`, ...)
- `ActiveSupport::Duration` (`1.day`, `2.weeks`, ...)
- Classes constants (`ActiveRecord::Base`, `MySpecialService`, ...)
- Struct instances (`Struct.new('Rectangle', :width, :height).new(12, 20)`, ...)
- `Hash`. Keys should be of `String` or `Symbol` type
- `ActiveSupport::HashWithIndifferentAccess`
- `Array`