be able to use different decorators for different instance variables, useful for collection vs. singular
This commit is contained in:
parent
53fe02ed82
commit
1a6dc17134
|
@ -16,7 +16,13 @@ require 'active_support/core_ext/class/attribute'
|
|||
module DecoratesBeforeRendering
|
||||
module ClassMethods
|
||||
def decorates(*unsigiled_ivar_names)
|
||||
self.__ivars_to_decorate__ = unsigiled_ivar_names.map { |i| "@#{i}" }
|
||||
options = {}
|
||||
if unsigiled_ivar_names.last.instance_of?(::Hash)
|
||||
options = unsigiled_ivar_names.pop
|
||||
end
|
||||
|
||||
self.__ivars_to_decorate__ ||= []
|
||||
self.__ivars_to_decorate__ << [ unsigiled_ivar_names.map { |i| "@#{i}" }, options ]
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -30,16 +36,20 @@ private
|
|||
def __decorate_ivars__
|
||||
ivars_to_decorate = self.class.__ivars_to_decorate__
|
||||
|
||||
return if ivars_to_decorate.nil?
|
||||
return if ivars_to_decorate.nil? or ivars_to_decorate.empty?
|
||||
|
||||
ivars_to_decorate.each do |ivar_name|
|
||||
ivar = instance_variable_get(ivar_name)
|
||||
instance_variable_set(ivar_name, __decorator_for__(ivar)) unless ivar.nil?
|
||||
ivars_to_decorate.each do |ivar_names, options|
|
||||
ivar_names.each do |ivar_name|
|
||||
if ivar = instance_variable_get(ivar_name)
|
||||
decorator = (options[:with] || __decorator_for__(ivar)).decorate(ivar)
|
||||
instance_variable_set(ivar_name, decorator)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def __decorator_for__(ivar)
|
||||
__decorator_name_for__(ivar).constantize.decorate(ivar)
|
||||
__decorator_name_for__(ivar).constantize
|
||||
end
|
||||
|
||||
def __decorator_name_for__(ivar)
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
require_relative '../lib/decorates_before_rendering'
|
||||
|
||||
class MyCompletelyFakeModelDecorator; end
|
||||
class MyOtherCompletelyFakeModelDecorator; end
|
||||
|
||||
describe DecoratesBeforeRendering do
|
||||
# NOTE: these are married together, so they're tested together.
|
||||
describe '::decorates + #render' do
|
||||
let(:sentinel) { double(:sentinel) }
|
||||
let(:ivar) { double('@ivar') }
|
||||
let(:ivars) { double('@ivars') }
|
||||
|
||||
# NOTE: This superclass is here so we know that the correct render gets
|
||||
# called. It can't be defined in the subclass, or else that one
|
||||
|
@ -27,16 +29,17 @@ describe DecoratesBeforeRendering do
|
|||
Class.new(superclass) do
|
||||
include DecoratesBeforeRendering
|
||||
|
||||
attr_reader :ivar
|
||||
attr_reader :ivar, :ivars
|
||||
|
||||
def initialize(sentinel, ivar)
|
||||
def initialize(sentinel, ivar, ivars = nil)
|
||||
super(sentinel)
|
||||
|
||||
@ivar = ivar
|
||||
@ivars = ivars
|
||||
end
|
||||
end
|
||||
end
|
||||
let(:instance) { klass.new(sentinel, ivar) }
|
||||
let(:instance) { klass.new(sentinel, ivar, ivars) }
|
||||
let(:args) { double('*args') }
|
||||
|
||||
context "no ivars" do
|
||||
|
@ -92,5 +95,19 @@ describe DecoratesBeforeRendering do
|
|||
subclass_instance.render(args)
|
||||
end
|
||||
end
|
||||
|
||||
context "Specify a different decorator class for an automatic decorator" do
|
||||
it "should function correctly" do
|
||||
klass.decorates(:ivars, :with => MyOtherCompletelyFakeModelDecorator)
|
||||
klass.decorates(:ivar)
|
||||
subclass_instance = Class.new(klass).new(sentinel, ivar, ivars)
|
||||
sentinel.should_receive(:render).with(args)
|
||||
MyOtherCompletelyFakeModelDecorator.should_receive(:decorate).with(ivars)
|
||||
MyCompletelyFakeModelDecorator.should_receive(:decorate).with(ivar)
|
||||
ivar.stub_chain(:class, :model_name => 'MyCompletelyFakeModel')
|
||||
subclass_instance.render(args)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue