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

Extract helper proxy

This commit is contained in:
Andrew Haines 2012-10-14 23:01:15 +01:00
parent 96db1d09b5
commit 8599e21e2f
5 changed files with 59 additions and 43 deletions

View file

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

View file

@ -162,48 +162,30 @@ module Draper
decorate(model_class.last, options)
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
# Rails helpers. Aliased to `.h` for convenience.
# Rails helpers. Aliased to `h` for convenience.
#
# @return [Object] proxy
# @return [HelperProxy] the helpers proxy
def helpers
@helpers ||= HelpersWrapper.new self.class.helpers
self.class.helpers
end
alias :h :helpers
# Localize is something that's used quite often. Even though
# it's available through helpers, that's annoying. Aliased
# to `.l` for convenience.
def localize(object, options = {})
self.class.helpers.localize(object, options)
# to `l` for convenience.
def localize(*args)
helpers.localize(*args)
end
alias :l :localize
# Access the helpers proxy to call built-in and user-defined
# Rails helpers from a class context.
#
# @return [Object] proxy
# @return [HelperProxy] the helpers proxy
class << self
def helpers
Draper::ViewContext.current
@helpers ||= HelperProxy.new
end
alias :h :helpers
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
context(".helpers") do
it "have a valid view_context" do
subject.helpers.should be
describe "#helpers" do
it "returns a HelperProxy" do
subject.helpers.should be_a Draper::HelperProxy
end
it "is aliased to .h" do
subject.h.should == subject.helpers
it "is aliased to #h" do
subject.h.should be subject.helpers
end
it "initializes the wrapper only once" do
@ -37,13 +37,25 @@ describe Draper::Decorator do
end
end
context("#helpers") do
it "have a valid view_context" do
Decorator.helpers.should be
describe "#localize" do
before { subject.helpers.should_receive(:localize).with(:an_object, {some: "options"}) }
it "delegates to helpers" do
subject.localize(:an_object, some: "options")
end
it "is aliased to #h" do
Decorator.h.should == Decorator.helpers
it "is aliased to #l" do
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
@ -673,13 +685,6 @@ describe Draper::Decorator do
decorator.sample_truncate.should == "Once..."
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
decorator.sample_html_escaped_text.should == '&lt;script&gt;danger&lt;/script&gt;'
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