Report abuse


			
require File.dirname(__FILE__) + '/fluent_forwardable'

module OrderSetup
  def new_forwardable_class
    klass = Class.new
    klass.class_eval { extend Forwardable }
    klass
  end

  def setup_order(klass)
    @order = klass.new
    @order.stub!(:shipping_address).and_return(@address=mock("address"))
  end
end

context "delegating readers" do
  include OrderSetup

  setup do
    klass = new_forwardable_class
    klass.class_eval { delegate_reader(:city).to(:shipping_address) }
    setup_order(klass)
  end

  specify "should delegate the reader to the receiver" do
    @address.should_receive(:city).once
    @order.city
  end

  specify "should not delegate writers" do
    @address.should_not_receive(:city=)
    lambda { @order.city = "New York" }.should raise_error(NoMethodError)
  end
end

context "delegate writers" do
  include OrderSetup

  setup do
    klass = new_forwardable_class
    klass.class_eval { delegate_writer(:city).to(:shipping_address) }
    setup_order(klass)
  end

  specify "should delegate the writer to the receiver" do
    @address.should_receive(:city=).once.with("New York")
    @order.city = "New York"
  end

  specify "should not delegate readers" do
    @address.should_not_receive(:city)
    lambda { @order.city }.should raise_error(NoMethodError)
  end
end

context "delegating accessors" do
  include OrderSetup

  setup do
    klass = new_forwardable_class
    klass.class_eval { delegate_accessor(:city).to(:shipping_address) }
    setup_order(klass)
  end

  specify "should delegate readers" do
    @address.should_receive(:city).once
    @order.city
  end

  specify "should delegate writers" do
    @address.should_receive(:city=).once.with("New York")
    @order.city = "New York"
  end
end

context "delegating to a method with a different name" do
  include OrderSetup

  setup do
    klass = new_forwardable_class
    klass.class_eval { delegate_reader(:city).as(:hometown).to(:shipping_address) }
    setup_order(klass)
  end

  specify "should use the specified name as the new method name" do
    @address.should_receive(:city).once
    @order.hometown
  end
end

context "delegating with a prefix" do
  include OrderSetup

  setup do
    klass = new_forwardable_class
    klass.class_eval { delegate_accessor(:city).with_prefix(:shipping).to(:shipping_address) }
    setup_order(klass)
  end

  specify "should use the prefix for any readers" do
    @address.should_receive(:city).once
    @order.shipping_city
  end

  specify "should use the prefix for any writers" do
    @address.should_receive(:city=).once.with("New York")
    @order.shipping_city = "New York" 
  end
end