mirror of
https://github.com/drapergem/draper
synced 2023-03-27 23:21:17 -04:00
Rename source_class
to object_class
This commit is contained in:
parent
d67a53a39f
commit
ae13cb58d5
4 changed files with 67 additions and 52 deletions
|
@ -26,7 +26,7 @@ module Draper
|
|||
def method_missing(method, *args, &block)
|
||||
return super unless delegatable?(method)
|
||||
|
||||
source_class.send(method, *args, &block)
|
||||
object_class.send(method, *args, &block)
|
||||
end
|
||||
|
||||
# Checks if the decorator responds to a class method, or is able to proxy
|
||||
|
@ -37,7 +37,7 @@ module Draper
|
|||
|
||||
# @private
|
||||
def delegatable?(method)
|
||||
source_class? && source_class.respond_to?(method)
|
||||
object_class? && object_class.respond_to?(method)
|
||||
end
|
||||
|
||||
# @private
|
||||
|
|
|
@ -39,7 +39,7 @@ module Draper
|
|||
end
|
||||
|
||||
# Automatically delegates instance methods to the source object. Class
|
||||
# methods will be delegated to the {source_class}, if it is set.
|
||||
# methods will be delegated to the {object_class}, if it is set.
|
||||
#
|
||||
# @return [void]
|
||||
def self.delegate_all
|
||||
|
@ -52,11 +52,11 @@ module Draper
|
|||
# source (including when using {decorates_finders}), and the source class
|
||||
# cannot be inferred from the decorator class (e.g. `ProductDecorator`
|
||||
# maps to `Product`).
|
||||
# @param [String, Symbol, Class] source_class
|
||||
# @param [String, Symbol, Class] object_class
|
||||
# source class (or class name) that corresponds to this decorator.
|
||||
# @return [void]
|
||||
def self.decorates(source_class)
|
||||
@source_class = source_class.to_s.camelize.constantize
|
||||
def self.decorates(object_class)
|
||||
@object_class = object_class.to_s.camelize.constantize
|
||||
end
|
||||
|
||||
# Returns the source class corresponding to the decorator class, as set by
|
||||
|
@ -64,22 +64,27 @@ module Draper
|
|||
# `ProductDecorator` maps to `Product`).
|
||||
#
|
||||
# @return [Class] the source class that corresponds to this decorator.
|
||||
def self.source_class
|
||||
@source_class ||= inferred_source_class
|
||||
def self.object_class
|
||||
@object_class ||= inferred_object_class
|
||||
end
|
||||
|
||||
# Checks whether this decorator class has a corresponding {source_class}.
|
||||
def self.source_class?
|
||||
source_class
|
||||
# Checks whether this decorator class has a corresponding {object_class}.
|
||||
def self.object_class?
|
||||
object_class
|
||||
rescue Draper::UninferrableSourceError
|
||||
false
|
||||
end
|
||||
|
||||
class << self # TODO deprecate this
|
||||
alias_method :source_class, :object_class
|
||||
alias_method :source_class?, :object_class?
|
||||
end
|
||||
|
||||
# Automatically decorates ActiveRecord finder methods, so that you can use
|
||||
# `ProductDecorator.find(id)` instead of
|
||||
# `ProductDecorator.decorate(Product.find(id))`.
|
||||
#
|
||||
# Finder methods are applied to the {source_class}.
|
||||
# Finder methods are applied to the {object_class}.
|
||||
#
|
||||
# @return [void]
|
||||
def self.decorates_finders
|
||||
|
@ -201,7 +206,7 @@ module Draper
|
|||
delegate :to_param, :to_partial_path
|
||||
|
||||
# ActiveModel compatibility
|
||||
singleton_class.delegate :model_name, to: :source_class
|
||||
singleton_class.delegate :model_name, to: :object_class
|
||||
|
||||
# @return [Class] the class created by {decorate_collection}.
|
||||
def self.collection_decorator_class
|
||||
|
@ -214,13 +219,13 @@ module Draper
|
|||
|
||||
private
|
||||
|
||||
def self.source_name
|
||||
def self.object_class_name
|
||||
raise NameError if name.nil? || name.demodulize !~ /.+Decorator$/
|
||||
name.chomp("Decorator")
|
||||
end
|
||||
|
||||
def self.inferred_source_class
|
||||
name = source_name
|
||||
def self.inferred_object_class
|
||||
name = object_class_name
|
||||
name.constantize
|
||||
rescue NameError => error
|
||||
raise if name && !error.missing_name?(name)
|
||||
|
@ -228,8 +233,8 @@ module Draper
|
|||
end
|
||||
|
||||
def self.collection_decorator_name
|
||||
plural = source_name.pluralize
|
||||
raise NameError if plural == source_name
|
||||
plural = object_class_name.pluralize
|
||||
raise NameError if plural == object_class_name
|
||||
"#{plural}Decorator"
|
||||
end
|
||||
|
||||
|
|
|
@ -5,26 +5,26 @@ module Draper
|
|||
module Finders
|
||||
|
||||
def find(id, options = {})
|
||||
decorate(source_class.find(id), options)
|
||||
decorate(object_class.find(id), options)
|
||||
end
|
||||
|
||||
def all(options = {})
|
||||
decorate_collection(source_class.all, options)
|
||||
decorate_collection(object_class.all, options)
|
||||
end
|
||||
|
||||
def first(options = {})
|
||||
decorate(source_class.first, options)
|
||||
decorate(object_class.first, options)
|
||||
end
|
||||
|
||||
def last(options = {})
|
||||
decorate(source_class.last, options)
|
||||
decorate(object_class.last, options)
|
||||
end
|
||||
|
||||
# Decorates dynamic finder methods (`find_all_by_` and friends).
|
||||
def method_missing(method, *args, &block)
|
||||
return super unless method =~ /^find_(all_|last_|or_(initialize_|create_))?by_/
|
||||
|
||||
result = source_class.send(method, *args, &block)
|
||||
result = object_class.send(method, *args, &block)
|
||||
options = args.extract_options!
|
||||
|
||||
if method =~ /^find_all/
|
||||
|
|
|
@ -157,74 +157,84 @@ module Draper
|
|||
describe ".decorates" do
|
||||
protect_class Decorator
|
||||
|
||||
it "sets .source_class with a symbol" do
|
||||
it "sets .object_class with a symbol" do
|
||||
Decorator.decorates :product
|
||||
|
||||
expect(Decorator.source_class).to be Product
|
||||
expect(Decorator.object_class).to be Product
|
||||
end
|
||||
|
||||
it "sets .source_class with a string" do
|
||||
it "sets .object_class with a string" do
|
||||
Decorator.decorates "product"
|
||||
|
||||
expect(Decorator.source_class).to be Product
|
||||
expect(Decorator.object_class).to be Product
|
||||
end
|
||||
|
||||
it "sets .source_class with a class" do
|
||||
it "sets .object_class with a class" do
|
||||
Decorator.decorates Product
|
||||
|
||||
expect(Decorator.source_class).to be Product
|
||||
expect(Decorator.object_class).to be Product
|
||||
end
|
||||
end
|
||||
|
||||
describe ".source_class" do
|
||||
describe ".object_class" do
|
||||
protect_class ProductDecorator
|
||||
protect_class Namespaced::ProductDecorator
|
||||
|
||||
context "when not set by .decorates" do
|
||||
it "raises an UninferrableSourceError for a so-named 'Decorator'" do
|
||||
expect{Decorator.source_class}.to raise_error UninferrableSourceError
|
||||
expect{Decorator.object_class}.to raise_error UninferrableSourceError
|
||||
end
|
||||
|
||||
it "raises an UninferrableSourceError for anonymous decorators" do
|
||||
expect{Class.new(Decorator).source_class}.to raise_error UninferrableSourceError
|
||||
expect{Class.new(Decorator).object_class}.to raise_error UninferrableSourceError
|
||||
end
|
||||
|
||||
it "raises an UninferrableSourceError for a decorator without a model" do
|
||||
expect{OtherDecorator.source_class}.to raise_error UninferrableSourceError
|
||||
expect{OtherDecorator.object_class}.to raise_error UninferrableSourceError
|
||||
end
|
||||
|
||||
it "raises an UninferrableSourceError for other naming conventions" do
|
||||
expect{ProductPresenter.source_class}.to raise_error UninferrableSourceError
|
||||
expect{ProductPresenter.object_class}.to raise_error UninferrableSourceError
|
||||
end
|
||||
|
||||
it "infers the source for '<Model>Decorator'" do
|
||||
expect(ProductDecorator.source_class).to be Product
|
||||
expect(ProductDecorator.object_class).to be Product
|
||||
end
|
||||
|
||||
it "infers namespaced sources" do
|
||||
expect(Namespaced::ProductDecorator.source_class).to be Namespaced::Product
|
||||
expect(Namespaced::ProductDecorator.object_class).to be Namespaced::Product
|
||||
end
|
||||
|
||||
context "when an unrelated NameError is thrown" do
|
||||
it "re-raises that error" do
|
||||
String.any_instance.stub(:constantize).and_return{SomethingThatDoesntExist}
|
||||
expect{ProductDecorator.source_class}.to raise_error NameError, /SomethingThatDoesntExist/
|
||||
expect{ProductDecorator.object_class}.to raise_error NameError, /SomethingThatDoesntExist/
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it "is aliased to .source_class" do
|
||||
expect(ProductDecorator.source_class).to be Product
|
||||
end
|
||||
end
|
||||
|
||||
describe ".source_class?" do
|
||||
it "returns truthy when .source_class is set" do
|
||||
Decorator.stub(:source_class).and_return(Model)
|
||||
describe ".object_class?" do
|
||||
it "returns truthy when .object_class is set" do
|
||||
Decorator.stub(:object_class).and_return(Model)
|
||||
|
||||
expect(Decorator.source_class?).to be_true
|
||||
expect(Decorator.object_class?).to be_true
|
||||
end
|
||||
|
||||
it "returns false when .source_class is not inferrable" do
|
||||
Decorator.stub(:source_class).and_raise(UninferrableSourceError.new(Decorator))
|
||||
it "returns false when .object_class is not inferrable" do
|
||||
Decorator.stub(:object_class).and_raise(UninferrableSourceError.new(Decorator))
|
||||
|
||||
expect(Decorator.source_class?).to be_false
|
||||
expect(Decorator.object_class?).to be_false
|
||||
end
|
||||
|
||||
it "is aliased to .source_class?" do
|
||||
Decorator.stub(:object_class).and_return(Model)
|
||||
|
||||
expect(Decorator.source_class?).to be_true
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -402,7 +412,7 @@ module Draper
|
|||
|
||||
describe ".model_name" do
|
||||
it "delegates to the source class" do
|
||||
Decorator.stub source_class: double(model_name: :delegated)
|
||||
Decorator.stub object_class: double(model_name: :delegated)
|
||||
|
||||
expect(Decorator.model_name).to be :delegated
|
||||
end
|
||||
|
@ -540,15 +550,15 @@ module Draper
|
|||
|
||||
context "with a source class" do
|
||||
it "delegates methods that exist on the source class" do
|
||||
source_class = Class.new
|
||||
source_class.stub hello_world: :delegated
|
||||
Decorator.stub source_class: source_class
|
||||
object_class = Class.new
|
||||
object_class.stub hello_world: :delegated
|
||||
Decorator.stub object_class: object_class
|
||||
|
||||
expect(Decorator.hello_world).to be :delegated
|
||||
end
|
||||
|
||||
it "does not delegate methods that do not exist on the source class" do
|
||||
Decorator.stub source_class: Class.new
|
||||
Decorator.stub object_class: Class.new
|
||||
|
||||
expect{Decorator.hello_world}.to raise_error NoMethodError
|
||||
end
|
||||
|
@ -602,13 +612,13 @@ module Draper
|
|||
context "with a source class" do
|
||||
it "returns true for its own class methods" do
|
||||
Decorator.class_eval{def self.hello_world; end}
|
||||
Decorator.stub source_class: Class.new
|
||||
Decorator.stub object_class: Class.new
|
||||
|
||||
expect(Decorator).to respond_to :hello_world
|
||||
end
|
||||
|
||||
it "returns true for the source's class methods" do
|
||||
Decorator.stub source_class: double(hello_world: :delegated)
|
||||
Decorator.stub object_class: double(hello_world: :delegated)
|
||||
|
||||
expect(Decorator).to respond_to :hello_world
|
||||
end
|
||||
|
@ -627,7 +637,7 @@ module Draper
|
|||
|
||||
describe ".respond_to_missing?" do
|
||||
it "allows .method to be called on delegated class methods" do
|
||||
Decorator.stub source_class: double(hello_world: :delegated)
|
||||
Decorator.stub object_class: double(hello_world: :delegated)
|
||||
|
||||
expect { Decorator.method(:hello_world) }.not_to raise_error NameError
|
||||
expect(Decorator.method(:hello_world)).not_to be_nil
|
||||
|
|
Loading…
Reference in a new issue