mirror of
https://github.com/drapergem/draper
synced 2023-03-27 23:21:17 -04:00
Unfreeze and protect CollectionDecorator#source
Makes CollectionDecorators behave more like dup'd arrays - you can modify them independently of the source.
This commit is contained in:
parent
b83a95f0f0
commit
dcc5e784c0
6 changed files with 9 additions and 33 deletions
|
@ -3,9 +3,6 @@ module Draper
|
|||
include Enumerable
|
||||
include ViewHelpers
|
||||
|
||||
attr_reader :source
|
||||
alias_method :to_source, :source
|
||||
|
||||
attr_accessor :context
|
||||
|
||||
array_methods = Array.instance_methods - Object.instance_methods
|
||||
|
@ -16,7 +13,7 @@ module Draper
|
|||
# @option options [Hash] :context context available to each item's decorator
|
||||
def initialize(source, options = {})
|
||||
options.assert_valid_keys(:with, :context)
|
||||
@source = source.to_a.dup.freeze
|
||||
@source = source
|
||||
@decorator_class = options[:with]
|
||||
@context = options.fetch(:context, {})
|
||||
end
|
||||
|
@ -26,7 +23,7 @@ module Draper
|
|||
end
|
||||
|
||||
def decorated_collection
|
||||
@decorated_collection ||= source.map{|item| decorate_item(item)}.freeze
|
||||
@decorated_collection ||= source.map{|item| decorate_item(item)}
|
||||
end
|
||||
|
||||
def find(*args, &block)
|
||||
|
@ -62,6 +59,8 @@ module Draper
|
|||
|
||||
protected
|
||||
|
||||
attr_reader :source
|
||||
|
||||
def decorate_item(item)
|
||||
item_decorator.call(item, context: context)
|
||||
end
|
||||
|
|
|
@ -16,27 +16,6 @@ describe Draper::CollectionDecorator do
|
|||
subject.map{|item| item.source}.should == source
|
||||
end
|
||||
|
||||
describe "#source" do
|
||||
it "duplicates the source collection" do
|
||||
subject.source.should == source
|
||||
subject.source.should_not be source
|
||||
end
|
||||
|
||||
it "is frozen" do
|
||||
subject.source.should be_frozen
|
||||
end
|
||||
|
||||
it "is aliased to #to_source" do
|
||||
subject.to_source.should == source
|
||||
end
|
||||
end
|
||||
|
||||
describe "#decorated_collection" do
|
||||
it "is frozen" do
|
||||
subject.decorated_collection.should be_frozen
|
||||
end
|
||||
end
|
||||
|
||||
context "with context" do
|
||||
subject { Draper::CollectionDecorator.new(source, with: ProductDecorator, context: {some: 'context'}) }
|
||||
|
||||
|
@ -151,7 +130,6 @@ describe Draper::CollectionDecorator do
|
|||
describe "#find" do
|
||||
context "with a block" do
|
||||
it "decorates Enumerable#find" do
|
||||
subject.stub decorated_collection: []
|
||||
subject.decorated_collection.should_receive(:find)
|
||||
subject.find {|p| p.title == "title" }
|
||||
end
|
||||
|
@ -208,13 +186,12 @@ describe Draper::CollectionDecorator do
|
|||
describe "#to_ary" do
|
||||
# required for `render @collection` in Rails
|
||||
it "delegates to the decorated collection" do
|
||||
subject.stub decorated_collection: double(to_ary: :an_array)
|
||||
subject.decorated_collection.stub to_ary: :an_array
|
||||
subject.to_ary.should == :an_array
|
||||
end
|
||||
end
|
||||
|
||||
it "delegates array methods to the decorated collection" do
|
||||
subject.stub decorated_collection: []
|
||||
subject.decorated_collection.should_receive(:[]).with(42).and_return(:the_answer)
|
||||
subject[42].should == :the_answer
|
||||
end
|
||||
|
|
|
@ -150,7 +150,7 @@ describe Draper::Decoratable do
|
|||
|
||||
decorator.should be_a Draper::CollectionDecorator
|
||||
decorator.decorator_class.should be WidgetDecorator
|
||||
decorator.source.should == Product.scoped
|
||||
decorator.should == Product.scoped
|
||||
end
|
||||
|
||||
it "accepts context" do
|
||||
|
|
|
@ -88,7 +88,7 @@ describe Draper::DecoratedAssociation do
|
|||
it "applies the scope before decoration" do
|
||||
scoped = [:scoped]
|
||||
associated.should_receive(:foo).and_return(scoped)
|
||||
decorated_association.call.source.should == scoped
|
||||
decorated_association.call.should == scoped
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -94,7 +94,7 @@ describe Draper::Decorator do
|
|||
|
||||
it "returns a collection decorator" do
|
||||
subject.should be_a Draper::CollectionDecorator
|
||||
subject.source.should == source
|
||||
subject.should == source
|
||||
end
|
||||
|
||||
it "uses itself as the item decorator by default" do
|
||||
|
|
|
@ -73,7 +73,7 @@ describe Draper::Finders do
|
|||
Product.stub(:find_all_by_name).and_return(found)
|
||||
decorator = ProductDecorator.find_all_by_name("apples")
|
||||
decorator.should be_a Draper::CollectionDecorator
|
||||
decorator.source.should == found
|
||||
decorator.should == found
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in a new issue