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