Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

be able to use different decorators for different instance variables,…

… useful for collection vs. singular
  • Loading branch information...
commit 1a6dc17134483e5e9a9b0ef26ebe6ed521b07659 1 parent 53fe02e
John Bintz johnbintz authored
22 lib/decorates_before_rendering.rb
View
@@ -16,7 +16,13 @@
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 @@ def render(*args)
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)
23 spec/decorates_before_rendering_spec.rb
View
@@ -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 @@ def render(*args)
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 @@ def initialize(sentinel, ivar)
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
+
Please sign in to comment.
Something went wrong with that request. Please try again.