aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/test/cases
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/test/cases')
-rw-r--r--activerecord/test/cases/batches_test.rb15
-rw-r--r--activerecord/test/cases/connection_adapters/connection_handler_test.rb4
-rw-r--r--activerecord/test/cases/nested_attributes_test.rb16
-rw-r--r--activerecord/test/cases/tasks/mysql_rake_test.rb46
-rw-r--r--activerecord/test/cases/transaction_isolation_test.rb108
-rw-r--r--activerecord/test/cases/transactions_test.rb14
6 files changed, 170 insertions, 33 deletions
diff --git a/activerecord/test/cases/batches_test.rb b/activerecord/test/cases/batches_test.rb
index 3b4ff83725..12d5245fbd 100644
--- a/activerecord/test/cases/batches_test.rb
+++ b/activerecord/test/cases/batches_test.rb
@@ -1,8 +1,9 @@
require 'cases/helper'
require 'models/post'
+require 'models/subscriber'
class EachTest < ActiveRecord::TestCase
- fixtures :posts
+ fixtures :posts, :subscribers
def setup
@posts = Post.order("id asc")
@@ -125,14 +126,14 @@ class EachTest < ActiveRecord::TestCase
end
def test_find_in_batches_should_use_any_column_as_primary_key
- title_order_posts = Post.order('title asc')
- start_title = title_order_posts.first.title
+ nick_order_subscribers = Subscriber.order('nick asc')
+ start_nick = nick_order_subscribers.second.nick
- posts = []
- PostWithTitlePrimaryKey.find_in_batches(:batch_size => 1, :start => start_title) do |batch|
- posts.concat(batch)
+ subscribers = []
+ Subscriber.find_in_batches(:batch_size => 1, :start => start_nick) do |batch|
+ subscribers.concat(batch)
end
- assert_equal title_order_posts.map(&:id), posts.map(&:id)
+ assert_equal nick_order_subscribers[1..-1].map(&:id), subscribers.map(&:id)
end
end
diff --git a/activerecord/test/cases/connection_adapters/connection_handler_test.rb b/activerecord/test/cases/connection_adapters/connection_handler_test.rb
index e1579d037f..4467ddfc39 100644
--- a/activerecord/test/cases/connection_adapters/connection_handler_test.rb
+++ b/activerecord/test/cases/connection_adapters/connection_handler_test.rb
@@ -4,8 +4,8 @@ module ActiveRecord
module ConnectionAdapters
class ConnectionHandlerTest < ActiveRecord::TestCase
def setup
- @klass = Class.new { include Model::Tag }
- @subklass = Class.new(@klass) { include Model::Tag }
+ @klass = Class.new { include ActiveRecord::Tag }
+ @subklass = Class.new(@klass) { include ActiveRecord::Tag }
@handler = ConnectionHandler.new
@handler.establish_connection @klass, Base.connection_pool.spec
diff --git a/activerecord/test/cases/nested_attributes_test.rb b/activerecord/test/cases/nested_attributes_test.rb
index 07862ca4ca..9120083eca 100644
--- a/activerecord/test/cases/nested_attributes_test.rb
+++ b/activerecord/test/cases/nested_attributes_test.rb
@@ -463,6 +463,22 @@ class TestNestedAttributesOnABelongsToAssociation < ActiveRecord::TestCase
end
end
+ def test_should_unset_association_when_an_existing_record_is_destroyed
+ @ship.reload
+ original_pirate_id = @ship.pirate.id
+ @ship.attributes = {:pirate_attributes => {:id => @ship.pirate.id, :_destroy => true}}
+ @ship.save!
+
+ assert_empty Pirate.where(["id = ?", original_pirate_id])
+ assert_nil @ship.pirate_id
+ assert_nil @ship.pirate
+
+ @ship.reload
+ assert_empty Pirate.where(["id = ?", original_pirate_id])
+ assert_nil @ship.pirate_id
+ assert_nil @ship.pirate
+ end
+
def test_should_not_destroy_an_existing_record_if_destroy_is_not_truthy
[nil, '0', 0, 'false', false].each do |not_truth|
@ship.update_attributes(:pirate_attributes => { :id => @ship.pirate.id, :_destroy => not_truth })
diff --git a/activerecord/test/cases/tasks/mysql_rake_test.rb b/activerecord/test/cases/tasks/mysql_rake_test.rb
index 46b97a1274..69a049fcfa 100644
--- a/activerecord/test/cases/tasks/mysql_rake_test.rb
+++ b/activerecord/test/cases/tasks/mysql_rake_test.rb
@@ -20,20 +20,32 @@ module ActiveRecord
ActiveRecord::Tasks::DatabaseTasks.create @configuration
end
- def test_creates_database_with_default_options
+ def test_creates_database_with_default_encoding_and_collation
@connection.expects(:create_database).
- with('my-app-db', {:charset => 'utf8', :collation => 'utf8_unicode_ci'})
+ with('my-app-db', charset: 'utf8', collation: 'utf8_unicode_ci')
ActiveRecord::Tasks::DatabaseTasks.create @configuration
end
- def test_creates_database_with_given_options
+ def test_creates_database_with_given_encoding_and_default_collation
@connection.expects(:create_database).
- with('my-app-db', {:charset => 'latin', :collation => 'latin_ci'})
+ with('my-app-db', charset: 'utf8', collation: 'utf8_unicode_ci')
- ActiveRecord::Tasks::DatabaseTasks.create @configuration.merge(
- 'encoding' => 'latin', 'collation' => 'latin_ci'
- )
+ ActiveRecord::Tasks::DatabaseTasks.create @configuration.merge('encoding' => 'utf8')
+ end
+
+ def test_creates_database_with_given_encoding_and_no_collation
+ @connection.expects(:create_database).
+ with('my-app-db', charset: 'latin1')
+
+ ActiveRecord::Tasks::DatabaseTasks.create @configuration.merge('encoding' => 'latin1')
+ end
+
+ def test_creates_database_with_given_collation_and_no_encoding
+ @connection.expects(:create_database).
+ with('my-app-db', collation: 'latin1_swedish_ci')
+
+ ActiveRecord::Tasks::DatabaseTasks.create @configuration.merge('collation' => 'latin1_swedish_ci')
end
def test_establishes_connection_to_database
@@ -62,8 +74,9 @@ module ActiveRecord
$stdout.stubs(:print).returns(nil)
@error.stubs(:errno).returns(1045)
ActiveRecord::Base.stubs(:connection).returns(@connection)
- ActiveRecord::Base.stubs(:establish_connection).raises(@error).then.
- returns(true)
+ ActiveRecord::Base.stubs(:establish_connection).
+ raises(@error).
+ then.returns(true)
end
def test_root_password_is_requested
@@ -74,12 +87,12 @@ module ActiveRecord
end
def test_connection_established_as_root
- ActiveRecord::Base.expects(:establish_connection).with({
+ ActiveRecord::Base.expects(:establish_connection).with(
'adapter' => 'mysql',
'database' => nil,
'username' => 'root',
'password' => 'secret'
- })
+ )
ActiveRecord::Tasks::DatabaseTasks.create @configuration
end
@@ -99,12 +112,12 @@ module ActiveRecord
def test_connection_established_as_normal_user
ActiveRecord::Base.expects(:establish_connection).returns do
- ActiveRecord::Base.expects(:establish_connection).with({
+ ActiveRecord::Base.expects(:establish_connection).with(
'adapter' => 'mysql',
'database' => 'my-app-db',
'username' => 'pat',
'password' => 'secret'
- })
+ )
raise @error
end
@@ -166,18 +179,17 @@ module ActiveRecord
def test_recreates_database_with_the_default_options
@connection.expects(:recreate_database).
- with('test-db', {:charset => 'utf8', :collation => 'utf8_unicode_ci'})
+ with('test-db', charset: 'utf8', collation: 'utf8_unicode_ci')
ActiveRecord::Tasks::DatabaseTasks.purge @configuration
end
def test_recreates_database_with_the_given_options
@connection.expects(:recreate_database).
- with('test-db', {:charset => 'latin', :collation => 'latin_ci'})
+ with('test-db', charset: 'latin', collation: 'latin1_swedish_ci')
ActiveRecord::Tasks::DatabaseTasks.purge @configuration.merge(
- 'encoding' => 'latin', 'collation' => 'latin_ci'
- )
+ 'encoding' => 'latin', 'collation' => 'latin1_swedish_ci')
end
end
diff --git a/activerecord/test/cases/transaction_isolation_test.rb b/activerecord/test/cases/transaction_isolation_test.rb
new file mode 100644
index 0000000000..1e34f93d8f
--- /dev/null
+++ b/activerecord/test/cases/transaction_isolation_test.rb
@@ -0,0 +1,108 @@
+require 'cases/helper'
+
+class TransactionIsolationUnsupportedTest < ActiveRecord::TestCase
+ self.use_transactional_fixtures = false
+
+ class Tag < ActiveRecord::Base
+ end
+
+ setup do
+ if ActiveRecord::Base.connection.supports_transaction_isolation?
+ skip "database supports transaction isolation; test is irrelevant"
+ end
+ end
+
+ test "setting the isolation level raises an error" do
+ assert_raises(ActiveRecord::TransactionIsolationError) do
+ Tag.transaction(isolation: :serializable) { }
+ end
+ end
+end
+
+class TransactionIsolationTest < ActiveRecord::TestCase
+ self.use_transactional_fixtures = false
+
+ class Tag < ActiveRecord::Base
+ self.table_name = 'tags'
+ end
+
+ class Tag2 < ActiveRecord::Base
+ self.table_name = 'tags'
+ end
+
+ setup do
+ unless ActiveRecord::Base.connection.supports_transaction_isolation?
+ skip "database does not support setting transaction isolation"
+ end
+
+ Tag.establish_connection 'arunit'
+ Tag2.establish_connection 'arunit'
+ Tag.destroy_all
+ end
+
+ # It is impossible to properly test read uncommitted. The SQL standard only
+ # specifies what must not happen at a certain level, not what must happen. At
+ # the read uncommitted level, there is nothing that must not happen.
+ test "read uncommitted" do
+ Tag.transaction(isolation: :read_uncommitted) do
+ assert_equal 0, Tag.count
+ Tag2.create
+ assert_equal 1, Tag.count
+ end
+ end
+
+ # We are testing that a dirty read does not happen
+ test "read committed" do
+ Tag.transaction(isolation: :read_committed) do
+ assert_equal 0, Tag.count
+
+ Tag2.transaction do
+ Tag2.create
+ assert_equal 0, Tag.count
+ end
+ end
+
+ assert_equal 1, Tag.count
+ end
+
+ # We are testing that a nonrepeatable read does not happen
+ test "repeatable read" do
+ tag = Tag.create(name: 'jon')
+
+ Tag.transaction(isolation: :repeatable_read) do
+ tag.reload
+ Tag2.find(tag.id).update_attributes(name: 'emily')
+
+ tag.reload
+ assert_equal 'jon', tag.name
+ end
+
+ tag.reload
+ assert_equal 'emily', tag.name
+ end
+
+ # We are only testing that there are no errors because it's too hard to
+ # test serializable. Databases behave differently to enforce the serializability
+ # constraint.
+ test "serializable" do
+ Tag.transaction(isolation: :serializable) do
+ Tag.create
+ end
+ end
+
+ test "setting isolation when joining a transaction raises an error" do
+ Tag.transaction do
+ assert_raises(ActiveRecord::TransactionIsolationError) do
+ Tag.transaction(isolation: :serializable) { }
+ end
+ end
+ end
+
+ test "setting isolation when starting a nested transaction raises error" do
+ Tag.transaction do
+ assert_raises(ActiveRecord::TransactionIsolationError) do
+ Tag.transaction(requires_new: true, isolation: :serializable) { }
+ end
+ end
+ end
+end
diff --git a/activerecord/test/cases/transactions_test.rb b/activerecord/test/cases/transactions_test.rb
index 0b5fda3817..bb4f2c8064 100644
--- a/activerecord/test/cases/transactions_test.rb
+++ b/activerecord/test/cases/transactions_test.rb
@@ -36,24 +36,24 @@ class TransactionTest < ActiveRecord::TestCase
end
end
- # FIXME: Get rid of this fucking global variable!
def test_successful_with_return
- class << Topic.connection
+ committed = false
+
+ Topic.connection.class_eval do
alias :real_commit_db_transaction :commit_db_transaction
- def commit_db_transaction
- $committed = true
+ define_method(:commit_db_transaction) do
+ committed = true
real_commit_db_transaction
end
end
- $committed = false
transaction_with_return
- assert $committed
+ 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
+ Topic.connection.class_eval do
remove_method :commit_db_transaction
alias :commit_db_transaction :real_commit_db_transaction rescue nil
end