mirror of
https://github.com/drapergem/draper
synced 2023-03-27 23:21:17 -04:00
Merge pull request #408 from haines/infer_collection_decorator
Infer collection decorator
This commit is contained in:
commit
0b8d88fbe9
5 changed files with 58 additions and 22 deletions
|
@ -41,7 +41,7 @@ module Draper
|
|||
"inferred decorators"
|
||||
end
|
||||
|
||||
"#<CollectionDecorator of #{klass} for #{source.inspect}>"
|
||||
"#<#{self.class.name} of #{klass} for #{source.inspect}>"
|
||||
end
|
||||
|
||||
def context=(value)
|
||||
|
|
|
@ -141,7 +141,7 @@ module Draper
|
|||
# @option options [Hash] :context context available to decorated items
|
||||
def self.decorate_collection(source, options = {})
|
||||
options.assert_valid_keys(:with, :context)
|
||||
Draper::CollectionDecorator.new(source, options.reverse_merge(with: self))
|
||||
collection_decorator_class.new(source, options.reverse_merge(with: self))
|
||||
end
|
||||
|
||||
# Get the chain of decorators applied to the object.
|
||||
|
@ -218,6 +218,14 @@ module Draper
|
|||
super || delegatable_method?(method)
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def self.collection_decorator_class
|
||||
collection_decorator_name.constantize
|
||||
rescue NameError
|
||||
Draper::CollectionDecorator
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def delegatable_method?(method)
|
||||
|
@ -228,18 +236,21 @@ module Draper
|
|||
source_class? && source_class.respond_to?(method)
|
||||
end
|
||||
|
||||
def self.source_name
|
||||
raise NameError if name.nil? || name.demodulize !~ /.+Decorator$/
|
||||
name.chomp("Decorator")
|
||||
end
|
||||
|
||||
def self.inferred_source_class
|
||||
uninferrable_source if name.nil? || name.demodulize !~ /.+Decorator$/
|
||||
|
||||
begin
|
||||
name.chomp("Decorator").constantize
|
||||
source_name.constantize
|
||||
rescue NameError
|
||||
uninferrable_source
|
||||
end
|
||||
raise Draper::UninferrableSourceError.new(self)
|
||||
end
|
||||
|
||||
def self.uninferrable_source
|
||||
raise Draper::UninferrableSourceError.new(self)
|
||||
def self.collection_decorator_name
|
||||
plural = source_name.pluralize
|
||||
raise NameError if plural == source_name
|
||||
"#{plural}Decorator"
|
||||
end
|
||||
|
||||
def self.define_proxy(method)
|
||||
|
|
|
@ -248,7 +248,7 @@ describe Draper::CollectionDecorator do
|
|||
let(:options) { {with: ProductDecorator} }
|
||||
|
||||
it "returns a string representation of the CollectionDecorator" do
|
||||
subject.to_s.should == '#<CollectionDecorator of ProductDecorator for ["a", "b", "c"]>'
|
||||
subject.to_s.should == '#<Draper::CollectionDecorator of ProductDecorator for ["a", "b", "c"]>'
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -256,7 +256,15 @@ describe Draper::CollectionDecorator do
|
|||
let(:options) { {} }
|
||||
|
||||
it "returns a string representation of the CollectionDecorator" do
|
||||
subject.to_s.should == '#<CollectionDecorator of inferred decorators for ["a", "b", "c"]>'
|
||||
subject.to_s.should == '#<Draper::CollectionDecorator of inferred decorators for ["a", "b", "c"]>'
|
||||
end
|
||||
end
|
||||
|
||||
context "for a custom subclass" do
|
||||
subject { ProductsDecorator.new(source) }
|
||||
|
||||
it "uses the custom class name" do
|
||||
subject.to_s.should =~ /ProductsDecorator/
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -76,7 +76,6 @@ describe Draper::Decorator do
|
|||
end
|
||||
|
||||
describe ".decorate_collection" do
|
||||
subject { ProductDecorator.decorate_collection(source) }
|
||||
let(:source) { [Product.new, Widget.new] }
|
||||
|
||||
describe "options validation" do
|
||||
|
@ -92,14 +91,31 @@ describe Draper::Decorator do
|
|||
end
|
||||
end
|
||||
|
||||
it "returns a collection decorator" do
|
||||
context "when a custom collection decorator does not exist" do
|
||||
subject { WidgetDecorator.decorate_collection(source) }
|
||||
|
||||
it "returns a regular collection decorator" do
|
||||
subject.should be_a Draper::CollectionDecorator
|
||||
subject.should == source
|
||||
end
|
||||
|
||||
it "uses itself as the item decorator by default" do
|
||||
subject.each {|item| item.should be_a WidgetDecorator}
|
||||
end
|
||||
end
|
||||
|
||||
context "when a custom collection decorator exists" do
|
||||
subject { ProductDecorator.decorate_collection(source) }
|
||||
|
||||
it "returns the custom collection decorator" do
|
||||
subject.should be_a ProductsDecorator
|
||||
subject.should == source
|
||||
end
|
||||
|
||||
it "uses itself as the item decorator by default" do
|
||||
subject.each {|item| item.should be_a ProductDecorator}
|
||||
end
|
||||
end
|
||||
|
||||
context "with context" do
|
||||
subject { ProductDecorator.decorate_collection(source, with: :infer, context: {some: 'context'}) }
|
||||
|
|
|
@ -49,7 +49,8 @@ class DummyApp
|
|||
|
||||
yield
|
||||
|
||||
Process.kill('KILL', out.pid)
|
||||
Process.kill("KILL", out.pid)
|
||||
File.delete("tmp/pids/server.pid")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -57,11 +58,11 @@ class DummyApp
|
|||
private
|
||||
|
||||
def root
|
||||
File.expand_path('../../dummy', __FILE__)
|
||||
File.expand_path("../../dummy", __FILE__)
|
||||
end
|
||||
|
||||
def localhost
|
||||
'127.0.0.1'
|
||||
"127.0.0.1"
|
||||
end
|
||||
|
||||
def port
|
||||
|
|
Loading…
Reference in a new issue