Skip to content

Commit

Permalink
Invoke parent serializer method instead of object method with the sam…
Browse files Browse the repository at this point in the history
…e name (#118)

* [fix] invoke object method instead of parent serializer method (#115)

* Correct rubocop offenses
  • Loading branch information
kolasss authored and nesaulov committed Sep 26, 2018
1 parent 4c98891 commit 918e685
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 2 deletions.
20 changes: 20 additions & 0 deletions lib/surrealist/serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,26 @@ def serializer_context(*array)

# Plural form ¯\_(ツ)_/¯
alias serializer_contexts serializer_context

# Only lookup for methods defined in Surrealist::Serializer subclasses
# to prevent invoke of Kernel methods
#
# @param [Symbol] method method to be invoked
#
# @return [Boolean]
def method_defined?(method)
return true if instance_methods(false).include?(method)
return false if superclass == Surrealist::Serializer

super
end

def private_method_defined?(method)
return true if private_instance_methods(false).include?(method)
return false if superclass == Surrealist::Serializer

super
end
end

# NOTE: #context will work only when using serializer explicitly,
Expand Down
7 changes: 5 additions & 2 deletions lib/surrealist/value_assigner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ def raw_value(instance, schema)
# @return [Object] the return value of the method
def invoke_method(instance, method)
object = instance.instance_variable_get(:@object)
instance_method = instance.class.instance_methods(false).include?(method) ||
instance.class.private_instance_methods(false).include?(method)
instance_method = instance.class.method_defined?(method) ||
instance.class.private_method_defined?(method)
invoke_object = !instance_method && object && object.respond_to?(method, true)
invoke_object ? object.send(method) : instance.send(method)
end
Expand Down Expand Up @@ -77,6 +77,7 @@ def coerce_value(value, schema)
# @return [Array] of schemas
def assign_nested_collection(instance, value)
return if @skip_set.include?(value.first.class)

with_skip_set(instance.class) { Surrealist.surrealize_collection(value, raw: true) }
end

Expand All @@ -88,6 +89,7 @@ def assign_nested_collection(instance, value)
# @return [Hash] schema
def assign_nested_record(instance, value)
return if @skip_set.include?(value.class)

with_skip_set(instance.class) { value.build_schema }
end

Expand All @@ -98,6 +100,7 @@ def assign_nested_record(instance, value)
# @return [Object] block result
def with_skip_set(klass)
return yield if @skip_set.include?(klass)

@skip_set.add(klass)
result = yield
@skip_set.delete(klass)
Expand Down
16 changes: 16 additions & 0 deletions spec/serializer_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,12 @@ def new_test
end
end

class FooChildSerializer < FooSerializer
json_schema do
{ new_test: String, private_test: String }
end
end

RSpec.describe Surrealist::Serializer do
describe 'Explicit surrealization through `Serializer.new`' do
describe 'instance' do
Expand Down Expand Up @@ -357,6 +363,16 @@ def new_test
expect(hash[:private_test]).to eq('serializer private method')
expect(hash[:another_private]).to eq('model private method')
end

context 'when serializer inherited' do
let(:instance) { FooChildSerializer.new(model) }
let(:hash) { instance.build_schema }

it 'prefer parent serializer method before object method with the same name' do
expect(hash[:new_test]).to eq('serializer public method')
expect(hash[:private_test]).to eq('serializer private method')
end
end
end
end
end

0 comments on commit 918e685

Please sign in to comment.