spec/draper/base_spec.rb in draper-0.9.5 vs spec/draper/base_spec.rb in draper-0.10.0

- old
+ new

@@ -56,12 +56,64 @@ it "creates a named accessor for the wrapped model" do pd = ProductDecorator.new(source) pd.send(:product).should == source end + + context("namespaced model supporting") do + let(:source){ Namespace::Product.new } + + it "sets the model class for the decorator" do + decorator = Namespace::ProductDecorator.new(source) + decorator.model_class.should == Namespace::Product + end + + it "creates a named accessor for the wrapped model" do + pd = Namespace::ProductDecorator.new(source) + pd.send(:product).should == source + end + end end + context(".decorates_association") do + context "for collection associations" do + before(:each){ subject.class_eval{ decorates_association :similar_products } } + it "causes the association's method to return a collection of wrapped objects" do + subject.similar_products.each{ |decorated| decorated.should be_instance_of(ProductDecorator) } + end + end + + context "for a singular association" do + before(:each){ subject.class_eval{ decorates_association :previous_version } } + it "causes the association's method to return a single wrapped object if the association is singular" do + subject.previous_version.should be_instance_of(ProductDecorator) + end + + it "causes the association's method to return nil if the association is nil" do + source.stub(:previous_version){ nil } + subject.previous_version.should be_nil + end + end + + context "with a specific decorator specified" do + before(:each){ subject.class_eval{ decorates_association :previous_version, :with => SpecificProductDecorator } } + it "causes the association to be decorated with the specified association" do + subject.previous_version.should be_instance_of(SpecificProductDecorator) + end + end + end + + context('.decorates_associations') do + subject { Decorator } + it "decorates each of the associations" do + subject.should_receive(:decorates_association).with(:similar_products) + subject.should_receive(:decorates_association).with(:previous_version) + + subject.decorates_associations :similar_products, :previous_version + end + end + context(".model / .to_model") do it "should return the wrapped object" do subject.to_model.should == source subject.model.should == source end @@ -119,11 +171,11 @@ pd.should be_instance_of(ProductDecorator) pd.model.should be_instance_of(Product) end it "should accept and store a context" do - pd = ProductDecorator.find(1, :admin) + pd = ProductDecorator.find(1, :context => :admin) pd.context.should == :admin end end context ".decorate" do @@ -148,11 +200,11 @@ end context "with a context" do let(:context) {{ :some => 'data' }} - subject { Draper::Base.decorate(source, context) } + subject { Draper::Base.decorate(source, :context => context) } context "when given a collection of source objects" do let(:source) { [Product.new, Product.new] } it "returns a collection of wrapped objects with the context" do @@ -165,19 +217,60 @@ its(:context) { should eq(context) } end end + context "does not infer collections by default" do + subject { Draper::Base.decorate(source).to_ary } + + let(:source) { [Product.new, Widget.new] } + + it "returns a collection of wrapped objects all with the same decorator" do + subject.first.class.name.should eql 'Draper::Base' + subject.last.class.name.should eql 'Draper::Base' + end + end + + context "does not infer single items by default" do + subject { Draper::Base.decorate(source) } + + let(:source) { Product.new } + + it "returns a decorator of the type explicity used in the call" do + subject.class.should eql Draper::Base + end + end + + context "returns a collection containing only the explicit decorator used in the call" do + subject { Draper::Base.decorate(source, :infer => true).to_ary } + + let(:source) { [Product.new, Widget.new] } + + it "returns a mixed collection of wrapped objects" do + subject.first.class.should eql ProductDecorator + subject.last.class.should eql WidgetDecorator + end + end + + context "when given a single object" do + subject { Draper::Base.decorate(source, :infer => true) } + + let(:source) { Product.new } + + it "can also infer its decorator" do + subject.class.should eql ProductDecorator + end + end end context('.==') do it "should compare the decorated models" do other = Draper::Base.new(source) subject.should == other end end - + context 'position accessors' do [:first, :last].each do |method| context "##{method}" do it "should return a decorated instance" do ProductDecorator.send(method).should be_instance_of ProductDecorator @@ -186,13 +279,13 @@ it "should return the #{method} instance of the wrapped class" do ProductDecorator.send(method).model.should == Product.send(method) end it "should accept an optional context" do - ProductDecorator.send(method, :admin).context.should == :admin + ProductDecorator.send(method, :context => :admin).context.should == :admin end - end + end end end describe "collection decoration" do @@ -253,17 +346,42 @@ new_paged_array = paged_array + [Product.new] subject_two = ProductDecorator.decorate(new_paged_array) subject_one.should_not == subject_two end + it "should allow decorated access by index" do + subject = ProductDecorator.decorate(paged_array) + subject[0].should be_instance_of ProductDecorator + end + + context "pretends to be of kind of wrapped collection class" do + subject { ProductDecorator.decorate(paged_array) } + + it "#kind_of? DecoratedEnumerableProxy" do + subject.should be_kind_of Draper::DecoratedEnumerableProxy + end + + it "#is_a? DecoratedEnumerableProxy" do + subject.is_a?(Draper::DecoratedEnumerableProxy).should be_true + end + + it "#kind_of? Array" do + subject.should be_kind_of Array + end + + it "#is_a? Array" do + subject.is_a?(Array).should be_true + end + end + context '#all' do it "should return a decorated collection" do ProductDecorator.all.first.should be_instance_of ProductDecorator end - + it "should accept a context" do - collection = ProductDecorator.all(:admin) + collection = ProductDecorator.all(:context => :admin) collection.first.context.should == :admin end end end @@ -358,8 +476,45 @@ decorator.sample_link.should == "<a href=\"/World\">Hello</a>" end it "should be able to use the pluralize helper" do decorator.sample_truncate.should == "Once..." + end + end + + describe "#method_missing" do + context "when #hello_world is called for the first time" do + it "hits method missing" do + subject.should_receive(:method_missing) + subject.hello_world + end + end + + context "when #hello_world is called again" do + before { subject.hello_world } + it "proxies method directly after first hit" do + subject.should_not_receive(:method_missing) + subject.hello_world + end + end + end + + describe "#kind_of?" do + context "pretends to be of kind of model class" do + it "#kind_of? decorator class" do + subject.should be_kind_of subject.class + end + + it "#is_a? decorator class" do + subject.is_a?(subject.class).should be_true + end + + it "#kind_of? source class" do + subject.should be_kind_of source.class + end + + it "#is_a? source class" do + subject.is_a?(source.class).should be_true + end end end end