spec/draper/base_spec.rb in draper-0.11.1 vs spec/draper/base_spec.rb in draper-0.12.0

- old
+ new

@@ -2,21 +2,22 @@ describe Draper::Base do before(:each){ ApplicationController.new.set_current_view_context } subject{ Decorator.new(source) } let(:source){ Product.new } + let(:non_active_model_source){ NonActiveModelProduct.new } context("proxying class methods") do it "should pass missing class method calls on to the wrapped class" do subject.class.sample_class_method.should == "sample class method" end it "should respond_to a wrapped class method" do subject.class.should respond_to(:sample_class_method) end - it "should still respond_to it's own class methods" do + it "should still respond_to its own class methods" do subject.class.should respond_to(:own_class_method) end end context(".helpers") do @@ -42,10 +43,15 @@ context(".decorates") do it "sets the model class for the decorator" do ProductDecorator.new(source).model_class.should == Product end + it "returns decorator if it's decorated model already" do + product_decorator = ProductDecorator.new(source) + ProductDecorator.new(product_decorator).model.should be_instance_of Product + end + it "should handle plural-like words properly'" do class Business; end expect do class BusinessDecorator < Draper::Base decorates:business @@ -188,11 +194,11 @@ subject.to_source == source subject.source == source end end - context("selecting methods") do + describe "method selection" do it "echos the methods of the wrapped class except default exclusions" do source.methods.each do |method| unless Draper::Base::DEFAULT_DENIED.include?(method) subject.should respond_to(method.to_sym) end @@ -201,31 +207,52 @@ it "should not override a defined method with a source method" do DecoratorWithApplicationHelper.new(source).length.should == "overridden" end - it "should always proxy to_param" do - source.send :class_eval, "def to_param; 1; end" - Draper::Base.new(source).to_param.should == 1 - end - - it "should always proxy id" do - source.send :class_eval, "def id; 123456789; end" - Draper::Base.new(source).id.should == 123456789 - end - it "should not copy the .class, .inspect, or other existing methods" do source.class.should_not == subject.class source.inspect.should_not == subject.inspect source.to_s.should_not == subject.to_s end + + context "when an ActiveModel descendant" do + it "should always proxy to_param" do + source.stub(:to_param).and_return(1) + Draper::Base.new(source).to_param.should == 1 + end + + it "should always proxy id" do + source.stub(:id).and_return(123456789) + Draper::Base.new(source).id.should == 123456789 + end + + it "should always proxy errors" do + Draper::Base.new(source).errors.should be_an_instance_of ActiveModel::Errors + end + end + + context "when not an ActiveModel descendant" do + it "does not proxy to_param" do + non_active_model_source.stub(:to_param).and_return(1) + Draper::Base.new(non_active_model_source).to_param.should_not == 1 + end + + it "does not proxy errors" do + Draper::Base.new(non_active_model_source).should_not respond_to :errors + end + end end context 'the decorated model' do it 'receives the mixin' do source.class.ancestors.include?(Draper::ModelSupport) end + + it 'includes ActiveModel support' do + source.class.ancestors.include?(Draper::ActiveModelSupport) + end end it "should wrap source methods so they still accept blocks" do subject.block{"marker"}.should == "marker" end @@ -262,17 +289,36 @@ it "runs complex finders" do Product.should_receive(:find_by_name_and_size) ProductDecorator.find_by_name_and_size("apples", "large") end + it "runs find_all_by_(x) finders" do + Product.should_receive(:find_all_by_name_and_size) + ProductDecorator.find_all_by_name_and_size("apples", "large") + end + + it "runs find_last_by_(x) finders" do + Product.should_receive(:find_last_by_name_and_size) + ProductDecorator.find_last_by_name_and_size("apples", "large") + end + + it "runs find_or_initialize_by_(x) finders" do + Product.should_receive(:find_or_initialize_by_name_and_size) + ProductDecorator.find_or_initialize_by_name_and_size("apples", "large") + end + + it "runs find_or_create_by_(x) finders" do + Product.should_receive(:find_or_create_by_name_and_size) + ProductDecorator.find_or_create_by_name_and_size("apples", "large") + end + it "accepts an options hash" do Product.should_receive(:find_by_name_and_size).with("apples", "large", {:role => :admin}) ProductDecorator.find_by_name_and_size("apples", "large", {:role => :admin}) end it "uses the options hash in the decorator instantiation" do - pending "Figure out an implementation that supports multiple args (find_by_name_and_count_and_size) plus an options hash" Product.should_receive(:find_by_name_and_size).with("apples", "large", {:role => :admin}) pd = ProductDecorator.find_by_name_and_size("apples", "large", {:role => :admin}) pd.context[:role].should == :admin end end @@ -287,10 +333,15 @@ its(:size) { should == source.size } it "returns a collection of wrapped objects" do subject.each{ |decorated| decorated.should be_instance_of(Draper::Base) } end + + it 'should accepted and store a context for a collection' do + subject.context = :admin + subject.each { |decorated| decorated.context.should == :admin } + end end context "when given a single source object" do let(:source) { Product.new } @@ -393,10 +444,18 @@ other = Draper::Base.new(source) subject.should == other end end + context ".respond_to?" do + it "should delegate respond_to? to the decorated model" do + other = Draper::Base.new(source) + source.should_receive(:respond_to?).with(:whatever, true) + subject.respond_to?(:whatever, true) + 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 @@ -439,11 +498,11 @@ subject.to_ary.first.should == ProductDecorator.decorate(paged_array.first) end it "should delegate respond_to? to the wrapped collection" do decorator = ProductDecorator.decorate(paged_array) - paged_array.should_receive(:respond_to?).with(:whatever) - decorator.respond_to?(:whatever) + paged_array.should_receive(:respond_to?).with(:whatever, true) + decorator.respond_to?(:whatever, true) end it "should return blank for a decorated empty collection" do # This tests that respond_to? is defined for the DecoratedEnumerableProxy # since activesupport calls respond_to?(:empty) in #blank