Started again with Rails 4
[feedcatcher.git] / vendor / rails / activerecord / test / cases / transactions_test.rb
diff --git a/vendor/rails/activerecord/test/cases/transactions_test.rb b/vendor/rails/activerecord/test/cases/transactions_test.rb
deleted file mode 100644 (file)
index f6533b5..0000000
+++ /dev/null
@@ -1,522 +0,0 @@
-require "cases/helper"
-require 'models/topic'
-require 'models/reply'
-require 'models/developer'
-require 'models/book'
-
-class TransactionTest < ActiveRecord::TestCase
-  self.use_transactional_fixtures = false
-  fixtures :topics, :developers
-
-  def setup
-    @first, @second = Topic.find(1, 2).sort_by { |t| t.id }
-  end
-
-  def test_successful
-    Topic.transaction do
-      @first.approved  = true
-      @second.approved = false
-      @first.save
-      @second.save
-    end
-
-    assert Topic.find(1).approved?, "First should have been approved"
-    assert !Topic.find(2).approved?, "Second should have been unapproved"
-  end
-
-  def transaction_with_return
-    Topic.transaction do
-      @first.approved  = true
-      @second.approved = false
-      @first.save
-      @second.save
-      return
-    end
-  end
-
-  def test_successful_with_return
-    class << Topic.connection
-      alias :real_commit_db_transaction :commit_db_transaction
-      def commit_db_transaction
-        $committed = true
-        real_commit_db_transaction
-      end
-    end
-
-    $committed = false
-    transaction_with_return
-    assert $committed
-
-    assert Topic.find(1).approved?, "First should have been approved"
-    assert !Topic.find(2).approved?, "Second should have been unapproved"
-  ensure
-    class << Topic.connection
-      alias :commit_db_transaction :real_commit_db_transaction rescue nil
-    end
-  end
-
-  def test_successful_with_instance_method
-    @first.transaction do
-      @first.approved  = true
-      @second.approved = false
-      @first.save
-      @second.save
-    end
-
-    assert Topic.find(1).approved?, "First should have been approved"
-    assert !Topic.find(2).approved?, "Second should have been unapproved"
-  end
-
-  def test_failing_on_exception
-    begin
-      Topic.transaction do
-        @first.approved  = true
-        @second.approved = false
-        @first.save
-        @second.save
-        raise "Bad things!"
-      end
-    rescue
-      # caught it
-    end
-
-    assert @first.approved?, "First should still be changed in the objects"
-    assert !@second.approved?, "Second should still be changed in the objects"
-
-    assert !Topic.find(1).approved?, "First shouldn't have been approved"
-    assert Topic.find(2).approved?, "Second should still be approved"
-  end
-
-  def test_raising_exception_in_callback_rollbacks_in_save
-    add_exception_raising_after_save_callback_to_topic
-
-    begin
-      @first.approved = true
-      @first.save
-      flunk
-    rescue => e
-      assert_equal "Make the transaction rollback", e.message
-      assert !Topic.find(1).approved?
-    ensure
-      remove_exception_raising_after_save_callback_to_topic
-    end
-  end
-
-  def test_cancellation_from_before_destroy_rollbacks_in_destroy
-    add_cancelling_before_destroy_with_db_side_effect_to_topic
-    begin
-      nbooks_before_destroy = Book.count
-      status = @first.destroy
-      assert !status
-      assert_nothing_raised(ActiveRecord::RecordNotFound) { @first.reload }
-      assert_equal nbooks_before_destroy, Book.count
-    ensure
-      remove_cancelling_before_destroy_with_db_side_effect_to_topic
-    end
-  end
-
-  def test_cancellation_from_before_filters_rollbacks_in_save
-    %w(validation save).each do |filter|
-      send("add_cancelling_before_#{filter}_with_db_side_effect_to_topic")
-      begin
-        nbooks_before_save = Book.count
-        original_author_name = @first.author_name
-        @first.author_name += '_this_should_not_end_up_in_the_db'
-        status = @first.save
-        assert !status
-        assert_equal original_author_name, @first.reload.author_name
-        assert_equal nbooks_before_save, Book.count
-      ensure
-        send("remove_cancelling_before_#{filter}_with_db_side_effect_to_topic")
-      end
-    end
-  end
-
-  def test_cancellation_from_before_filters_rollbacks_in_save!
-    %w(validation save).each do |filter|
-      send("add_cancelling_before_#{filter}_with_db_side_effect_to_topic")
-      begin
-        nbooks_before_save = Book.count
-        original_author_name = @first.author_name
-        @first.author_name += '_this_should_not_end_up_in_the_db'
-        @first.save!
-        flunk
-      rescue => e
-        assert_equal original_author_name, @first.reload.author_name
-        assert_equal nbooks_before_save, Book.count
-      ensure
-        send("remove_cancelling_before_#{filter}_with_db_side_effect_to_topic")
-      end
-    end
-  end
-
-  def test_callback_rollback_in_create
-    new_topic = Topic.new(
-      :title => "A new topic",
-      :author_name => "Ben",
-      :author_email_address => "ben@example.com",
-      :written_on => "2003-07-16t15:28:11.2233+01:00",
-      :last_read => "2004-04-15",
-      :bonus_time => "2005-01-30t15:28:00.00+01:00",
-      :content => "Have a nice day",
-      :approved => false)
-    new_record_snapshot = new_topic.new_record?
-    id_present = new_topic.has_attribute?(Topic.primary_key)
-    id_snapshot = new_topic.id
-
-    # Make sure the second save gets the after_create callback called.
-    2.times do
-      begin
-        add_exception_raising_after_create_callback_to_topic
-        new_topic.approved = true
-        new_topic.save
-        flunk
-      rescue => e
-        assert_equal "Make the transaction rollback", e.message
-        assert_equal new_record_snapshot, new_topic.new_record?, "The topic should have its old new_record value"
-        assert_equal id_snapshot, new_topic.id, "The topic should have its old id"
-        assert_equal id_present, new_topic.has_attribute?(Topic.primary_key)
-      ensure
-        remove_exception_raising_after_create_callback_to_topic
-      end
-    end
-  end
-
-  def test_nested_explicit_transactions
-    Topic.transaction do
-      Topic.transaction do
-        @first.approved  = true
-        @second.approved = false
-        @first.save
-        @second.save
-      end
-    end
-
-    assert Topic.find(1).approved?, "First should have been approved"
-    assert !Topic.find(2).approved?, "Second should have been unapproved"
-  end
-
-  def test_manually_rolling_back_a_transaction
-    Topic.transaction do
-      @first.approved  = true
-      @second.approved = false
-      @first.save
-      @second.save
-
-      raise ActiveRecord::Rollback
-    end
-
-    assert @first.approved?, "First should still be changed in the objects"
-    assert !@second.approved?, "Second should still be changed in the objects"
-
-    assert !Topic.find(1).approved?, "First shouldn't have been approved"
-    assert Topic.find(2).approved?, "Second should still be approved"
-  end
-
-  def test_invalid_keys_for_transaction
-    assert_raise ArgumentError do
-      Topic.transaction :nested => true do
-      end
-    end
-  end
-
-  def test_force_savepoint_in_nested_transaction
-    Topic.transaction do
-      @first.approved = true
-      @second.approved = false
-      @first.save!
-      @second.save!
-
-      begin
-        Topic.transaction :requires_new => true do
-          @first.happy = false
-          @first.save!
-          raise
-        end
-      rescue
-      end
-    end
-
-    assert @first.reload.approved?
-    assert !@second.reload.approved?
-  end if Topic.connection.supports_savepoints?
-
-  def test_no_savepoint_in_nested_transaction_without_force
-    Topic.transaction do
-      @first.approved = true
-      @second.approved = false
-      @first.save!
-      @second.save!
-
-      begin
-        Topic.transaction do
-          @first.approved = false
-          @first.save!
-          raise
-        end
-      rescue
-      end
-    end
-
-    assert !@first.reload.approved?
-    assert !@second.reload.approved?
-  end if Topic.connection.supports_savepoints?
-  
-  def test_many_savepoints
-    Topic.transaction do
-      @first.content = "One"
-      @first.save!
-      
-      begin
-        Topic.transaction :requires_new => true do
-          @first.content = "Two"
-          @first.save!
-          
-          begin
-            Topic.transaction :requires_new => true do
-              @first.content = "Three"
-              @first.save!
-              
-              begin
-                Topic.transaction :requires_new => true do
-                  @first.content = "Four"
-                  @first.save!
-                  raise
-                end
-              rescue
-              end
-              
-              @three = @first.reload.content
-              raise
-            end
-          rescue
-          end
-          
-          @two = @first.reload.content
-          raise
-        end
-      rescue
-      end
-      
-      @one = @first.reload.content
-    end
-    
-    assert_equal "One", @one
-    assert_equal "Two", @two
-    assert_equal "Three", @three
-  end if Topic.connection.supports_savepoints?
-
-  def test_rollback_when_commit_raises
-    Topic.connection.expects(:begin_db_transaction)
-    Topic.connection.expects(:commit_db_transaction).raises('OH NOES')
-    Topic.connection.expects(:outside_transaction?).returns(false)
-    Topic.connection.expects(:rollback_db_transaction)
-
-    assert_raise RuntimeError do
-      Topic.transaction do
-        # do nothing
-      end
-    end
-  end
-  
-  if current_adapter?(:PostgreSQLAdapter) && defined?(PGconn::PQTRANS_IDLE)
-    def test_outside_transaction_works
-      assert Topic.connection.outside_transaction?
-      Topic.connection.begin_db_transaction
-      assert !Topic.connection.outside_transaction?
-      Topic.connection.rollback_db_transaction
-      assert Topic.connection.outside_transaction?
-    end
-    
-    def test_rollback_wont_be_executed_if_no_transaction_active
-      assert_raise RuntimeError do
-        Topic.transaction do
-          Topic.connection.rollback_db_transaction
-          Topic.connection.expects(:rollback_db_transaction).never
-          raise "Rails doesn't scale!"
-        end
-      end
-    end
-    
-    def test_open_transactions_count_is_reset_to_zero_if_no_transaction_active
-      Topic.transaction do
-        Topic.transaction do
-          Topic.connection.rollback_db_transaction
-        end
-        assert_equal 0, Topic.connection.open_transactions
-      end
-      assert_equal 0, Topic.connection.open_transactions
-    end
-  end
-
-  def test_sqlite_add_column_in_transaction
-    return true unless current_adapter?(:SQLite3Adapter, :SQLiteAdapter)
-
-    # Test first if column creation/deletion works correctly when no
-    # transaction is in place.
-    #
-    # We go back to the connection for the column queries because
-    # Topic.columns is cached and won't report changes to the DB
-    
-    assert_nothing_raised do
-      Topic.reset_column_information
-      Topic.connection.add_column('topics', 'stuff', :string)
-      assert Topic.column_names.include?('stuff')
-      
-      Topic.reset_column_information
-      Topic.connection.remove_column('topics', 'stuff')
-      assert !Topic.column_names.include?('stuff')
-    end
-
-    if Topic.connection.supports_ddl_transactions?
-      assert_nothing_raised do
-        Topic.transaction { Topic.connection.add_column('topics', 'stuff', :string) }
-      end
-    else
-      Topic.transaction do
-        assert_raise(ActiveRecord::StatementInvalid) { Topic.connection.add_column('topics', 'stuff', :string) }
-        raise ActiveRecord::Rollback
-      end
-    end
-  end
-
-  private
-    def add_exception_raising_after_save_callback_to_topic
-      Topic.class_eval { def after_save() raise "Make the transaction rollback" end }
-    end
-
-    def remove_exception_raising_after_save_callback_to_topic
-      Topic.class_eval { remove_method :after_save }
-    end
-
-    def add_exception_raising_after_create_callback_to_topic
-      Topic.class_eval { def after_create() raise "Make the transaction rollback" end }
-    end
-
-    def remove_exception_raising_after_create_callback_to_topic
-      Topic.class_eval { remove_method :after_create }
-    end
-
-    %w(validation save destroy).each do |filter|
-      define_method("add_cancelling_before_#{filter}_with_db_side_effect_to_topic") do
-        Topic.class_eval "def before_#{filter}() Book.create; false end"
-      end
-
-      define_method("remove_cancelling_before_#{filter}_with_db_side_effect_to_topic") do
-        Topic.class_eval "remove_method :before_#{filter}"
-      end
-    end
-end
-
-class TransactionsWithTransactionalFixturesTest < ActiveRecord::TestCase
-  self.use_transactional_fixtures = true
-  fixtures :topics
-
-  def test_automatic_savepoint_in_outer_transaction
-    @first = Topic.find(1)
-    
-    begin
-      Topic.transaction do
-        @first.approved = true
-        @first.save!
-        raise
-      end
-    rescue
-      assert !@first.reload.approved?
-    end
-  end
-
-  def test_no_automatic_savepoint_for_inner_transaction
-    @first = Topic.find(1)
-
-    Topic.transaction do
-      @first.approved = true
-      @first.save!
-
-      begin
-        Topic.transaction do
-          @first.approved = false
-          @first.save!
-          raise
-        end
-      rescue
-      end
-    end
-
-    assert !@first.reload.approved?
-  end
-end if Topic.connection.supports_savepoints?
-
-if current_adapter?(:PostgreSQLAdapter)
-  class ConcurrentTransactionTest < TransactionTest
-    use_concurrent_connections
-
-    # This will cause transactions to overlap and fail unless they are performed on
-    # separate database connections.
-    def test_transaction_per_thread
-      assert_nothing_raised do
-        threads = (1..3).map do
-          Thread.new do
-            Topic.transaction do
-              topic = Topic.find(1)
-              topic.approved = !topic.approved?
-              topic.save!
-              topic.approved = !topic.approved?
-              topic.save!
-            end
-          end
-        end
-
-        threads.each { |t| t.join }
-      end
-    end
-
-    # Test for dirty reads among simultaneous transactions.
-    def test_transaction_isolation__read_committed
-      # Should be invariant.
-      original_salary = Developer.find(1).salary
-      temporary_salary = 200000
-
-      assert_nothing_raised do
-        threads = (1..3).map do
-          Thread.new do
-            Developer.transaction do
-              # Expect original salary.
-              dev = Developer.find(1)
-              assert_equal original_salary, dev.salary
-
-              dev.salary = temporary_salary
-              dev.save!
-
-              # Expect temporary salary.
-              dev = Developer.find(1)
-              assert_equal temporary_salary, dev.salary
-
-              dev.salary = original_salary
-              dev.save!
-
-              # Expect original salary.
-              dev = Developer.find(1)
-              assert_equal original_salary, dev.salary
-            end
-          end
-        end
-
-        # Keep our eyes peeled.
-        threads << Thread.new do
-          10.times do
-            sleep 0.05
-            Developer.transaction do
-              # Always expect original salary.
-              assert_equal original_salary, Developer.find(1).salary
-            end
-          end
-        end
-
-        threads.each { |t| t.join }
-      end
-
-      assert_equal original_salary, Developer.find(1).salary
-    end
-  end
-end