aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/test
diff options
context:
space:
mode:
authorwycats <wycats@gmail.com>2010-06-08 18:10:27 -0400
committerwycats <wycats@gmail.com>2010-06-08 18:10:27 -0400
commitdf40dbe6f13c6799e972b20dcc1fbf11f0a02c61 (patch)
treed3daec753c2e55c859c63053d8411306bb11d603 /activerecord/test
parent6ebc7c8ee6de0f3f441a68baa6351416a6ac0a59 (diff)
parent5c9f27abaabba0d008ccd710ed1af5f6caa4e371 (diff)
downloadrails-df40dbe6f13c6799e972b20dcc1fbf11f0a02c61.tar.gz
rails-df40dbe6f13c6799e972b20dcc1fbf11f0a02c61.tar.bz2
rails-df40dbe6f13c6799e972b20dcc1fbf11f0a02c61.zip
Merge branch 'master' of github.com:rails/rails
Diffstat (limited to 'activerecord/test')
-rw-r--r--activerecord/test/cases/active_schema_test_mysql.rb8
-rw-r--r--activerecord/test/cases/active_schema_test_postgresql.rb1
-rw-r--r--activerecord/test/cases/adapter_test.rb8
-rwxr-xr-xactiverecord/test/cases/base_test.rb17
-rw-r--r--activerecord/test/cases/transaction_callbacks_test.rb240
-rw-r--r--activerecord/test/cases/transactions_test.rb33
6 files changed, 300 insertions, 7 deletions
diff --git a/activerecord/test/cases/active_schema_test_mysql.rb b/activerecord/test/cases/active_schema_test_mysql.rb
index 3526f49afd..d7431e5158 100644
--- a/activerecord/test/cases/active_schema_test_mysql.rb
+++ b/activerecord/test/cases/active_schema_test_mysql.rb
@@ -4,6 +4,7 @@ class ActiveSchemaTest < ActiveRecord::TestCase
def setup
ActiveRecord::ConnectionAdapters::MysqlAdapter.class_eval do
alias_method :execute_without_stub, :execute
+ remove_method :execute
def execute(sql, name = nil) return sql end
end
end
@@ -66,7 +67,7 @@ class ActiveSchemaTest < ActiveRecord::TestCase
assert_equal "DROP TABLE `otherdb`.`people`", drop_table('otherdb.people')
end
- def test_add_timestamps
+ def test_add_timestamps
with_real_execute do
begin
ActiveRecord::Base.connection.create_table :delete_me do |t|
@@ -79,8 +80,8 @@ class ActiveSchemaTest < ActiveRecord::TestCase
end
end
end
-
- def test_remove_timestamps
+
+ def test_remove_timestamps
with_real_execute do
begin
ActiveRecord::Base.connection.create_table :delete_me do |t|
@@ -106,6 +107,7 @@ class ActiveSchemaTest < ActiveRecord::TestCase
ensure
#before finishing, we restore the alias to the mock-up method
ActiveRecord::ConnectionAdapters::MysqlAdapter.class_eval do
+ remove_method :execute
alias_method :execute, :execute_with_stub
end
end
diff --git a/activerecord/test/cases/active_schema_test_postgresql.rb b/activerecord/test/cases/active_schema_test_postgresql.rb
index af80f724f2..4f04c6735c 100644
--- a/activerecord/test/cases/active_schema_test_postgresql.rb
+++ b/activerecord/test/cases/active_schema_test_postgresql.rb
@@ -4,6 +4,7 @@ class PostgresqlActiveSchemaTest < Test::Unit::TestCase
def setup
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.class_eval do
alias_method :real_execute, :execute
+ remove_method :execute
def execute(sql, name = nil) sql end
end
end
diff --git a/activerecord/test/cases/adapter_test.rb b/activerecord/test/cases/adapter_test.rb
index 0152b7be2a..fc08c2178a 100644
--- a/activerecord/test/cases/adapter_test.rb
+++ b/activerecord/test/cases/adapter_test.rb
@@ -145,13 +145,13 @@ class AdapterTest < ActiveRecord::TestCase
def test_add_limit_offset_should_sanitize_sql_injection_for_limit_without_comas
sql_inject = "1 select * from schema"
- assert_no_match /schema/, @connection.add_limit_offset!("", :limit=>sql_inject)
- assert_no_match /schema/, @connection.add_limit_offset!("", :limit=>sql_inject, :offset=>7)
+ assert_no_match(/schema/, @connection.add_limit_offset!("", :limit=>sql_inject))
+ assert_no_match(/schema/, @connection.add_limit_offset!("", :limit=>sql_inject, :offset=>7))
end
def test_add_limit_offset_should_sanitize_sql_injection_for_limit_with_comas
sql_inject = "1, 7 procedure help()"
- assert_no_match /procedure/, @connection.add_limit_offset!("", :limit=>sql_inject)
- assert_no_match /procedure/, @connection.add_limit_offset!("", :limit=>sql_inject, :offset=>7)
+ assert_no_match(/procedure/, @connection.add_limit_offset!("", :limit=>sql_inject))
+ assert_no_match(/procedure/, @connection.add_limit_offset!("", :limit=>sql_inject, :offset=>7))
end
end
diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb
index 36c572b5e7..5c175de6d4 100755
--- a/activerecord/test/cases/base_test.rb
+++ b/activerecord/test/cases/base_test.rb
@@ -2334,6 +2334,23 @@ class BasicsTest < ActiveRecord::TestCase
assert !Minimalistic.new.freeze.dup.frozen?
end
+ def test_compute_type_success
+ assert_equal Author, ActiveRecord::Base.send(:compute_type, 'Author')
+ end
+
+ def test_compute_type_nonexistent_constant
+ assert_raises NameError do
+ ActiveRecord::Base.send :compute_type, 'NonexistentModel'
+ end
+ end
+
+ def test_compute_type_no_method_error
+ String.any_instance.stubs(:constantize).raises(NoMethodError)
+ assert_raises NoMethodError do
+ ActiveRecord::Base.send :compute_type, 'InvalidModel'
+ end
+ end
+
protected
def with_env_tz(new_tz = 'US/Eastern')
old_tz, ENV['TZ'] = ENV['TZ'], new_tz
diff --git a/activerecord/test/cases/transaction_callbacks_test.rb b/activerecord/test/cases/transaction_callbacks_test.rb
new file mode 100644
index 0000000000..ebc16653cb
--- /dev/null
+++ b/activerecord/test/cases/transaction_callbacks_test.rb
@@ -0,0 +1,240 @@
+require "cases/helper"
+require 'models/topic'
+require 'models/reply'
+
+class TransactionCallbacksTest < ActiveRecord::TestCase
+ self.use_transactional_fixtures = false
+ fixtures :topics
+
+ class TopicWithCallbacks < ActiveRecord::Base
+ set_table_name :topics
+
+ after_commit{|record| record.send(:do_after_commit, nil)}
+ after_commit(:on => :create){|record| record.send(:do_after_commit, :create)}
+ after_commit(:on => :update){|record| record.send(:do_after_commit, :update)}
+ after_commit(:on => :destroy){|record| record.send(:do_after_commit, :destroy)}
+ after_rollback{|record| record.send(:do_after_rollback, nil)}
+ after_rollback(:on => :create){|record| record.send(:do_after_rollback, :create)}
+ after_rollback(:on => :update){|record| record.send(:do_after_rollback, :update)}
+ after_rollback(:on => :destroy){|record| record.send(:do_after_rollback, :destroy)}
+
+ def history
+ @history ||= []
+ end
+
+ def after_commit_block(on = nil, &block)
+ @after_commit ||= {}
+ @after_commit[on] ||= []
+ @after_commit[on] << block
+ end
+
+ def after_rollback_block(on = nil, &block)
+ @after_rollback ||= {}
+ @after_rollback[on] ||= []
+ @after_rollback[on] << block
+ end
+
+ def do_after_commit(on)
+ blocks = @after_commit[on] if defined?(@after_commit)
+ blocks.each{|b| b.call(self)} if blocks
+ end
+
+ def do_after_rollback(on)
+ blocks = @after_rollback[on] if defined?(@after_rollback)
+ blocks.each{|b| b.call(self)} if blocks
+ end
+ end
+
+ def setup
+ @first, @second = TopicWithCallbacks.find(1, 3).sort_by { |t| t.id }
+ end
+
+ def test_call_after_commit_after_transaction_commits
+ @first.after_commit_block{|r| r.history << :after_commit}
+ @first.after_rollback_block{|r| r.history << :after_rollback}
+
+ @first.save!
+ assert_equal [:after_commit], @first.history
+ end
+
+ def test_only_call_after_commit_on_update_after_transaction_commits_for_existing_record
+ @first.after_commit_block(:create){|r| r.history << :commit_on_create}
+ @first.after_commit_block(:update){|r| r.history << :commit_on_update}
+ @first.after_commit_block(:destroy){|r| r.history << :commit_on_destroy}
+ @first.after_rollback_block(:create){|r| r.history << :rollback_on_create}
+ @first.after_rollback_block(:update){|r| r.history << :rollback_on_update}
+ @first.after_rollback_block(:destroy){|r| r.history << :rollback_on_destroy}
+
+ @first.save!
+ assert_equal [:commit_on_update], @first.history
+ end
+
+ def test_only_call_after_commit_on_destroy_after_transaction_commits_for_destroyed_record
+ @first.after_commit_block(:create){|r| r.history << :commit_on_create}
+ @first.after_commit_block(:update){|r| r.history << :commit_on_update}
+ @first.after_commit_block(:destroy){|r| r.history << :commit_on_destroy}
+ @first.after_rollback_block(:create){|r| r.history << :rollback_on_create}
+ @first.after_rollback_block(:update){|r| r.history << :rollback_on_update}
+ @first.after_rollback_block(:destroy){|r| r.history << :rollback_on_destroy}
+
+ @first.destroy
+ assert_equal [:commit_on_destroy], @first.history
+ end
+
+ def test_only_call_after_commit_on_create_after_transaction_commits_for_new_record
+ @new_record = TopicWithCallbacks.new(:title => "New topic", :written_on => Date.today)
+ @new_record.after_commit_block(:create){|r| r.history << :commit_on_create}
+ @new_record.after_commit_block(:update){|r| r.history << :commit_on_update}
+ @new_record.after_commit_block(:destroy){|r| r.history << :commit_on_destroy}
+ @new_record.after_rollback_block(:create){|r| r.history << :rollback_on_create}
+ @new_record.after_rollback_block(:update){|r| r.history << :rollback_on_update}
+ @new_record.after_rollback_block(:destroy){|r| r.history << :rollback_on_destroy}
+
+ @new_record.save!
+ assert_equal [:commit_on_create], @new_record.history
+ end
+
+ def test_call_after_rollback_after_transaction_rollsback
+ @first.after_commit_block{|r| r.history << :after_commit}
+ @first.after_rollback_block{|r| r.history << :after_rollback}
+
+ Topic.transaction do
+ @first.save!
+ raise ActiveRecord::Rollback
+ end
+
+ assert_equal [:after_rollback], @first.history
+ end
+
+ def test_only_call_after_rollback_on_update_after_transaction_rollsback_for_existing_record
+ @first.after_commit_block(:create){|r| r.history << :commit_on_create}
+ @first.after_commit_block(:update){|r| r.history << :commit_on_update}
+ @first.after_commit_block(:destroy){|r| r.history << :commit_on_destroy}
+ @first.after_rollback_block(:create){|r| r.history << :rollback_on_create}
+ @first.after_rollback_block(:update){|r| r.history << :rollback_on_update}
+ @first.after_rollback_block(:destroy){|r| r.history << :rollback_on_destroy}
+
+ Topic.transaction do
+ @first.save!
+ raise ActiveRecord::Rollback
+ end
+
+ assert_equal [:rollback_on_update], @first.history
+ end
+
+ def test_only_call_after_rollback_on_destroy_after_transaction_rollsback_for_destroyed_record
+ @first.after_commit_block(:create){|r| r.history << :commit_on_create}
+ @first.after_commit_block(:update){|r| r.history << :commit_on_update}
+ @first.after_commit_block(:destroy){|r| r.history << :commit_on_update}
+ @first.after_rollback_block(:create){|r| r.history << :rollback_on_create}
+ @first.after_rollback_block(:update){|r| r.history << :rollback_on_update}
+ @first.after_rollback_block(:destroy){|r| r.history << :rollback_on_destroy}
+
+ Topic.transaction do
+ @first.destroy
+ raise ActiveRecord::Rollback
+ end
+
+ assert_equal [:rollback_on_destroy], @first.history
+ end
+
+ def test_only_call_after_rollback_on_create_after_transaction_rollsback_for_new_record
+ @new_record = TopicWithCallbacks.new(:title => "New topic", :written_on => Date.today)
+ @new_record.after_commit_block(:create){|r| r.history << :commit_on_create}
+ @new_record.after_commit_block(:update){|r| r.history << :commit_on_update}
+ @new_record.after_commit_block(:destroy){|r| r.history << :commit_on_destroy}
+ @new_record.after_rollback_block(:create){|r| r.history << :rollback_on_create}
+ @new_record.after_rollback_block(:update){|r| r.history << :rollback_on_update}
+ @new_record.after_rollback_block(:destroy){|r| r.history << :rollback_on_destroy}
+
+ Topic.transaction do
+ @new_record.save!
+ raise ActiveRecord::Rollback
+ end
+
+ assert_equal [:rollback_on_create], @new_record.history
+ end
+
+ def test_call_after_rollback_when_commit_fails
+ @first.connection.class.send(:alias_method, :real_method_commit_db_transaction, :commit_db_transaction)
+ begin
+ @first.connection.class.class_eval do
+ def commit_db_transaction; raise "boom!"; end
+ end
+
+ @first.after_commit_block{|r| r.history << :after_commit}
+ @first.after_rollback_block{|r| r.history << :after_rollback}
+
+ assert !@first.save rescue nil
+ assert_equal [:after_rollback], @first.history
+ ensure
+ @first.connection.class.send(:remove_method, :commit_db_transaction)
+ @first.connection.class.send(:alias_method, :commit_db_transaction, :real_method_commit_db_transaction)
+ end
+ end
+
+ def test_only_call_after_rollback_on_records_rolled_back_to_a_savepoint
+ def @first.rollbacks(i=0); @rollbacks ||= 0; @rollbacks += i if i; end
+ def @first.commits(i=0); @commits ||= 0; @commits += i if i; end
+ @first.after_rollback_block{|r| r.rollbacks(1)}
+ @first.after_commit_block{|r| r.commits(1)}
+
+ def @second.rollbacks(i=0); @rollbacks ||= 0; @rollbacks += i if i; end
+ def @second.commits(i=0); @commits ||= 0; @commits += i if i; end
+ @second.after_rollback_block{|r| r.rollbacks(1)}
+ @second.after_commit_block{|r| r.commits(1)}
+
+ Topic.transaction do
+ @first.save!
+ Topic.transaction(:requires_new => true) do
+ @second.save!
+ raise ActiveRecord::Rollback
+ end
+ end
+
+ assert_equal 1, @first.commits
+ assert_equal 0, @first.rollbacks
+ assert_equal 0, @second.commits
+ assert_equal 1, @second.rollbacks
+ end
+
+ def test_only_call_after_rollback_on_records_rolled_back_to_a_savepoint_when_release_savepoint_fails
+ def @first.rollbacks(i=0); @rollbacks ||= 0; @rollbacks += i if i; end
+ def @first.commits(i=0); @commits ||= 0; @commits += i if i; end
+
+ @first.after_rollback_block{|r| r.rollbacks(1)}
+ @first.after_commit_block{|r| r.commits(1)}
+
+ Topic.transaction do
+ @first.save
+ Topic.transaction(:requires_new => true) do
+ @first.save!
+ raise ActiveRecord::Rollback
+ end
+ Topic.transaction(:requires_new => true) do
+ @first.save!
+ raise ActiveRecord::Rollback
+ end
+ end
+
+ assert_equal 1, @first.commits
+ assert_equal 2, @first.rollbacks
+ end
+
+ def test_after_transaction_callbacks_should_not_raise_errors
+ def @first.last_after_transaction_error=(e); @last_transaction_error = e; end
+ def @first.last_after_transaction_error; @last_transaction_error; end
+ @first.after_commit_block{|r| r.last_after_transaction_error = :commit; raise "fail!";}
+ @first.after_rollback_block{|r| r.last_after_transaction_error = :rollback; raise "fail!";}
+
+ @first.save!
+ assert_equal :commit, @first.last_after_transaction_error
+
+ Topic.transaction do
+ @first.save!
+ raise ActiveRecord::Rollback
+ end
+
+ assert_equal :rollback, @first.last_after_transaction_error
+ end
+end
diff --git a/activerecord/test/cases/transactions_test.rb b/activerecord/test/cases/transactions_test.rb
index 00f3b527d7..958a4e4f94 100644
--- a/activerecord/test/cases/transactions_test.rb
+++ b/activerecord/test/cases/transactions_test.rb
@@ -320,6 +320,33 @@ class TransactionTest < ActiveRecord::TestCase
end
end
+ def test_restore_active_record_state_for_all_records_in_a_transaction
+ topic_1 = Topic.new(:title => 'test_1')
+ topic_2 = Topic.new(:title => 'test_2')
+ Topic.transaction do
+ assert topic_1.save
+ assert topic_2.save
+ @first.save
+ @second.destroy
+ assert_equal false, topic_1.new_record?
+ assert_not_nil topic_1.id
+ assert_equal false, topic_2.new_record?
+ assert_not_nil topic_2.id
+ assert_equal false, @first.new_record?
+ assert_not_nil @first.id
+ assert_equal true, @second.destroyed?
+ raise ActiveRecord::Rollback
+ end
+
+ assert_equal true, topic_1.new_record?
+ assert_nil topic_1.id
+ assert_equal true, topic_2.new_record?
+ assert_nil topic_2.id
+ assert_equal false, @first.new_record?
+ assert_not_nil @first.id
+ assert_equal false, @second.destroyed?
+ end
+
if current_adapter?(:PostgreSQLAdapter) && defined?(PGconn::PQTRANS_IDLE)
def test_outside_transaction_works
assert Topic.connection.outside_transaction?
@@ -382,6 +409,12 @@ class TransactionTest < ActiveRecord::TestCase
end
private
+ def define_callback_method(callback_method)
+ define_method(callback_method) do
+ self.history << [callback_method, :method]
+ end
+ end
+
def add_exception_raising_after_save_callback_to_topic
Topic.class_eval <<-eoruby, __FILE__, __LINE__ + 1
remove_method(:after_save_for_transaction)