1
0
Fork 0
mirror of https://github.com/drapergem/draper synced 2023-03-27 23:21:17 -04:00

Merge pull request #310 from haines/helper_proxy

Extract helper proxy
This commit is contained in:
Steve Klabnik 2012-10-15 10:49:51 -07:00
commit 7b645eae23
5 changed files with 59 additions and 43 deletions

View file

@ -4,6 +4,7 @@ require 'draper/version'
require 'draper/system' require 'draper/system'
require 'draper/active_model_support' require 'draper/active_model_support'
require 'draper/decorator' require 'draper/decorator'
require 'draper/helper_proxy'
require 'draper/lazy_helpers' require 'draper/lazy_helpers'
require 'draper/decoratable' require 'draper/decoratable'
require 'draper/security' require 'draper/security'

View file

@ -162,48 +162,30 @@ module Draper
decorate(model_class.last, options) decorate(model_class.last, options)
end end
# Some helpers are private, for example html_escape... as a workaround
# we are wrapping the helpers in a delegator that passes the methods
# along through a send, which will ignore private/public distinctions
class HelpersWrapper
def initialize(helpers)
@helpers = helpers
end
def method_missing(method, *args, &block)
@helpers.send(method, *args, &block)
end
#needed for tests
def ==(other)
other.instance_variable_get(:@helpers) == @helpers
end
end
# Access the helpers proxy to call built-in and user-defined # Access the helpers proxy to call built-in and user-defined
# Rails helpers. Aliased to `.h` for convenience. # Rails helpers. Aliased to `h` for convenience.
# #
# @return [Object] proxy # @return [HelperProxy] the helpers proxy
def helpers def helpers
@helpers ||= HelpersWrapper.new self.class.helpers self.class.helpers
end end
alias :h :helpers alias :h :helpers
# Localize is something that's used quite often. Even though # Localize is something that's used quite often. Even though
# it's available through helpers, that's annoying. Aliased # it's available through helpers, that's annoying. Aliased
# to `.l` for convenience. # to `l` for convenience.
def localize(object, options = {}) def localize(*args)
self.class.helpers.localize(object, options) helpers.localize(*args)
end end
alias :l :localize alias :l :localize
# Access the helpers proxy to call built-in and user-defined # Access the helpers proxy to call built-in and user-defined
# Rails helpers from a class context. # Rails helpers from a class context.
# #
# @return [Object] proxy # @return [HelperProxy] the helpers proxy
class << self class << self
def helpers def helpers
Draper::ViewContext.current @helpers ||= HelperProxy.new
end end
alias :h :helpers alias :h :helpers
end end

View file

@ -0,0 +1,16 @@
module Draper
class HelperProxy
# Some helpers are private, for example html_escape... as a workaround
# we are wrapping the helpers in a delegator that passes the methods
# along through a send, which will ignore private/public distinctions
def method_missing(method, *args, &block)
view_context.send(method, *args, &block)
end
private
def view_context
Draper::ViewContext.current
end
end
end

View file

@ -20,13 +20,13 @@ describe Draper::Decorator do
end end
end end
context(".helpers") do describe "#helpers" do
it "have a valid view_context" do it "returns a HelperProxy" do
subject.helpers.should be subject.helpers.should be_a Draper::HelperProxy
end end
it "is aliased to .h" do it "is aliased to #h" do
subject.h.should == subject.helpers subject.h.should be subject.helpers
end end
it "initializes the wrapper only once" do it "initializes the wrapper only once" do
@ -37,13 +37,25 @@ describe Draper::Decorator do
end end
end end
context("#helpers") do describe "#localize" do
it "have a valid view_context" do before { subject.helpers.should_receive(:localize).with(:an_object, {some: "options"}) }
Decorator.helpers.should be
it "delegates to helpers" do
subject.localize(:an_object, some: "options")
end end
it "is aliased to #h" do it "is aliased to #l" do
Decorator.h.should == Decorator.helpers subject.l(:an_object, some: "options")
end
end
describe ".helpers" do
it "returns a HelperProxy" do
Decorator.helpers.should be_a Draper::HelperProxy
end
it "is aliased to .h" do
Decorator.h.should be Decorator.helpers
end end
end end
@ -673,13 +685,6 @@ describe Draper::Decorator do
decorator.sample_truncate.should == "Once..." decorator.sample_truncate.should == "Once..."
end end
it "is able to use l rather than helpers.l" do
now = Time.now
helper_proxy = decorator.helpers.instance_variable_get(:@helpers)
helper_proxy.should_receive(:localize).with(now, :format => :long)
decorator.l now, :format => :long
end
it "is able to access html_escape, a private method" do it "is able to access html_escape, a private method" do
decorator.sample_html_escaped_text.should == '&lt;script&gt;danger&lt;/script&gt;' decorator.sample_html_escaped_text.should == '&lt;script&gt;danger&lt;/script&gt;'
end end

View file

@ -0,0 +1,12 @@
require 'spec_helper'
describe Draper::HelperProxy do
subject(:helper_proxy) { Draper::HelperProxy.new }
let(:view_context) { Object.new }
before { helper_proxy.stub(:view_context).and_return(view_context) }
it "proxies methods to the view context" do
view_context.should_receive(:foo).with("bar")
helper_proxy.foo("bar")
end
end