Permalink
Browse files

Freeze collections

Closes #387
  • Loading branch information...
1 parent c2d1e75 commit fd944cfe11e6a5b1bd4c43bb0b6bf16126007898 @haines haines committed Dec 24, 2012
@@ -16,7 +16,7 @@ class CollectionDecorator
# @option options [Hash] :context context available to each item's decorator
def initialize(source, options = {})
options.assert_valid_keys(:with, :context)
- @source = source
+ @source = source.dup.freeze
@decorator_class = options[:with]
@context = options.fetch(:context, {})
end
@@ -26,7 +26,7 @@ class << self
end
def decorated_collection
- @decorated_collection ||= source.collect {|item| decorate_item(item) }
+ @decorated_collection ||= source.map{|item| decorate_item(item)}.freeze
end
def find(*args, &block)
@@ -16,6 +16,27 @@
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'}) }
@@ -81,16 +102,6 @@
end
end
- describe "#source" do
- it "returns the source collection" do
- subject.source.should be source
- end
-
- it "is aliased to #to_source" do
- subject.to_source.should be source
- end
- end
-
describe "item decoration" do
subject { subject_class.new(source, options) }
let(:decorator_classes) { subject.decorated_collection.map(&:class) }
@@ -140,6 +151,7 @@
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
@@ -196,7 +208,7 @@
describe "#to_ary" do
# required for `render @collection` in Rails
it "delegates to the decorated collection" do
- subject.decorated_collection.should_receive(:to_ary).and_return(:an_array)
+ subject.stub decorated_collection: double(to_ary: :an_array)
subject.to_ary.should == :an_array
end
end
@@ -212,20 +224,10 @@
end
end
- context "Array methods" do
- describe "#include?" do
- it "delegates to the decorated collection" do
- subject.decorated_collection.should_receive(:include?).with(:something).and_return(true)
- subject.should include :something
- end
- end
-
- describe "#[]" do
- it "delegates to the decorated collection" do
- subject.decorated_collection.should_receive(:[]).with(42).and_return(:something)
- subject[42].should == :something
- 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
describe "#==" do
@@ -150,7 +150,7 @@
decorator.should be_a Draper::CollectionDecorator
decorator.decorator_class.should be WidgetDecorator
- decorator.source.should be Product.scoped
+ decorator.source.should == Product.scoped
end
it "accepts context" do
@@ -88,7 +88,7 @@
it "applies the scope before decoration" do
scoped = [:scoped]
associated.should_receive(:foo).and_return(scoped)
- decorated_association.call.source.should be scoped
+ decorated_association.call.source.should == scoped
end
end
end
@@ -94,7 +94,7 @@
it "returns a collection decorator" do
subject.should be_a Draper::CollectionDecorator
- subject.source.should be source
+ subject.source.should == source
end
it "uses itself as the item decorator by default" do
@@ -64,7 +64,7 @@
describe ".find_all_by_" do
it "proxies to the model class" do
- Product.should_receive(:find_all_by_name_and_size).with("apples", "large")
+ Product.should_receive(:find_all_by_name_and_size).with("apples", "large").and_return([])
ProductDecorator.find_all_by_name_and_size("apples", "large")
end
@@ -73,7 +73,7 @@
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 be found
+ decorator.source.should == found
end
end

0 comments on commit fd944cf

Please sign in to comment.