1
0
Fork 0
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:
Andrew Haines 2012-12-29 12:36:44 +00:00
parent b83a95f0f0
commit dcc5e784c0
6 changed files with 9 additions and 33 deletions

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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