require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))

describe DataMapper::Transaction do

  before :all do
    class Smurf
      include DataMapper::Resource
      property :id, Integer, :key => true
    end
  end

  before :each do
    @adapter = mock("adapter", :name => 'mock_adapter')
    @repository = mock("repository")
    @repository_adapter = mock("repository adapter", :name => 'mock_repository_adapter')
    @resource = Smurf.new
    @transaction_primitive = mock("transaction primitive")
    @repository_transaction_primitive = mock("repository transaction primitive")
    @array = [@adapter, @repository]

    @adapter.should_receive(:is_a?).any_number_of_times.with(Array).and_return(false)
    @adapter.should_receive(:is_a?).any_number_of_times.with(DataMapper::Adapters::AbstractAdapter).and_return(true)
    @adapter.should_receive(:transaction_primitive).any_number_of_times.and_return(@transaction_primitive)
    @repository.should_receive(:is_a?).any_number_of_times.with(Array).and_return(false)
    @repository.should_receive(:is_a?).any_number_of_times.with(DataMapper::Adapters::AbstractAdapter).and_return(false)
    @repository.should_receive(:is_a?).any_number_of_times.with(DataMapper::Repository).and_return(true)
    @repository.should_receive(:adapter).any_number_of_times.and_return(@repository_adapter)
    @repository_adapter.should_receive(:is_a?).any_number_of_times.with(Array).and_return(false)
    @repository_adapter.should_receive(:is_a?).any_number_of_times.with(DataMapper::Adapters::AbstractAdapter).and_return(true)
    @repository_adapter.should_receive(:transaction_primitive).any_number_of_times.and_return(@repository_transaction_primitive)
    @transaction_primitive.should_receive(:respond_to?).any_number_of_times.with(:close).and_return(true)
    @transaction_primitive.should_receive(:respond_to?).any_number_of_times.with(:begin).and_return(true)
    @transaction_primitive.should_receive(:respond_to?).any_number_of_times.with(:prepare).and_return(true)
    @transaction_primitive.should_receive(:respond_to?).any_number_of_times.with(:rollback).and_return(true)
    @transaction_primitive.should_receive(:respond_to?).any_number_of_times.with(:rollback_prepared).and_return(true)
    @transaction_primitive.should_receive(:respond_to?).any_number_of_times.with(:commit).and_return(true)
    @repository_transaction_primitive.should_receive(:respond_to?).any_number_of_times.with(:close).and_return(true)
    @repository_transaction_primitive.should_receive(:respond_to?).any_number_of_times.with(:begin).and_return(true)
    @repository_transaction_primitive.should_receive(:respond_to?).any_number_of_times.with(:prepare).and_return(true)
    @repository_transaction_primitive.should_receive(:respond_to?).any_number_of_times.with(:rollback).and_return(true)
    @repository_transaction_primitive.should_receive(:respond_to?).any_number_of_times.with(:rollback_prepared).and_return(true)
    @repository_transaction_primitive.should_receive(:respond_to?).any_number_of_times.with(:commit).and_return(true)
  end

  it "should be able to initialize with an Array" do
    DataMapper::Transaction.new(@array)
  end
  it "should be able to initialize with DataMapper::Adapters::AbstractAdapters" do
    DataMapper::Transaction.new(@adapter)
  end
  it "should be able to initialize with DataMapper::Repositories" do
    DataMapper::Transaction.new(@repository)
  end
  it "should be able to initialize with DataMapper::Resource subclasses" do
    DataMapper::Transaction.new(Smurf)
  end
  it "should be able to initialize with DataMapper::Resources" do
    DataMapper::Transaction.new(Smurf.new)
  end
  it "should initialize with no transaction_primitives" do
    DataMapper::Transaction.new.transaction_primitives.empty?.should == true
  end
  it "should initialize with state :none" do
    DataMapper::Transaction.new.state.should == :none
  end
  it "should initialize the adapters given on creation" do
    DataMapper::Transaction.new(Smurf).adapters.should == {Smurf.repository.adapter => :none}
  end
  it "should be able receive multiple adapters on creation" do
    DataMapper::Transaction.new(Smurf, @resource, @adapter, @repository)
  end
  it "should be able to initialize with a block" do
    p = Proc.new do end
    @transaction_primitive.stub!(:begin)
    @transaction_primitive.stub!(:prepare)
    @transaction_primitive.stub!(:commit)
    @adapter.stub!(:push_transaction)
    @adapter.stub!(:pop_transaction)
    @transaction_primitive.stub!(:close)
    DataMapper::Transaction.new(@adapter, &p)
  end
  it "should accept new adapters after creation" do
    t = DataMapper::Transaction.new(@adapter, @repository)
    t.adapters.should == {@adapter => :none, @repository_adapter => :none}
    t.link(@resource)
    t.adapters.should == {@adapter => :none, @repository_adapter => :none, Smurf.repository.adapter => :none}
  end
  it "should not accept new adapters after state is changed" do
    t = DataMapper::Transaction.new(@adapter, @repository)
    @transaction_primitive.stub!(:begin)
    @repository_transaction_primitive.stub!(:begin)
    t.begin
    lambda do t.link(@resource) end.should raise_error(Exception, /Illegal state/)
  end
  describe "#begin" do
    before :each do
      @transaction = DataMapper::Transaction.new(@adapter, @repository)
    end
    it "should raise error if state is changed" do
      @transaction_primitive.stub!(:begin)
      @repository_transaction_primitive.stub!(:begin)
      @transaction.begin
      lambda do @transaction.begin end.should raise_error(Exception, /Illegal state/)
    end
    it "should try to connect each adapter (or log fatal error), then begin each adapter (or rollback and close)" do
      @transaction.should_receive(:each_adapter).with(:connect_adapter, [:log_fatal_transaction_breakage])
      @transaction.should_receive(:each_adapter).with(:begin_adapter, [:rollback_and_close_adapter_if_begin, :close_adapter_if_none])
      @transaction.begin
    end
    it "should leave with state :begin" do
      @transaction_primitive.stub!(:begin)
      @repository_transaction_primitive.stub!(:begin)
      @transaction.begin
      @transaction.state.should == :begin
    end
  end
  describe "#rollback" do
    before :each do
      @transaction = DataMapper::Transaction.new(@adapter, @repository)
    end
    it "should raise error if state is :none" do
      lambda do @transaction.rollback end.should raise_error(Exception, /Illegal state/)
    end
    it "should raise error if state is :commit" do
      @transaction_primitive.stub!(:begin)
      @repository_transaction_primitive.stub!(:begin)
      @transaction_primitive.stub!(:prepare)
      @repository_transaction_primitive.stub!(:prepare)
      @transaction_primitive.stub!(:commit)
      @repository_transaction_primitive.stub!(:commit)
      @transaction_primitive.stub!(:close)
      @repository_transaction_primitive.stub!(:close)
      @transaction.begin
      @transaction.commit
      lambda do @transaction.rollback end.should raise_error(Exception, /Illegal state/)
    end
    it "should try to rollback each adapter (or rollback and close), then then close (or log fatal error)" do
      @transaction.should_receive(:each_adapter).with(:connect_adapter, [:log_fatal_transaction_breakage])
      @transaction.should_receive(:each_adapter).with(:begin_adapter, [:rollback_and_close_adapter_if_begin, :close_adapter_if_none])
      @transaction.should_receive(:each_adapter).with(:rollback_adapter_if_begin, [:rollback_and_close_adapter_if_begin, :close_adapter_if_none])
      @transaction.should_receive(:each_adapter).with(:close_adapter_if_open, [:log_fatal_transaction_breakage])
      @transaction.should_receive(:each_adapter).with(:rollback_prepared_adapter_if_prepare, [:rollback_prepared_and_close_adapter_if_begin, :close_adapter_if_none])
      @transaction.begin
      @transaction.rollback
    end
    it "should leave with state :rollback" do
      @transaction_primitive.stub!(:begin)
      @repository_transaction_primitive.stub!(:begin)
      @transaction_primitive.stub!(:rollback)
      @repository_transaction_primitive.stub!(:rollback)
      @transaction_primitive.stub!(:close)
      @repository_transaction_primitive.stub!(:close)
      @transaction.begin
      @transaction.rollback
      @transaction.state.should == :rollback
    end
  end
  describe "#commit" do
    describe "without a block" do
      before :each do
        @transaction = DataMapper::Transaction.new(@adapter, @repository)
      end
      it "should raise error if state is :none" do
        lambda do @transaction.commit end.should raise_error(Exception, /Illegal state/)
      end
      it "should raise error if state is :commit" do
        @transaction_primitive.stub!(:begin)
        @repository_transaction_primitive.stub!(:begin)
        @transaction_primitive.stub!(:prepare)
        @repository_transaction_primitive.stub!(:prepare)
        @transaction_primitive.stub!(:commit)
        @repository_transaction_primitive.stub!(:commit)
        @transaction_primitive.stub!(:close)
        @repository_transaction_primitive.stub!(:close)
        @transaction.begin
        @transaction.commit
        lambda do @transaction.commit end.should raise_error(Exception, /Illegal state/)
      end
      it "should raise error if state is :rollback" do
        @transaction_primitive.stub!(:begin)
        @repository_transaction_primitive.stub!(:begin)
        @transaction_primitive.stub!(:rollback)
        @repository_transaction_primitive.stub!(:rollback)
        @transaction_primitive.stub!(:close)
        @repository_transaction_primitive.stub!(:close)
        @transaction.begin
        @transaction.rollback
        lambda do @transaction.commit end.should raise_error(Exception, /Illegal state/)
      end
      it "should try to prepare each adapter (or rollback and close), then commit each adapter (or log fatal error), then close (or log fatal error)" do
        @transaction.should_receive(:each_adapter).with(:connect_adapter, [:log_fatal_transaction_breakage])
        @transaction.should_receive(:each_adapter).with(:begin_adapter, [:rollback_and_close_adapter_if_begin, :close_adapter_if_none])
        @transaction.should_receive(:each_adapter).with(:prepare_adapter, [:rollback_and_close_adapter_if_begin, :rollback_prepared_and_close_adapter_if_prepare])
        @transaction.should_receive(:each_adapter).with(:commit_adapter, [:log_fatal_transaction_breakage])
        @transaction.should_receive(:each_adapter).with(:close_adapter, [:log_fatal_transaction_breakage])
        @transaction.begin
        @transaction.commit
      end
      it "should leave with state :commit" do
        @transaction_primitive.stub!(:begin)
        @repository_transaction_primitive.stub!(:begin)
        @transaction_primitive.stub!(:prepare)
        @repository_transaction_primitive.stub!(:prepare)
        @transaction_primitive.stub!(:commit)
        @repository_transaction_primitive.stub!(:commit)
        @transaction_primitive.stub!(:close)
        @repository_transaction_primitive.stub!(:close)
        @transaction.begin
        @transaction.commit
        @transaction.state.should == :commit
      end
    end
    describe "with a block" do
      before :each do
        @transaction = DataMapper::Transaction.new(@adapter, @repository)
      end
      it "should raise if state is not :none" do
        @transaction_primitive.stub!(:begin)
        @repository_transaction_primitive.stub!(:begin)
        @transaction.begin
        lambda do @transaction.commit do end end.should raise_error(Exception, /Illegal state/)
      end
      it "should begin, yield and commit if the block raises no exception" do
        @repository_transaction_primitive.should_receive(:begin)
        @repository_transaction_primitive.should_receive(:prepare)
        @repository_transaction_primitive.should_receive(:commit)
        @repository_transaction_primitive.should_receive(:close)
        @transaction_primitive.should_receive(:begin)
        @transaction_primitive.should_receive(:prepare)
        @transaction_primitive.should_receive(:commit)
        @transaction_primitive.should_receive(:close)
        p = Proc.new do end
        @transaction.should_receive(:within).with(&p)
        @transaction.commit(&p)
      end
      it "should rollback if the block raises an exception" do
        @repository_transaction_primitive.should_receive(:begin)
        @repository_transaction_primitive.should_receive(:rollback)
        @repository_transaction_primitive.should_receive(:close)
        @transaction_primitive.should_receive(:begin)
        @transaction_primitive.should_receive(:rollback)
        @transaction_primitive.should_receive(:close)
        p = Proc.new do raise "test exception, never mind me" end
        @transaction.should_receive(:within).with(&p)
        lambda do @transaction.commit(&p) end.should raise_error(Exception, /test exception, never mind me/)
      end
    end
  end
  describe "#within" do
    before :each do
      @transaction = DataMapper::Transaction.new(@adapter, @repository)
    end
    it "should raise if no block is provided" do
      lambda do @transaction.within end.should raise_error(Exception, /No block/)
    end
    it "should raise if state is not :begin" do
      lambda do @transaction.within do end end.should raise_error(Exception, /Illegal state/)
    end
    it "should push itself on the per thread transaction context of each adapter and then pop itself out again" do
      @repository_transaction_primitive.should_receive(:begin)
      @transaction_primitive.should_receive(:begin)
      @repository_adapter.should_receive(:push_transaction).with(@transaction)
      @adapter.should_receive(:push_transaction).with(@transaction)
      @repository_adapter.should_receive(:pop_transaction)
      @adapter.should_receive(:pop_transaction)
      @transaction.begin
      @transaction.within do end
    end
    it "should push itself on the per thread transaction context of each adapter and then pop itself out again even if an exception was raised" do
      @repository_transaction_primitive.should_receive(:begin)
      @transaction_primitive.should_receive(:begin)
      @repository_adapter.should_receive(:push_transaction).with(@transaction)
      @adapter.should_receive(:push_transaction).with(@transaction)
      @repository_adapter.should_receive(:pop_transaction)
      @adapter.should_receive(:pop_transaction)
      @transaction.begin
      lambda do @transaction.within do raise "test exception, never mind me" end end.should raise_error(Exception, /test exception, never mind me/)
    end
  end
  describe "#method_missing" do
    before :each do
      @transaction = DataMapper::Transaction.new(@adapter, @repository)
      @adapter.should_receive(:is_a?).any_number_of_times.with(Spec::Mocks::AnyArgsConstraint).and_return(false)
      @adapter.should_receive(:is_a?).any_number_of_times.with(Spec::Mocks::NoArgsConstraint).and_return(false)
      @adapter.should_receive(:is_a?).any_number_of_times.with(Regexp).and_return(false)
    end
    it "should delegate calls to [a method we have]_if_[state](adapter) to [a method we have](adapter) if state of adapter is [state]" do
      @transaction.should_receive(:state_for).with(@adapter).and_return(:begin)
      @transaction.should_receive(:connect_adapter).with(@adapter)
      @transaction.connect_adapter_if_begin(@adapter)
    end
    it "should not delegate calls to [a method we have]_if_[state](adapter) to [a method we have](adapter) if state of adapter is not [state]" do
      @transaction.should_receive(:state_for).with(@adapter).and_return(:commit)
      @transaction.should_not_receive(:connect_adapter).with(@adapter)
      @transaction.connect_adapter_if_begin(@adapter)
    end
    it "should delegate calls to [a method we have]_unless_[state](adapter) to [a method we have](adapter) if state of adapter is not [state]" do
      @transaction.should_receive(:state_for).with(@adapter).and_return(:none)
      @transaction.should_receive(:connect_adapter).with(@adapter)
      @transaction.connect_adapter_unless_begin(@adapter)
    end
    it "should not delegate calls to [a method we have]_unless_[state](adapter) to [a method we have](adapter) if state of adapter is [state]" do
      @transaction.should_receive(:state_for).with(@adapter).and_return(:begin)
      @transaction.should_not_receive(:connect_adapter).with(@adapter)
      @transaction.connect_adapter_unless_begin(@adapter)
    end
    it "should not delegate calls whose first argument is not a DataMapper::Adapters::AbstractAdapter" do
      lambda do @transaction.connect_adapter_unless_begin("plur") end.should raise_error
    end
    it "should not delegate calls that do not look like an if or unless followed by a state" do
      lambda do @transaction.connect_adapter_unless_hepp(@adapter) end.should raise_error
      lambda do @transaction.connect_adapter_when_begin(@adapter) end.should raise_error
    end
    it "should not delegate calls that we can not respond to" do
      lambda do @transaction.connect_adapters_unless_begin(@adapter) end.should raise_error
      lambda do @transaction.connect_adapters_if_begin(@adapter) end.should raise_error
    end
  end
  it "should be able to produce the connection for an adapter" do
    @transaction_primitive.stub!(:begin)
    @repository_transaction_primitive.stub!(:begin)
    @transaction = DataMapper::Transaction.new(@adapter, @repository)
    @transaction.begin
    @transaction.primitive_for(@adapter).should == @transaction_primitive
  end
  describe "#each_adapter" do
    before :each do
      @transaction = DataMapper::Transaction.new(@adapter, @repository)
      @adapter.should_receive(:is_a?).any_number_of_times.with(Spec::Mocks::AnyArgsConstraint).and_return(false)
      @adapter.should_receive(:is_a?).any_number_of_times.with(Spec::Mocks::NoArgsConstraint).and_return(false)
      @adapter.should_receive(:is_a?).any_number_of_times.with(Regexp).and_return(false)
      @repository_adapter.should_receive(:is_a?).any_number_of_times.with(Spec::Mocks::AnyArgsConstraint).and_return(false)
      @repository_adapter.should_receive(:is_a?).any_number_of_times.with(Spec::Mocks::NoArgsConstraint).and_return(false)
      @repository_adapter.should_receive(:is_a?).any_number_of_times.with(Regexp).and_return(false)
    end
    it "should send the first argument to itself once for each adapter" do
      @transaction.should_receive(:plupp).with(@adapter)
      @transaction.should_receive(:plupp).with(@repository_adapter)
      @transaction.instance_eval do each_adapter(:plupp, [:plur]) end
    end
    it "should stop sending if any call raises an exception, then send each element of the second argument to itself with each adapter as argument" do
      a1 = @repository_adapter
      a2 = @adapter
      @transaction.adapters.instance_eval do
        @a1 = a1
        @a2 = a2
        def each(&block)
          yield(@a1, :none)
          yield(@a2, :none)
        end
      end
      @transaction.should_receive(:plupp).with(@repository_adapter).and_throw(Exception.new("test error - dont mind me"))
      @transaction.should_not_receive(:plupp).with(@adapter)
      @transaction.should_receive(:plur).with(@adapter)
      @transaction.should_receive(:plur).with(@repository_adapter)
      lambda do @transaction.instance_eval do each_adapter(:plupp, [:plur]) end end.should raise_error(Exception, /test error - dont mind me/)
    end
    it "should send each element of the second argument to itself with each adapter as argument even if exceptions occur in the process" do
      a1 = @repository_adapter
      a2 = @adapter
      @transaction.adapters.instance_eval do
        @a1 = a1
        @a2 = a2
        def each(&block)
          yield(@a1, :none)
          yield(@a2, :none)
        end
      end
      @transaction.should_receive(:plupp).with(@repository_adapter).and_throw(Exception.new("test error - dont mind me"))
      @transaction.should_not_receive(:plupp).with(@adapter)
      @transaction.should_receive(:plur).with(@adapter).and_throw(Exception.new("another test error"))
      @transaction.should_receive(:plur).with(@repository_adapter).and_throw(Exception.new("yet another error"))
      lambda do @transaction.instance_eval do each_adapter(:plupp, [:plur]) end end.should raise_error(Exception, /test error - dont mind me/)
    end
  end
  it "should be able to return the state for a given adapter" do
    @transaction = DataMapper::Transaction.new(@adapter, @repository)
    a1 = @adapter
    a2 = @repository_adapter
    @transaction.instance_eval do state_for(a1) end.should == :none
    @transaction.instance_eval do state_for(a2) end.should == :none
    @transaction.instance_eval do @adapters[a1] = :begin end
    @transaction.instance_eval do state_for(a1) end.should == :begin
    @transaction.instance_eval do state_for(a2) end.should == :none
  end
  describe "#do_adapter" do
    before :each do
      @transaction = DataMapper::Transaction.new(@adapter, @repository)
      @adapter.should_receive(:is_a?).any_number_of_times.with(Spec::Mocks::AnyArgsConstraint).and_return(false)
      @adapter.should_receive(:is_a?).any_number_of_times.with(Spec::Mocks::NoArgsConstraint).and_return(false)
      @adapter.should_receive(:is_a?).any_number_of_times.with(Regexp).and_return(false)
    end
    it "should raise if there is no connection for the adapter" do
      a1 = @adapter
      lambda do @transaction.instance_eval do do_adapter(a1, :ping, :pong) end end.should raise_error(Exception, /No primitive/)
    end
    it "should raise if the adapter has the wrong state" do
      @transaction_primitive.stub!(:begin)
      @repository_transaction_primitive.stub!(:begin)
      @transaction.begin
      a1 = @adapter
      @adapter.should_not_receive(:ping_transaction).with(@transaction)
      lambda do @transaction.instance_eval do do_adapter(a1, :ping, :pong) end end.should raise_error(Exception, /Illegal state/)
    end
    it "should delegate to the adapter if the connection exists and we have the right state" do
      @transaction_primitive.stub!(:begin)
      @repository_transaction_primitive.stub!(:begin)
      @transaction.begin
      a1 = @adapter
      @transaction_primitive.should_receive(:ping)
      @transaction.instance_eval do do_adapter(a1, :ping, :begin) end
    end
  end
  describe "#connect_adapter" do
    before :each do
      @other_adapter = mock("adapter")
      @other_adapter.should_receive(:is_a?).any_number_of_times.with(Array).and_return(false)
      @other_adapter.should_receive(:is_a?).any_number_of_times.with(DataMapper::Adapters::AbstractAdapter).and_return(true)
      @transaction = DataMapper::Transaction.new(@other_adapter)
    end
    it "should be able to connect an adapter" do
      a1 = @other_adapter
      @other_adapter.should_receive(:transaction_primitive).and_return(@transaction_primitive)
      @transaction.instance_eval do connect_adapter(a1) end
      @transaction.transaction_primitives[@other_adapter].should == @transaction_primitive
    end
  end
  describe "#close adapter" do
    before :each do
      @other_adapter = mock("adapter")
      @other_adapter.should_receive(:is_a?).any_number_of_times.with(Array).and_return(false)
      @other_adapter.should_receive(:is_a?).any_number_of_times.with(DataMapper::Adapters::AbstractAdapter).and_return(true)
      @transaction = DataMapper::Transaction.new(@other_adapter)
    end
    it "should be able to close the connection of an adapter" do
      a1 = @other_adapter
      @transaction_primitive.should_receive(:close)
      @other_adapter.should_receive(:transaction_primitive).and_return(@transaction_primitive)
      @transaction.instance_eval do connect_adapter(a1) end
      @transaction.transaction_primitives[@other_adapter].should == @transaction_primitive
      @transaction.instance_eval do close_adapter(a1) end
      @transaction.transaction_primitives[@other_adapter].should == nil
    end
  end
  describe "the transaction operation methods" do
    before :each do
      @other_adapter = mock("adapter")
      @other_adapter.should_receive(:is_a?).any_number_of_times.with(Array).and_return(false)
      @other_adapter.should_receive(:is_a?).any_number_of_times.with(DataMapper::Adapters::AbstractAdapter).and_return(true)
      @other_adapter.should_receive(:is_a?).any_number_of_times.with(Spec::Mocks::AnyArgsConstraint).and_return(false)
      @other_adapter.should_receive(:is_a?).any_number_of_times.with(Spec::Mocks::NoArgsConstraint).and_return(false)
      @other_adapter.should_receive(:is_a?).any_number_of_times.with(Regexp).and_return(false)
      @transaction = DataMapper::Transaction.new(@other_adapter)
    end
    it "should only allow adapters in state :none to begin" do
      a1 = @other_adapter
      @transaction.should_receive(:do_adapter).with(@other_adapter, :begin, :none)
      @transaction.instance_eval do begin_adapter(a1) end
    end
    it "should only allow adapters in state :begin to prepare" do
      a1 = @other_adapter
      @transaction.should_receive(:do_adapter).with(@other_adapter, :prepare, :begin)
      @transaction.instance_eval do prepare_adapter(a1) end
    end
    it "should only allow adapters in state :prepare to commit" do
      a1 = @other_adapter
      @transaction.should_receive(:do_adapter).with(@other_adapter, :commit, :prepare)
      @transaction.instance_eval do commit_adapter(a1) end
    end
    it "should only allow adapters in state :begin to rollback" do
      a1 = @other_adapter
      @transaction.should_receive(:do_adapter).with(@other_adapter, :rollback, :begin)
      @transaction.instance_eval do rollback_adapter(a1) end
    end
    it "should only allow adapters in state :prepare to rollback_prepared" do
      a1 = @other_adapter
      @transaction.should_receive(:do_adapter).with(@other_adapter, :rollback_prepared, :prepare)
      @transaction.instance_eval do rollback_prepared_adapter(a1) end
    end
    it "should do delegate properly for rollback_and_close" do
      a1 = @other_adapter
      @transaction.should_receive(:rollback_adapter).with(@other_adapter)
      @transaction.should_receive(:close_adapter).with(@other_adapter)
      @transaction.instance_eval do rollback_and_close_adapter(a1) end
    end
    it "should do delegate properly for rollback_prepared_and_close" do
      a1 = @other_adapter
      @transaction.should_receive(:rollback_prepared_adapter).with(@other_adapter)
      @transaction.should_receive(:close_adapter).with(@other_adapter)
      @transaction.instance_eval do rollback_prepared_and_close_adapter(a1) end
    end
  end
end
