mirror of
https://github.com/drapergem/draper
synced 2023-03-27 23:21:17 -04:00
Let decorator_class infer anonymous class' decorator from superclass (#820)
* Let decorator_class infer anonymous class' decorator from superclass * Replace constantize with safe_constantize on decorator's private methods * Don't raise NameError on decorator private methods. To prevent rescuing and checking if NameError is from internal decorator private methods, we change to return nil on these private methods. * Revise decorator inferred_object_class and collection_decorator_name based on code review comments
This commit is contained in:
parent
815c4186dd
commit
cc23669889
4 changed files with 30 additions and 16 deletions
|
@ -72,9 +72,9 @@ module Draper
|
|||
def decorator_class
|
||||
prefix = respond_to?(:model_name) ? model_name : name
|
||||
decorator_name = "#{prefix}Decorator"
|
||||
decorator_name.constantize
|
||||
rescue NameError => error
|
||||
raise unless error.missing_name?(decorator_name)
|
||||
decorator_name_constant = decorator_name.safe_constantize
|
||||
return decorator_name_constant unless decorator_name_constant.nil?
|
||||
|
||||
if superclass.respond_to?(:decorator_class)
|
||||
superclass.decorator_class
|
||||
else
|
||||
|
|
|
@ -225,9 +225,9 @@ module Draper
|
|||
# @return [Class] the class created by {decorate_collection}.
|
||||
def self.collection_decorator_class
|
||||
name = collection_decorator_name
|
||||
name.constantize
|
||||
rescue NameError
|
||||
Draper::CollectionDecorator
|
||||
name_constant = name && name.safe_constantize
|
||||
|
||||
name_constant || Draper::CollectionDecorator
|
||||
end
|
||||
|
||||
private
|
||||
|
@ -242,22 +242,23 @@ module Draper
|
|||
end
|
||||
|
||||
def self.object_class_name
|
||||
raise NameError if name.nil? || name.demodulize !~ /.+Decorator$/
|
||||
return nil if name.nil? || name.demodulize !~ /.+Decorator$/
|
||||
name.chomp("Decorator")
|
||||
end
|
||||
|
||||
def self.inferred_object_class
|
||||
name = object_class_name
|
||||
name.constantize
|
||||
rescue NameError => error
|
||||
raise if name && !error.missing_name?(name)
|
||||
name_constant = name && name.safe_constantize
|
||||
return name_constant unless name_constant.nil?
|
||||
|
||||
raise Draper::UninferrableObjectError.new(self)
|
||||
end
|
||||
|
||||
def self.collection_decorator_name
|
||||
plural = object_class_name.pluralize
|
||||
raise NameError if plural == object_class_name
|
||||
"#{plural}Decorator"
|
||||
singular = object_class_name
|
||||
plural = singular && singular.pluralize
|
||||
|
||||
"#{plural}Decorator" unless plural == singular
|
||||
end
|
||||
|
||||
def handle_multiple_decoration(options)
|
||||
|
|
|
@ -205,10 +205,22 @@ module Draper
|
|||
|
||||
context "when an unrelated NameError is thrown" do
|
||||
it "re-raises that error" do
|
||||
allow_any_instance_of(String).to receive(:constantize) { Draper::Base }
|
||||
# Not related to safe_constantize behavior, we just want to raise a NameError inside the function
|
||||
allow_any_instance_of(String).to receive(:safe_constantize) { Draper::Base }
|
||||
expect{Product.decorator_class}.to raise_error NameError, /Draper::Base/
|
||||
end
|
||||
end
|
||||
|
||||
context "when an anonymous class is given" do
|
||||
it "infers the decorator from a superclass" do
|
||||
anonymous_class = Class.new(Product) do
|
||||
def self.name
|
||||
to_s
|
||||
end
|
||||
end
|
||||
expect(anonymous_class.decorator_class).to be ProductDecorator
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -202,7 +202,8 @@ module Draper
|
|||
|
||||
context "when an unrelated NameError is thrown" do
|
||||
it "re-raises that error" do
|
||||
allow_any_instance_of(String).to receive(:constantize) { SomethingThatDoesntExist }
|
||||
# Not related to safe_constantize behavior, we just want to raise a NameError inside the function
|
||||
allow_any_instance_of(String).to receive(:safe_constantize) { SomethingThatDoesntExist }
|
||||
expect{ProductDecorator.object_class}.to raise_error NameError, /SomethingThatDoesntExist/
|
||||
end
|
||||
end
|
||||
|
@ -225,7 +226,7 @@ module Draper
|
|||
|
||||
describe '.collection_decorator_class' do
|
||||
it 'defaults to CollectionDecorator' do
|
||||
allow_any_instance_of(String).to receive(:constantize) { SomethingThatDoesntExist }
|
||||
allow_any_instance_of(String).to receive(:safe_constantize) { nil }
|
||||
expect(ProductDecorator.collection_decorator_class).to be Draper::CollectionDecorator
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in a new issue