aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/test/cases
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/test/cases')
-rw-r--r--activerecord/test/cases/associations/cascaded_eager_loading_test.rb8
-rw-r--r--activerecord/test/cases/associations/eager_test.rb48
-rw-r--r--activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb11
-rw-r--r--activerecord/test/cases/associations/has_many_associations_test.rb9
-rwxr-xr-xactiverecord/test/cases/base_test.rb5
-rw-r--r--activerecord/test/cases/callbacks_test.rb44
-rw-r--r--activerecord/test/cases/defaults_test.rb63
-rw-r--r--activerecord/test/cases/dirty_test.rb26
-rw-r--r--activerecord/test/cases/helper.rb2
-rw-r--r--activerecord/test/cases/json_serialization_test.rb2
-rw-r--r--activerecord/test/cases/named_scope_test.rb22
-rw-r--r--activerecord/test/cases/transactions_test.rb166
12 files changed, 371 insertions, 35 deletions
diff --git a/activerecord/test/cases/associations/cascaded_eager_loading_test.rb b/activerecord/test/cases/associations/cascaded_eager_loading_test.rb
index 8c9ae8a031..45e74ea024 100644
--- a/activerecord/test/cases/associations/cascaded_eager_loading_test.rb
+++ b/activerecord/test/cases/associations/cascaded_eager_loading_test.rb
@@ -104,6 +104,14 @@ class CascadedEagerLoadingTest < ActiveRecord::TestCase
authors.first.posts.first.special_comments.first.post.very_special_comment
end
end
+
+ def test_eager_association_loading_where_first_level_returns_nil
+ authors = Author.find(:all, :include => {:post_about_thinking => :comments}, :order => 'authors.id DESC')
+ assert_equal [authors(:mary), authors(:david)], authors
+ assert_no_queries do
+ authors[1].post_about_thinking.comments.first
+ end
+ end
end
require 'models/vertex'
diff --git a/activerecord/test/cases/associations/eager_test.rb b/activerecord/test/cases/associations/eager_test.rb
index a2d0efab92..14099d4176 100644
--- a/activerecord/test/cases/associations/eager_test.rb
+++ b/activerecord/test/cases/associations/eager_test.rb
@@ -771,4 +771,52 @@ class EagerAssociationTest < ActiveRecord::TestCase
assert_equal author_addresses(:david_address), authors[0].author_address
end
+ def test_preload_belongs_to_uses_exclusive_scope
+ people = Person.males.find(:all, :include => :primary_contact)
+ assert_not_equal people.length, 0
+ people.each do |person|
+ assert_no_queries {assert_not_nil person.primary_contact}
+ assert_equal Person.find(person.id).primary_contact, person.primary_contact
+ end
+ end
+
+ def test_preload_has_many_uses_exclusive_scope
+ people = Person.males.find :all, :include => :agents
+ people.each do |person|
+ assert_equal Person.find(person.id).agents, person.agents
+ end
+ end
+
+ def test_preload_has_many_using_primary_key
+ expected = Firm.find(:first).clients_using_primary_key.to_a
+ firm = Firm.find :first, :include => :clients_using_primary_key
+ assert_no_queries do
+ assert_equal expected, firm.clients_using_primary_key
+ end
+ end
+
+ def test_include_has_many_using_primary_key
+ expected = Firm.find(1).clients_using_primary_key.sort_by &:name
+ firm = Firm.find 1, :include => :clients_using_primary_key, :order => 'clients_using_primary_keys_companies.name'
+ assert_no_queries do
+ assert_equal expected, firm.clients_using_primary_key
+ end
+ end
+
+ def test_preload_has_one_using_primary_key
+ expected = Firm.find(:first).account_using_primary_key
+ firm = Firm.find :first, :include => :account_using_primary_key
+ assert_no_queries do
+ assert_equal expected, firm.account_using_primary_key
+ end
+ end
+
+ def test_include_has_one_using_primary_key
+ expected = Firm.find(1).account_using_primary_key
+ firm = Firm.find(:all, :include => :account_using_primary_key, :order => 'accounts.id').detect {|f| f.id == 1}
+ assert_no_queries do
+ assert_equal expected, firm.account_using_primary_key
+ end
+ end
+
end
diff --git a/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb b/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb
index 2f08e09d43..1e3b423471 100644
--- a/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb
+++ b/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb
@@ -775,4 +775,15 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
end
end
end
+
+ def test_caching_of_columns
+ david = Developer.find(1)
+ # clear cache possibly created by other tests
+ david.projects.reset_column_information
+ assert_queries(0) { david.projects.columns; david.projects.columns }
+ # and again to verify that reset_column_information clears the cache correctly
+ david.projects.reset_column_information
+ assert_queries(0) { david.projects.columns; david.projects.columns }
+ end
+
end
diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb
index 20b9acda44..428fb50013 100644
--- a/activerecord/test/cases/associations/has_many_associations_test.rb
+++ b/activerecord/test/cases/associations/has_many_associations_test.rb
@@ -698,7 +698,8 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
authors(:david).destroy
end
- assert_equal [author_address.id], AuthorAddress.destroyed_author_address_ids[authors(:david).id]
+ assert_equal nil, AuthorAddress.find_by_id(authors(:david).author_address_id)
+ assert_equal nil, AuthorAddress.find_by_id(authors(:david).author_address_extra_id)
end
def test_invalid_belongs_to_dependent_option_raises_exception
@@ -1115,5 +1116,11 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
assert !client_association.respond_to?(:private_method)
assert client_association.respond_to?(:private_method, true)
end
+
+ def test_creating_using_primary_key
+ firm = Firm.find(:first)
+ client = firm.clients_using_primary_key.create!(:name => 'test')
+ assert_equal firm.name, client.firm_name
+ end
end
diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb
index ce77ba4dbf..0f03dae829 100755
--- a/activerecord/test/cases/base_test.rb
+++ b/activerecord/test/cases/base_test.rb
@@ -1198,6 +1198,11 @@ class BasicsTest < ActiveRecord::TestCase
assert b_true.value?
end
+ def test_new_record_returns_boolean
+ assert_equal Topic.new.new_record?, true
+ assert_equal Topic.find(1).new_record?, false
+ end
+
def test_clone
topic = Topic.find(1)
cloned_topic = nil
diff --git a/activerecord/test/cases/callbacks_test.rb b/activerecord/test/cases/callbacks_test.rb
index 11830a2ef6..33b1ea034d 100644
--- a/activerecord/test/cases/callbacks_test.rb
+++ b/activerecord/test/cases/callbacks_test.rb
@@ -121,9 +121,19 @@ end
class CallbackCancellationDeveloper < ActiveRecord::Base
set_table_name 'developers'
- def before_create
- false
- end
+
+ attr_reader :after_save_called, :after_create_called, :after_update_called, :after_destroy_called
+ attr_accessor :cancel_before_save, :cancel_before_create, :cancel_before_update, :cancel_before_destroy
+
+ def before_save; !@cancel_before_save; end
+ def before_create; !@cancel_before_create; end
+ def before_update; !@cancel_before_update; end
+ def before_destroy; !@cancel_before_destroy; end
+
+ def after_save; @after_save_called = true; end
+ def after_update; @after_update_called = true; end
+ def after_create; @after_create_called = true; end
+ def after_destroy; @after_destroy_called = true; end
end
class CallbacksTest < ActiveRecord::TestCase
@@ -349,19 +359,47 @@ class CallbacksTest < ActiveRecord::TestCase
assert !david.valid?
assert !david.save
assert_raises(ActiveRecord::RecordInvalid) { david.save! }
+
+ someone = CallbackCancellationDeveloper.find(1)
+ someone.cancel_before_save = true
+ assert someone.valid?
+ assert !someone.save
+ assert_save_callbacks_not_called(someone)
end
def test_before_create_returning_false
someone = CallbackCancellationDeveloper.new
+ someone.cancel_before_create = true
assert someone.valid?
assert !someone.save
+ assert_save_callbacks_not_called(someone)
+ end
+
+ def test_before_update_returning_false
+ someone = CallbackCancellationDeveloper.find(1)
+ someone.cancel_before_update = true
+ assert someone.valid?
+ assert !someone.save
+ assert_save_callbacks_not_called(someone)
end
def test_before_destroy_returning_false
david = ImmutableDeveloper.find(1)
assert !david.destroy
assert_not_nil ImmutableDeveloper.find_by_id(1)
+
+ someone = CallbackCancellationDeveloper.find(1)
+ someone.cancel_before_destroy = true
+ assert !someone.destroy
+ assert !someone.after_destroy_called
+ end
+
+ def assert_save_callbacks_not_called(someone)
+ assert !someone.after_save_called
+ assert !someone.after_create_called
+ assert !someone.after_update_called
end
+ private :assert_save_callbacks_not_called
def test_zzz_callback_returning_false # must be run last since we modify CallbackDeveloper
david = CallbackDeveloper.find(1)
diff --git a/activerecord/test/cases/defaults_test.rb b/activerecord/test/cases/defaults_test.rb
index 38e4853dc0..b4032c23e6 100644
--- a/activerecord/test/cases/defaults_test.rb
+++ b/activerecord/test/cases/defaults_test.rb
@@ -18,11 +18,43 @@ class DefaultTest < ActiveRecord::TestCase
end
end
- if current_adapter?(:MysqlAdapter)
+ if current_adapter?(:PostgreSQLAdapter, :FirebirdAdapter, :OpenBaseAdapter, :OracleAdapter)
+ def test_default_integers
+ default = Default.new
+ assert_instance_of Fixnum, default.positive_integer
+ assert_equal 1, default.positive_integer
+ assert_instance_of Fixnum, default.negative_integer
+ assert_equal -1, default.negative_integer
+ assert_instance_of BigDecimal, default.decimal_number
+ assert_equal BigDecimal.new("2.78"), default.decimal_number
+ end
+ end
+
+ if current_adapter?(:PostgreSQLAdapter)
+ def test_multiline_default_text
+ # older postgres versions represent the default with escapes ("\\012" for a newline)
+ assert ( "--- []\n\n" == Default.columns_hash['multiline_default'].default ||
+ "--- []\\012\\012" == Default.columns_hash['multiline_default'].default)
+ end
+ end
+end
- #MySQL 5 and higher is quirky with not null text/blob columns.
- #With MySQL Text/blob columns cannot have defaults. If the column is not null MySQL will report that the column has a null default
- #but it behaves as though the column had a default of ''
+if current_adapter?(:MysqlAdapter)
+ class DefaultsTestWithoutTransactionalFixtures < ActiveRecord::TestCase
+ # ActiveRecord::Base#create! (and #save and other related methods) will
+ # open a new transaction. When in transactional fixtures mode, this will
+ # cause ActiveRecord to create a new savepoint. However, since MySQL doesn't
+ # support DDL transactions, creating a table will result in any created
+ # savepoints to be automatically released. This in turn causes the savepoint
+ # release code in AbstractAdapter#transaction to fail.
+ #
+ # We don't want that to happen, so we disable transactional fixtures here.
+ self.use_transactional_fixtures = false
+
+ # MySQL 5 and higher is quirky with not null text/blob columns.
+ # With MySQL Text/blob columns cannot have defaults. If the column is not
+ # null MySQL will report that the column has a null default
+ # but it behaves as though the column had a default of ''
def test_mysql_text_not_null_defaults
klass = Class.new(ActiveRecord::Base)
klass.table_name = 'test_mysql_text_not_null_defaults'
@@ -48,8 +80,7 @@ class DefaultTest < ActiveRecord::TestCase
ensure
klass.connection.drop_table(klass.table_name) rescue nil
end
-
-
+
# MySQL uses an implicit default 0 rather than NULL unless in strict mode.
# We use an implicit NULL so schema.rb is compatible with other databases.
def test_mysql_integer_not_null_defaults
@@ -77,24 +108,4 @@ class DefaultTest < ActiveRecord::TestCase
klass.connection.drop_table(klass.table_name) rescue nil
end
end
-
- if current_adapter?(:PostgreSQLAdapter, :FirebirdAdapter, :OpenBaseAdapter, :OracleAdapter)
- def test_default_integers
- default = Default.new
- assert_instance_of Fixnum, default.positive_integer
- assert_equal 1, default.positive_integer
- assert_instance_of Fixnum, default.negative_integer
- assert_equal -1, default.negative_integer
- assert_instance_of BigDecimal, default.decimal_number
- assert_equal BigDecimal.new("2.78"), default.decimal_number
- end
- end
-
- if current_adapter?(:PostgreSQLAdapter)
- def test_multiline_default_text
- # older postgres versions represent the default with escapes ("\\012" for a newline)
- assert ( "--- []\n\n" == Default.columns_hash['multiline_default'].default ||
- "--- []\\012\\012" == Default.columns_hash['multiline_default'].default)
- end
- end
end
diff --git a/activerecord/test/cases/dirty_test.rb b/activerecord/test/cases/dirty_test.rb
index 10cdbdc622..1c9e281cc0 100644
--- a/activerecord/test/cases/dirty_test.rb
+++ b/activerecord/test/cases/dirty_test.rb
@@ -21,6 +21,10 @@ private
end
end
+class NumericData < ActiveRecord::Base
+ self.table_name = 'numeric_data'
+end
+
class DirtyTest < ActiveRecord::TestCase
def test_attribute_changes
# New record - no changes.
@@ -58,7 +62,7 @@ class DirtyTest < ActiveRecord::TestCase
assert_equal parrot.name_change, parrot.title_change
end
- def test_nullable_integer_not_marked_as_changed_if_new_value_is_blank
+ def test_nullable_number_not_marked_as_changed_if_new_value_is_blank
pirate = Pirate.new
["", nil].each do |value|
@@ -68,6 +72,26 @@ class DirtyTest < ActiveRecord::TestCase
end
end
+ def test_nullable_decimal_not_marked_as_changed_if_new_value_is_blank
+ numeric_data = NumericData.new
+
+ ["", nil].each do |value|
+ numeric_data.bank_balance = value
+ assert !numeric_data.bank_balance_changed?
+ assert_nil numeric_data.bank_balance_change
+ end
+ end
+
+ def test_nullable_float_not_marked_as_changed_if_new_value_is_blank
+ numeric_data = NumericData.new
+
+ ["", nil].each do |value|
+ numeric_data.temperature = value
+ assert !numeric_data.temperature_changed?
+ assert_nil numeric_data.temperature_change
+ end
+ end
+
def test_nullable_integer_zero_to_string_zero_not_marked_as_changed
pirate = Pirate.new
pirate.parrot_id = 0
diff --git a/activerecord/test/cases/helper.rb b/activerecord/test/cases/helper.rb
index 2043138ca3..24ce35e2e2 100644
--- a/activerecord/test/cases/helper.rb
+++ b/activerecord/test/cases/helper.rb
@@ -34,7 +34,7 @@ rescue LoadError
end
ActiveRecord::Base.connection.class.class_eval do
- IGNORED_SQL = [/^PRAGMA/, /^SELECT currval/, /^SELECT CAST/, /^SELECT @@IDENTITY/, /^SELECT @@ROWCOUNT/]
+ IGNORED_SQL = [/^PRAGMA/, /^SELECT currval/, /^SELECT CAST/, /^SELECT @@IDENTITY/, /^SELECT @@ROWCOUNT/, /^SAVEPOINT/, /^ROLLBACK TO SAVEPOINT/, /^RELEASE SAVEPOINT/, /SHOW FIELDS/]
def execute_with_query_record(sql, name = nil, &block)
$queries_executed ||= []
diff --git a/activerecord/test/cases/json_serialization_test.rb b/activerecord/test/cases/json_serialization_test.rb
index 3446e5e7f0..975acde096 100644
--- a/activerecord/test/cases/json_serialization_test.rb
+++ b/activerecord/test/cases/json_serialization_test.rb
@@ -200,6 +200,6 @@ class DatabaseConnectedJsonEncodingTest < ActiveRecord::TestCase
2 => @mary
}
- assert_equal %({1: {"name": "David"}}), authors_hash.to_json(:only => [1, :name])
+ assert_equal %({"1": {"name": "David"}}), authors_hash.to_json(:only => [1, :name])
end
end
diff --git a/activerecord/test/cases/named_scope_test.rb b/activerecord/test/cases/named_scope_test.rb
index 64e899780c..bab842cf66 100644
--- a/activerecord/test/cases/named_scope_test.rb
+++ b/activerecord/test/cases/named_scope_test.rb
@@ -254,7 +254,7 @@ class NamedScopeTest < ActiveRecord::TestCase
end
def test_should_use_where_in_query_for_named_scope
- assert_equal Developer.find_all_by_name('Jamis'), Developer.find_all_by_id(Developer.jamises)
+ assert_equal Developer.find_all_by_name('Jamis').to_set, Developer.find_all_by_id(Developer.jamises).to_set
end
def test_size_should_use_count_when_results_are_not_loaded
@@ -278,3 +278,23 @@ class NamedScopeTest < ActiveRecord::TestCase
assert_equal post.comments.size, Post.scoped(:joins => join).scoped(:joins => join, :conditions => "posts.id = #{post.id}").size
end
end
+
+class DynamicScopeMatchTest < ActiveRecord::TestCase
+ def test_scoped_by_no_match
+ assert_nil ActiveRecord::DynamicScopeMatch.match("not_scoped_at_all")
+ end
+
+ def test_scoped_by
+ match = ActiveRecord::DynamicScopeMatch.match("scoped_by_age_and_sex_and_location")
+ assert_not_nil match
+ assert match.scope?
+ assert_equal %w(age sex location), match.attribute_names
+ end
+end
+
+class DynamicScopeTest < ActiveRecord::TestCase
+ def test_dynamic_scope
+ assert_equal Post.scoped_by_author_id(1).find(1), Post.find(1)
+ assert_equal Post.scoped_by_author_id_and_title(1, "Welcome to the weblog").first, Post.find(:first, :conditions => { :author_id => 1, :title => "Welcome to the weblog"})
+ end
+end
diff --git a/activerecord/test/cases/transactions_test.rb b/activerecord/test/cases/transactions_test.rb
index b12ec36455..4a07a8bb1d 100644
--- a/activerecord/test/cases/transactions_test.rb
+++ b/activerecord/test/cases/transactions_test.rb
@@ -213,11 +213,104 @@ class TransactionTest < ActiveRecord::TestCase
assert Topic.find(2).approved?, "Second should still be approved"
end
+ def test_invalid_keys_for_transaction
+ assert_raises 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?
+
uses_mocha 'mocking connection.commit_db_transaction' do
def test_rollback_when_commit_raises
Topic.connection.expects(:begin_db_transaction)
- Topic.connection.expects(:transaction_active?).returns(true) if current_adapter?(:PostgreSQLAdapter)
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
@@ -227,6 +320,38 @@ class TransactionTest < ActiveRecord::TestCase
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
+
+ uses_mocha 'mocking connection.rollback_db_transaction' do
+ 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
+ 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_raises_statement_invalid
return true unless current_adapter?(:SQLite3Adapter, :SQLiteAdapter)
@@ -282,6 +407,45 @@ class TransactionTest < ActiveRecord::TestCase
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